<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>冬日の草原</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="https://blog.amito.cc/"/>
  <updated>2022-04-16T14:26:24.372Z</updated>
  <id>https://blog.amito.cc/</id>
  
  <author>
    <name>Yujiang Bi</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Deploy And Manage Drupal with Composer Under Rocky 8</title>
    <link href="https://blog.amito.cc/2022/03/Deploy-And-Manage-Drupal-with-Composer-Under-Rocky-8/"/>
    <id>https://blog.amito.cc/2022/03/Deploy-And-Manage-Drupal-with-Composer-Under-Rocky-8/</id>
    <published>2022-03-31T06:44:26.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Drupal is a general used CMS framework all over the world, and <a href="https://getcomposer.org/download">Composer</a> is one of the best PHP package manager. It’s very easy to deploy a drupal site with composer.</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="Prerequisites">Prerequisites</h2><p>Drupal now (&gt;=9.0) requires:</p><ul><li>PHP &gt;= 7.2</li><li>SQL<ul><li>PostgreSQL</li><li>MySQL</li></ul></li><li>Nginx</li></ul><h3 id="Nginx">Nginx</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo dnf module install -y nginx:1.20</span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now nginx</span><br></pre></td></tr></tbody></table></figure><h3 id="PostgreSQL-13">PostgreSQL 13</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo dnf module install postgresql:13</span><br></pre></td></tr></tbody></table></figure><h3 id="PHP-7-4">PHP 7.4</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo dnf module install php:7.4 -y</span><br><span class="line">$ sudo sed -i -e <span class="string">"s|^user = apache|user = nginx|g"</span> -e <span class="string">"s|^group = apache|group = nginx|g"</span> /etc/php-fpm.d/www.conf</span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now php-fpm.service</span><br></pre></td></tr></tbody></table></figure><h3 id="Composer">Composer</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ php -r <span class="string">"copy('https://getcomposer.org/installer', 'composer-setup.php');"</span></span><br><span class="line">$ php -r <span class="string">"if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"</span></span><br><span class="line">$ php composer-setup.php</span><br><span class="line">$ php -r <span class="string">"unlink('composer-setup.php');"</span></span><br><span class="line">$ sudo mv composer.phar /usr/bin/composer</span><br></pre></td></tr></tbody></table></figure><p>Or just:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo wget https://getcomposer.org/download/latest-stable/composer.phar -O /usr/bin/composer</span><br><span class="line">$ sudo chmod +x /usr/bin/composer</span><br></pre></td></tr></tbody></table></figure><h3 id="Drupal">Drupal</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#### Install drupal</span></span><br><span class="line">$ <span class="built_in">cd</span> /path/to/web/</span><br><span class="line">$ composer create-project drupal/recommended-project my-project</span><br><span class="line">$ <span class="built_in">cd</span> my-project</span><br><span class="line"><span class="comment">#### install drush</span></span><br><span class="line">$ composer require drush/drush</span><br></pre></td></tr></tbody></table></figure><h3 id="Selinux">Selinux</h3><p>Disable Selinux for convenience.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo setenforce 0</span><br><span class="line">$ sudo sed -i <span class="string">"s|SELINUX=enforcing|SELINUX=disabled|g"</span> /etc/selinux/config</span><br></pre></td></tr></tbody></table></figure><p>Or</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#### For nginx</span></span><br><span class="line">$ sudo semanage permissive -a httpd_t</span><br><span class="line"><span class="comment"># or</span></span><br><span class="line">$ sudo setsebool -P httpd_can_network_connect 1</span><br><span class="line"><span class="comment">#</span></span><br><span class="line">$ chcon -R -t httpd_sys_content_t /path/to/drupal/site</span><br><span class="line"><span class="comment">#### For php-fpm</span></span><br></pre></td></tr></tbody></table></figure><h2 id="Deploy-Drupal">Deploy Drupal</h2><h3 id="Nginx-Config">Nginx Config</h3><p>A typical nginx config:</p><figure class="highlight nginx"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#### ssl</span></span><br><span class="line"><span class="attribute">server_tokens</span> <span class="literal">off</span>;</span><br><span class="line"><span class="comment"># </span></span><br><span class="line"><span class="attribute">add_header</span> X-Frame-Options SAMEORIGIN;</span><br><span class="line"><span class="attribute">add_header</span> X-Content-Type-Options nosniff;</span><br><span class="line"><span class="attribute">add_header</span> X-XSS-Protection <span class="string">"1;mode=block"</span>;</span><br><span class="line"><span class="attribute">add_header</span> Content-Security-Policy <span class="string">"default-src *; style-src static.addtoany.com self 'unsafe-inline' 'unsafe-eval'; script-src static.addtoany.com self 'unsafe-inline' 'unsafe-eval'; img-src 'self' 'unsafe-inline'; script-src-elem 'static.addtoany.com' 'self' 'unsafe-inline' 'unsafe-eval';"</span>;</span><br><span class="line"><span class="comment">#add_header Content-Security-Policy "default-src *; style-src static.addtoany.com self unsafe-inline unsafe-eval; script-src static.addtoany.com self unsafe-inline unsafe-eval; img-src self unsafe-inline; script-src-elem static.addtoany.com self unsafe-inline unsafe-eval;";</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ssl config</span></span><br><span class="line"></span><br><span class="line"><span class="attribute">ssl_certificate</span>                 /etc/nginx/ssl/ssl.crt;</span><br><span class="line"><span class="attribute">ssl_certificate_key</span>             /etc/nginx/ssl/ssl.key;</span><br><span class="line"></span><br><span class="line"><span class="attribute">ssl_session_cache</span> shared:SSL:<span class="number">10m</span>;</span><br><span class="line"><span class="attribute">ssl_session_timeout</span> <span class="number">5m</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">#perfect Forward Security</span></span><br><span class="line"><span class="attribute">ssl_protocols</span> TLSv1 TLSv1.<span class="number">1</span> TLSv1.<span class="number">2</span>;</span><br><span class="line"><span class="attribute">ssl_prefer_server_ciphers</span> <span class="literal">on</span>;</span><br><span class="line"><span class="attribute">add_header</span> Strict-Transport-Security max-age=<span class="number">2592000</span>;</span><br><span class="line"></span><br><span class="line"><span class="attribute">ssl_ciphers</span>  ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;</span><br><span class="line"></span><br><span class="line"><span class="attribute">fastcgi_max_temp_file_size</span> <span class="number">0</span>;</span><br><span class="line"><span class="attribute">fastcgi_buffers</span> <span class="number">16</span> <span class="number">16k</span>;</span><br><span class="line"><span class="attribute">fastcgi_buffer_size</span> <span class="number">32k</span>;</span><br><span class="line"></span><br><span class="line"><span class="attribute">fastcgi_read_timeout</span> <span class="number">600</span>;</span><br><span class="line"><span class="attribute">fastcgi_send_timeout</span> <span class="number">600</span>;</span><br><span class="line"><span class="attribute">map_hash_max_size</span> <span class="number">64</span>;</span><br><span class="line"><span class="attribute">map_hash_bucket_size</span> <span class="number">64</span>;</span><br><span class="line"></span><br><span class="line"><span class="section">server</span> {</span><br><span class="line">    <span class="attribute">listen</span>       <span class="number">80</span>;</span><br><span class="line">    <span class="attribute">listen</span>       [::]:<span class="number">80</span>;</span><br><span class="line">    <span class="attribute">listen</span>       <span class="number">443</span> default_server ssl;</span><br><span class="line">    <span class="attribute">listen</span>       [::]:<span class="number">443</span> default_server ssl;</span><br><span class="line">    <span class="attribute">if</span> ($scheme = http){</span><br><span class="line">        <span class="attribute">return</span> <span class="number">301</span> https://$server_name$request_uri;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment">#server_name  my-site-ltd;</span></span><br><span class="line">    <span class="attribute">root</span> /path/to/drupal/site;</span><br><span class="line"></span><br><span class="line">    <span class="attribute">location</span> = /favicon.ico {</span><br><span class="line">        <span class="attribute">log_not_found</span> <span class="literal">off</span>;</span><br><span class="line">        <span class="attribute">access_log</span> <span class="literal">off</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="attribute">location</span> = /robots.txt {</span><br><span class="line">        <span class="attribute">allow</span> all;</span><br><span class="line">        <span class="attribute">log_not_found</span> <span class="literal">off</span>;</span><br><span class="line">        <span class="attribute">access_log</span> <span class="literal">off</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Very rarely should these ever be accessed outside of your lan</span></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~* \.(txt|log)$</span> {</span><br><span class="line">        <span class="attribute">allow</span> <span class="number">192.168.0.0</span>/<span class="number">16</span>;</span><br><span class="line">        <span class="attribute">deny</span> all;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~ \..*/.*\.php$</span> {</span><br><span class="line">        <span class="attribute">return</span> <span class="number">403</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~ ^/sites/.*/private/</span> {</span><br><span class="line">        <span class="attribute">return</span> <span class="number">403</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Block access to scripts in site files directory</span></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~ ^/sites/[^/]+/files/.*\.php$</span> {</span><br><span class="line">        <span class="attribute">deny</span> all;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Allow "Well-Known URIs" as per RFC 5785</span></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~* ^/.well-known/</span> {</span><br><span class="line">        <span class="attribute">allow</span> all;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Block access to "hidden" files and directories whose names begin with a</span></span><br><span class="line">    <span class="comment"># period. This includes directories used by version control systems such</span></span><br><span class="line">    <span class="comment"># as Subversion or Git to store control files.</span></span><br><span class="line"><span class="comment">#    location ~ (^|/)\. {</span></span><br><span class="line"><span class="comment">#        return 403;</span></span><br><span class="line"><span class="comment">#    }</span></span><br><span class="line"></span><br><span class="line">    <span class="attribute">location</span> / {</span><br><span class="line">        <span class="attribute">try_files</span> $uri /index.php?$query_string; <span class="comment"># For Drupal &gt;= 7</span></span><br><span class="line">    }</span><br><span class="line">    <span class="attribute">rewrite</span><span class="regexp"> ^/core/authorize.php/core/authorize.php(.*)$</span> /core/authorize.php<span class="variable">$1</span>;</span><br><span class="line">    <span class="attribute">location</span> @rewrite {</span><br><span class="line">        <span class="comment">#rewrite ^/(.*)$ /index.php?q=$1; # For Drupal &lt;= 6</span></span><br><span class="line">        <span class="attribute">rewrite</span><span class="regexp"> ^</span> /index.php; <span class="comment"># For Drupal &gt;= 7</span></span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Don't allow direct access to PHP files in the vendor directory.</span></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~ /vendor/.*\.php$</span> {</span><br><span class="line">        <span class="attribute">deny</span> all;</span><br><span class="line">        <span class="attribute">return</span> <span class="number">404</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Protect files and directories from prying eyes.</span></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~* \.(engine|inc|install|make|module|profile|po|sh|.*sql|theme|twig|tpl(\.php)?|xtmpl|yml)(~|\.sw[op]|\.bak|\.orig|\.save)?$|^(\.(?!well-known).*|Entries.*|Repository|Root|Tag|Template|composer\.(json|lock)|web\.config)$|^#.*#$|\.php(~|\.sw[op]|\.bak|\.orig|\.save)$</span> {</span><br><span class="line">        <span class="attribute">deny</span> all;</span><br><span class="line">        <span class="attribute">return</span> <span class="number">404</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment"># In Drupal 8, we must also match new paths where the '.php' appears in</span></span><br><span class="line">    <span class="comment"># the middle, such as update.php/selection. The rule we use is strict,</span></span><br><span class="line">    <span class="comment"># and only allows this pattern with the update.php front controller.</span></span><br><span class="line">    <span class="comment"># This allows legacy path aliases in the form of</span></span><br><span class="line">    <span class="comment"># blog/index.php/legacy-path to continue to route to Drupal nodes. If</span></span><br><span class="line">    <span class="comment"># you do not have any paths like that, then you might prefer to use a</span></span><br><span class="line">    <span class="comment"># laxer rule, such as:</span></span><br><span class="line">    <span class="comment">#   location ~ \.php(/|$) {</span></span><br><span class="line">    <span class="comment"># The laxer rule will continue to work if Drupal uses this new URL</span></span><br><span class="line">    <span class="comment"># pattern with front controllers other than update.php in a future</span></span><br><span class="line">    <span class="comment"># release.</span></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~ '\.php$|^/update.php'</span> {</span><br><span class="line">        <span class="attribute">fastcgi_split_path_info</span><span class="regexp"> ^(.+?\.php)(|/.*)$</span>;</span><br><span class="line">        <span class="comment"># Ensure the php file exists. Mitigates CVE-2019-11043</span></span><br><span class="line">        <span class="attribute">try_files</span> $fastcgi_script_name =<span class="number">404</span>;</span><br><span class="line">        <span class="comment"># Security note: If you're running a version of PHP older than the</span></span><br><span class="line">        <span class="comment"># latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.</span></span><br><span class="line">        <span class="comment"># See http://serverfault.com/q/627903/94922 for details.</span></span><br><span class="line">        <span class="attribute">include</span> fastcgi_params;</span><br><span class="line">        <span class="comment"># Block httpoxy attacks. See https://httpoxy.org/.</span></span><br><span class="line">        <span class="attribute">fastcgi_param</span> HTTP_PROXY <span class="string">""</span>;</span><br><span class="line">        <span class="attribute">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;</span><br><span class="line">        <span class="attribute">fastcgi_param</span> PATH_INFO $fastcgi_path_info;</span><br><span class="line">        <span class="attribute">fastcgi_param</span> QUERY_STRING $query_string;</span><br><span class="line">        <span class="attribute">fastcgi_intercept_errors</span> <span class="literal">on</span>;</span><br><span class="line">        <span class="comment"># PHP 5 socket location.</span></span><br><span class="line">        <span class="comment">#fastcgi_pass unix:/var/run/php5-fpm.sock;</span></span><br><span class="line">        <span class="comment"># PHP 7 socket location.</span></span><br><span class="line">        <span class="attribute">fastcgi_pass</span>  <span class="number">127.0.0.1:9000</span>;</span><br><span class="line"><span class="comment">#        fastcgi_pass unix:/var/run/php-fpm/www.sock;</span></span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line"><span class="comment">#    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {</span></span><br><span class="line"><span class="comment">#        try_files $uri @rewrite;</span></span><br><span class="line"><span class="comment">#        expires max;</span></span><br><span class="line"><span class="comment">#        log_not_found off;</span></span><br><span class="line"><span class="comment">#    }</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># Fighting with Styles? This little gem is amazing.</span></span><br><span class="line">    <span class="comment"># location ~ ^/sites/.*/files/imagecache/ { # For Drupal &lt;= 6</span></span><br><span class="line"><span class="comment">#    location ~ ^/sites/.*/files/styles/ { # For Drupal &gt;= 7</span></span><br><span class="line"><span class="comment">#        try_files $uri @rewrite;</span></span><br><span class="line"><span class="comment">#    }</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># Handle private files through Drupal. Private file's path can come</span></span><br><span class="line">    <span class="comment"># with a language prefix.</span></span><br><span class="line">    <span class="attribute">location</span> <span class="regexp">~ ^(/[a-z\-]+)?/system/files/</span> { <span class="comment"># For Drupal &gt;= 7</span></span><br><span class="line">        <span class="attribute">try_files</span> $uri /index.php?$query_string;</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="PostgreSQL-Config">PostgreSQL Config</h3><p>Run via docker</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run -dit --name postgres --restart always -e POSTGRES_PASSWORD=mysecretpassword -e POSTGRES_USER=drupal -e POSTGRES_DB=drupal -e PGDATA=/var/lib/postgresql/data/ -e TZ=Asia/Shanghai -v /custom/mount:/var/lib/postgresql/data -p 5432:5432 postgres:13</span><br></pre></td></tr></tbody></table></figure><h3 id="Drupal-Config">Drupal Config</h3><h3 id="Drupal-Update">Drupal Update</h3><ol><li>Put drupal into maintainence mode</li><li>Update drupal via composer</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">cd</span> /path/to/drupal/site</span><br><span class="line"><span class="comment">#### To check if any update for drupal/core or drupal/core-recommended</span></span><br><span class="line">$ composer outdated <span class="string">"drupal/*"</span></span><br><span class="line"><span class="comment">#### Update drupal/core-recommended</span></span><br><span class="line">$ composer show drupal/core-recommended</span><br><span class="line">$ composer update drupal/core <span class="string">"drupal/core-*"</span> --with-all-dependencies</span><br><span class="line"><span class="comment">#### Update drupal/core</span></span><br><span class="line">$ composer update drupal/core --with-dependencies</span><br><span class="line"><span class="comment">#### Update database via drush</span></span><br><span class="line">$ drush updatedb</span><br><span class="line">$ drush cache:rebuild</span><br></pre></td></tr></tbody></table></figure><hr><p>To be continued…</p><hr><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Drupal is a general used CMS framework all over the world, and &lt;a href=&quot;https://getcomposer.org/download&quot;&gt;Composer&lt;/a&gt; is one of the best PHP package manager. It’s very easy to deploy a drupal site with composer.&lt;/p&gt;
    
    </summary>
    
      <category term="Web" scheme="https://blog.amito.cc/categories/Web/"/>
    
    
      <category term="Drupal" scheme="https://blog.amito.cc/tags/Drupal/"/>
    
      <category term="Composer" scheme="https://blog.amito.cc/tags/Composer/"/>
    
      <category term="PHP" scheme="https://blog.amito.cc/tags/PHP/"/>
    
  </entry>
  
  <entry>
    <title>在远程服务器上挂载 Ceph RBD 块设备</title>
    <link href="https://blog.amito.cc/2020/04/Map-and-Mount-Ceph-RBD-on-Remote-Servers/"/>
    <id>https://blog.amito.cc/2020/04/Map-and-Mount-Ceph-RBD-on-Remote-Servers/</id>
    <published>2020-04-03T07:09:59.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Ceph 存储一个重要的使用场景就是其块设备，本文将会介绍一下如何挂载 Ceph RBD 到远程服务器上。从安全角度考虑，一般不建议这样做。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="准备工作-4">准备工作</h2><p>Ceph 安装 repo:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">[ceph]</span><br><span class="line">name=Ceph packages <span class="keyword">for</span> <span class="variable">$basearch</span></span><br><span class="line">baseurl=https://download.ceph.com/rpm-mimic/el7/<span class="variable">$basearch</span></span><br><span class="line">enabled=1</span><br><span class="line">priority=2</span><br><span class="line">gpgcheck=1</span><br><span class="line">gpgkey=https://download.ceph.com/keys/release.asc</span><br><span class="line"></span><br><span class="line">[ceph-noarch]</span><br><span class="line">name=Ceph noarch packages</span><br><span class="line">baseurl=https://download.ceph.com/rpm-mimic/el7/noarch</span><br><span class="line">enabled=1</span><br><span class="line">priority=2</span><br><span class="line">gpgcheck=1</span><br><span class="line">gpgkey=https://download.ceph.com/keys/release.asc</span><br><span class="line"></span><br><span class="line">[ceph-source]</span><br><span class="line">name=Ceph <span class="built_in">source</span> packages</span><br><span class="line">baseurl=https://download.ceph.com/rpm-mimic/el7/SRPMS</span><br><span class="line">enabled=0</span><br><span class="line">priority=2</span><br><span class="line">gpgcheck=1</span><br><span class="line">gpgkey=https://download.ceph.com/keys/release.asc</span><br></pre></td></tr></tbody></table></figure><p>安装 Ceph 和 RBD 客户端:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install -y ceph-common python-rbd</span><br></pre></td></tr></tbody></table></figure><h2 id="远程服务器挂载">远程服务器挂载</h2><h3 id="创建-RBD">创建 RBD</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ rbd create --pool volulmes --size 50G lintao_test</span><br></pre></td></tr></tbody></table></figure><h3 id="Ceph-配置">Ceph 配置</h3><p><code>/etc/ceph/ceph.conf</code>:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">[global]</span><br><span class="line">fsid = 1da65d0e-4284-41e0-868e-8c25b89648fc</span><br><span class="line">mon_initial_members = ceph01, ceph02, ceph03</span><br><span class="line">mon_host = 192.168.15.38,192.168.15.39,192.168.15.40</span><br><span class="line">auth_cluster_required = cephx</span><br><span class="line">auth_service_required = cephx</span><br><span class="line">auth_client_required = cephx</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">[mon]</span><br><span class="line">mgr initial modules = dashboard</span><br><span class="line"></span><br><span class="line">[client.cinder]</span><br><span class="line">keyring = /etc/ceph/ceph.client.cinder.keyring</span><br></pre></td></tr></tbody></table></figure><p>远程客户端使用 key: <code>/etc/ceph/ceph.client.rbd.keyring</code>:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[client.rbd]</span><br><span class="line">key = AQBooSldwwbkAhAAtxRH0lHGfnUautW2rF6pkQ==</span><br></pre></td></tr></tbody></table></figure><h3 id="Ceph-RBD-Map">Ceph RBD Map</h3><ol><li>map rbd</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo rbd map volumes/lintao_test --id cinder</span><br><span class="line">/dev/rbd0</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>if unmap rbd</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo rbd unmap volumes/lintao_test --id cinder</span><br></pre></td></tr></tbody></table></figure><h3 id="格式化与挂载">格式化与挂载</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ sudo fdisk /dev/rbd/volumes/lintao_test</span><br><span class="line">...</span><br><span class="line">$ sudo mkfs.ext4 /dev/rbd/volumes/lintao_test-part1</span><br><span class="line">...</span><br><span class="line">$ sudo mkdir /data </span><br><span class="line">$ sudo mount /dev/rbd/volumes/lintao_test-part1 /data</span><br></pre></td></tr></tbody></table></figure><h3 id="自动挂载-3">自动挂载</h3><ol><li><code>/etc/ceph/rbdmap</code></li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">volumes/lintao_test id=cinder,keyring=/etc/ceph/ceph.client.keyring</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>enable rbdmap service</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now rbdmap</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li><code>/etc/fstab</code></li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo blkid /dev/rbd/volumes/lintao_test-part1</span><br><span class="line"><span class="comment">### /etc/fstab</span></span><br><span class="line">UUID=0a9d74d8-8f37-4a80-ac70-28c292e79784    /data    ext4 defaults 0 0</span><br></pre></td></tr></tbody></table></figure><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Ceph 存储一个重要的使用场景就是其块设备，本文将会介绍一下如何挂载 Ceph RBD 到远程服务器上。从安全角度考虑，一般不建议这样做。&lt;/p&gt;
    
    </summary>
    
      <category term="Ceph" scheme="https://blog.amito.cc/categories/Ceph/"/>
    
    
      <category term="Ceph" scheme="https://blog.amito.cc/tags/Ceph/"/>
    
      <category term="RBD" scheme="https://blog.amito.cc/tags/RBD/"/>
    
  </entry>
  
  <entry>
    <title>Install And Configure Docker under CentOS 8</title>
    <link href="https://blog.amito.cc/2020/03/Install-And-Configure-Docker-under-CentOS-8/"/>
    <id>https://blog.amito.cc/2020/03/Install-And-Configure-Docker-under-CentOS-8/</id>
    <published>2020-03-05T16:10:50.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>红帽已经在 CentOS 8 中用 Podman 替代了 Docker， 它是与 Docker 类似的容器技术，使用命令都十分相似， 但对于熟悉 Docker 及配置的管理人员，他们可能会倾向于使用 Docker。 本文会简单介绍如何在 CentOS 8 下安装、配置 Docker。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc -->## 安装 Docker### 准备工作1. 卸载旧版本的 Docker.<figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo dnf remove docker-common docker  container-selinux docker-selinux docker-engine</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>添加 Docker 安装源</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo curl  https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>安装最新版的 <code>Containerd</code>. 你可能需要主动查看最新版本，目前 (06/03/2020) 是 <code>1.2.6-3.3</code>.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo dnf install -y https://download.docker.com/linux/centos/7/x86_64/stable/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>安装 Docker CE</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo dnf install -y docker-ce</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>启用 Docker 服务</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now docker</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>为非 Root 用户添加运行 Docker 的权限</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo groupadd docker</span><br><span class="line">$ sudo useradd -m -d /home/<span class="built_in">test</span> -U -r <span class="built_in">test</span></span><br><span class="line">$ sudo usermoad -aG docker <span class="built_in">test</span></span><br></pre></td></tr></tbody></table></figure><ol start="7"><li>验证 Docker 是否正确安装</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker run busybox ping -c 5 google.com</span><br></pre></td></tr></tbody></table></figure><p>不出意外， docker  ping  是不通的。 我们安装的 Docker 是有问题的， 防火墙并没有正确配置。</p><h2 id="配置系统防火墙">配置系统防火墙</h2><h3 id="0-开启-IP-转发">0. 开启 IP 转发</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">echo</span> <span class="string">"net.ipv4.ip_forward = 1"</span> | sudo tee /etc/sysctl.conf</span><br><span class="line">$ sudo sysctl -p</span><br></pre></td></tr></tbody></table></figure><h3 id="1-关闭防火墙">1. 关闭防火墙</h3><p>One easily way that makes docker access the network is stop the firewall. CentOS 8 using firewalld with <code>nftables</code> to protect the system.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo systemctl <span class="built_in">disable</span> --now firewalld</span><br><span class="line">$ sudo systemctl mask --now firewalld</span><br></pre></td></tr></tbody></table></figure><p>But this will expose our server to security attacks. So, we need configure the firewalld to granting docker the network access.</p><h3 id="2-配置防火墙">2. 配置防火墙</h3><ol><li>检查活动的 <code>zone</code> 和 <code>docker0</code> 所在的 <code>zone</code></li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo firewall-cmd --get-active-zones</span><br><span class="line">$ sudo firewall-cmd --get-zone-of-interface=docker0</span><br></pre></td></tr></tbody></table></figure><p>我们发现 Docker 的 <code>docker0</code> 没有在任何 <code>zone</code> 中, 我们需要将其加到某一个 <code>zone</code> 如 <code>public</code> 中</p><ol><li>添加 <code>docker0</code> 到 <code>public</code> zone.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ firewall-cmd --permanent --zone=public --change-interface=docker0</span><br><span class="line"><span class="comment">#or</span></span><br><span class="line">$ firewall-cmd --permanent --zone=public --add-interface=docker0</span><br><span class="line"><span class="comment">#or</span></span><br><span class="line">$ nmcli connection modify docker0 connection.zone public</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>为 <code>docker0</code> 配置 iptables 规则.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 4 -i docker0 -j ACCEPT</span><br><span class="line">$ firewall-cmd --permanent --direct --add-rule ipv6 filter INPUT 6 -i docker0 -j ACCEPT</span><br><span class="line">$ firewall-cmd --zone=public --add-masquerade --permanent</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>打开所需要的端口.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">## dns</span></span><br><span class="line">$ firewall-cmd --zone=public --add-port=53/tcp</span><br><span class="line"><span class="comment">## http</span></span><br><span class="line">$ firewall-cmd --zone=public --add-port=80/tcp</span><br><span class="line"><span class="comment">## https</span></span><br><span class="line">$ firewall-cmd --zone=public --add-port=443/tcp</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>重新载入防火墙规则，重启 Docker 服务.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo firewall-cmd --reload</span><br><span class="line">$ sudo systemctl restart docker</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>验证 Docker 是否能连接网络</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$ docker run busybox ping -c 5 google.com</span><br><span class="line">PING google.com (172.217.11.46): 56 data bytes</span><br><span class="line">64 bytes from 172.217.11.46: seq=0 ttl=55 time=10.850 ms</span><br><span class="line">64 bytes from 172.217.11.46: seq=1 ttl=55 time=1.786 ms</span><br><span class="line">64 bytes from 172.217.11.46: seq=2 ttl=55 time=1.759 ms</span><br><span class="line">64 bytes from 172.217.11.46: seq=3 ttl=55 time=1.978 ms</span><br><span class="line">64 bytes from 172.217.11.46: seq=4 ttl=55 time=1.797 ms</span><br><span class="line"></span><br><span class="line">--- google.com ping statistics ---</span><br><span class="line">5 packets transmitted, 5 packets received, 0% packet loss</span><br><span class="line">round-trip min/avg/max = 1.759/3.634/10.850 ms</span><br></pre></td></tr></tbody></table></figure><p>可以看到，现在 Docker  已经能够访问网络了。</p><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;红帽已经在 CentOS 8 中用 Podman 替代了 Docker， 它是与 Docker 类似的容器技术，使用命令都十分相似， 但对于熟悉 Docker 及配置的管理人员，他们可能会倾向于使用 Docker。 本文会简单介绍如何在 CentOS 8 下安装、配置 Docker。&lt;/p&gt;
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>XCache 的配置、测试与优化</title>
    <link href="https://blog.amito.cc/2020/01/XCache-Config-Testing-And-Optimizing/"/>
    <id>https://blog.amito.cc/2020/01/XCache-Config-Testing-And-Optimizing/</id>
    <published>2020-01-04T02:51:47.000Z</published>
    <updated>2022-04-16T14:26:24.388Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>XRoodD is the common protocol generally used in high energy physics computing. XRootD proxy for file cache(XCache) is a typical way for XRootD.</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="XRootD-代理服务">XRootD 代理服务</h2><h3 id="XRootD-直接代理模式">XRootD 直接代理模式</h3><h3 id="XRootD-转发代理模式">XRootD 转发代理模式</h3><h3 id="XRootD-联合代理模式">XRootD 联合代理模式</h3><h3 id="XRootD-自动代理">XRootD 自动代理</h3><h2 id="XRootD-代理缓存服务">XRootD 代理缓存服务</h2><h3 id="XRootD-磁盘缓存模式">XRootD 磁盘缓存模式</h3><p>XRootD 自带了几个简单的文件缓存配置 - <code>xrootd-filecache-cluster.cf</code> 和 <code>xrootd-filecache-standalone.cfg</code>, 下面是一个磁盘缓存模式 <code>Disk Cache</code> 的配置文件:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">all.export /</span><br><span class="line"></span><br><span class="line">ofs.osslib libXrdPss.so</span><br><span class="line"></span><br><span class="line">xrootd.trace emsg login stall redirect</span><br><span class="line">xrd.trace info</span><br><span class="line">ofs.trace info</span><br><span class="line"></span><br><span class="line">pss.origin = some_server:1094</span><br><span class="line"></span><br><span class="line"><span class="comment">### 包含 Disk Cache Proxy 插件的共享库。</span></span><br><span class="line">pss.cachelib  libXrdFileCache.so</span><br><span class="line"></span><br><span class="line"><span class="comment">### 用来缓存需要写到磁盘上的代理缓冲的最大允许 RAM。超过这个值，代理会将请求发送到远程服务器。</span></span><br><span class="line">pfc.ram   16g</span><br><span class="line"></span><br><span class="line">pss.setopt DebugLevel 0</span><br><span class="line"></span><br><span class="line">oss.memfile max 80% check map preload</span><br><span class="line"></span><br><span class="line"><span class="comment">### 用来保存缓存文件的位置</span></span><br><span class="line">oss.localroot  /data</span><br><span class="line"></span><br><span class="line">pfc.trace  DebugLevel</span><br><span class="line">pfc.prefetch  8</span><br><span class="line"></span><br><span class="line">pfc.blocksize  512k</span><br><span class="line"></span><br><span class="line">ofs.ckslib * libXrdPss.so</span><br><span class="line"></span><br><span class="line">pfc.user xrootd</span><br></pre></td></tr></tbody></table></figure><h3 id="XRootD-内存缓存模式">XRootD 内存缓存模式</h3><p>与 <code>Disk Cache</code> 模式不同的是，XRootD 内存缓存模式 <code>Memory Cache</code> 是将最近访问过的文件缓存在内存中，所以要求作为服务器的内存要足够大。 XRootD <code>Disk Cache</code>  与  <code>Memory Cache</code> 是不能共存的。 XRootD Memory Cache 与标准的 XRoot Proxy 服务 相比，只多了一个 <code>pss.cahce</code> 语句。 下面是一个 Memory Cahce 的配置文件。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">all.export /</span><br><span class="line"></span><br><span class="line">ofs.osslib libXrdPss.so</span><br><span class="line"></span><br><span class="line">xrootd.trace emsg login stall redirect</span><br><span class="line">xrd.trace info</span><br><span class="line">ofs.trace info</span><br><span class="line"></span><br><span class="line">pss.origin = some_server:1094</span><br><span class="line">pss.cache logstats max2cache 16g sfiles on r preread</span><br><span class="line">pss.setopt DebugLevel 0</span><br></pre></td></tr></tbody></table></figure><h2 id="XCache-测试">XCache 测试</h2><h2 id="参考-7">参考</h2><ol><li><a href="http://xrootd.org/doc/dev47/pss_config.htm">Proxy Storage Services (Caching, Non-Caching, &amp; Server-less Caching) Configuration Reference</a></li><li><a href="https://doi.org/10.1088/1742-6596/513/4/042044">XRootd, disk-based, caching proxy for optimization of data access, data placement and data replication</a></li><li><a href="https://twiki.cern.ch/twiki/bin/view/AtlasComputing/Tier3gXrootdSetup">Installing and configuring xrootd</a></li><li><a href="https://www.researchgate.net/publication/328387441_A_federated_Xrootd_cache">A fedorated Xrootd Cache</a></li><li><a href="https://opensciencegrid.org/StashCache/admin/install/">Stash Cache Installation</a></li><li><a href="https://indico.nikhef.nl/event/1318/session/1/contribution/10/material/slides/0.pdf">Distributed and on-demand cache for CMS experiment at LHC</a></li><li><a href="https://gitlab.ekp.kit.edu/ETP-HTC/XRootD-Caching-Setup/tree/master">XRootD-Caching-Setup</a></li><li><a href="https://indico.egi.eu/indico/event/3973/contribution/97">The adoption of the HTTP/XRootD protocols for a new data caching architecture in WLCG experiments</a></li><li><a href="http://digitalcommons.unl.edu/cgi/viewcontent.cgi?article=1003&amp;context=hollandfacpub">Distributed Caching Using the HTCondor CacheD</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;XRoodD is the common protocol generally used in high energy physics computing. XRootD proxy for file cache(XCache) is a typical way for XRootD.&lt;/p&gt;
    
    </summary>
    
      <category term="EOS" scheme="https://blog.amito.cc/categories/EOS/"/>
    
    
      <category term="EOS" scheme="https://blog.amito.cc/tags/EOS/"/>
    
      <category term="XRootD" scheme="https://blog.amito.cc/tags/XRootD/"/>
    
  </entry>
  
  <entry>
    <title>在 Beamer 中添加计时器和 Logo</title>
    <link href="https://blog.amito.cc/2019/04/Adding-Timer-and-Logo-in-Beamer/"/>
    <id>https://blog.amito.cc/2019/04/Adding-Timer-and-Logo-in-Beamer/</id>
    <published>2019-04-16T00:48:18.000Z</published>
    <updated>2022-04-16T14:26:24.368Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>在 PPT 中有一个演讲计时功能，能够帮助报告人掌握演讲时间。 其实 pdf 中也有这一功能，在 beamer 中添加计时器比较方便。 此外，在 beamer 标题中加上特定的 Logo 也是比较简单的。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="添加-timer-计时器">添加 timer 计时器</h2><p>LaTeX 中 <strong>tdclock</strong> 包可以提供定时功能。添加一个计时器也很简单。</p><ol><li><p>在导言区加入 <strong>tdclock</strong> 包。可以设置一次提醒，二次提醒时间，更新时间间隔等等。</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\usepackage</span>[timeinterval=2.0, timeduration=2.0, timedeath=0,</span><br><span class="line">fillcolorwarningsecond=white!60!yellow,timewarningfirst=900,timewarningsecond=1080]{tdclock}</span><br></pre></td></tr></tbody></table></figure></li><li><p><strong>\initclock</strong> 初始化。在适当的位置，如 titlepage 中加入这一命令。</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\begin</span>{frame}</span><br><span class="line"><span class="keyword">\titlepage</span></span><br><span class="line"><span class="keyword">\initclock</span></span><br><span class="line"><span class="keyword">\end</span>{frame}</span><br></pre></td></tr></tbody></table></figure></li><li><p>在要显示的地方加入 <strong>\crono</strong> 命令，比如在 footer 中。如果使用的三段式 footer 结构，可以在 footer 中显示时间，则可以这样做：</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\begin</span>{frame}</span><br><span class="line"><span class="keyword">\titlepage</span></span><br><span class="line"><span class="keyword">\initclock</span></span><br><span class="line"><span class="keyword">\end</span>{frame}</span><br><span class="line"><span class="keyword">\date</span>{<span class="keyword">\today</span> <span class="keyword">\crono</span>}</span><br></pre></td></tr></tbody></table></figure></li></ol><p>这样会显示日期和从 <strong>00:00:00</strong> 开始的计时器，如下图黑框所示。<br><img src="/images/beamer-timer.png" alt="timer"></p><ol start="4"><li><strong>tdclock</strong> 与 <strong>xelatex</strong> 一起使用会有些小问题，会显示不完全， <a href="https://tex.stackexchange.com/a/407730">这里</a> 提供了一种解决方法。测试是可以的。</li></ol><h2 id="在-frame-中加入-logo">在 frame 中加入 logo</h2><h3 id="在标题中加入-logo">在标题中加入 logo</h3><p>通过简单地修改 frametitle 就能加入 logo， 而不用 textopt 等包。</p><ol><li><p>在 <strong>\begin{document}</strong>  之前重新定义 frametitle，这会在 frametitle 最右端显示一个 logo:</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\setbeamertemplate</span>{frametitle}</span><br><span class="line">{</span><br><span class="line">    <span class="keyword">\begin</span>{beamercolorbox}[wd=<span class="keyword">\paperwidth</span>]{frametitle}</span><br><span class="line">      <span class="keyword">\strut</span><span class="keyword">\hspace</span>{0.5em}<span class="keyword">\insertframetitle</span><span class="keyword">\strut</span></span><br><span class="line">      <span class="keyword">\hfill</span></span><br><span class="line">      <span class="keyword">\raisebox</span>{-2mm}{<span class="keyword">\includegraphics</span>[width=1cm]{<span class="built_in">$</span>logo<span class="built_in">$</span>}}</span><br><span class="line">    <span class="keyword">\end</span>{beamercolorbox}</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure></li><li><p>只为 titlepage 页面，定义新的 logo，而不是在 title 中添加 logo。</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"><span class="keyword">\setbeamertemplate</span>{logo}{}</span><br><span class="line"><span class="keyword">\titlegraphic</span>{<span class="keyword">\includegraphics</span>[height=1.8cm]{images/logo.jpg}<span class="keyword">\hspace</span>{1em}<span class="keyword">\includegraphics</span>[height=1.8cm]{images/lhaaso.png}}</span><br><span class="line"><span class="keyword">\begin</span>{frame}</span><br><span class="line"><span class="keyword">\titlepage</span></span><br><span class="line"><span class="keyword">\initclock</span></span><br><span class="line"><span class="keyword">\end</span>{frame}</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure></li><li><p>最终结果如下图所示</p></li></ol><p><img src="/images/beamer-logo.png" alt="logo"></p><h3 id="在页面右下角加入-logo。">在页面右下角加入 logo。</h3><p>有时我们会想在其它地方加上 logo， 比如 页面右下角， 这时一般直接使用 <strong>\logo</strong> 命令即可。</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\logo</span>{<span class="keyword">\includegraphics</span>[height=1cm]{my<span class="built_in">_</span>logo.png}</span><br></pre></td></tr></tbody></table></figure><p>如果想要调整位置，可以使用 pgf 命令， 但坐标位置需要仔细调整。</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">\logo</span>{<span class="keyword">\pgfputat</span>{<span class="keyword">\pgfxy</span>(-9,9)}{<span class="keyword">\pgfbox</span>[center,base]{<span class="keyword">\includegraphics</span>[width=1.5cm]{<span class="built_in">$</span>logo<span class="built_in">$</span>}}}}</span><br></pre></td></tr></tbody></table></figure><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;在 PPT 中有一个演讲计时功能，能够帮助报告人掌握演讲时间。 其实 pdf 中也有这一功能，在 beamer 中添加计时器比较方便。 此外，在 beamer 标题中加上特定的 Logo 也是比较简单的。&lt;/p&gt;
    
    </summary>
    
      <category term="LaTeX" scheme="https://blog.amito.cc/categories/LaTeX/"/>
    
    
      <category term="LaTeX" scheme="https://blog.amito.cc/tags/LaTeX/"/>
    
      <category term="Beamer" scheme="https://blog.amito.cc/tags/Beamer/"/>
    
  </entry>
  
  <entry>
    <title>利用 Grafana 监控 Ceph 集群的状态和性能</title>
    <link href="https://blog.amito.cc/2019/02/Monitor-Ceph-Cluster-Status-and-Performance-with-Grafana/"/>
    <id>https://blog.amito.cc/2019/02/Monitor-Ceph-Cluster-Status-and-Performance-with-Grafana/</id>
    <published>2019-02-14T04:43:37.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Grafana 是一套开源的跨平台的可视化工具，可以将采集的数据进行可视化展示，并进行通知，展示方式多样，能够让我们随时掌控系统的运行情况。这里我们介绍如何使用 Grafana 来对 Ceph 集群进行性能和运行状态的监控。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="在-CentoS-7-下安装-Grafana">在 CentoS 7 下安装 Grafana</h2><p>最简单的方法是通过 Grafana 的官方 Repo 来安装 Grafana。</p><ol><li>添加 grafana repo</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">$ cat &lt;&lt; <span class="string">EOF | sudo tee /etc/yum.repos.d/grafana.repo</span></span><br><span class="line"><span class="string">[grafana]</span></span><br><span class="line"><span class="string">name=grafana</span></span><br><span class="line"><span class="string">baseurl=https://packagecloud.io/grafana/stable/el/7/</span></span><br><span class="line"><span class="string">repo_gpgcheck=1</span></span><br><span class="line"><span class="string">enabled=1</span></span><br><span class="line"><span class="string">gpgcheck=1</span></span><br><span class="line"><span class="string">gpgkey=https://packagecloud.io/gpg.key https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana</span></span><br><span class="line"><span class="string">sslverify=1</span></span><br><span class="line"><span class="string">sslcacert=/etc/pki/tls/certs/ca-bundle.crt</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>安装 grafana</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install -y grafana</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>启动 Grafana：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now grafana-server</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>设置防火墙，打开 3000 端口：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo firewall-cmd --permanent --add-port=3000/tcp</span><br><span class="line">$ sudo firewall-cmd --reload</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>在浏览器中访问 <code>server-ip:3000</code> 就可以看到 Grafana 界面了。默认用户和组都是 <code>admin</code>。</li></ol><p>Grafana 默认配置文件在 <code>/etc/grafana/grafana.in</code>, 数据库在 <code>/var/lib/grafana/grafana.db</code>, log 存储在 <code>/var/log/grafana</code>。</p><h2 id="使用-Telegraf-和-InfluxDB-监控-Ceph">使用 Telegraf 和 InfluxDB 监控 Ceph</h2><p>to be updated…</p><h2 id="利用-Prometheus-监控-Ceph">利用 Prometheus 监控 Ceph</h2><p>我们需要安装 Prometheus 和 ceph-exporter 来为 Grafana 提供 Ceph 的信息，</p><h3 id="在-CentoS-7-下安装-Prometheus">在 CentoS 7 下安装 Prometheus</h3><ol><li>创建一个 Prometheus 系统组和账户：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### uid, gid &lt; 1000</span></span><br><span class="line">$ sudo useradd -s /sbin/nologin -r -U prometheus</span><br><span class="line"><span class="comment">### </span></span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>创建 Prometheus 数据和配置文件夹</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p /etc/prometheus/{rules,rules.d}</span><br><span class="line">$ sudo mkdir -p /var/lib/prometheus</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>下载最新的 Prometheus 二进制包进行安装(2。7.1)</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ VER=2.7.1</span><br><span class="line">$ wget https://github.com/prometheus/prometheus/releases/download/v<span class="variable">${VER}</span>/prometheus-<span class="variable">${VER}</span>.linux-amd64.tar.gz</span><br><span class="line">$ tar xf prometheus-<span class="variable">${VER}</span>.linux-amd64.tar.bz2 &amp;&amp; <span class="built_in">cd</span> prometheus-<span class="variable">${VER}</span>.linux-amd64</span><br><span class="line"><span class="comment">### binary</span></span><br><span class="line">$ sudo cp prometheus promtool /usr/bin/</span><br><span class="line"><span class="comment">### configuration</span></span><br><span class="line">$ sudo cp -r consoles console_libraries prometheus.yml /etc/prometheus</span><br><span class="line"><span class="comment">### permissions</span></span><br><span class="line">$ sudo chown -R prometheus:prometheus /var/lib/prometheus /etc/prometheus/</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>创建 Prometheus 配置文件:</li></ol><figure class="highlight yml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Global config</span></span><br><span class="line"><span class="attr">global:</span></span><br><span class="line">  <span class="attr">scrape_interval:</span> <span class="string">15s</span></span><br><span class="line">  <span class="attr">evaluation_interval:</span> <span class="string">15s</span></span><br><span class="line">  <span class="attr">scrape_timeout:</span> <span class="string">15s</span></span><br><span class="line"><span class="attr">scrape_configs:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">job_name:</span> <span class="string">'prometheus'</span></span><br><span class="line">    <span class="attr">static_configs:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">targets:</span> [<span class="string">'localhost:9090'</span>]</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>创建 systemd 服务单元 <code>prometheus.service</code>, 其中，<code>Environment="GOMAXPROCS=2"</code> 是服务器上的 vCPUs 数量:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line">[Unit]</span><br><span class="line">Description=Prometheus</span><br><span class="line">Documentation=https://prometheus.io/docs/introduction/overview/</span><br><span class="line">Wants=network-online.target</span><br><span class="line">After=network-online.target</span><br><span class="line"></span><br><span class="line">[Service]</span><br><span class="line">Type=simple</span><br><span class="line">Environment=<span class="string">"GOMAXPROCS=2"</span></span><br><span class="line">User=prometheus</span><br><span class="line">Group=prometheus</span><br><span class="line">ExecReload=/bin/<span class="built_in">kill</span> -HUP <span class="variable">$MAINPID</span></span><br><span class="line">ExecStart=/usr/bin/prometheus \</span><br><span class="line">  --config.file=/etc/prometheus/prometheus.yml \</span><br><span class="line">  --storage.tsdb.path=/var/lib/prometheus \</span><br><span class="line">  --web.console.templates=/etc/prometheus/consoles \</span><br><span class="line">  --web.console.libraries=/etc/prometheus/console_libraries \</span><br><span class="line">  --web.listen-address=0.0.0.0:9090 \</span><br><span class="line">  --web.external-url=</span><br><span class="line"></span><br><span class="line">SyslogIdentifier=prometheus</span><br><span class="line">Restart=always</span><br><span class="line"></span><br><span class="line">[Install]</span><br><span class="line">WantedBy=multi-user.target</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>启动 Prometheus 服务：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo cp prometheus.service /usr/lib/systemd/system</span><br><span class="line">$ sudo systemctl daemon-reload</span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now prometheus</span><br></pre></td></tr></tbody></table></figure><ol start="7"><li>配置防火墙，打开相应的端口</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### open to all ip</span></span><br><span class="line">$ sudo firewall-cmd --permanent --add-port=9090/tcp</span><br><span class="line"><span class="comment">### open to subnets</span></span><br><span class="line">$ sudo firewall-cmd --permanent --add-rich-rule <span class="string">'rule family="ipv4" source address="192.168.60.0/24" port protocol="tcp" port="9090" accept'</span></span><br><span class="line">$ sudo firewall-cmd --reload</span><br></pre></td></tr></tbody></table></figure><h3 id="安装-Docker">安装  Docker</h3><p>在用作 Docker 服务器上安装 Docker：</p><ol><li>移除之前安装的 Docker：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum remove -y docker docker-common docker-selinux docker-engine</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>安装依赖包</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install -y yum-utils device-mapper-persistent-data lvm2</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>添加 Docker 源：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo wget https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker.repo</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>安装 Docker CE:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install docker-ce</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>启动 Docker 服务：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now docker</span><br></pre></td></tr></tbody></table></figure><h3 id="构建-Ceph-exporter-镜像">构建 Ceph-exporter 镜像</h3><ol><li>从 Github clone <code>ceph-exporter</code>：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git <span class="built_in">clone</span> https://github.com/digitalocean/ceph_exporter</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>构建 ceph-exporter 镜像：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ docker build . -t ceph-exporter</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>启动一个 Docker 容器运行 Ceph-exporter：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### 1. docker run:</span></span><br><span class="line">$ docker run --name ceph-exporter -v /etc/ceph:/etc/ceph --net host -p 9128:9128 --restart unless-stopped -dit digitalocean/ceph-exporter</span><br><span class="line"><span class="comment">### 2. docker-compose:</span></span><br><span class="line">$ cat &lt;&lt; <span class="string">EOF &gt;&gt; docker-compose.yml</span></span><br><span class="line"><span class="string"># Example usage of exporter in use</span></span><br><span class="line"><span class="string">version: '2'</span></span><br><span class="line"><span class="string">services:</span></span><br><span class="line"><span class="string">  ceph-exporter:</span></span><br><span class="line"><span class="string">    image: ceph_exporter</span></span><br><span class="line"><span class="string">    restart: unless-stopped</span></span><br><span class="line"><span class="string">    network_mode: "host"</span></span><br><span class="line"><span class="string">    volumes:</span></span><br><span class="line"><span class="string">        - /etc/ceph:/etc/ceph</span></span><br><span class="line"><span class="string">    ports:</span></span><br><span class="line"><span class="string">        - '9128:9128'</span></span><br><span class="line"><span class="string">EOF</span></span><br><span class="line">$ docker-compose up -d</span><br><span class="line"><span class="comment">### 3. systemd:</span></span><br><span class="line">$ cat &lt;&lt; <span class="string">EOF | sudo tee /usr/lib/systemd/system/ceph-exporter.service</span></span><br><span class="line"><span class="string">[Service]</span></span><br><span class="line"><span class="string">Restart=always</span></span><br><span class="line"><span class="string">TimeoutStartSec=0</span></span><br><span class="line"><span class="string">ExecStartPre=-/usr/bin/docker kill ceph_exporter</span></span><br><span class="line"><span class="string">ExecStartPre=-/usr/bin/docker rm ceph_exporter</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">ExecStart=/usr/bin/docker run \</span></span><br><span class="line"><span class="string">--name ceph_exporter \</span></span><br><span class="line"><span class="string">-v /etc/ceph:/etc/ceph \</span></span><br><span class="line"><span class="string">--net host \</span></span><br><span class="line"><span class="string">-p 9128:9128 \</span></span><br><span class="line"><span class="string">ceph_exporter</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">ExecStop=-/usr/bin/docker kill ceph_exporter</span></span><br><span class="line"><span class="string">ExecStop=-/usr/bin/docker rm ceph_exporter</span></span><br><span class="line"><span class="string">EOF</span></span><br><span class="line">$ sudo systemctl daemon-reload </span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> ceph-exporter</span><br><span class="line">$ sudo systemctl status ceph-exporter</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>设置防火墙，打开 9128 端口：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo firewall-cmd --permanent --add-rich-rule <span class="string">'rule family="ipv4" \</span></span><br><span class="line"><span class="string">source address="192.168.60.0/24" port protocol="tcp" port="9128" accept'</span></span><br><span class="line">$ sudo firewall-cmd --reload</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>Grafana 配置文件中加入 <code>ceph-exporter</code> 部分，修改 <strong>ceph-exporter-ip</strong> 为真实的 IP.IP，并<strong>重启</strong> Grafana 服务。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">scrape_configs:</span><br><span class="line">    - job_name: prometheus</span><br><span class="line">      static_configs:</span><br><span class="line">          - targets: [<span class="string">'localhost:9090'</span>]</span><br><span class="line">    - job_name: <span class="string">'ceph-exporter'</span></span><br><span class="line">      static_configs:</span><br><span class="line">        - targets: [<span class="string">'ceph-exporter-ip:9128'</span>]</span><br><span class="line">          labels:</span><br><span class="line">            <span class="built_in">alias</span>: ceph-exporter</span><br></pre></td></tr></tbody></table></figure><h3 id="将-Prometheus-数据添加到-Grafana">将 Prometheus 数据添加到 Grafana</h3><p>安装配置好上面的之后，我们需要在 Grafana 中添加 Prometheus 数据源。登陆到 Grafana Web 服务器，在设置中，添加数据源，选择 Prometheus：</p><div class="figure center" style="width:;"><img class="fig-img" src="grafana-data-source.png" alt=""></div><p>添加数据源，需要提供的是：</p><ul><li>Name： 数据源名</li><li>URL: 数据源地址</li><li>Access: Server(Proxy) or Browser(Direct)</li></ul><p>添加界面如下：</p><div class="figure center" style="width:;"><img class="fig-img" src="grafana-prometheus.png" alt=""></div><p>填好后，点击 <code>Save and Test</code> 按钮即可。</p><h3 id="启用-Ceph-的-Prometheus-模块">启用 Ceph 的 Prometheus 模块</h3><p>在 Ceph 中启用 mgr 的 promtheus 监控模块：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ceph mgr module <span class="built_in">enable</span> prometheus</span><br></pre></td></tr></tbody></table></figure><h3 id="导入-Ceph-集群的-Grafana-Dashboards">导入 Ceph 集群的 Grafana Dashboards</h3><p><a href="https://grafana.com/dashboards">Grafana</a> 官网上有一些已经写好的 Dashboards， 我们可以从上面导入一些设计比较好的。 Dashboard 是 json 文件，我们也可以自己修改设计 Ceph 的 Dashboard。Ceph 本身也有一些 <a href="https://github.com/ceph/ceph/tree/master/monitoring/grafana/dashboards">Dashboards</a>, 可以作为参考。在 Grafana Web 界面左侧的工具栏选择 <strong>+ -&gt; Import</strong>，导入界面大致如下：</p><div class="figure center" style="width:;"><img class="fig-img" src="grafana-import.png" alt=""></div><p>有三种方法可以导入 Dashboard：</p><ul><li>填写 Dashboard 在 <a href="http://Grafana.com">Grafana.com</a> Dashboard 中的 url 或 id</li><li>上传 JSON 文件</li><li>直接粘贴 JSON 内容</li></ul><p>导入合适的 Dashboard 后，就可以在 Dashboards 界面选择查看导入的 Dashboards 了。</p><p><strong>PS</strong>: <a href="https://github.com/digitalocean/ceph_exporter">ceph-exporter</a> 中提供了 <code>docker-compose.yml</code>，包含了 Prometheus、Grafana 和 ceph-exporter， 我们可以使用 docker-compose 一起运行这三个服务。</p><h2 id="参考-5">参考</h2><ol><li><a href="https://grafana.com/dashboards/7056">Grafana Ceph - Cluster 7056</a></li><li><a href="https://grafana.com/dashboards/2842">Grafana Ceph - Cluster 2842</a></li><li><a href="https://grafana.com/dashboards/917">Grafana Ceph - Cluster 917</a></li><li><a href="https://grafana.com/dashboards/923">Grafana Ceph - Cluster 923</a></li><li><a href="https://grafana.com/dashboards/926">Grafana Ceph - Cluster 926</a></li><li><a href="https://computingforgeeks.com/monitoring-ceph-cluster-with-prometheus-and-grafana/">Monitoring Ceph Cluster with Prometheus and Grafana</a></li><li><a href="http://docs.ceph.com/docs/mimic/mgr/prometheus/">Prometheus plugin</a></li><li><a href="https://github.com/ceph/ceph/tree/master/monitoring">Ceph Monitoring</a></li><li><a href="https://computingforgeeks.com/install-prometheus-server-on-centos-7/">Install Prometheus Server on CentOS 7 and Ubuntu 18.04</a></li><li><a href="https://computingforgeeks.com/monitoring-ceph-cluster-with-prometheus-and-grafana/">Monitoring Ceph Cluster with Prometheus and Grafana</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Grafana 是一套开源的跨平台的可视化工具，可以将采集的数据进行可视化展示，并进行通知，展示方式多样，能够让我们随时掌控系统的运行情况。这里我们介绍如何使用 Grafana 来对 Ceph 集群进行性能和运行状态的监控。&lt;/p&gt;
    
    </summary>
    
      <category term="Ceph" scheme="https://blog.amito.cc/categories/Ceph/"/>
    
    
      <category term="Ceph" scheme="https://blog.amito.cc/tags/Ceph/"/>
    
      <category term="Grafana" scheme="https://blog.amito.cc/tags/Grafana/"/>
    
  </entry>
  
  <entry>
    <title>将 Ceph 文件系统 CephFS 挂载为 NFS</title>
    <link href="https://blog.amito.cc/2019/01/Mount-CephFS-over-NFS/"/>
    <id>https://blog.amito.cc/2019/01/Mount-CephFS-over-NFS/</id>
    <published>2019-01-04T02:05:37.000Z</published>
    <updated>2022-04-16T14:26:24.376Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>利用 NFS-Ganesha 或 ceph-fuse 与 nfsd， 我们可以将 CephFS 通过 NFS 协议对外发布出去，用户可以通过 NFS 客户端挂载 CephFS 文件系统进行访问。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="Ceph-与-NFS">Ceph 与 NFS</h2><p>Ceph 是一种开源的分布式存储系统，具有优异的性能、可靠性和可扩展性。 Ceph 底层使用 RADOS，提供 RBD、RGW 和 CephFS 三种标准的访问接口。从 Luminous 版本开始， CephFS 已经具有相当好的稳定性，可用在生产环境。</p><div class="figure center" style="width:;"><img class="fig-img" src="/images/ceph-structure.png" alt="Ceph Structure"><span class="caption">Ceph Structure</span></div><p>NFS (Network File System) 是常用的网络文件系统，用户通过 NFS 可以像访问本地文件一样访问远程的文件，NFS 服务端和客户端之间通过 NFS 协议进行通信。</p><p>用户可以用 Ceph 提供的 ceph-fuse 挂载 CephFS 进行访问，也可以通过 ceph 的内核模块进行挂载访问，具体可参考<a href="/2018/CephFS-Introduction-Installation-and-Configuration/">Ceph 文件系统 CephFS 的介绍与配置</a>。 但有时候，由于各种原因，一些系统无法通过这两种方法访问 CephFS，我们可以将 CephFS 通过 NFS 协议发布出去，用户可以通过 NFS 客户端挂载发布出去的 CephFS。</p><h2 id="NFS-Ganesha-挂载-CephFS">NFS-Ganesha 挂载 CephFS</h2><p>CephFS 可以通过 <a href="https://github.com/nfs-ganesha/nfs-ganesha/wiki">NFS-Ganesha</a> 使用 NFS 协议发布出去。</p><h3 id="准备条件">准备条件</h3><ul><li>一个设置好的 CephFS 文件系统</li><li>在 NFS 服务器上，安装 <code>libcephfs2</code>、<code>nfs-ganesha</code> 和 <code>nfs-ganesha-ceph</code> (ganesha &gt;= 2.5) 包。</li><li>NFS-Ganesha 服务器与 CephFS 网路相连。</li></ul><h3 id="安装-NFS-Ganesha">安装 NFS-Ganesha</h3><ol><li>通过包管理器安装：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install nfs-ganesha-fsal-ceph</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>通过源码安装：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir -p ~/tmp/ &amp;&amp; <span class="built_in">cd</span> ~/tmp</span><br><span class="line">$ git <span class="built_in">clone</span> https://github.com/nfs-ganesha/nfs-ganesha.git</span><br><span class="line">$ mkdir build &amp;&amp; <span class="built_in">cd</span> build</span><br><span class="line">$ cmake -DUSE_FSAL_CEPH=ON ../nfs-ganesha</span><br><span class="line">$ make &amp;&amp; sudo make install</span><br></pre></td></tr></tbody></table></figure><h3 id="配置-NFS-Ganesha">配置 NFS-Ganesha</h3><ol><li>关闭防火墙或打开 <code>2049</code> 端口：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### turn off firewall</span></span><br><span class="line">$ sudo systemctl <span class="built_in">disable</span> --now firewalld</span><br><span class="line">$ sudo systemctl <span class="built_in">disable</span> --now iptables</span><br><span class="line"><span class="comment">### or open port 2049</span></span><br><span class="line">$ sudo firewall-cmd --permanent --add-port=2049/tcp</span><br><span class="line">$ sudo firewall-cmd --reload</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>启动 <code>rpcbind</code> 和 <code>rpcstatd</code> 服务：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now rpcbind</span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now rpcstatd</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>复制 Ceph 配置文件到 <code>/etc/ceph/ceph.conf</code></li><li>根据 NFS-Ganesha 的 <a href="https://github.com/nfs-ganesha/nfs-ganesha/blob/next/src/config_samples/ceph.conf">Ceph 配置例子</a>， 创建 <code>/etc/ganashe/ceph.conf</code>，类似如下:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">NFS_CORE_PARAM</span><br><span class="line">{</span><br><span class="line">Enable_NLM = <span class="literal">false</span>;</span><br><span class="line">Enable_RQUOTA = <span class="literal">false</span>;</span><br><span class="line">Protocols = 4;</span><br><span class="line">}</span><br><span class="line">NFSv4</span><br><span class="line">{</span><br><span class="line">    Allow_Numeric_Owners = <span class="literal">true</span>;</span><br><span class="line">    Only_Numeric_Owners = <span class="literal">true</span>;</span><br><span class="line">Delegations = active;</span><br><span class="line">}</span><br><span class="line">CACHEINODE</span><br><span class="line">{</span><br><span class="line">Dir_Chunk = 0;</span><br><span class="line">NParts = 1;</span><br><span class="line">Cache_Size = 1;</span><br><span class="line">}</span><br><span class="line">EXPORT</span><br><span class="line">{</span><br><span class="line">Export_ID = 1;</span><br><span class="line">Protocols = 4;</span><br><span class="line">Transports = TCP;</span><br><span class="line">Path = /;</span><br><span class="line">Pseudo = /cephfs/;</span><br><span class="line">Access_type = RW;</span><br><span class="line">Delegations = RW;</span><br><span class="line"><span class="comment"># Squash = root;</span></span><br><span class="line">FSAL{</span><br><span class="line">NAME = CEPH;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>启动 NFS-Ganesha 服务：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ganesha.nfsd -f /etc/ganesha/ceph.conf -L /var/<span class="built_in">log</span>/ganesha.log -N NIV_CRIT</span><br><span class="line">$ sudo showmount -e</span><br></pre></td></tr></tbody></table></figure><p>这样就把 CephFS 通过 NFS 协议导出了。值得注意的是，<strong>目前一个运行的 Ganesha 进程只能导出一个 CephFS 中的一个目录</strong>；如果多个 CephFS 或 一个 CephFS 中的多个目录需要导出，需要有相应多个 Ganesha 进程。</p><h3 id="NFS-客户端挂载">NFS  客户端挂载</h3><p>在 NFS 客户端服务器上挂载 CephFS 到 <code>/cephfs</code>：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### Usage:</span></span><br><span class="line">$ sudo mount -t nfs4 -o nfsvers=4.1,protoc=tcp,rw,notime &lt;ganesha-host&gt;:&lt;ganesha-pseudo-path&gt; &lt;mount-point&gt;</span><br><span class="line"><span class="comment">### e.g.:</span></span><br><span class="line">$ sudo mount -t nfs4 -o nfsvers=4.1,proto=tcp,rw,notime &lt;ganesha-host&gt;:/ /cephfs</span><br></pre></td></tr></tbody></table></figure><p>这样用户就可以通过 NFS 协议访问 CephFS 了。</p><h2 id="ceph-fuse-和-nfsd-挂载-CephFS">ceph-fuse 和 nfsd 挂载 CephFS</h2><p>Ceph 提供了 <code>ceph-fuse</code> 来挂载和访问 CephFS。在 NFS 服务器上通过 <code>ceph-fuse</code> 挂载 CephFS 后，我们可以通过 nfsd 将其发布出去。</p><h3 id="NFS-服务端设置">NFS 服务端设置</h3><ol><li>在 NFS 服务器上挂载 CephFS。</li><li>在 <code>/etc/exports</code> 中添加如下内容:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### Usage:</span></span><br><span class="line">/path/to/mount * (rw,sync,no_root_squash,fsid=ceph-id)</span><br><span class="line"><span class="comment">### example:</span></span><br><span class="line">/cephfs * (rw,sync,no_root_squash,fsid=87761f6e-f839-4597-bfe2-fd850d9a03cf)</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>运行 <code>exportfs</code>，并启动 <code>rpcbind</code> 和 <code>nfs-server</code> 服务，将 该节点变成 NFS 服务器。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo exportfs</span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now rpcbind</span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now nfs-server</span><br></pre></td></tr></tbody></table></figure><h3 id="NFS-客户端挂载-2">NFS 客户端挂载</h3><p>跟前面一样，在 NFS 客户端上通过 NFS 协议挂载 CephFS：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mount -t nfs4 -o nfsvers=4.1,proto=tcp,rw,notime &lt;nfs-host&gt;:/cephfs /cephfs</span><br></pre></td></tr></tbody></table></figure><p>这样用户就可以通过 NFS 协议访问 CephFS 了。</p><h2 id="两种方案对比">两种方案对比</h2><h2 id="参考文献">参考文献</h2><ol><li><a href="https://mp.weixin.qq.com/s?__biz=MzIzNzA5NzM3Ng==&amp;mid=2651857179&amp;idx=1&amp;sn=de46bd8b6ff1414b762e983bbe129464&amp;chksm=f32959d4c45ed0c227939f4712c1ed46df2a88763e09dfc95fdd0f8e6da8239bb02f43f25736&amp;scene=21">NFS+CephFS构建基于Ceph的NAS服务</a></li><li><a href="https://zhoubofsy.github.io/2017/05/25/storage/ceph/ceph-nfs-service-by-rgw-with-nfs-ganesha/">Ceph提供NFS服务 —— RGW＋nfs-ganesha</a></li><li><a href="http://manjusri.ucsc.edu/2017/10/11/mpi-io-cephfs/">MPI-IO with CephFS?</a></li><li><a href="https://docs.oracle.com/cd/E52668_01/E96266/html/ceph-luminous-nfs-cephfs.html">Exporting Ceph FS Over NFS</a></li><li><a href="http://docs.ceph.com/docs/mimic/cephfs/nfs/">NFS CephFS Using Ganesha</a></li><li><a href="http://docs.ceph.com/docs/mimic/radosgw/nfs/">NFS RadosGW Using Ganesha</a></li><li><a href="http://cloud.51cto.com/art/201507/482289.htm">以 CephFS 为例解析如何在云中提供 NAS 服务</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;利用 NFS-Ganesha 或 ceph-fuse 与 nfsd， 我们可以将 CephFS 通过 NFS 协议对外发布出去，用户可以通过 NFS 客户端挂载 CephFS 文件系统进行访问。&lt;/p&gt;
    
    </summary>
    
      <category term="Ceph" scheme="https://blog.amito.cc/categories/Ceph/"/>
    
    
      <category term="Ceph" scheme="https://blog.amito.cc/tags/Ceph/"/>
    
      <category term="CephFS" scheme="https://blog.amito.cc/tags/CephFS/"/>
    
      <category term="NFS" scheme="https://blog.amito.cc/tags/NFS/"/>
    
  </entry>
  
  <entry>
    <title>在 OpenStack 中将虚拟机实例转成启动镜像</title>
    <link href="https://blog.amito.cc/2018/12/Convert-An-Instance-to-An-Image-in-OpenStack/"/>
    <id>https://blog.amito.cc/2018/12/Convert-An-Instance-to-An-Image-in-OpenStack/</id>
    <published>2018-12-30T07:21:20.000Z</published>
    <updated>2022-04-16T14:26:24.368Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>在 OpenStack 中，我们对虚拟机实例做了修改后，可以以此实例为模版创建新的虚拟机镜像，其过程也很简单。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h3 id="创建实例的快照">创建实例的快照</h3><ol><li>找到将要作为模版的实例，并将其关掉。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">source</span> ~/keystonerc_admin</span><br><span class="line">$ nova list</span><br><span class="line">...</span><br><span class="line">| 8e640acc-6cca-4a4a-8ca5-763150d107bd | my_instance    | ACTIVE  | -          | Running     | V2018=192.168.18.20 |</span><br><span class="line">...</span><br><span class="line">$ nova stop my_instance</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>确保实例已经关机。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ nova list</span><br><span class="line">...</span><br><span class="line">| 8e640acc-6cca-4a4a-8ca5-763150d107bd | my_instance    | ACTIVE  | -          | SHUTOFF     | V2018=192.168.18.20 |</span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>使用 <code>nova image-create</code> 创建实例快照。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ nova image-create --poll my_instance my_instance_snp</span><br><span class="line">Server snapshotting... 100% complete</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>确保 Nova 镜像处于 <code>ACTIVE</code> 状态。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ nova image-list</span><br><span class="line">...</span><br><span class="line">| 5c8e13b7-2eea-4bf7-9440-c1e7c603380f | my_instance_snp          | ACTIVE | 8e640acc-6cca-4a4a-8ca5-763150d107bd |</span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><h3 id="下载快照到本地">下载快照到本地</h3><ol><li>获取快照 ID。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ nova image-list</span><br><span class="line">...</span><br><span class="line">| 5c8e13b7-2eea-4bf7-9440-c1e7c603380f | my_instance_snp          | ACTIVE | 8e640acc-6cca-4a4a-8ca5-763150d107bd |</span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><ol><li>将快照下载到本地。使用快照 ID 而不是名字。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ glance image-download --file my_instance_image.qcow2 5c8e13b7-2eea-4bf7-9440-c1e7c603380f</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>如果需要，将镜像复制到新环境中。</li></ol><h3 id="从快照镜像生成镜像">从快照镜像生成镜像</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ glance --os-image-api-version 1 image-create --container-format bare --disk-format qcow2 -name <span class="string">"my_new_image"</span> --file my_instance_image.qcow2</span><br><span class="line"><span class="comment">### or</span></span><br><span class="line">$ glance --os-image-api-version 1 image-create --container-format bare --disk-format qcow2 -name <span class="string">"my_new_image"</span> --copy_from my_instance_image_url</span><br></pre></td></tr></tbody></table></figure><h3 id="从新镜像启动新实例">从新镜像启动新实例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ nova boot --flavor m1.tiny --image my_new_image my_new_instance</span><br></pre></td></tr></tbody></table></figure><h3 id="参考-2">参考</h3><ol><li><a href="https://docs.openstack.org/mitaka/user-guide/cli_use_snapshots_to_migrate_instances.html">Use snapshots to migrate instances</a></li><li><a href="http://khmel.org/?p=1188">OpenStack – convert an instance to an image</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;在 OpenStack 中，我们对虚拟机实例做了修改后，可以以此实例为模版创建新的虚拟机镜像，其过程也很简单。&lt;/p&gt;
    
    </summary>
    
      <category term="OpenStack" scheme="https://blog.amito.cc/categories/OpenStack/"/>
    
    
      <category term="OpenStack" scheme="https://blog.amito.cc/tags/OpenStack/"/>
    
      <category term="Virtualization" scheme="https://blog.amito.cc/tags/Virtualization/"/>
    
  </entry>
  
  <entry>
    <title>使用 Pandoc 来制作 HTML 和 beamer 风格的幻灯片</title>
    <link href="https://blog.amito.cc/2018/12/Using-Pandoc-to-Make-HTML-and-Beamer-Slides/"/>
    <id>https://blog.amito.cc/2018/12/Using-Pandoc-to-Make-HTML-and-Beamer-Slides/</id>
    <published>2018-12-28T05:06:46.000Z</published>
    <updated>2022-04-16T14:26:24.376Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Pandoc 是一款开源的文档格式转换工具，能够实现大部分的文件格式互转。这里我们主要用来将 Markdown 文档转换成 HTML 和 PDF 风格的幻灯片。 Markdown 语法、结构简单，只需要写出文档的提纲和结构，就能转换成简洁明了又美观的 Slides。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="Pandoc-格式转换利器">Pandoc - 格式转换利器</h2><p>Pandoc 是全平台的转换工具，在命令行能够很方便的进行格式转换。 Pandoc 支持的格式及转换方式如下图所示。</p><div class="figure center" style="width:60%;"><img class="fig-img" src="pandoc.png" style="width:60%;" alt=""></div><p>更多的可以打开<a href="/2018/Using-Pandoc-to-Make-HTML-and-Beamer-Slides/pandoc.jpg">这里</a> 查看，可以看到 Pandoc 支持的格式是极多的。</p><p>Pandoc 的安装是非常简单的， 可按照 <a href="http://johnmacfarlane.net/pandoc/installing.html">说明</a> 很方便地安装到系统中。</p><h2 id="文档语法结构">文档语法结构</h2><p>Pandoc 支持标准的 Markdown 语法，但在结构上与一般的用 Markdown 写博客有点区别。</p><h3 id="元数据">元数据</h3><p>为了让 Pandoc 能渲染 Markdown 文件生成 Slides， 需要在文档头部加上几行元数据信息。</p><figure class="highlight markdown"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">% Title</span><br><span class="line">% Author</span><br><span class="line">% Tate</span><br></pre></td></tr></tbody></table></figure><p>这样就能生成幻灯片的标题页了。</p><h3 id="文档结构">文档结构</h3><p>一般情况下，一个 Markdown 文档只有一个一级标题。 Pandoc 中，默认情况下，一级标题代表 一个章节， 三个一级标题就是把幻灯片分为三部分；二级标题代表一张幻灯片； 三级标题则一般是幻灯片内部的块。 一个基本的文档结构如下所示</p><figure class="highlight markdown"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">% Title</span><br><span class="line">% Author</span><br><span class="line">% Tate</span><br><span class="line"></span><br><span class="line"><span class="section"># Part I</span></span><br><span class="line"><span class="section">## slide I</span></span><br><span class="line"><span class="bullet">-</span> list 1</span><br><span class="line"><span class="bullet">-</span> list 2</span><br><span class="line"></span><br><span class="line"><span class="section">## slide II</span></span><br><span class="line"><span class="bullet">1.</span> list 1</span><br><span class="line"><span class="bullet">2.</span> list 2</span><br><span class="line"></span><br><span class="line"><span class="section"># Part II</span></span><br><span class="line"><span class="section">## slide III</span></span><br><span class="line">[<span class="string">amito</span>](<span class="link">amito.me</span>)</span><br><span class="line"><span class="section">## slide IV</span></span><br><span class="line">![<span class="string">picture</span>](<span class="link">pic.png</span>)</span><br></pre></td></tr></tbody></table></figure><h3 id="数学公式">数学公式</h3><p>Pandoc 支持转换 TeX 数学公式， 能够将数学公式转换成 MathML， 或者通过 MathJax 显示。</p><figure class="highlight tex"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">$</span><span class="keyword">\frac</span>{a}{b<span class="built_in">^</span>2+c<span class="built_in">^</span>3}<span class="built_in">$</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">$</span><span class="built_in">$</span><span class="keyword">\frac</span>{a}{b<span class="built_in">^</span>2+c<span class="built_in">^</span>3}<span class="built_in">$</span><span class="built_in">$</span></span><br></pre></td></tr></tbody></table></figure><p>显示效果为：$\frac{a}{b<sup>2+c</sup>3}$<br>$$\frac{a}{b<sup>2+c</sup>3}$$</p><h2 id="幻灯片样式">幻灯片样式</h2><p>在 <code>/usr/share/pandoc-xxx/data</code> 下面有 Pandoc 自带的转换模版， html 幻灯片模版有 <code>dszlides</code>, <code>html</code>, <code>html5</code>, <code>revealjs</code>, <code>s5</code>, <code>slideous</code>, <code>slidy</code> 等等。下面简单介绍几种。</p><h3 id="s5">s5</h3><p><a href="http://meyerweb.com/eric/tools/s5/">s5</a> 是很流行的 HTML 幻灯片模版，可以从网站上下载后使用，也可以在线使用。本地使用主要是其中的 <code>ui/default</code>, 将其复制到 markdown 所在目录。在线使用需要指定 <code>s5-url</code></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#### local</span></span><br><span class="line">$ pandoc -s -t s5 -o s5.html s5.md</span><br><span class="line"><span class="comment">#### online</span></span><br><span class="line">$ pandoc -s -t s5 -V s5-url=https://cdn.docbook.org/release/xsl-nons/current/slides/s5/ui/default/ -o s5.html s5.md</span><br></pre></td></tr></tbody></table></figure><h3 id="reveal-js">reveal.js</h3><p>reveal.js 是非常火的 HTML 幻灯片库，本身支持 Markdown 语法。 离线使用 reveal.js 需要将其下载下来，在线使用可以指定 <code>revealjs-url</code>。下载 <a href="https://github.com/hakimel/reveal.js">reveal.js</a></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git <span class="built_in">clone</span> https://github.com/hakimel/reveal.js</span><br></pre></td></tr></tbody></table></figure><p>渲染 markdown 文件生成 HTML 幻灯片，在线使用可以通过指定 <code>revealjs-url</code> 来使用。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ pandoc -s -t revealjs -o h5.html h5.md</span><br><span class="line">$ pandoc -s -t revealjs -V revealjs-url=https://cdnjs.com/libraries/reveal.js/3.6.0 -o h5.htmnl h5.md</span><br></pre></td></tr></tbody></table></figure><p>reveal.js 自带了一些模版可供选择，通过 <code>-V css=/path/to/css</code> 来指定自带的或自己定制的模版，</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#### local</span></span><br><span class="line">$ pandoc -s -t revealjs -V css=reveal.js/css/theme/night.css -o h5.html h5.md</span><br><span class="line"><span class="comment">#### online</span></span><br><span class="line">url=<span class="string">"https://cdnjs.com/libraries/reveal.js/3.6.0/"</span></span><br><span class="line">$ pandoc -s -t revealjs -V revealjs-url=<span class="variable">$url</span> -V css=<span class="variable">$url</span>/css/theme/night.css -V -o h5.html h5.md</span><br></pre></td></tr></tbody></table></figure><p>也可以修改 reveal.js 模版 <code>/usr/share/pandoc-xxx/data/templates/default.revealjs</code>。</p><figure class="highlight html"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">$if(css)$</span><br><span class="line">$for(css)$</span><br><span class="line">    <span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"$css$"</span>/&gt;</span></span><br><span class="line">$endfor$</span><br><span class="line">$else$</span><br><span class="line">    <span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"$revealjs-url$/css/theme/simple.css"</span> <span class="attr">id</span>=<span class="string">"theme"</span>&gt;</span></span><br><span class="line">$endif$</span><br></pre></td></tr></tbody></table></figure><p>改为</p><figure class="highlight html"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">$if(css)$</span><br><span class="line">$for(css)$</span><br><span class="line">    <span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"$revealjs-url$/css/theme/$css$"</span>/&gt;</span></span><br><span class="line">$endfor$</span><br><span class="line">$endif$</span><br><span class="line">$if(theme)$</span><br><span class="line">    <span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"$revealjs-url$/css/theme/$theme$.css"</span> <span class="attr">id</span>=<span class="string">"theme"</span>&gt;</span></span><br><span class="line">$else$</span><br><span class="line">    <span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"$revealjs-url$/css/theme/simple.css"</span> <span class="attr">id</span>=<span class="string">"theme"</span>&gt;</span></span><br><span class="line">$endif$</span><br></pre></td></tr></tbody></table></figure><p>这样就可以简单指定<code>theme</code>了。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ pandoc -s -t revealjs -V theme=night -o h5.html h5.md</span><br></pre></td></tr></tbody></table></figure><h2 id="Beamer-样式">Beamer 样式</h2><p>Pandoc 能非常方便地将 markdown 转换为独立的 tex 文档，然后通过 tex 命令 可以生成 pdf 幻灯片。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ pandoc -s -t beamer -o slide.tex slide.md</span><br><span class="line">$ latexmk -pdf slide.tex</span><br></pre></td></tr></tbody></table></figure><h3 id="Beamer-模版">Beamer 模版</h3><p>Pandoc 有默认的 beamer 模版，使用 platex 编译，如果不喜欢，可以参考默认模版 <code>/usr/share/pandoc-xxx/data/templates/default.beamer</code> 自己定制一个 beamer 模版，网上也有一些现成的模版，可以参考。下面是默认模版生成的幻灯片样式。</p><div class="figure center" style="width:;"><img class="fig-img" src="beamer.png" alt=""></div><h3 id="中文字体">中文字体</h3><ol><li>首先查看系统中文字体：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ fc-list :lang=zh</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>转换时指定字体：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ pandoc -s -t beamer --pdf-engine=xelatex -V CJKmainfont=KaiTi srs.md -o srs.pdf</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>Markdown 文件中加入设置。默认的 beamer 模版中有 <code>CJKmainfont</code> 变量，指定后会使用 <code>xeCJK</code> 包：</li></ol><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">CJKmainfont:</span> <span class="string">STSong</span></span><br><span class="line"><span class="attr">CJKoptions:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">BoldFont=STHeiti</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">ItalicFont=STKaiti</span></span><br><span class="line"><span class="meta">---</span></span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>定制模版，这是比较方便的一种方式，能更改的地方也更多，<a href="https://github.com/darkshell/beamer/blob/master/themes/ponde.tex">这里</a>是我根据<a href="https://github.com/cympfh/beamer">网上</a> 模版修改过的。</li></ol><h2 id="参考-6">参考</h2><ol><li><a href="https://linux.cn/article-4080-1.html">Markdown+Pandoc→HTML幻灯片速成</a></li><li><a href="https://stackoverflow.com/questions/40892725/pandoc-does-not-recognize-chinese-characters">pandoc does not recognize Chinese characters</a></li><li><a href="https://pandoc.org/demos.html">Pandoc Demo</a></li><li><a href="https://nval.andreasherten.de/2016/01/26/latex-beamer-with-markdown.html">Talks with LaTeX Beamer, written in Markdown</a></li><li><a href="https://bl.ocks.org/lmullen/c3d4c7883f081ed8692a">PDF slides and handouts using Pandoc and Beamer</a></li><li><a href="https://github.com/jgm/pandoc/wiki/User-contributed-templates">User contributed templates</a></li><li><a href="http://www.bagualu.net/wordpress/archives/5396">用pandoc把markdown转化为pdf文档</a></li><li><a href="https://jdhao.github.io/2017/12/10/pandoc-markdown-with-chinese/">纯文本做笔记 — 使用 Pandoc 与 Markdown 生成 PDF 文件</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Pandoc 是一款开源的文档格式转换工具，能够实现大部分的文件格式互转。这里我们主要用来将 Markdown 文档转换成 HTML 和 PDF 风格的幻灯片。 Markdown 语法、结构简单，只需要写出文档的提纲和结构，就能转换成简洁明了又美观的 Slides。&lt;/p&gt;
    
    </summary>
    
      <category term="LaTeX" scheme="https://blog.amito.cc/categories/LaTeX/"/>
    
    
      <category term="LaTeX" scheme="https://blog.amito.cc/tags/LaTeX/"/>
    
      <category term="Beamer" scheme="https://blog.amito.cc/tags/Beamer/"/>
    
      <category term="Pandoc" scheme="https://blog.amito.cc/tags/Pandoc/"/>
    
  </entry>
  
  <entry>
    <title>为 Nginx 创建自签名的 SSL 证书</title>
    <link href="https://blog.amito.cc/2018/12/Generating-A-Self-Signed-SSL-Certificate-for-Nginx/"/>
    <id>https://blog.amito.cc/2018/12/Generating-A-Self-Signed-SSL-Certificate-for-Nginx/</id>
    <published>2018-12-27T15:09:52.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>SSL 及其继任者 TLS 能够加密客户端与服务端的网络连接，保证网络传输信息的安全及完整性，不被他人窃取。有时我们会想要在本机测试加密网络连接，SSL 加密需要有一个 SSL 证书，我们可以为本机生成一个证书来测试。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="自签名的-SSL-证书">自签名的 SSL 证书</h2><p>使用 OpenSSL 创建一个自签名的单域名和泛著名的 SSL 证书很容易，一行命令主就可以。假设我们为本地的多个项目添加了多个 <code>.local</code> 结尾的域名。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ openssl req -x509 -nodes -days 1024 -newkey rsa:4096 -keyout local.key -out local.crt</span><br></pre></td></tr></tbody></table></figure><p>运行后的结果如下：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">$ openssl req -x509 -nodes -days 1024 -newkey rsa:4096 -keyout local.key -out local.crt</span><br><span class="line">Generating a 4096 bit RSA private key</span><br><span class="line">..........................................++</span><br><span class="line">..............++</span><br><span class="line">writing new private key to <span class="string">'local.key'</span></span><br><span class="line">-----</span><br><span class="line">You are about to be asked to enter information that will be incorporated</span><br><span class="line">into your certificate request.</span><br><span class="line">What you are about to enter is what is called a Distinguished Name or a DN.</span><br><span class="line">There are quite a few fields but you can leave some blank</span><br><span class="line">For some fields there will be a default value,</span><br><span class="line">If you enter <span class="string">'.'</span>, the field will be left blank.</span><br><span class="line">-----</span><br><span class="line">Country Name (2 letter code) [XX]:CN</span><br><span class="line">State or Province Name (full name) []:Beijing</span><br><span class="line">Locality Name (eg, city) [Default City]:Beijing</span><br><span class="line">Organization Name (eg, company) [Default Company Ltd]:<span class="built_in">local</span></span><br><span class="line">Organizational Unit Name (eg, section) []:<span class="built_in">local</span></span><br><span class="line">Common Name (eg, your name or your server<span class="string">'s hostname) []:local,*.local</span></span><br><span class="line"><span class="string">Email Address []:me@amito.me</span></span><br></pre></td></tr></tbody></table></figure><p>各选项含义比较明显，比较重要的是 <code>Common Name</code>， 这是与要用 SSL 加密的域名或服务器 IP 相关的。如果是单域名， 就填 <code>local</code>；要是有多个项目，就填 <code>local,*.local</code>。知道创建的过程后，就可以一行命令自动生成了。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">echo</span> -e <span class="string">"CN\nBJ\n\Beijing\nlocal\nlocal\nlocal,\*.local\nme@amito.me"</span>|openssl req -x509 -nodes -days 1024 -newkey rsa:4096 -keyout local.key -out local.crt</span><br></pre></td></tr></tbody></table></figure><p>这样我们就在当前目录生成了一个 ssl 证书 <code>local.crt</code> 和对应的密钥 <code>local.key</code>。</p><h2 id="创建-RootCA-及自签名证书">创建 RootCA 及自签名证书</h2><h3 id="生成-Root-SSL-证书">生成 Root SSL 证书</h3><ol><li>生成 Root Key</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ openssl genrsa -des3 -out RootCA.key 4096</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>生成 RootCA 证书</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.pem</span><br></pre></td></tr></tbody></table></figure><h3 id="信任-Root-SSL-证书">信任 Root SSL 证书</h3><h3 id="生成-网站-SSL-证书">生成 网站 SSL 证书</h3><h2 id="配置-Nginx-使用-SSL">配置 Nginx 使用 SSL</h2><h2 id="参考-3">参考</h2><ol><li><a href="https://cloud.tencent.com/developer/article/1160294">如何为Nginx创建自签名SSL证书</a></li><li><a href="https://www.cnblogs.com/loleina/p/8418111.html">https学习笔记三----OpenSSL生成root CA及签发证书</a></li><li><a href="https://medium.freecodecamp.org/how-to-get-https-working-on-your-local-development-environment-in-5-minutes-7af615770eec">How to get HTTPS working on your local development environment in 5 minutes</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;SSL 及其继任者 TLS 能够加密客户端与服务端的网络连接，保证网络传输信息的安全及完整性，不被他人窃取。有时我们会想要在本机测试加密网络连接，SSL 加密需要有一个 SSL 证书，我们可以为本机生成一个证书来测试。&lt;/p&gt;
    
    </summary>
    
      <category term="Linux" scheme="https://blog.amito.cc/categories/Linux/"/>
    
    
      <category term="SSL" scheme="https://blog.amito.cc/tags/SSL/"/>
    
      <category term="Nginx" scheme="https://blog.amito.cc/tags/Nginx/"/>
    
  </entry>
  
  <entry>
    <title>LVM 调整分区大小</title>
    <link href="https://blog.amito.cc/2018/12/LVM-Resize-Partitions/"/>
    <id>https://blog.amito.cc/2018/12/LVM-Resize-Partitions/</id>
    <published>2018-12-25T12:09:56.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>最近在三台服务器上安装了系统，安装的时候选择的是自动分区，创建了一个 LVM 卷组， 结果大部分空间都分给了 HOME ， root 很小。 现在要求要将大部分空间重新分给 ROOT。 常用的文件系统如 ext4，xfs 都能很方便地在线调整大小的。 这里就简单记录一下如何调整分区大小的。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h3 id="制作一个-Linux-LiveCD-启动盘">制作一个 Linux LiveCD 启动盘</h3><p>对系统的 root 分区和 home 分区进行调整大小，可以直接线上调整大小。但是文件系统是 XFS 格式的，不好在线减少空间，就选取了这一个比较稳妥的方法 - 离线调整大小。</p><p>下载一个 LiveCD 镜像，然后刻录到 U 盘上， 或者通过 grub2 引导镜像启动。</p><h3 id="减小-HOME-分区大小">减小 HOME 分区大小</h3><ol><li>系统自动分区时创建了一个 LVM 卷组 <code>/dev/centos</code>， 分为 <code>swap</code>、<code>home</code>、<code>root</code> 三个卷。 在 Live 系统中，挂载 home 和 root 卷到：</li></ol><figure class="highlight awk"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p <span class="regexp">/mnt/</span>{home,root}</span><br><span class="line">$ sudo mount <span class="regexp">/dev/</span>centos<span class="regexp">/root /m</span>nt/root</span><br><span class="line">$ sudo mount <span class="regexp">/dev/</span>centos<span class="regexp">/home /m</span>nt/home</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>默认分区格式为 XFS，无法减小大小。需要减小后重新格式化。减小之前做好数据备份。 还好 <code>home</code> 卷内容很少。-_-…</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo xfsdump -f /mnt/root/home/home.dump /mnt/home</span><br><span class="line">$ sudo umount /mnt/home</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>减小 home 卷大小</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo lvreduce -L 25G /dev/centos/home</span><br><span class="line">$ sudo mkfs.xfs -f /dev/centos/home</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>恢复 home 数据</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mount /dev/centos/home /mnt/home</span><br><span class="line">$ sudo xfsrestore -f /mnt/root/home/home.dump /mnt/home</span><br><span class="line">$ sudo rm -f /mnt/root/home/home.dump</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>若是 <code>ext4</code> 分区，则要简单的多。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ sudo lvreduce -L 25G /dev/centos/home</span><br><span class="line">$ sudo resize2fs /dev/centos/home</span><br><span class="line"><span class="comment">### or simply and safely</span></span><br><span class="line">$ sudo lvresize --resize --size 25G /dev/centos/home</span><br></pre></td></tr></tbody></table></figure><h3 id="增大-ROOT-分区大小">增大 ROOT 分区大小</h3><p>扩大 root 分区就比较简单了。</p><ol><li>LVM 调整大小。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo lvextend -l +100%FREE /dev/centos/root</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li><code>xfs</code> 分区确认大小调整</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo xfs_growfs /dev/centos/root</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li><code>ext4</code> 分区确认大小调整</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo resize2fs /dev/centos/root</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>确认调整后的分区大小</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">$ sudo lsblk</span><br><span class="line">NAME                                   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT</span><br><span class="line">sda                                      8:0    0   931G  0 disk</span><br><span class="line">├─sda1                                   8:1    0   200M  0 part /boot/efi</span><br><span class="line">├─sda2                                   8:2    0     1G  0 part /boot</span><br><span class="line">└─sda3                                   8:3    0 929.8G  0 part</span><br><span class="line">  ├─centos-root                        253:0    0 900.8G  0 lvm  /</span><br><span class="line">  ├─centos-swap                        253:1    0     4G  0 lvm  [SWAP]</span><br><span class="line">  └─centos-home                        253:2    0    25G  0 lvm  /home</span><br></pre></td></tr></tbody></table></figure><h3 id="重启系统">重启系统</h3><p>调整好之后，就可以重启系统了。</p><h3 id="在线调整大小">在线调整大小</h3><p>一般分区只能在线扩容，不能减少。鉴于 home 分区没有使用，可以不用重启系统到 Live 系统。 确保没有程序在使用 home 分区后， 备份 home 分区，然后可以按照上面的步骤进行调整大小了。 不过在线调整大小有风险，最好提前做好数据备份。</p><p>在<a href="https://unix.stackexchange.com/questions/226872/how-to-shrink-root-filesystem-without-booting-a-livecd/227318#227318">这篇</a> 回答中，提到了一种不重启减小 root 分区的方法，不过，如无必要，建议使用 Live 系统减小 root 分区容量。</p><hr><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;最近在三台服务器上安装了系统，安装的时候选择的是自动分区，创建了一个 LVM 卷组， 结果大部分空间都分给了 HOME ， root 很小。 现在要求要将大部分空间重新分给 ROOT。 常用的文件系统如 ext4，xfs 都能很方便地在线调整大小的。 这里就简单记录一下如何调整分区大小的。&lt;/p&gt;
    
    </summary>
    
      <category term="Linux" scheme="https://blog.amito.cc/categories/Linux/"/>
    
    
      <category term="LVM" scheme="https://blog.amito.cc/tags/LVM/"/>
    
      <category term="XFS" scheme="https://blog.amito.cc/tags/XFS/"/>
    
      <category term="ext4" scheme="https://blog.amito.cc/tags/ext4/"/>
    
  </entry>
  
  <entry>
    <title>通过网络远程安装 CentOS 7</title>
    <link href="https://blog.amito.cc/2018/12/Install-CentOS-7-Remotely-through-Internet/"/>
    <id>https://blog.amito.cc/2018/12/Install-CentOS-7-Remotely-through-Internet/</id>
    <published>2018-12-07T14:37:17.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>最近工作中需要将几台服务器重装系统, 将 CentOS 6 换成最新的 CentOS 7.5. 于是研究了一下怎么从 grub lagecy 和 grub2 通过网络来升级或安装 CentOS 7.</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><p>从 grub 通过网络安装很容易, 还可以设置 VNC 远程安装. 从 CentOS 6 安装 CentOS 7, 和对 CentOS 7 重装比较类似.</p><h2 id="从-CentOS-6-安装-CentOS-7">从 CentOS 6 安装 CentOS 7</h2><p>在启动之前, 我们需要下载 <a href="http://mirrors.ustc.edu.cn/centos/7/os/x86_64/isolinux/vmlinuz">vmlinuz</a> 和 <a href="http://mirrors.ustc.edu.cn/centos/7/os/x86_64/isoinux/initrd.img">initrd.img</a> 到 <code>/boot/netinstall</code> 文件夹下, 如果哦已经无法进入系统, 可以放在一个可以访问的 U 盘上.</p><p>CentOS 6 的启动方式是 grub lagecy, 配置文件是 <code>/boot/grub/grub.conf</code>, 我们需要在启动项开始或结束加入一个新的启动项. 如果已经无法进入系统, 在 grub 没有毁坏的情况下, 在启动选择界面 按c进入手动输入模式, 输入以下启动命令.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">title CentOS 7 Install</span><br><span class="line">root (hd0,2)</span><br><span class="line">kernel /netinstall/vmlinuz ro ip=192.168.1.10 netmask=255.255.255.254 gateway=192.168.1.1 dns=1.1.1.1 method=http://mirrors.ustc.edu.cn/centos/7/os/x86_64 lang=en_US keymap=us ksdevice=eth0</span><br><span class="line">initrd /netinstall/initrd.img</span><br></pre></td></tr></tbody></table></figure><p>其中, <code>ip</code>, <code>netmask</code>, <code>gateway</code>, <code>dns</code> 是网络连接信息, <code>method</code> 是网络安装包位置. 根据需要修改网络信息和安装位置. 根据 <code>/boot</code> 所在位置和所下载文件位置, 修改相应路径. 如果要利用 <strong>vnc</strong> 通过远程拖动进行安装, 需要在<code>kernel</code> 语句后面加上 <code>vnc vncpassword=MyPassword</code> 就可以了. 另外, 如果默认网卡<strong>不是</strong> <code>eth0</code>, 比如<code>eno1</code> 的话, 需要在 <code>kernel</code> 命令行加上 <code>ksdevice=eno1</code></p><p>如果一切没有问题, 之后便会进入图形化安装界面. 如果想自动进行安装, 你可以指定 <code>Kickstart</code> 安装文件. 并在 <code>kernel</code> 语句后面加上文件位置如 <code>ks=http://localfile/centos7.ks</code>, 这样就会自动进行安装了, 当然需要实现准备好 <code>ks</code> 文件.</p><h2 id="从-CentOS-7-重装-CentOS-7">从 CentOS 7 重装 CentOS 7</h2><p>重装 CentOS 7 的过程与 从 CentOS 6 安装 CentOS 7 类似. CentOS 7 使用的引导器是 <code>grub2</code>, 启动项参数相应有些改变.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">menuentry <span class="string">"CentOS-7-Install"</span>{</span><br><span class="line"><span class="built_in">set</span> root=(hd0,msdos2)</span><br><span class="line">linux /netinstall/vmlinuz ro ip=192.168.1.10::192.168.1.1:255.255.255.254:my_hostname:eth0:none nameserver=1.1.1.1 inst.repo=http://mirrors.ustc.edu.cn/centos/7/os/x86_64/ inst.vnc inst.vncpassword=MyPassword ksdevice=eth0 ks=<span class="string">"http://where.my.ks.file.is"</span> inst.lang=en_US inst.keymap=us</span><br><span class="line">initrd /netinstall/initrd.img</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>其中 <code>ip</code> 的格式为 <code>ip::gateway:netmask:hostname:interface:none</code>, 或者 <code>ip=dhcp</code>.如果 硬盘是 <code>GPT</code> 格式的,则需要将 <code>(hd0,msdos2)</code> 改成 <code>(hd0,gpt2)</code>, 且要加上 <code>inst.gpt</code> 选项. 同样的，需要注意网卡名 <strong>interface</strong> 和 ksdevice 一定要正确。 之后重启进入 CentOS 7 安装：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">grub2-reboot CentOS-7-Install</span><br></pre></td></tr></tbody></table></figure><p>这样重启后一般就会进入自动化安装 <code>CentOS 7</code> 的程序啦.</p><h2 id="Kickstart-配置文件">Kickstart 配置文件</h2><p>一般安装好 <code>CentOS</code> 或 <code>Fedora</code> 后, 会在 <code>/root</code> 下有一个 <code>anaconda-ks.cfg</code>, 这就是一个 <code>Kickstart</code> 配置文件, 可以参考这个修改成适合自己的安装脚本。RHEL/CentOS 有一个图形化的配置工具 <strong>system-config-kickstart</strong> 可以简化 Kickstart 文件的生成配置。</p><p>下面是一个简单的 ks 配置文件。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#version=DEVEL</span></span><br><span class="line"><span class="comment"># System authorization information</span></span><br><span class="line">auth --enableshadow --passalgo=sha512</span><br><span class="line"><span class="comment"># Use network installation</span></span><br><span class="line">url --url=<span class="string">"http://mirror.ihep.ac.cn/centos/7/os/x86_64"</span></span><br><span class="line"><span class="comment"># Use graphical install</span></span><br><span class="line">graphical</span><br><span class="line"><span class="comment"># Run the Setup Agent on first boot</span></span><br><span class="line">firstboot --<span class="built_in">enable</span></span><br><span class="line">ignoredisk --only-use=sda</span><br><span class="line"><span class="comment"># Keyboard layouts</span></span><br><span class="line"><span class="comment"># old format: keyboard us</span></span><br><span class="line"><span class="comment"># new format:</span></span><br><span class="line">keyboard --vckeymap=us --xlayouts=<span class="string">'us'</span></span><br><span class="line"><span class="comment"># System language</span></span><br><span class="line">lang en_US.UTF-8</span><br><span class="line"><span class="comment"># Network information</span></span><br><span class="line">network  --bootproto=static --device=eno1 --gateway=202.122.33.1 --ip=202.122.33.38 --nameserver=202.122.33.44 --netmask=255.255.255.128 --ipv6=auto --activate</span><br><span class="line">network  --bootproto=dhcp --device=eno2 --onboot=off --ipv6=auto</span><br><span class="line">network  --bootproto=dhcp --device=eno3 --onboot=off --ipv6=auto</span><br><span class="line">network  --bootproto=dhcp --device=eno4 --onboot=off --ipv6=auto</span><br><span class="line">network  --hostname=localhost.localdomain</span><br><span class="line"><span class="comment"># Root password</span></span><br><span class="line">rootpw --iscrypted $6$7Xg630Hqe96PUCMu<span class="variable">$mUzleXYhsnNBxHl</span>.U1AZTGGVSqJ6U/7n2.psJ8nlXg0.MMFcEjngSAytOZhD8yM52d2s3PF7vpojhiF6s0iT2/</span><br><span class="line"><span class="comment"># System services</span></span><br><span class="line">services --enabled=<span class="string">"chronyd"</span></span><br><span class="line"><span class="comment"># System timezone</span></span><br><span class="line">timezone Asia/Harbin --isUtc</span><br><span class="line">user --groups=wheel --name=eos --password=$6$VWhRMFl9A7LKcekg<span class="variable">$0zZOGfO2ezcfbGPRLbNVsrzylddEmlsFw5WTkZSa</span>/0Oh5IGxVXvljRAn8O/sSFxdtHKiqioSYXXZpJ/ipqOaA/ --iscrypted --uid=1000 --gecos=<span class="string">"eos"</span> --gid=1000</span><br><span class="line"><span class="comment"># System bootloader configuration</span></span><br><span class="line">bootloader --append=<span class="string">" crashkernel=auto"</span> --location=mbr --boot-drive=sda</span><br><span class="line"><span class="comment"># Partition clearing information</span></span><br><span class="line">clearpart --all --initlabel --drives=sda</span><br><span class="line"><span class="comment"># Disk partitioning information</span></span><br><span class="line">part /data --fstype=<span class="string">"ext4"</span> --ondisk=sda --size=123775 --label=data</span><br><span class="line">part swap --fstype=<span class="string">"swap"</span> --ondisk=sda --size=8191</span><br><span class="line">part / --fstype=<span class="string">"ext4"</span> --ondisk=sda --size=51200 --label=root</span><br><span class="line">part /var --fstype=<span class="string">"ext4"</span> --ondisk=sda --size=102400 --label=var</span><br><span class="line">part /boot --fstype=<span class="string">"ext4"</span> --ondisk=sda --size=500 --label=boot</span><br><span class="line">%packages</span><br><span class="line">@^developer-workstation-environment</span><br><span class="line">@base</span><br><span class="line">@core</span><br><span class="line">@debugging</span><br><span class="line">@desktop-debugging</span><br><span class="line">@development</span><br><span class="line">@dial-up</span><br><span class="line">@directory-client</span><br><span class="line">@file-server</span><br><span class="line">@fonts</span><br><span class="line">@gnome-apps</span><br><span class="line">@gnome-desktop</span><br><span class="line">@guest-desktop-agents</span><br><span class="line">@hardware-monitoring</span><br><span class="line">@input-methods</span><br><span class="line">@internet-applications</span><br><span class="line">@internet-browser</span><br><span class="line">@java-platform</span><br><span class="line">@load-balancer</span><br><span class="line">@mariadb</span><br><span class="line">@multimedia</span><br><span class="line">@network-file-system-client</span><br><span class="line">@performance</span><br><span class="line">@perl-runtime</span><br><span class="line">@print-client</span><br><span class="line">@python-web</span><br><span class="line">@ruby-runtime</span><br><span class="line">@system-admin-tools</span><br><span class="line">@virtualization-client</span><br><span class="line">@virtualization-hypervisor</span><br><span class="line">@virtualization-tools</span><br><span class="line">@web-server</span><br><span class="line">@x11</span><br><span class="line">chrony</span><br><span class="line">kexec-tools</span><br><span class="line">%end</span><br><span class="line">%addon com_redhat_kdump --<span class="built_in">enable</span> --reserve-mb=<span class="string">'auto'</span></span><br><span class="line">%end</span><br><span class="line">%anaconda</span><br><span class="line">pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty</span><br><span class="line">pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok</span><br><span class="line">pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty</span><br><span class="line">%end</span><br></pre></td></tr></tbody></table></figure><p>需要特别注意的是，安装位置选择硬盘一定要慎重，一定要确定好所选<strong>硬盘</strong>和<strong>分区</strong>方案后，才能进行安装，否则容易造成数据丢失。</p><hr><h2 id="参考-4">参考</h2><ol><li><a href="http://www.danpros.com/2016/02/how-to-install-centos-7-remotely-using-vnc">How to install CentOS 7 remotely using VNC</a></li><li><a href="https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/installation_guide/ap-admin-options">Redhat Enterprise Linux 6 - Installation Guide - BOOT OPTIONS</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;最近工作中需要将几台服务器重装系统, 将 CentOS 6 换成最新的 CentOS 7.5. 于是研究了一下怎么从 grub lagecy 和 grub2 通过网络来升级或安装 CentOS 7.&lt;/p&gt;
    
    </summary>
    
      <category term="Linux" scheme="https://blog.amito.cc/categories/Linux/"/>
    
    
      <category term="Linux" scheme="https://blog.amito.cc/tags/Linux/"/>
    
      <category term="CentOS" scheme="https://blog.amito.cc/tags/CentOS/"/>
    
  </entry>
  
  <entry>
    <title>Ceph 集群停机维护一般过程</title>
    <link href="https://blog.amito.cc/2018/11/Ceph-Cluster-Maintenance-Procedures/"/>
    <id>https://blog.amito.cc/2018/11/Ceph-Cluster-Maintenance-Procedures/</id>
    <published>2018-11-30T08:59:56.000Z</published>
    <updated>2022-04-16T14:26:24.368Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Ceph 集群运行久了，需要对其进行停机维护。 而停止 Ceph 服务需要按照一定的流程来进行，以避免 Ceph 集群出现性能问题。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="停机维护">停机维护</h2><ol><li>关掉所有使用 Ceph 集群的客户端</li><li>保证集群的健康状态(healthy state) 为 OK</li><li>设置 OSD flags</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">## osd no out</span></span><br><span class="line">$ ceph osd <span class="built_in">set</span> noout</span><br><span class="line"><span class="comment">## not backfill data to other osd</span></span><br><span class="line">$ ceph osd <span class="built_in">set</span> nobackfill</span><br><span class="line"><span class="comment">## not recover</span></span><br><span class="line">$ ceph osd <span class="built_in">set</span> norecover</span><br><span class="line"><span class="comment">## 上面一些flags 对于关掉集群应该已经足够安全了，</span></span><br><span class="line"><span class="comment">## 还可以设置如下的flags以完全停止集群</span></span><br><span class="line">$ ceph osd <span class="built_in">set</span> norebalance</span><br><span class="line">$ ceph osd <span class="built_in">set</span> nodown</span><br><span class="line">$ ceph osd <span class="built_in">set</span> pause</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>依次关掉 Ceph 的客户端节点</li><li>查看 Ceph Service</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">$ ceph -s</span><br><span class="line">  cluster:</span><br><span class="line">    id:     1272c14d-2389-48db-a313-02600a50212f</span><br><span class="line">    health: HEALTH_OK</span><br><span class="line"> </span><br><span class="line">  services:</span><br><span class="line">    mon: 3 daemons, quorum ceph01,ceph02,ceph03</span><br><span class="line">    mgr: ceph03(active), standbys: ceph02, ceph01</span><br><span class="line">    mds: cephfs-1/1/1 up  {0=ceph03=up:active}, 2 up:standby</span><br><span class="line">    osd: 18 osds: 18 up, 18 <span class="keyword">in</span></span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>依次关掉 Ceph MDS/FUSE 服务</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### MDS &amp;&amp; FUSE</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> ceph0{1..3}; <span class="keyword">do</span></span><br><span class="line">ssh <span class="variable">$i</span> <span class="string">"systemctl stop ceph-fuse@-ceph.service; systemctl stop ceph-mds@<span class="variable">${i}</span>.service"</span></span><br><span class="line"><span class="keyword">done</span></span><br><span class="line"><span class="comment">###</span></span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>依次关停 Ceph 的 OSD 服务</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### OSD</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> $(ceph osd status | awk <span class="string">'/ceph/{print $2 ":" $4}'</span>);<span class="keyword">do</span></span><br><span class="line">idx=$(<span class="built_in">echo</span> <span class="variable">$i</span>|awk -F : <span class="string">'{print $1}'</span>)</span><br><span class="line">host=$(<span class="built_in">echo</span> <span class="variable">$i</span> | awk -F : <span class="string">'{print $2}'</span>)</span><br><span class="line">ssh <span class="variable">$host</span> <span class="string">"systemctl stop ceph-osd@<span class="variable">${idx}</span>.service"</span></span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>依次关停 Ceph 的 Mon 服务</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> ceph0{1..3};<span class="keyword">do</span></span><br><span class="line">ssh <span class="variable">$i</span> <span class="string">"systemctl stop ceph-mon@<span class="variable">${i}</span>.service"</span></span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></tbody></table></figure><ol start="7"><li>依次关停 Ceph 的 MGR 服务</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> ceph0{1..3}; <span class="keyword">do</span></span><br><span class="line">ssh <span class="variable">$i</span> <span class="string">"systemctl stop ceph-mgr@<span class="variable">${i}</span>.service"</span></span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></tbody></table></figure><ol start="8"><li>进行关机等维护工作</li></ol><h2 id="开机启动-Ceph-集群">开机启动 Ceph 集群</h2><ol><li>启动 MGR 节点</li><li>启动 MOM 节点</li><li>启动 OSD 节点</li><li>在所有节点启动上线后，确认所有服务都已正常</li><li>取消之前设置的 flags</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">$ ceph osd <span class="built_in">unset</span> noout</span><br><span class="line">$ ceph osd <span class="built_in">unset</span> nobackfill</span><br><span class="line">$ ceph osd <span class="built_in">unset</span> norecover</span><br><span class="line">$ ceph osd <span class="built_in">unset</span> norebalance</span><br><span class="line">$ ceph osd <span class="built_in">unset</span> nodown</span><br><span class="line">$ ceph osd <span class="built_in">unset</span> pause</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>检查 Ceph 健康状态，确定为 OK。</li><li>检查 Ceph 客户端是否能连接上 Ceph 集群</li></ol><h2 id="参考">参考</h2><ol><li><a href="https://ceph.com/planet/how-to-do-a-ceph-cluster-maintenance-shutdown/">How to do a Ceph cluster maintenance/shutdown</a></li><li><a href="http://lists.ceph.com/pipermail/ceph-users-ceph.com/2017-April/017378.html">[ceph-users] Steps to stop/restart entire ceph cluster</a></li></ol><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Ceph 集群运行久了，需要对其进行停机维护。 而停止 Ceph 服务需要按照一定的流程来进行，以避免 Ceph 集群出现性能问题。&lt;/p&gt;
    
    </summary>
    
      <category term="Ceph" scheme="https://blog.amito.cc/categories/Ceph/"/>
    
    
      <category term="Ceph" scheme="https://blog.amito.cc/tags/Ceph/"/>
    
      <category term="Linux" scheme="https://blog.amito.cc/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>DocDB 介绍，安装与配置维护</title>
    <link href="https://blog.amito.cc/2018/11/DocDB-Introduction-Installation-And-Managment/"/>
    <id>https://blog.amito.cc/2018/11/DocDB-Introduction-Installation-And-Managment/</id>
    <published>2018-11-13T01:56:20.000Z</published>
    <updated>2022-04-16T14:26:24.372Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p><a href="https://github.com/ericvaandering/DocDB/">DocDB</a> 是一个功能强大且灵活的协作文档服务器。 最初是由 Fermilab 的 <a href="http://www-btev.fnal.gov/">BTeV</a> 合作组开发的，现在已用于其他 20 多个实验的文档协作。 DocDB非常适合用于在几百人的合作组间管理和分享文档。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="安装-DocDB">安装 DocDB</h2><p>DocDB 的安装包括三部分：1). 一个关系数据库，用来存储文档信息, 2). 一个文件系统，用来存储文档本身 和 3). 一个合适的 CGI 脚本，用来提供文档和其信息的一致访问。</p><ul><li>DocDB 在 MySQL 数据库中维护着一份文档的版本列表。 存储的信息包括 <strong>作者</strong>, <strong>标题</strong>，<strong>主题</strong>,<strong>事件</strong>, <strong>创建与修改时间</strong>, <strong>修订版本号</strong>, <strong>简介</strong>,<strong>关键字</strong>,<strong>文档类型</strong>, <strong>指向实际文件的指针</strong>, <strong>访问限制信息</strong> 等等。</li><li>对 DocDB 的访问由 运行在 Web 服务器上的 CGI 脚本控制。</li><li>当一个文件上传到 DocDB 时， 文档(从本地硬盘或 url)被复制到 Web 服务器下的一个目录， 文档可能由多个文件构成。</li><li>文档会被集中复制到一个位置，这样当有人整理或删除文档时，它们就不会消失。这也有助于集中化备份。</li><li>对文档的更改会生成一个新版本的文档。此时旧的文档仍可以访问，提供历史存档功能。不同版本有着不同的访问限制，因此文档可以在私有状态进行修改，然后正式发布。</li><li>DockDB 包含一个健壮的事件和议程管理系统，可以允许全大小的文档与会议结合起来。</li><li></li></ul><p>下面就简单介绍一下如何安装 DocDB。</p><h3 id="安装配置-MySQL">安装配置 MySQL</h3><p>Fedora/CentOS 下可以使用 MariaDB，也可以下载 <a href="http://www.mysql.com/">MySQL</a> 安装</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### Fedora/CentOS</span></span><br><span class="line">$ sudo yum install -y mariadb mariadb-server mariadb-devel</span><br><span class="line"><span class="comment">### Ubuntu/Debian</span></span><br><span class="line">$ sudo apt install -y mariadb mariadb-client mariadb-server mariadb-common</span><br><span class="line"><span class="comment">### start mariadb server</span></span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now mariadb</span><br><span class="line"><span class="comment">### set root password</span></span><br><span class="line">$ sudo mysql_secure_installation</span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><p>为 DocDB 创建新的 MySQL 用户和数据库：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">$ mysql -u root -p</span><br><span class="line">Enter password:</span><br><span class="line">...</span><br><span class="line"><span class="comment">### User</span></span><br><span class="line">MariaDB [(none)]&gt; create user <span class="string">'docdbadmin'</span>@<span class="string">'localhost'</span> identified by <span class="string">'admin_password'</span>;</span><br><span class="line">MariaDB [(none)]&gt; create user <span class="string">'docdbrw'</span>@<span class="string">'localhost'</span> identified by <span class="string">'rw_password'</span>;</span><br><span class="line">MariaDB [(none)]&gt; create user <span class="string">'docdbro'</span>@<span class="string">'localhsot'</span> identified by <span class="string">'ro_password'</span>;</span><br><span class="line"><span class="comment">### Database</span></span><br><span class="line">MaraiDB [(none)]&gt; create database <span class="string">'docdb'</span>;</span><br><span class="line"><span class="comment">### Grant Privileges</span></span><br><span class="line">MariaDB [(none)]&gt; grant all on docdb.* to <span class="string">'docdbadmin'</span>@<span class="string">'localhost'</span> identified by <span class="string">'admin_password'</span>;</span><br><span class="line">MariaDB [(none)]&gt; grant select,insert,update,delete,create on docdb.* to <span class="string">'docdbrw'</span>@<span class="string">'localhost'</span> identified by <span class="string">'rw_password'</span>;</span><br><span class="line">MariaDB [(none)]&gt; grant select on docdb.* to <span class="string">'docdbro'</span>@<span class="string">'localhost'</span> identified by <span class="string">'ro_password'</span>;</span><br></pre></td></tr></tbody></table></figure><h3 id="安装-Perl-模块">安装 Perl 模块</h3><h3 id="下载-DocDB">下载 DocDB</h3><p>现在 DocDB 主要在 Github 上发布，在 <a href="https://github.com/ericvaandering/DocDB/releases">这里</a> 下载最新的版本：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ wget https://github.com/ericvaandering/DocDB/archive/8.8.9.tar.gz -O DocDB-8.8.9.tar.gz</span><br></pre></td></tr></tbody></table></figure><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;a href=&quot;https://github.com/ericvaandering/DocDB/&quot;&gt;DocDB&lt;/a&gt; 是一个功能强大且灵活的协作文档服务器。 最初是由 Fermilab 的 &lt;a href=&quot;http://www-btev.fnal.gov/&quot;&gt;BTeV&lt;/a&gt; 合作组开发的，现在已用于其他 20 多个实验的文档协作。 DocDB非常适合用于在几百人的合作组间管理和分享文档。&lt;/p&gt;
    
    </summary>
    
      <category term="Web" scheme="https://blog.amito.cc/categories/Web/"/>
    
    
      <category term="DocDB" scheme="https://blog.amito.cc/tags/DocDB/"/>
    
      <category term="MySQL" scheme="https://blog.amito.cc/tags/MySQL/"/>
    
  </entry>
  
  <entry>
    <title>配置 EOS 使用 QuarkDB 作为 NS</title>
    <link href="https://blog.amito.cc/2018/10/Configure-EOS-to-Use-QuarkDB-for-Namespace/"/>
    <id>https://blog.amito.cc/2018/10/Configure-EOS-to-Use-QuarkDB-for-Namespace/</id>
    <published>2018-10-24T05:20:27.000Z</published>
    <updated>2022-04-16T14:26:24.368Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>QuarkDB 被设计用来作为 EOS 下一代的 Namespace. 要使用 QuarkDB, EOS 版本必须是 4.4.0 以上. 目前 (<code>2018.11.1</code>) EOS 稳定版本是 <code>4.3.12</code>, github 上的版本则到了 <a href="https://github.com/cern-eos/eos/releases/tag/4.4.10">4.4.10</a>.  要安装 4.4.0 以上版本, 可以从 EOS 的 <a href="http://storage-ci.web.cern.ch/storage-ci/eos/citrine/commit/el-7/x86_64/">commit</a> 源安装. 本文主要参考 <a href="https://github.com/cern-eos/eos/blob/master/doc/quickstart/ns_quarkdb.rst">Namespace in QuarkDB configuration</a>.</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><div class="figure center" style="width:;"><img class="fig-img" src="/images/eos-quarkdb.jpg" alt=""></div><h2 id="搭建一个-QuarkDB-集群">搭建一个 QuarkDB 集群</h2><p>为了使用 QuarkDB 作为 EOS MGM 的 namespace, 我们首先要搭建一个 QuarkDB 集群, 可以参考 <a href="../Deploy-And-Run-A-QuarkDB-Cluster/">搭建并运行管理 QuarkDB 集群</a>) 安装好 QuarkDB 并搭建好一个有三个 quardb node 如 <code>qdb-1:7777</code>, <code>qdb-2:7777</code>, <code>qdb-3:7777</code> 的集群.</p><h2 id="配置-EOS-MGM-使用-QuarkDB">配置 EOS MGM 使用 QuarkDB</h2><p>要将 MGM 服务与 QuarkDB 整合到一起, 我们要对 <code>/etc/xrd.cf.mgm</code> 做一些修改.</p><ol><li>修改 <code>mgm.nslib</code> 指令, 导入 Namespace 的 QuarkDB 实现.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mgm.nslib /usr/lib64/libEosNsQuarkdb.so</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>列出 MGM 进程连接的 QuarkDB 集群的端点.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mgmofs.qdbcluster qdb-1:7777 qdb-2:7777 qdb-3:7777</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>如果 QuarkDB 启用了密码认证， 则要修改以下选项：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">mgmofs.cfgtype quarkdb</span><br><span class="line">mgmofs.qdbpassword_file /etc/qdb.passwd</span><br></pre></td></tr></tbody></table></figure><p>其中 <code>/etc/qdb.passwd</code> 是 QuarDB 的密码文件.<br>4. 以 <code>master</code> 模式运行 MGM 服务.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ systemctl start eos@master</span><br><span class="line">$ systemctl start eos@mgm</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>如果一切正常, 可以看到如下一些进程.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ ps aux|grep xrootd</span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><p>在生产环境下, 为了有更好的性能, 应该:</p><ol><li>QuarkDB 集群服务 和 MGM 服务运行在<strong>不同</strong>的节点上.</li><li>至少 QuarkDB 主进程的 <code>/var/lib/quarkdb/</code> 文件夹应存储到 <strong>SSD</strong> 分区.</li></ol><h2 id="内存-NS-到-QuarkDB-NS-的转化">内存 NS 到 QuarkDB NS 的转化</h2><p>使用 <code>eos-log-compact</code> 工具压缩 Changelog 文件:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ eos-log-compact /var/eos/md/file.mdlog /var/eos/md/compacted_file.mdlog</span><br><span class="line">$ eos-log-compact /var/eos/md/directory.mdlog /var/eos/md/compacted_directory.mdlog</span><br></pre></td></tr></tbody></table></figure><p>压缩需要将 namespace 整体加载到内存中, 因此压缩 log 的机器必须有<strong>足够大</strong>的内存来保存 namespace 数据结构. 为了更好的性能, 建议 changelog 文件也应该存储在 <code>SSD</code> 分区.</p><p>为了加速初始的导入,  QuarkDB 有一个特殊的 <code>bulkload</code> 配置模式, 在这种模式下, 我们期待只做的就是向后端写入, QuarkDB 中的数据压缩只发生在导入最后阶段. 因此减少了I/O次数,加速了整个过程.</p><p>使用 <code>quarkdb-create</code> 工具创建一个压缩用 QuarkDB 集群, 下面是一个 QuarkDB 配置文件的例子:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">xrd.port 7777</span><br><span class="line">xrd.protocol redis:7777 /usr/lib64/libXrdQuarkDB.so</span><br><span class="line">redis.mode bulkload</span><br><span class="line">redis.database /var/lib/quarkdb/convert/</span><br></pre></td></tr></tbody></table></figure><p>启动 QuarkDB 集群后, 我们可以使用 <code>eos-ns-convert</code> 工具来进行实际的 namespace 转换过程:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ eos-ns-convert /var/eos/md/compacted_file.mdlog /var/eos/md/compacted_directory localhost 7777</span><br></pre></td></tr></tbody></table></figure><p><code>eos-ns-convert</code> 必须使用压缩后的 changelog 文件作为输入.</p><p>等 <code>bulkload</code> 完成后, 就可以关掉 QuarkDB 实例, 然后使用 <code>quarkdb-create</code> 在不同的位置建一个新的 QuarkDB 目录, 列出组建 QuarkDB 集群的节点. 新建的 QuarkDB <code>raft-journal</code> 目录可以删除掉. 存储在 <code>/var/lib/quarkdb/convert</code> 的 raft 日志可以利用 <code>cp/scp/rsync</code> 等等复制到新的 QuarkDB 集群的所有实例上. 确保 QuarkDB 集群是运行在 <strong>raft</strong> 模式而不是 <strong>bulkload</strong> 模式. 复制完成后, QuarkDB 集群所有实例就可以启动了, 系统会很快达到一个主节点多个副本节点的稳定配置状态.</p><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;QuarkDB 被设计用来作为 EOS 下一代的 Namespace. 要使用 QuarkDB, EOS 版本必须是 4.4.0 以上. 目前 (&lt;code&gt;2018.11.1&lt;/code&gt;) EOS 稳定版本是 &lt;code&gt;4.3.12&lt;/code&gt;, github 上的版本则到了 &lt;a href=&quot;https://github.com/cern-eos/eos/releases/tag/4.4.10&quot;&gt;4.4.10&lt;/a&gt;.  要安装 4.4.0 以上版本, 可以从 EOS 的 &lt;a href=&quot;http://storage-ci.web.cern.ch/storage-ci/eos/citrine/commit/el-7/x86_64/&quot;&gt;commit&lt;/a&gt; 源安装. 本文主要参考 &lt;a href=&quot;https://github.com/cern-eos/eos/blob/master/doc/quickstart/ns_quarkdb.rst&quot;&gt;Namespace in QuarkDB configuration&lt;/a&gt;.&lt;/p&gt;
    
    </summary>
    
      <category term="EOS" scheme="https://blog.amito.cc/categories/EOS/"/>
    
    
      <category term="QuarkDB" scheme="https://blog.amito.cc/tags/QuarkDB/"/>
    
      <category term="EOS" scheme="https://blog.amito.cc/tags/EOS/"/>
    
  </entry>
  
  <entry>
    <title>Ceph 文件系统 CephFS 的介绍与配置</title>
    <link href="https://blog.amito.cc/2018/10/CephFS-Introduction-Installation-and-Configuration/"/>
    <id>https://blog.amito.cc/2018/10/CephFS-Introduction-Installation-and-Configuration/</id>
    <published>2018-10-02T13:56:07.000Z</published>
    <updated>2022-04-16T14:26:24.368Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Ceph File System (CephFS) 是与 POSIX 标准兼容的文件系统, 能够提供对 Ceph 存储集群上的文件访问. Jewel 版本(10.2.0) 是第一个包含稳定 CephFS 的 Ceph 版本. CephFS 需要至少一个元数据服务器 (<code>Metadata Server - MDS</code>) daemon (<code>ceph-mds</code>) 运行, MDS daemon 管理着与存储在 CephFS 上的文件相关的元数据, 并且协调着对 Ceph 存储系统的访问.</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="Ceph-文件系统简介">Ceph 文件系统简介</h2><p>CephFS 会在任何可能的情况下使用 POSIX 方法. 例如, CephFS 会在所有客户端之间保持缓存强一致性, 但在某些情况下, CephFS 会与严格的 POSIX 语义有些区别.</p><h3 id="CephFS-架构">CephFS 架构</h3><p>下图展示了 CephFS 的层次结构:</p><div class="figure center" style="width:;"><img class="fig-img" src="/images/ceph-cephfs-structure.png" alt=""></div><p>底层是核心集群所依赖的, 包括:</p><ul><li><code>OSDs (ceph-osd)</code>: CephFS 的数据和元数据就存储在 OSDs 上</li><li><code>MDS (ceph-mds)</code>: <code>Metadata Servers</code>, 管理着 CephFS 的元数据</li><li><code>Mons (ceph-mon)</code>: Monitors 管理着集群 Map 的主副本</li></ul><p>Ceph 存储集群的协议层是 Ceph 原生的 <code>librados</code> 库, 与核心集群交互.</p><p>CephFS 库层包括 CephFS 库 <code>libcephfs</code>, 工作在 <code>librados</code> 的顶层, 代表着 Ceph 文件系统.</p><p>最上层是能够访问 Ceph 文件系统的两类客户端.</p><h3 id="CephFS-主要特性">CephFS 主要特性</h3><h3 id="CephFS-的限制">CephFS 的限制</h3><h2 id="配置-CephFS-MDS">配置 CephFS MDS</h2><p>要使用 CephFS， 至少就需要一个 metadata server 进程。可以手动创建一个 MDS， 也可以使用 <code>ceph-deploy</code> 或者 <code>ceph-ansible</code> 来部署 MDS。</p><h3 id="ceph-deploy-部署-MDS">ceph-deploy 部署 MDS</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ceph-deploy mds create mds [mds2 ...]</span><br></pre></td></tr></tbody></table></figure><h3 id="手动部署-MDS">手动部署 MDS</h3><ol><li>建立 MDS 元数据文件夹</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p /var/lib/ceph/mds/ceph-{<span class="variable">$id</span>}</span><br></pre></td></tr></tbody></table></figure><p>为提高性能， 可以将该文件夹挂载到 SSD 上。<br>2. 在 <code>/etc/ceph/ceph.conf</code> 中加入下面一节</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[mds.{<span class="variable">$id</span>}]</span><br><span class="line">host = {hostname}</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>创建认证密钥</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ceph auth get-or-create mds.{<span class="variable">$id</span>} mon <span class="string">'profile mds'</span> mgr <span class="string">'profile mds'</span> mds <span class="string">'allow *'</span> osd <span class="string">'allow *'</span> &gt; /var/lib/ceph/mds/ceph-{<span class="variable">$id</span>}/keyring</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>启动 MDS 服务</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now ceph-mds@{<span class="variable">$id</span>}</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>查看集群状态：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ ceph -s</span><br><span class="line">...</span><br><span class="line">mds: cephfs_a-1/1/1 up  {0=c=up:active}, 3 up:standby</span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><h3 id="移除一个-MDS">移除一个 MDS</h3><p>如果想要移除集群中的一个 MDS，可以通过如下步骤</p><ol><li>先创建一个 MDS</li><li>停止旧的 MDS, 启用新的 MDS</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ceph mds fail &lt;mds name&gt;</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>移除旧 MDS 的数据文件夹</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo rm -rf /var/lib/ceph/mds/ceph-{<span class="variable">$id</span>}</span><br></pre></td></tr></tbody></table></figure><h2 id="部署-Ceph-文件系统">部署 Ceph 文件系统</h2><p>部署一个 CephFS, 步骤如下:</p><ol><li>在一个 Mon 节点上创建 Ceph 文件系统.</li><li>若使用 <code>CephX</code> 认证, 需要创建一个访问 CephFS 的客户端</li><li>挂载 CephFS 到一个专用的节点.<ul><li><a href="#%E4%BB%A5-kernel-client-%E5%BD%A2%E5%BC%8F%E6%8C%82%E8%BD%BD-CephFS">以 kernel client 形式挂载 CephFS</a></li><li><a href="#%E4%BB%A5-FUSE-client-%E5%BD%A2%E5%BC%8F%E6%8C%82%E8%BD%BD-CephFS">以 FUSE client 形式挂载 CephFS</a></li></ul></li></ol><h3 id="创建一个-Ceph-文件系统">创建一个 Ceph 文件系统</h3><ol><li>CephFS 需要两个 Pools - <code>cephfs-data</code> 和 <code>cephfs-metadata</code>, 分别存储文件数据和文件元数据:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ ceph osd pool create cephfs-data 256 256</span><br><span class="line">$ ceph osd pool create cephfs-metadata 64 64</span><br></pre></td></tr></tbody></table></figure><p>一般 metadata pool 可以从相对较少的 PGs 启动, 之后可以根据需要增加 PGs. 因为 metadata pool 存储着 CephFS 文件的元数据, 为了保证安全, 最好有较多的副本数. 为了能有较低的延迟, 可以考虑将 metadata 存储在 SSDs 上.<br>2. 安装 <code>ceph-common</code> 包:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install -y ceph-common</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>创建一个 CephFS, 名字为 <code>cephfs</code>:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ceph fs new cephfs cephfs-metadata cephfs-data</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>验证至少有一个 <code>MDS</code> 已经进入 <code>Active</code> 状态:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ceph fs status cephfs</span><br></pre></td></tr></tbody></table></figure><h3 id="创建访问-CephFS-和客户端">创建访问 CephFS 和客户端</h3><ol><li>在 Monitor 上, 创建一个用户:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">$ ceph auth get-or-create client.&lt;id&gt; &lt;capabilities&gt;</span><br><span class="line"><span class="comment">### e.g.:</span></span><br><span class="line">$ ceph auth get-or-create client.cephfs mon <span class="string">'allow r'</span> mds <span class="string">'allow rw'</span> osd <span class="string">'allow rw pool=cephfs-data, allow rw pool=cephfs-metadata'</span></span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>验证生成的 key：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">$ ceph auth get client.&lt;id&gt;</span><br><span class="line"><span class="comment">### e.g.:</span></span><br><span class="line">$ ceph auth get client.cephfs</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>将 client keyring 复制到 client 节点的 <code>/etc/ceph</code> 目录下，并修改权限：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo scp root@mon1:/etc/ceph/ceph.client.cephfs.keyring /etc/ceph/ceph.client.cephfs.keyring</span><br><span class="line">$ sudo chmod 644 /etc/ceph/ceph.client.cephfs.keyring</span><br></pre></td></tr></tbody></table></figure><h3 id="以-kernel-client-形式挂载-CephFS">以 kernel client 形式挂载 CephFS</h3><p>可以手动用 <code>mount</code> 命令挂载 CephFS 或者通过 <code>/etc/fstab</code> 自动挂载 CephFS.</p><h4 id="手动挂载">手动挂载</h4><ol><li>建立挂载点, 例如 <code>/cephfs</code>:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p /cephfs</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>挂载 CephFS. 列出多个 Monitors 的地址, 指定 <code>CephX</code> 所需的密钥文件和客户端名, 注意不是 keyring file:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mount -t ceph mon1:6789,mon2:6789,mon3:6789/ /cephfs -o name=cephfs,secretfile=/etc/ceph/cephfs.secret</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>验证 CephFS 已经成功挂载:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">stat</span> -f /cephfs</span><br></pre></td></tr></tbody></table></figure><h4 id="自动挂载">自动挂载</h4><ol><li>创建挂载点:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p /cephfs</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>编辑 <code>/etc/fstab</code> 文件:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">echo</span> <span class="string">"mon1:6789,mon2:6789,mon3:6789:/ /cephfs ceph name=cephfs,secretfile=/etc/ceph/cephfs.key,_netdev,noatime 0 0"</span> | sudo tee -a /etc/fstab</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>重启或者:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mount -a</span><br></pre></td></tr></tbody></table></figure><h3 id="以-FUSE-client-形式挂载-CephFS">以 FUSE client 形式挂载 CephFS</h3><p>同样地, 可以手动通过 <code>ceph-fuse</code> 挂载或者通过向 <code>/etc/fstab</code> 添加挂载项自动挂载.</p><ol><li>将 <code>ceph.conf</code> 从 Monitor 节点复制到客户端节点,</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo scp root@mon1:/etc/ceph/ceph.conf /etc/ceph/ceph.conf</span><br><span class="line">$ sudo chmod 644 /etc/ceph/ceph.conf</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>客户端上安装 <code>ceph-fuse</code>:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo yum install ceph-fuse -y</span><br></pre></td></tr></tbody></table></figure><h4 id="手动挂载-2">手动挂载</h4><ol><li>创建挂载点, 例如 <code>/cephfs</code>:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p /cephfs</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>使用 <code>ceph-fuse</code> 挂载 CephFS, 如果 对应的 keyring 不在 <code>/etc/ceph</code> 下, 则要显示指定:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ceph-fuse -n client.cephfs [--keyring /etc/ceph/client.cephfs.keyring] /cephfs</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>验证 CephFS 已经成功挂载:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">stat</span> -f /cephfs</span><br></pre></td></tr></tbody></table></figure><h4 id="自动挂载-2">自动挂载</h4><ol><li>创建挂载点:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p /cephfs</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>向 <code>/etc/fstab</code> 添加一项:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ <span class="built_in">echo</span> <span class="string">"none /cephfs fuse.ceph ceph.id=cephfs[,ceph.conf=/etc/ceph/ceph.conf],_netdev,defaults 0 0"</span>| sudo tee -a /etc/fstab</span><br><span class="line"><span class="comment">### or</span></span><br><span class="line">$ <span class="built_in">echo</span> <span class="string">"id=cephfs,conf=/etc/ceph/ceph.conf /mnt/ceph2  fuse.ceph _netdev,defaults 0 0"</span>| sudo tee -a /etc/fstab</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>挂载 CephFS:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mount -a</span><br><span class="line"><span class="comment">## or</span></span><br><span class="line">$ sudo reboot</span><br></pre></td></tr></tbody></table></figure><h2 id="管理-Ceph-文件系统">管理 Ceph 文件系统</h2><h2 id="卸载-Ceph-文件系统">卸载 Ceph 文件系统</h2><h3 id="卸载以-kernel-clients-形式挂载的-CephFS">卸载以 kernel clients 形式挂载的 CephFS</h3><p>跟卸载其他挂载的磁盘一样：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">$ sudo umount &lt;mount-point&gt;</span><br><span class="line"><span class="comment">### e.g.:</span></span><br><span class="line">$ sudo umount /cephfs</span><br></pre></td></tr></tbody></table></figure><h3 id="卸载以-FUSE-client-形式挂载的-CephFS">卸载以 FUSE client 形式挂载的 CephFS</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">$ fusermount -u &lt;mount-point&gt;</span><br><span class="line"><span class="comment">### e.g.:</span></span><br><span class="line">$ sudo fusermount -u /cephfs</span><br></pre></td></tr></tbody></table></figure><h2 id="CephFS-管理命令">CephFS 管理命令</h2><h3 id="文件系统">文件系统</h3><ol><li>创建一个 CephFS。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs new &lt;file system name&gt; &lt;metadata pool name&gt; &lt;data pool name&gt;</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>Ceph 默认只能创建一个 CephFS，若要创建多个，需要设置可创建多个文件系统：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs flag <span class="built_in">set</span> enable_multiple <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>列出所有文件系统：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs ls</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>导出文件系统元数据。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs dump &lt;epoch&gt;</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>删除文件系统。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs rm &lt;file system name&gt; [--yes-i-really-mean-it]</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>获取文件系统设置。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs get &lt;file system name&gt;</span><br></pre></td></tr></tbody></table></figure><ol start="7"><li>更改文件系统设置。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs <span class="built_in">set</span> &lt;file system name&gt; &lt;var&gt; &lt;val&gt;</span><br></pre></td></tr></tbody></table></figure><ol start="8"><li>增加/删除数据 Pool</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">## add data pool</span></span><br><span class="line">ceph fs add_data_pool &lt;file system name&gt; &lt;pool name/id&gt;</span><br><span class="line"><span class="comment">## del data pool</span></span><br><span class="line">ceph fs rm_data_pool &lt;file system name&gt; &lt;pool name/id&gt;</span><br></pre></td></tr></tbody></table></figure><h3 id="设置">设置</h3><ol><li>更改最大文件大小限制：</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs <span class="built_in">set</span> &lt;fs name&gt; max_file_size &lt;size <span class="keyword">in</span> bytes&gt;</span><br></pre></td></tr></tbody></table></figure><p>如果大小设为0， 不意味着大小没有限制，而是只能创建大小为0的文件。最大文件大小过大</p><ol start="2"><li>兼容性设置。设置客户端最小兼容版本</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">## usage</span></span><br><span class="line">ceph fs <span class="built_in">set</span> &lt;fs name&gt; min_compat_client &lt;release&gt;</span><br><span class="line"><span class="comment">## e.g.</span></span><br><span class="line">ceph fs <span class="built_in">set</span> cephfs min_compat_client naultilus</span><br></pre></td></tr></tbody></table></figure><h3 id="上线-下线-文件系统">上线/下线 文件系统</h3><ol><li>下线 CephFS</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs <span class="built_in">set</span> &lt;fs_name&gt; down <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>上线 CephFS</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph fs <span class="built_in">set</span> &lt;fs_name&gt; down <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Ceph File System (CephFS) 是与 POSIX 标准兼容的文件系统, 能够提供对 Ceph 存储集群上的文件访问. Jewel 版本(10.2.0) 是第一个包含稳定 CephFS 的 Ceph 版本. CephFS 需要至少一个元数据服务器 (&lt;code&gt;Metadata Server - MDS&lt;/code&gt;) daemon (&lt;code&gt;ceph-mds&lt;/code&gt;) 运行, MDS daemon 管理着与存储在 CephFS 上的文件相关的元数据, 并且协调着对 Ceph 存储系统的访问.&lt;/p&gt;
    
    </summary>
    
      <category term="Ceph" scheme="https://blog.amito.cc/categories/Ceph/"/>
    
    
      <category term="Ceph" scheme="https://blog.amito.cc/tags/Ceph/"/>
    
      <category term="Storage" scheme="https://blog.amito.cc/tags/Storage/"/>
    
  </entry>
  
  <entry>
    <title>手动部署一个 Ceph 存储集群</title>
    <link href="https://blog.amito.cc/2018/09/Deploy-A-Ceph-Cluster-Manually/"/>
    <id>https://blog.amito.cc/2018/09/Deploy-A-Ceph-Cluster-Manually/</id>
    <published>2018-09-30T05:56:23.000Z</published>
    <updated>2022-04-16T14:26:24.368Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Ceph 提供了 <code>ceph-deploy</code> 工具可以很方便地部署一个 Ceph 集群，为了更好理解和管理 Ceph 集群， 我们也可以手动部署一个 Ceph 集群。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><p>所有的 Ceph 集群都心须有一个 monitor，然后有尽可能多的 OSDs 来存储对象。 Monitors 自举是部署 Ceph 集群的第一步, Monitors 的部署也为整个集群设定了非常重要的条件，比如 Pools 副本数量， 每个 OSD 上的 PG 数， 心跳间隔、是否要求认证等等。 大多数的选项都被设置成默认值。</p><div class="figure center" style="width:;"><img class="fig-img" src="/images/ceph-components.png" alt=""></div><p>接下来我们会建立一个有2个 Monitor nodes 同时作为 OSDs nodes 的 Ceph 集群。</p><h2 id="手动部署-Ceph-集群">手动部署 Ceph 集群</h2><h3 id="Monitor-自举">Monitor 自举</h3><p>一个 Monitor 自举需要以下几个方面：</p><ul><li><strong>唯一标志符</strong>： <code>fsid</code> 是集群的的一个唯一标志符， 当  Ceph 用做 Ceph FileSystem时，也代表着 文件系统 ID。现在 Ceph 支持原生接口，块设备，以及对象存储网关接口等等。所以 <code>fsid</code> 现有点用词不当。</li><li><strong>集群名字</strong>: Ceph 集群有一个集群名字，是一个没有空格的字符串。 默认的名字是 <code>ceph</code>， 可以指定一个不同的名字。当在管理多个集群时，给集群起一个名字是非常有用的，你需要明确指定你要操作的是哪个集群。 这里我们使用 <code>amito</code> 作为集群名字。</li><li><strong>Monitor 名字</strong>: 每一个 monitor 实例都有一个唯一的名字，一般地， Ceph Monitor 名字就是 host 名字。官方推荐 Ceph 的 OSD 实例不要和 Monitor 在同一个 node 上。</li><li><strong>Monitor Map</strong>： 初始的 Monitors 自举要求我们生成一个 monitor map。 Monitor map 需要 <code>fsid</code>， 集群名字，还有至少一个节点名字与 IP 地址。</li><li><strong>Monitor Keyring</strong>: Ceph 中 Monitors 是使用 keyring 来进行认证的来互相通信的，所以需要一个 keyring, 我们需要生成提供一个 monitor secret。</li><li><strong>Administrator Keyring</strong>: 管理节点也需要一个 keyring 来与集群交互, 使用的用户为 <code>client.admin</code>。</li></ul><p>前面的要求并不是指 Ceph 配置文件的生成。但为了方便，官方建议创建一个 包含 <code>fsid</code>，<code>mon initial members</code> 和 <code>mon host</code> 的Ceph 配置文件。步骤如下：</p><ol><li>登陆到 初始 monitor 节点上</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ssh mon-host</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>确保 <code>/etc/ceph</code> 文件夹存在, 安装 ceph 时会创建这一个文件夹。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ls /etc/ceph</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>创建一个 Ceph 配置文件， 默认为 <code>/etc/ceph/ceph.conf</code>， 这里为 <code>/etc/ceph/amito.conf</code></li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo vim /etc/ceph/amito.conf</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>为集群生成一个唯一 ID (fsid)</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ uuidgen &gt; uuid.txt</span><br><span class="line">$ cat uuid.txt</span><br><span class="line">17e4176b-29c6-4479-bb8c-72e0918d908c</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>将这唯一 ID 加到 <code>amito.conf</code> 中。</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fsid = 17e4176b-29c6-4479-bb8c-72e0918d908c</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>添加初始 monitors 到 Ceph 配置文件中</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mon initial members = node1, node2</span><br></pre></td></tr></tbody></table></figure><ol start="7"><li>添加初始 monitors 的 IPs 到 Ceph 配置文件中</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mon host = 192.168.10.1, 10=92.168.10.2</span><br></pre></td></tr></tbody></table></figure><ol start="8"><li>为集群生成一个 keyring, 并生成一个 monitor secret key</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ceph-authtool --create-keyring /tmp/amito.mon.keyring --gen-key -n mon. -<span class="built_in">cap</span> mon <span class="string">'allow *'</span></span><br></pre></td></tr></tbody></table></figure><ol start="9"><li>生成一个 <code>administrator</code> keyring， 一个 <code>client.admin</code> 用户， 并加到 keyring 中</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ceph-authtool --create-keyring /etc/ceph/amito.client.admin.keyring --gen-key -n client.admin --<span class="built_in">cap</span> mon <span class="string">'allow *'</span> --<span class="built_in">cap</span> osd <span class="string">'allow *'</span> --<span class="built_in">cap</span> mds <span class="string">'allow *'</span> --<span class="built_in">cap</span> mgr <span class="string">'allow *'</span></span><br></pre></td></tr></tbody></table></figure><ol start="10"><li>创建一个 <code>bootstrap－osd</code> keyring, 生成一个 <code>bootstrap-osd</code> 用户，并加到 keyring 中</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo ceph-authtool --create-keyring /var/lib/ceph/bootstrap-osd/amito.keyring --gen-key -n client.bootstrap-osd --<span class="built_in">cap</span> mon <span class="string">'profile bootstrap-osd'</span></span><br></pre></td></tr></tbody></table></figure><ol start="11"><li>将生成的 keyrings 加到 <code>amito.mon.keyring</code> 中</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ceph-authtool /tmp/amito.mon.keyring --import-keyring /etc/ceph/amito.client.admin.keyring</span><br><span class="line">$ sudo ceph-authtool /tmp/amito.mon.keyring --import-keyring /var/lib/ceph/bootstrap-osd/amito.keyring</span><br></pre></td></tr></tbody></table></figure><ol start="12"><li>使用 <code>节点名</code>，<code>IP地址</code>， 和 <code>fsid</code> 生成一个 <code>monitor map</code>， 保存到 <code>/tmp/monmap</code></li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ monmaptool --create --add {hostname} {ip-address} --fsid {uuid} /tmp/monmap</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ monmaptool --create --add node1 192.168.10.1 --fsid {uuid} /tmp/monmap</span><br><span class="line">$ monmaptool --add node2 192.168.10.2 --fsid {uuid} /tmp/monmap</span><br></pre></td></tr></tbody></table></figure><ol start="13"><li>在 monitor 节点上创建默认的数据文件夹</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ sudo mkdir -p /var/lib/ceph/mon/{cluster-name}-{hostname}</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ sudo mkdir -p /var/lib/ceph/mon/amito-node1</span><br></pre></td></tr></tbody></table></figure><ol start="14"><li>利用 monitor map 和 keyring 配置 Mon 节点.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">$ sudo ceph-mon [--cluster cluster-name] --mkfs -i {hostname}  --monmap  /tmp/monmap --keyring /tmp/ceph.mon.keyring</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ sudo ceph-mon --cluster amito --mkfs -i 192.168.10.1 --monmap /tmp/monmap --keyring /tmp/ceph.mon.keyring</span><br></pre></td></tr></tbody></table></figure><ol start="15"><li>设置 Ceph 配置文件. 如下是一个例子.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">[global]</span><br><span class="line">fsid = 17e4176b-29c6-4479-bb8c-72e0918d908c</span><br><span class="line">mon initial members = node1</span><br><span class="line">mon host = 192.168.10.1</span><br><span class="line">public network = 192.168.0.0/24</span><br><span class="line">auth cluster required = cephx</span><br><span class="line">auth service required = cephx</span><br><span class="line">auth client required = cephx</span><br><span class="line">osd journal size = 1024</span><br><span class="line">osd pool default size = 2</span><br><span class="line">osd pool default min size = 1</span><br><span class="line">osd pool default pg num = 256</span><br><span class="line">osd pool default pgp num = 256</span><br><span class="line">osd crush chooseleaf <span class="built_in">type</span> = 1</span><br></pre></td></tr></tbody></table></figure><ol start="16"><li>创建完成文件. 标记 monitor 已经创建完并可以启动.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">$ sudo touch /var/lib/ceph/mon/{cluster-name}-{hostname}/<span class="keyword">done</span></span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ sudo touch /var/lib/ceph/mon/amito-node1/<span class="keyword">done</span></span><br></pre></td></tr></tbody></table></figure><ol start="17"><li>启动 Ceph Monitor.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### systemd</span></span><br><span class="line">$ sudo su -c <span class="string">'echo "CLUSTER={cluster-name}" &gt; /etc/sysconfig/ceph'</span></span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now ceph-mon@{hostname}</span><br><span class="line"><span class="comment">###　older debian, centos or rhel</span></span><br><span class="line">$ sudo /etc/init.d/ceph start mon.{hostname}</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ sudo systemctl <span class="built_in">enable</span> --now ceph-mon@node1</span><br></pre></td></tr></tbody></table></figure><ol start="18"><li>查看 Ceph 集群状态.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">$ ceph -s</span><br><span class="line">cluster:</span><br><span class="line">  id:     17e4176b-29c6-4479-bb8c-72e0918d908c</span><br><span class="line">  health: HEALTH_OK</span><br><span class="line"></span><br><span class="line">services:</span><br><span class="line">  mon: 2 daemons, quorum node1, node2</span><br><span class="line">  osd: 0 osds: 0 up, 0 <span class="keyword">in</span></span><br><span class="line"></span><br><span class="line">data:</span><br><span class="line">  pools:   0 pools, 0 pgs</span><br><span class="line">  objects: 0 objects, 0 bytes</span><br><span class="line">  usage:   0 kB used, 0 kB / 0 kB avail</span><br><span class="line">  pgs:</span><br></pre></td></tr></tbody></table></figure><h3 id="设置-Ceph-Manager">设置 Ceph Manager</h3><ol><li>生成一个认证 Key</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ name={hostname}</span><br><span class="line">$ ceph --cluster amito auth get-or-create mgr.<span class="variable">$name</span> mon <span class="string">'allow profile mgr'</span> osd <span class="string">'allow *'</span> mds <span class="string">'allow *'</span></span><br></pre></td></tr></tbody></table></figure><p>将 生成的 Key 放在 mgr data 文件夹, 一般是在 <code>/var/lib/ceph/mgr/{cluster-name}-{name}</code><br>2. 启动 ceph-mgr:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo ceph-mgr -i <span class="variable">$name</span></span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>查看 mgr 状态:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ ceph -s</span><br><span class="line">...</span><br><span class="line">mgr status: <span class="variable">${name}</span></span><br></pre></td></tr></tbody></table></figure><p>一般为了高可用, 每个 mon 节点都应该运行一个 mgr 进程.</p><h3 id="添加-OSD">添加 OSD</h3><p>在初始 monitors 开始运行后, 我们就该添加 OSDs 到 集群中了. 集群只有在有足够的 OSDs 来处理对象副本数量时才会达到 <code>active+clean</code> 状态.</p><h4 id="自动模式">自动模式</h4><h4 id="BLUSTORE">BLUSTORE</h4><ol><li>创建 OSD: 联合模式</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ ssh node1</span><br><span class="line">$ sudo ceph-volume lvm create --data {data-path}</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ sudo ceph-volume lvm create --data /dev/sdb1</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>创建 OSD: 分裂模式</li></ol><figure class="highlight clean"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">#### <span class="number">1.</span> prepare osd</span><br><span class="line">$ sudo ceph-volume lvm prepare --data {data-path}</span><br><span class="line">$ sudo ceph-volume lvm list</span><br><span class="line">### e.g.</span><br><span class="line">$ sudo ceph-volume lvm prepare --data /dev/sdb2</span><br><span class="line">#### <span class="number">2.</span> activate osd</span><br><span class="line">$ sudo ceph-volume lvm activate {ID} {FSID}</span><br><span class="line">### e.g</span><br><span class="line">$ sudo ceph-volume lvm activate <span class="number">1</span> <span class="number">17e4176</span>b<span class="number">-29</span>c6<span class="number">-4479</span>-bb8c<span class="number">-72e0918</span>d908c</span><br></pre></td></tr></tbody></table></figure><h4 id="FILESTORE">FILESTORE</h4><ol><li>创建 OSD: 联合模式</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ ssh node1</span><br><span class="line">$ sudo ceph-volume lvm create --filestore --data {data-path}</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ sudo ceph-volume lvm create --filestore --data /dev/sdb3</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>创建 OSD: 分裂模式</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#### 1. prepare osd</span></span><br><span class="line">$ sudo ceph-volume lvm prepare --filestore --data {data-path}</span><br><span class="line">$ sudo ceph-volume lvm list</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ sudo ceph-volume lvm prepare --filestore --data /dev/sdb4</span><br><span class="line"><span class="comment">#### 2. activate osd</span></span><br><span class="line">$ sudo ceph-volume lvm activate {ID} {FSID}</span><br><span class="line"><span class="comment">### e.g</span></span><br><span class="line">$ sudo ceph-volume lvm activate 4 17e4176b-29c6-4479-bb8c-72e0918d908c</span><br></pre></td></tr></tbody></table></figure><h4 id="手动模式">手动模式</h4><ol><li>登陆到 OSD 节点:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ ssh node1</span><br><span class="line">$ sudo bash</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>生成一个 UUID</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ uuidgen &gt; osd.uuid.txt</span><br><span class="line">$ cat osd.uuid.txt</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>创建一个 CephX key:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ OSD_SECRET=$(ceph-authtool --get-print-key)</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>创建 OSD.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">ID=$(<span class="built_in">echo</span> <span class="string">"{\"cephx_secret\": \"<span class="variable">$OSD_SECRET</span>\"}"</span> | \</span><br><span class="line">   ceph osd new <span class="variable">$UUID</span> -i - \</span><br><span class="line">   -n client.bootstrap-osd -k /var/lib/ceph/bootstrap-osd/ceph.keyring) </span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>创建 OSD 目录文件.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir /var/lib/ceph/osd/ceph-<span class="variable">$ID</span></span><br></pre></td></tr></tbody></table></figure><h3 id="添加-MDS">添加 MDS</h3><ol><li>创建 MDS 数据文件夹. id 为任意名字, 一般取为 hostname.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ mkdir -p /var/lib/ceph/mds/{cluster-name}-{id}</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>生成 Keyring.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ ceph-authtool --create-keyring /var/lib/ceph/mds/{cluster-name}-{id}/keyring --gen-key -n mds.{id}</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li>导入 Key 并设置 caps.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ceph auth add mds.{id} osd <span class="string">"allow rwx"</span> mds <span class="string">"allow"</span> mon <span class="string">"allow profile mds"</span> -i /var/lib/ceph/mds/{cluster}-{id}/keyring</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>将设置写入 Ceph 配置文件</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[mds.{id}]</span><br><span class="line">host = {id}</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>手动启动 mds</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">$ ceph-mds --cluster {cluster-name} -i {id} -m {mon-hostname}:{mon-port} [-f]</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ ceph-mds --cluster ceph -i node1 -m {mon-hostname}:{mon-port} -f</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>或者使用 <code>systemd</code> 或者 <code>sysinitv</code> 启动:</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### usage:</span></span><br><span class="line">sudo systemctl <span class="built_in">enable</span> --now ceph-mds@id</span><br><span class="line">7. 安装 Ceph FileSystem</span><br></pre></td></tr></tbody></table></figure><h3 id="总结">总结</h3><p>在设置了 monitor, manager 和 OSDs 后, 可以查看 Ceph 集群的状态:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ ceph -s</span><br><span class="line">$ ceph -w</span><br><span class="line">$ ceph osd tree</span><br></pre></td></tr></tbody></table></figure><h2 id="重命名-Ceph-集群">重命名 Ceph 集群</h2><p>通过上面的手动创建过程可以看到, Ceph 集群名字更多是一个标志名, 没有进行硬编码. 所以可以对 Ceph 集群进行重命名. 具体过程就是将所有的文件夹和文件重命名, 例如从 <code>ceph</code> 到 <code>remote</code>.  改完后重启整个集群.</p><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Ceph 提供了 &lt;code&gt;ceph-deploy&lt;/code&gt; 工具可以很方便地部署一个 Ceph 集群，为了更好理解和管理 Ceph 集群， 我们也可以手动部署一个 Ceph 集群。&lt;/p&gt;
    
    </summary>
    
      <category term="Ceph" scheme="https://blog.amito.cc/categories/Ceph/"/>
    
    
      <category term="Ceph" scheme="https://blog.amito.cc/tags/Ceph/"/>
    
      <category term="Linux" scheme="https://blog.amito.cc/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>在 Linux 中使用 Cron 执行定时任务</title>
    <link href="https://blog.amito.cc/2018/09/Using-Crontab-in-Linux/"/>
    <id>https://blog.amito.cc/2018/09/Using-Crontab-in-Linux/</id>
    <published>2018-09-30T02:08:36.000Z</published>
    <updated>2022-04-16T14:26:24.376Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>工作中我们常常需要在某些时候执行一些任务，Windows 下有定时任务管理， Linux 下则有 Crontab， 接触过 Linux 的童鞋一定不陌生。</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><p>Cron 是 Unix，Solaris， Linux 等系统下的可以自动在后台执行定时任务的工具，比如在某一天 9 点提醒你开会， 某一天 6 点去给女票买礼物等等， 这是由 cron 守护进程定期执行的。 如果启用了 <code>cron</code>（一般默认启用), <code>cron 守护进程</code> 会在系统启动后自动启动， 并按时执行任务。 <code>cron</code> 也能手动启用、关闭、重启等。</p><h2 id="认识-crontab">认识 crontab</h2><p>Crontab 是 cron 的任务库文件，它存储了 cron 要执行的计划任务项目。 不同系统下该文件的位置可能不同。</p><ul><li><strong>macOS</strong>: <code>/usr/lib/cron/tabs/</code></li><li><strong>BSD Unix</strong>: <code>/var/cron/tabs/</code></li><li><strong>Solaris, Debian</strong>: <code>/var/spool/cron/crontabs/</code></li><li><strong>RHEL, CentOS, Fedora</strong>: <code>/var/spool/cron/</code></li></ul><p><code>cron</code> 任务是一个包含特定日期，特定时间和要执行的命令的集合, 存储在 <code>crontab</code> 里。一个 <code>crontab</code> 条目如下图所示，指定了在每个月的所有周日凌晨 2 点 36 分 执行 <code>/usr/local/sbin/</code>  下的 <code>backup.sh</code> 脚本。</p><div class="figure center" style="width:;"><img class="fig-img" src="/images/crontab.jpg" alt="Crontab"><span class="caption">Crontab</span></div><h2 id="Crontab-命令">Crontab 命令</h2><p>crontab 命令很简单，</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost ~]$ crontab [-u username] [-l|-r|-e] [-n &lt;host&gt;|-c] [-s] [-x &lt;mask&gt;]</span><br></pre></td></tr></tbody></table></figure><p>各选项含义如下：</p><ul><li><strong>-u</strong>: 指定 <code>crontab</code> 的用户名, 此选项只能 <code>root</code> 使用</li><li><strong>-e</strong>: 编辑 <code>crontab</code> 文件， 如果没有，会新建一个</li><li><strong>-l</strong>: 打印出 <code>crontab</code> 文件内容，列出计划任务</li><li><strong>-r</strong>: 移出 <code>crontab</code> 文件</li><li><strong>-n <host></host></strong>: 设定在 集群中的 host 主机上执行用户 crontabs</li><li><strong>-c</strong>: 获取用户在集群上的 crontabs</li><li><strong>-s</strong>: selinux 相关内容</li><li><strong>-x <mask></mask></strong>: 开启 debug<br>执行 <code>crontab -e</code> 后就会进入 <code>crontab</code> 编辑环境。</li></ul><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># # Example of job definition:</span></span><br><span class="line">.---------------- minute (0 - 59)</span><br><span class="line">|  .------------- hour (0 - 23)</span><br><span class="line">|  |  .---------- day of month (1 - 31)</span><br><span class="line">|  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...</span><br><span class="line">|  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat</span><br><span class="line">|  |  |  |  |</span><br><span class="line">*  *  *  *  *   <span class="built_in">command</span> to be executed</span><br></pre></td></tr></tbody></table></figure><p>时间格式为 <code>min hour day_of_month month day_of_week</code>, 每一项都是一定范围的整数或者数组或者范围。 一些辅助的字符有特别的意义。</p><table><thead><tr><th>特殊字符</th><th>代表含义</th></tr></thead><tbody><tr><td>*</td><td>代表任何可能的值</td></tr><tr><td>,</td><td>代表分隔时段， <code>0 3,6 * * * command</code> 表示在每天 3:00， 6:00 执行任务</td></tr><tr><td>-</td><td>代表时间范围， <code>0 10-20 * * * command</code> 表示在每天10:00 到 20:00 执行任务</td></tr><tr><td>/n</td><td>代表 <code>每隔 n 单位时间</code> 重复一次</td></tr></tbody></table><p>下面举几个 Crontab 的使用例子。</p><h2 id="Crontab-例子">Crontab 例子</h2><h3 id="备份系统">备份系统</h3><p>每天 00:00 准时备份系统</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0 0 * * * /usr/<span class="built_in">local</span>/bin/backup.sh</span><br></pre></td></tr></tbody></table></figure><h3 id="会议提醒">会议提醒</h3><p>提醒每周五下午 2:30 开会</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">20 14 * * 5 /path/to/alert.sh</span><br></pre></td></tr></tbody></table></figure><h3 id="记录-IP">记录 IP</h3><p>每隔 3 小时记录 IP 并发送到指定邮箱</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0 */3 * * * <span class="built_in">echo</span> <span class="string">"<span class="subst">$(date)</span> : <span class="subst">$(hostname -I)</span>"</span> | mutt -s <span class="string">"your ip"</span> your_email_address &gt; /dev/null 2&gt;&amp;1</span><br></pre></td></tr></tbody></table></figure><h2 id="Crontab-使用补充">Crontab 使用补充</h2><h3 id="系统设定">系统设定</h3><p>如果你要做的是系统的例行性任务，则可以使用 <code>/etc/crontab</code>, 在里面加入你的定时任务就好。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost ~]$ cat /etc/crontab</span><br><span class="line">SHELL=/bin/bash                     &lt;==使用哪种 shell</span><br><span class="line">PATH=/sbin:/bin:/usr/sbin:/usr/bin  &lt;==执行程序搜索路径</span><br><span class="line">MAILTO=root                         &lt;==若有額外STDOUT，以 email 将输出发送给谁</span><br><span class="line"></span><br><span class="line"><span class="comment"># Example of job definition:</span></span><br><span class="line"><span class="comment"># .---------------- minute (0 - 59)</span></span><br><span class="line"><span class="comment"># |  .------------- hour (0 - 23)</span></span><br><span class="line"><span class="comment"># |  |  .---------- day of month (1 - 31)</span></span><br><span class="line"><span class="comment"># |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...</span></span><br><span class="line"><span class="comment"># |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat</span></span><br><span class="line"><span class="comment"># |  |  |  |  |</span></span><br><span class="line"><span class="comment"># *  *  *  *  * user-name  command to be executed</span></span><br></pre></td></tr></tbody></table></figure><p>可以按照这个格式添加任务， 其中相对于 <code>crontab -e</code>， 多了一个 user-name， 即运行任务的用户。</p><h3 id="系统资源">系统资源</h3><p>若定期运行的任务很多， 有时候会在某一时候运行很多任务， 系统资源会比较紧张，可以将任务分散开，使得系统负载相对平稳。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">[root@localhost ~]$ cat /etc/crontab</span><br><span class="line">0,5,10,15,20,25,30,35,40,45,50,55 * * * * root  scripts_1.sh</span><br><span class="line">1,6,11,16,21,26,31,36,41,46,51,56 * * * * root  scripts_2.sh</span><br><span class="line">2,7,12,17,22,27,32,37,42,47,52,57 * * * * root  scripts_3.sh</span><br><span class="line">3,8,13,18,23,28,33,38,43,48,53,58 * * * * root  scripts_4.sh</span><br><span class="line">4,9,14,19,24,29,34,39,44,49,54,59 * * * * root  scripts_5.sh</span><br></pre></td></tr></tbody></table></figure><h3 id="使用限制">使用限制</h3><p>如果你的用户名在 <code>/etc/cron.allow</code> 中， 那是可以使用 <code>crontab</code> 的，但如果是在<br><code>/etc/cron.deny</code> 中， 则无法使用并安排定时任务的。 <code>/etc/cron.allow</code> 的优先级高于 <code>/etc/cron.deny</code>。</p><h3 id="关闭邮件通知">关闭邮件通知</h3><p><code>cron</code> 任务默认会在执行一个 cronjob 后发送一封邮件的，如果执行任务勤了，会产生大量的邮件。如果输出不是必要的， 则可以通过在任务结尾加上重定向：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt;/dev/null 2&gt;&amp;1</span><br></pre></td></tr></tbody></table></figure><p>或者重定向到一个日志文件：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&gt; /path/to/your/<span class="built_in">log</span>/file 2&gt;&amp;1</span><br></pre></td></tr></tbody></table></figure><h3 id="环境变量">环境变量</h3><p><code>cron</code> 会在用户 <code>HOME</code> 文件夹下执行命令，默认的环境变量有：</p><ul><li><strong>HOME=user-home-directory</strong></li><li><strong>LOGNAME=user-login-id</strong></li><li><strong>PATH=/usr/bin:/usr/sbin</strong></li><li><strong>SHELL=/usr/bin/sh</strong><br>要是你想要任务开始时执行 <code>~/.profile</code> 里的命令， 需要显示地在脚本里执行 <code>source ~/.profile</code></li></ul><h3 id="安全检测">安全检测</h3><p>有可能服务器会被人入侵，植入的木马一般都会以定时任务的形式运行，可以检查 <code>/var/spool/cron/</code> 有没有问题。</p><h3 id="周与日">周与日</h3><p><code>day_of_month</code> 与 <code>day_of _week</code> 一般不能同时设定，若同时设定了，系统会在所有符合一个或两个的日期都执行命令。</p><h3 id="执行关机期间的任务">执行关机期间的任务</h3><p>如果关机有任务没有执行， 开机后 cron 也不会执行过期的任务。想要执行过期任务，可以使用 <code>anacron</code>。 它作为定时会每小时被执行一次， 执行 cron 没有执行的任务。</p><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;工作中我们常常需要在某些时候执行一些任务，Windows 下有定时任务管理， Linux 下则有 Crontab， 接触过 Linux 的童鞋一定不陌生。&lt;/p&gt;
    
    </summary>
    
      <category term="Linux" scheme="https://blog.amito.cc/categories/Linux/"/>
    
    
      <category term="Linux" scheme="https://blog.amito.cc/tags/Linux/"/>
    
      <category term="Shell" scheme="https://blog.amito.cc/tags/Shell/"/>
    
  </entry>
  
  <entry>
    <title>使用 Ceph 作为 QEMU KVM 虚拟机的存储</title>
    <link href="https://blog.amito.cc/2018/09/Using-Ceph-RBD-as-A-Backend-for-QEMU-KVM-Instances/"/>
    <id>https://blog.amito.cc/2018/09/Using-Ceph-RBD-as-A-Backend-for-QEMU-KVM-Instances/</id>
    <published>2018-09-26T07:23:15.000Z</published>
    <updated>2022-04-16T14:26:24.376Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>Ceph RBD 块设备存储是十分适合作为虚拟化平台的存储后端的, 这也是其最常用的情景之一. 这篇主要介绍如何将 Ceph RBD 作为 QEMU 等的存储端.</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><p>RBD 具有快照的特性, 我们又可以对 RBD 快照进行克隆, 创建一系列的写时复制克隆复本. RBD 的这一特性可以让 Ceph 能够很快地给虚拟机提供块设备, 因为客户端不需要每次在新建虚拟机时都下载整个镜像.</p><div class="figure center" style="width:;"><img class="fig-img" src="/images/ceph-rbd-qemu.png" alt=""></div><p><code>libvirt</code> 为 OpenStack, CloudStack 等云计算平台提供 Ceph 块设备服务, 云计算平台使用 <code>libvirt</code> 与 <code>QEMU/KVM</code> 等交互, <code>QEMU/KVM</code> 等使用 <code>librbd</code> 与 Ceph RBD 块设备交互.</p><p>Ceph RBD 可以作为 VMs 的数据盘和系统盘来使用. 下面我们就来看看如何实现这一目标.</p><h2 id="配置-Ceph">配置 Ceph</h2><p>要配置 Ceph 来配合 <code>libvirt</code>, 可依照如下步骤.</p><ol><li><strong>创建一个 Pool</strong>. 专门为 <code>libvirt</code> 创建一个 Pool, 并初始化.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ ceph osd pool create libvirt-pool 128 128</span><br><span class="line">[ceph@ceph0 ~]$ ceph osd lspools</span><br><span class="line">[ceph@ceph0 ~]$ rbd pool init libvirt-pool</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li><strong>创建与 Ceph 交互的 User</strong>. 这里使用 <code>client.libvirt</code> 作为用户名, libvirt 会使用 <code>libvirt</code> 而不是 <code>client.libvirt</code> 与 Ceph 交互.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ ceph auth get-or-create client.libvirt mon <span class="string">'profile rbd'</span> osd <span class="string">'profile rbd pool=libvirt-pool'</span></span><br><span class="line">[ceph@ceph0 ~]$ ceph auth ls</span><br></pre></td></tr></tbody></table></figure><ol start="3"><li><strong>使用 QEMU 新建 images</strong>. 比如新建一个 <code>linux-image</code>, 一个 <code>windows-image</code>.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ qemu-img create -f rbd rbd:libvirt-pool/linux-image 60G</span><br><span class="line">[ceph@ceph0 ~]$ qemu-img create -f rbd rbd:libvirt-pool/windows-image 80G</span><br><span class="line">[ceph@ceph0 ~]$ rbd -p libvirt-pool ls</span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>添加如下部分到 <code>/etc/ceph/ceph.conf</code> 中,以便调试错误. (可选)</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">[client.libvirt]</span><br><span class="line"><span class="built_in">log</span> file = /var/<span class="built_in">log</span>/ceph/qemu-guest-<span class="variable">$pid</span>.<span class="built_in">log</span></span><br><span class="line">admin socket = /var/run/ceph/<span class="variable">$cluster</span>-<span class="variable">$type</span>.<span class="variable">$id</span>.<span class="variable">$pid</span>.<span class="variable">$cctid</span>.asok</span><br></pre></td></tr></tbody></table></figure><h2 id="配置-VM-Managers">配置 VM Managers</h2><p><code>libvirt</code> 可以直接创建 VMs, 但是使用 <code>virt-manager</code> 可能麦加方便一些.</p><ol><li><strong>安装 VM manager</strong>.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ sudo yum install -y virt-manager</span><br></pre></td></tr></tbody></table></figure><ol start="2"><li><strong>准备好 OS images</strong>. 这里我们用 <code>CentOS 7.5</code> 和 <code>Windows 7 64 bit</code> 两个系统.</li><li><strong>启动 VMs manager</strong>.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ virt-manager</span><br></pre></td></tr></tbody></table></figure><p>接下来我们就开始安装 VMs 了.</p><h2 id="创建-VMs">创建 VMs</h2><h3 id="创建-Linux-VMs">创建 Linux VMs</h3><ol><li>点击 <code>Create New Virtual Machine</code> 按钮.</li><li>命名 虚拟机 的域. 例如 <code>centos</code>.</li><li>导入 OS image.</li><li>配置启动 VM</li><li>要使用 Ceph RBD 作为系统盘, 先不要安装系统,</li><li>要使用 Ceph RBD 作为数据盘, 可以先安装系统.VM.</li></ol><p>接下我们先关掉 VM.</p><h3 id="配置-Linux-VMS">配置 Linux VMS</h3><ol><li>打开 VM 配置文件.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo virsh edit centos</span><br></pre></td></tr></tbody></table></figure><p>在 <code>&lt;devices&gt;</code> 下应该有一个 <code>&lt;disk&gt;</code> 项.</p><figure class="highlight xml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">devices</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">emulator</span>&gt;</span>/usr/bin/kvm<span class="tag">&lt;/<span class="name">emulator</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">disk</span> <span class="attr">type</span>=<span class="string">'file'</span> <span class="attr">device</span>=<span class="string">'disk'</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">driver</span> <span class="attr">name</span>=<span class="string">'qemu'</span> <span class="attr">type</span>=<span class="string">'raw'</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">source</span> <span class="attr">file</span>=<span class="string">'/path/to/image/recent-linux.img'</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">target</span> <span class="attr">dev</span>=<span class="string">'vda'</span> <span class="attr">bus</span>=<span class="string">'virtio'</span>/&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">address</span> <span class="attr">type</span>=<span class="string">'drive'</span> <span class="attr">controller</span>=<span class="string">'0'</span> <span class="attr">bus</span>=<span class="string">'0'</span> <span class="attr">unit</span>=<span class="string">'0'</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">disk</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">devices</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure><ol start="2"><li>如果使用 RBD 作为数据盘, 在其下面加上下面项.  如果用作系统盘, 去掉上面的一项, 再加上下面一项.</li></ol><figure class="highlight xml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">disk</span> <span class="attr">type</span>=<span class="string">'network'</span> <span class="attr">device</span>=<span class="string">'disk'</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">source</span> <span class="attr">protocol</span>=<span class="string">'rbd'</span> <span class="attr">name</span>=<span class="string">'libvirt-pool/new-libvirt-image'</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">host</span> <span class="attr">name</span>=<span class="string">'{monitor-host}'</span> <span class="attr">port</span>=<span class="string">'6789'</span>/&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">source</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">target</span> <span class="attr">dev</span>=<span class="string">'vda'</span> <span class="attr">bus</span>=<span class="string">'virtio'</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">disk</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure><p>将其中的 <code>{monitor-host}</code> 替换成真实的 hosts. 保存并退出.<br>3. 配置 <code>Ceph Authentication</code>. 一般 Ceph 集群都设置了登录认证. 我们需要生成一个 <code>secret</code>.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">cat &gt; secret.xml &lt;&lt;<span class="string">EOF</span></span><br><span class="line"><span class="string">&lt;secret ephemeral='no' private='no'&gt;</span></span><br><span class="line"><span class="string">        &lt;usage type='ceph'&gt;</span></span><br><span class="line"><span class="string">                &lt;name&gt;client.libvirt secret&lt;/name&gt;</span></span><br><span class="line"><span class="string">        &lt;/usage&gt;</span></span><br><span class="line"><span class="string">&lt;/secret&gt;</span></span><br><span class="line"><span class="string">EOF</span></span><br></pre></td></tr></tbody></table></figure><ol start="4"><li>定义 <code>secret</code>.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ sudo virsh secret-define --file secret.xml &gt; uuid.txt</span><br></pre></td></tr></tbody></table></figure><ol start="5"><li>获取 <code>client.libvirt</code> key, 并保存到 <code>client.libvirt.key</code>.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ ceph auth get-key client.libvirt | sudo tee client.libvirt.key</span><br></pre></td></tr></tbody></table></figure><ol start="6"><li>设置 <code>secret</code> 的 UUID.</li></ol><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ sudo virsh secret-value --secret $(cat uuid.txt) --base64 $(cat client.libvirt.key)</span><br></pre></td></tr></tbody></table></figure><ol start="7"><li>在虚拟机配置里加上认证信息. 在<code>&lt;disk type='network' device='disk'&gt;</code>下面加上如下项.</li></ol><figure class="highlight xml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">auth</span> <span class="attr">username</span>=<span class="string">'libvirt'</span>&gt;</span></span><br><span class="line">     <span class="tag">&lt;<span class="name">secret</span> <span class="attr">type</span>=<span class="string">'ceph'</span> <span class="attr">uuid</span>=<span class="string">'9ec59067-fdbc-a6c0-03ff-df165c0587b8'</span>/&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">auth</span>&gt;</span></span><br></pre></td></tr></tbody></table></figure><ol start="8"><li>开机启动 VM, 就可以使用 rbd 来当作系统盘或数据盘了.</li></ol><h3 id="配置-Windows-VMs">配置 Windows VMs</h3><p>Windows VM 与 Linux VM 下同的一点是它没有自带 <code>virtio</code> 的驱动, 所以在安装系统时, Windows 并不能识别 rbd 设备. 需要下载 <a href="https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso">virtio-win</a>.<br>将下载的镜像挂载到 VM 上, 在选择安装到硬盘界面时, 选择加载驱动, 选择 virtio-win 镜像下的 <code>/viostor/w7/amd64/</code> 文件夹. 加载之后, 就可以识别了. 然后就可以将 Window 安装到 Ceph 的 RBD 上了.</p><p>要是将 RBD 当作数据盘, 可以在安装好系统后, 在 Window 下安装驱动, 这更方便.</p><h3 id="挂载到现有-VMs">挂载到现有 VMs</h3><p>可以动态将 Volume 挂载到 VMs 上:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">$ cat &lt;&lt; <span class="string">EOF &gt; device.xml</span></span><br><span class="line"><span class="string">&lt;disk type='network' device='disk'&gt;</span></span><br><span class="line"><span class="string">&lt;driver name='qemu' type='raw'/&gt;</span></span><br><span class="line"><span class="string">&lt;auth username='vmimages'&gt;</span></span><br><span class="line"><span class="string">&lt;secret type='ceph' uuid='9ec59067-fdbc-a6c0-03ff-df165c0587b8'/&gt;</span></span><br><span class="line"><span class="string">&lt;/auth&gt;</span></span><br><span class="line"><span class="string">&lt;source protocol='rbd' name='libvirt-pool/new-libvirt-image'&gt;</span></span><br><span class="line"><span class="string">&lt;host name='{monitor-host}' port='6789'/&gt;</span></span><br><span class="line"><span class="string">&lt;/source&gt;</span></span><br><span class="line"><span class="string">&lt;target dev='vdc' bus='virtio'/&gt;</span></span><br><span class="line"><span class="string">&lt;/disk&gt;</span></span><br><span class="line"><span class="string">EOF</span></span><br><span class="line">$ virsh attach-device centos device.xml --persistent</span><br></pre></td></tr></tbody></table></figure><h3 id="查看-QEMU-与-CEPH-交互">查看 QEMU 与 CEPH 交互</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ sudo virsh qemu-monitor-command --hmp {vm-domain-name} <span class="string">'info block'</span></span><br></pre></td></tr></tbody></table></figure><h2 id="配置-QEMU-KVM">配置 QEMU/KVM</h2><p>要使 libvirt 能够操作 Ceph RBD, 需要安装 <code>qemu-block-rbd</code>:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ sudo yum install -y qemu-block-rbd</span><br></pre></td></tr></tbody></table></figure><p>这里简单介绍一个 与 rbd 相关的 <code>qemu-img</code> 的用法.</p><h3 id="基本用法">基本用法</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[ceph@ceph0 ~]$ qemu-img {<span class="built_in">command</span>} [options] rbd:{pool-name}/{image-name}[@snapshot-name]:[:option1=value1][:option2=value2...]</span><br></pre></td></tr></tbody></table></figure><p>例如, 指定 user id 和 conf 文件</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ qemu-img {<span class="built_in">command</span>} [options] rbd:libvirt-pool/linux:id=libvirt:conf=/etc/ceph/ceph.conf</span><br></pre></td></tr></tbody></table></figure><h3 id="创建-images">创建 images</h3><p>我们可以用 <code>qemu-img</code> 来创建 image, 如下所示. <code>rbd</code> 是必须指定的, pool name 和 image name 也是必须的. 格式 <code>-f raw</code> 是最合理的格式. 其他格式也可以,但可能会引起不必要的又比较麻烦的问题.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### Usage</span></span><br><span class="line">$ qemu-img create -f raw rbd:{pool-name}/{image-name} {size}</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ qemu-img create -f raw rbd:libvirt-pool/new-image 20G</span><br></pre></td></tr></tbody></table></figure><h3 id="调整-images-大小">调整 images 大小</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### Usage</span></span><br><span class="line">$ qemu-img resize rbd:{pool-name}/{image-name} {size}</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ qemu-img resize rbd:libvirt-pool/new-image 50G</span><br><span class="line">$ qemu-img resize rbd:libvirt-pool/new-image +20G</span><br></pre></td></tr></tbody></table></figure><h3 id="获取-image-信息">获取 image 信息</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">### Usage</span></span><br><span class="line">$ qemu-img info rbd:{pool-name}/{image-name}</span><br><span class="line"><span class="comment">### e.g.</span></span><br><span class="line">$ qemu-img info rbd:libvirt-pool/new-image</span><br></pre></td></tr></tbody></table></figure><h3 id="运行-VMs">运行 VMs</h3><p>QEMU 可以通过 <code>librbd</code> 直接将 rbd 作为虚拟块设备使用. <code>qemu-img</code> 可以将已经存在的虚拟机镜像转换到 Ceph RBD images. 如</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ qemu-img convert -f qcow2 -O raw centos.qcow2 rbd:libvirt-pool/centos</span><br></pre></td></tr></tbody></table></figure><p>要从转换后的 image 启动一个虚拟机, 运行如下命令:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ qemu -m 1024 -drive format=raw,file=rbd:data/centos,cache=writeback</span><br></pre></td></tr></tbody></table></figure><p>上面的 <code>cache=writeback</code> 是启用 RBD的 caching 功能, 可大大提高 VMs 性能…</p><h3 id="调用-Discard-Trim">调用 Discard/Trim</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ qemu -m 1024 -drive format=raw,file=rbd:libvirt-pool/centos,id=libvirt,<span class="keyword">if</span>=none -device driver=ide-hd,drive=drive1,discard_granularity=512</span><br></pre></td></tr></tbody></table></figure><h3 id="QEMU-Cache-选项">QEMU Cache 选项</h3><ol><li><strong>writeback</strong>:</li></ol><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">rbd_cache</span> = <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><ol start="2"><li><strong>writethrough</strong>:</li></ol><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">rbd_cache</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">rbd_cache_max_dirty</span> = <span class="number">0</span></span><br></pre></td></tr></tbody></table></figure><ol start="3"><li><strong>None</strong>:</li></ol><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">rbd_cache</span> = <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><p>QEMU 的 cache 设置会覆掉 Ceph 的设置.</p><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Ceph RBD 块设备存储是十分适合作为虚拟化平台的存储后端的, 这也是其最常用的情景之一. 这篇主要介绍如何将 Ceph RBD 作为 QEMU 等的存储端.&lt;/p&gt;
    
    </summary>
    
      <category term="Ceph" scheme="https://blog.amito.cc/categories/Ceph/"/>
    
    
      <category term="Ceph" scheme="https://blog.amito.cc/tags/Ceph/"/>
    
      <category term="KVM" scheme="https://blog.amito.cc/tags/KVM/"/>
    
      <category term="QEMU" scheme="https://blog.amito.cc/tags/QEMU/"/>
    
  </entry>
  
  <entry>
    <title>解决 SSH 连接提示 Too Many Authentication Failures 问题</title>
    <link href="https://blog.amito.cc/2018/09/Solving-SSH-Too-Many-Authentication-Failures/"/>
    <id>https://blog.amito.cc/2018/09/Solving-SSH-Too-Many-Authentication-Failures/</id>
    <published>2018-09-26T02:55:38.000Z</published>
    <updated>2022-04-16T14:26:24.376Z</updated>
    
    <content type="html"><![CDATA[<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/hint.css/2.4.1/hint.min.css"><p>最近在使用 ssh 连接远程服务器时, 出现了 “Too many authentication failures for xxxx” 的问题, 然而之前是可以正常登录的. 貌似服务器也没有做什么更改. 那是什么原因呢?</p><span id="more"></span><hr width="100%" color="#C0C0C0" size="2"><!-- toc --><h2 id="问题">问题</h2><p>在登录远程服务器时, 会出现如下提示:</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.</span><br><span class="line">Received disconnect from 172.16.22.11 port 22:2: Too many authentication failures <span class="keyword">for</span> xxx</span><br><span class="line">Disconnected from 172.16.22.11 port 22</span><br></pre></td></tr></tbody></table></figure><p>显示指定所用的公钥后, 仍旧不行. 在加上 <code>-vvv</code> 输出 debug 信息后, 发现 ssh 在登录时, 尝试了 <code>~/.ssh</code> 下的所有密钥, 很不幸的是, 服务器用的密钥很靠后, 还没有尝试到该密钥就已经超出限制了.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line">ssh th2 -vvv</span><br><span class="line">OpenSSH_7.8p1, OpenSSL 1.1.0i-fips  14 Aug 2018</span><br><span class="line">debug1: Reading configuration data /home/user/.ssh/config</span><br><span class="line">debug1: /home/user/.ssh/config line 4: Applying options <span class="keyword">for</span> *</span><br><span class="line">debug1: /home/user/.ssh/config line 7: Deprecated option <span class="string">"cipher"</span></span><br><span class="line">debug1: /home/user/.ssh/config line 111: Applying options <span class="keyword">for</span> th2</span><br><span class="line">debug1: Reading configuration data /etc/ssh/ssh_config</span><br><span class="line">...</span><br><span class="line">SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.</span><br><span class="line">Please contact your system administrator.</span><br><span class="line">Add correct host key <span class="keyword">in</span> /home/user/.ssh/known_hosts to get rid of this message.</span><br><span class="line">Offending ECDSA key <span class="keyword">in</span> /home/user/.ssh/known_hosts:121</span><br><span class="line">Password authentication is disabled to avoid man-in-the-middle attacks.</span><br><span class="line">Keyboard-interactive authentication is disabled to avoid man-in-the-middle attacks.</span><br><span class="line">...</span><br><span class="line">debug2: key: /home/user/.ssh/ceph_rsa (0x55d8ec4dd860), agent</span><br><span class="line">debug2: key: /home/user/.ssh/amito_rsa (0x55d8ec4d8c30), agent</span><br><span class="line">debug2: key: aaaa (0xxxxxxxxxxxxx), agent</span><br><span class="line">debug2: key: bbbb (0xxxxxxxxxxxxx), agent</span><br><span class="line">debug2: key: cccc (0xxxxxxxxxxxxx), agent</span><br><span class="line">debug2: key: dddd (0xxxxxxxxxxxxx), agent</span><br><span class="line">debug2: key: /home/user/.ssh/xxxx ((nil)), explicit</span><br><span class="line">...</span><br><span class="line">debug2: we did not send a packet, <span class="built_in">disable</span> method</span><br><span class="line">debug3: authmethod_lookup publickey</span><br><span class="line">debug3: remaining preferred: </span><br><span class="line">debug3: authmethod_is_enabled publickey</span><br><span class="line">debug1: Next authentication method: publickey</span><br><span class="line">debug1: Offering public key: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /home/user/.ssh/eeee_rsa</span><br><span class="line">debug3: send packet: <span class="built_in">type</span> 50</span><br><span class="line">debug2: we sent a publickey packet, <span class="built_in">wait</span> <span class="keyword">for</span> reply</span><br><span class="line">debug3: receive packet: <span class="built_in">type</span> 51</span><br><span class="line">debug1: Authentications that can <span class="built_in">continue</span>: publickey,gssapi-keyex,gssapi-with-mic</span><br><span class="line">debug1: Offering public key: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /home/user/.ssh/aaaa_rsa</span><br><span class="line">debug3: send packet: <span class="built_in">type</span> 50</span><br><span class="line">debug2: we sent a publickey packet, <span class="built_in">wait</span> <span class="keyword">for</span> reply</span><br><span class="line">debug3: receive packet: <span class="built_in">type</span> 51</span><br><span class="line">debug1: Authentications that can <span class="built_in">continue</span>: publickey,gssapi-keyex,gssapi-with-mic</span><br><span class="line">debug1: Offering public key: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx bbbb</span><br><span class="line">debug3: send packet: <span class="built_in">type</span> 50</span><br><span class="line">debug2: we sent a publickey packet, <span class="built_in">wait</span> <span class="keyword">for</span> reply</span><br><span class="line">debug3: receive packet: <span class="built_in">type</span> 51</span><br><span class="line">debug1: Authentications that can <span class="built_in">continue</span>: publickey,gssapi-keyex,gssapi-with-mic</span><br><span class="line">debug1: Offering public key: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx cccc</span><br><span class="line">debug3: send packet: <span class="built_in">type</span> 50</span><br><span class="line">debug2: we sent a publickey packet, <span class="built_in">wait</span> <span class="keyword">for</span> reply</span><br><span class="line">debug3: receive packet: <span class="built_in">type</span> 51</span><br><span class="line">debug1: Authentications that can <span class="built_in">continue</span>: publickey,gssapi-keyex,gssapi-with-mic</span><br><span class="line">debug1: Offering public key: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx eeee</span><br><span class="line">debug3: send packet: <span class="built_in">type</span> 50</span><br><span class="line">debug2: we sent a publickey packet, <span class="built_in">wait</span> <span class="keyword">for</span> reply</span><br><span class="line">debug3: receive packet: <span class="built_in">type</span> 51</span><br><span class="line">debug1: Authentications that can <span class="built_in">continue</span>: publickey,gssapi-keyex,gssapi-with-mic</span><br><span class="line">debug1: Offering public key: RSA SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ffff</span><br><span class="line">debug3: send packet: <span class="built_in">type</span> 50</span><br><span class="line">debug2: we sent a publickey packet, <span class="built_in">wait</span> <span class="keyword">for</span> reply</span><br><span class="line">debug3: receive packet: <span class="built_in">type</span> 1</span><br><span class="line">Received disconnect from 172.16.22.11 port 22:2: Too many authentication failures</span><br><span class="line">Disconnected from 172.16.22.11 port 22</span><br></pre></td></tr></tbody></table></figure><p>原来 SSH 在登录时, 会依次尝试密钥, 直到找到一个能成功的. 然而 SSH 服务端会设置几次登录失败后就将其禁掉. 找到了原因, 解决方法也简单…</p><h2 id="方法">方法</h2><p>一个简单的方法是将多的密钥移除, 但是密钥自有其存在的意义, 使用同一个密钥登录所有服务器也不现实. 另一个方法就是在 <code>~/.ssh/config</code> 中指定使用的密钥, 并且加上 <code>IdentitiesOnly=yes</code>.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Host myhost</span><br><span class="line">Hostname my_host_ip</span><br><span class="line">User user</span><br><span class="line">Port port</span><br><span class="line">Identitiesonly=yes</span><br><span class="line">Identityfile ~/.ssh/id_rsa</span><br></pre></td></tr></tbody></table></figure><p>为简便, 可以对所有 <code>host</code> 都进行设置.</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Host *</span><br><span class="line">Serveraliveinterval 60</span><br><span class="line">StrictHostKeyChecking no</span><br><span class="line">Identitiesonly=yes</span><br></pre></td></tr></tbody></table></figure><script>        document.querySelectorAll('.github-emoji')          .forEach(el => {            if (!el.dataset.src) { return; }            const img = document.createElement('img');            img.style = 'display:none !important;';            img.src = el.dataset.src;            img.addEventListener('error', () => {              img.remove();              el.style.color = 'inherit';              el.style.backgroundImage = 'none';              el.style.background = 'none';            });            img.addEventListener('load', () => {              img.remove();            });            document.body.appendChild(img);          });      </script>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;最近在使用 ssh 连接远程服务器时, 出现了 “Too many authentication failures for xxxx” 的问题, 然而之前是可以正常登录的. 貌似服务器也没有做什么更改. 那是什么原因呢?&lt;/p&gt;
    
    </summary>
    
      <category term="Linux" scheme="https://blog.amito.cc/categories/Linux/"/>
    
    
      <category term="Linux" scheme="https://blog.amito.cc/tags/Linux/"/>
    
      <category term="ssh" scheme="https://blog.amito.cc/tags/ssh/"/>
    
  </entry>
  
</feed>
