<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Yee&#39;s Blog</title>
  
  <subtitle>今晚的月色真美</subtitle>
  <link href="https://blog.yeefire.com/atom.xml" rel="self"/>
  
  <link href="https://blog.yeefire.com/"/>
  <updated>2021-09-06T02:05:41.000Z</updated>
  <id>https://blog.yeefire.com/</id>
  
  <author>
    <name>YeeFire</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>腾讯云/轻量云 安装ArchLinux的个人记录</title>
    <link href="https://blog.yeefire.com/2021_09/tencent_cloud_arch.html"/>
    <id>https://blog.yeefire.com/2021_09/tencent_cloud_arch.html</id>
    <published>2021-09-06T02:03:21.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="腾讯云-轻量云-安装ArchLinux的个人记录"><a href="#腾讯云-轻量云-安装ArchLinux的个人记录" class="headerlink" title="腾讯云/轻量云 安装ArchLinux的个人记录"></a>腾讯云/轻量云 安装ArchLinux的个人记录</h1><h2 id="联系我购买腾讯、阿里云有8折甚至更低的折上折优惠哦！"><a href="#联系我购买腾讯、阿里云有8折甚至更低的折上折优惠哦！" class="headerlink" title="联系我购买腾讯、阿里云有8折甚至更低的折上折优惠哦！"></a>联系我购买腾讯、阿里云有8折甚至更低的折上折优惠哦！</h2><p>本文仅用于个人学习使用，过阵子再以教程的形式重新发布出来。如果你现在完全按这篇文章操作不一定会成功。</p><p>请同时搭配<a href="https://blog.yeefire.com/2021_06/m720q_arch_setup.html">记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程</a>食用。</p><h2 id="准备工作"><a href="#准备工作" class="headerlink" title="准备工作"></a>准备工作</h2><h3 id="下载镜像"><a href="#下载镜像" class="headerlink" title="下载镜像"></a>下载镜像</h3><p>wget <span class="exturl" data-url="aHR0cHM6Ly9taXJyb3JzLnR1bmEudHNpbmdodWEuZWR1LmNuL2FyY2hsaW51eC9pc28vMjAyMS4wOC4wMS9hcmNobGludXgtMjAyMS4wOC4wMS14ODZfNjQuaXNv" title="https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/2021.08.01/archlinux-2021.08.01-x86_64.iso">https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/2021.08.01/archlinux-2021.08.01-x86_64.iso<i class="fa fa-external-link"></i></span></p><p>编辑<code>/boot/grub/grub.cfg</code>文件，添加下列内容</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">set timeout=60</span><br><span class="line">menuentry &#x27;ArchISO&#x27; --class iso &#123;</span><br><span class="line">  set isofile=/archlinux-2021.08.01-x86_64.iso</span><br><span class="line">  loopback loop0 $isofile</span><br><span class="line">  #archisolabel设置archiso文件驻留的文件系统标签。</span><br><span class="line">  #img_dev指明archiso文件驻留的设备</span><br><span class="line">  #img_loop是archiso文件在img_dev里的绝对位置</span><br><span class="line">  linux (loop0)/arch/boot/x86_64/vmlinuz-linux archisolabel=ARCH20210801 img_dev=/dev/vda1 img_loop=$isofile</span><br><span class="line">  initrd (loop0)/arch/boot/x86_64/initramfs-linux.img</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>Reboot 选择ArchISO引导项</p><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="替换文件"><a href="#替换文件" class="headerlink" title="替换文件"></a>替换文件</h3><p><code>mkdir mnt</code></p><p><code>mount -o rw /dev/vda1 mnt</code></p><p><code>mount -o rw,remount mnt </code></p><p><code>rm -rf mnt/*</code></p><p><code>pacstrap ./mnt base linux linux-firmware  networkmanager sudo openssh</code></p><p><code>genfstab -U mnt &gt;&gt; mnt/etc/fstab</code></p><p><code>vim mnt/etc/fstab</code> 将ro修改为rw可读写</p><p>切换到Arch</p><p><code>arch-chroot mnt</code></p><p>安装一些可能接下来会用到的包</p><p><code>pacman -S vim bash-completion</code></p><p>剩下还有一些步骤参考<a href="https://blog.yeefire.com/2021_06/m720q_arch_setup.html">记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程</a></p><h3 id="开机自启动一些服务"><a href="#开机自启动一些服务" class="headerlink" title="开机自启动一些服务"></a>开机自启动一些服务</h3><p><code>systemctl enable NetworkManager sshd </code></p><p>如果没有启动<code>NetworkManager</code>和<code>sshd</code>这两个服务的话，下次启动时没有网络并且无法ssh远程访问。</p><h3 id="添加用户并设置密码"><a href="#添加用户并设置密码" class="headerlink" title="添加用户并设置密码"></a>添加用户并设置密码</h3><p>将<code>username</code>替换为你要创建的用户名。</p><p><code>useradd -m username</code></p><p><code>passwd username</code></p><h3 id="配置sudo"><a href="#配置sudo" class="headerlink" title="配置sudo"></a>配置sudo</h3><p><code>usermod -aG wheel username</code></p><p>编辑<code>/etc/sudoers</code>文件允许<code>wheel</code>组中用户使用sudo提权到root级别权限。</p><p>一定要将公钥添加到用户家目录的<code>.ssh/authorized_keys</code>文件内，否则重启后只能通过VNC访问这台机器进行后续配置。</p><p>安装grub引导<br>pacman -S grub efibootmgr<br>grub-install –target=i386-pc /dev/vda<br>生成grub2配置文件<br>grub-mkconfig -o /boot/grub/grub.cfg</p><p>reboot<br>重启后将使用本机ssh远程这台Arch轻量云实例，所以<strong>需要你在重启前配置好sshd服务并且将本机公钥传入到刚刚创建的用户的家目录</strong>。</p><p>记录一次引导失败插曲：<br>忘记生成grub2配置文件，好在腾讯轻量云提供了远程VNC。<br>按照下面的命令，手动引导系统。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">grub&gt; set root=(hd0,msdos1)</span><br><span class="line">grub&gt; linux /boot/vmliunz-linux root=/dev/vda1</span><br><span class="line">grub&gt; initrd /boot/initramfs-linux.img</span><br><span class="line">grub&gt; boot</span><br></pre></td></tr></table></figure><p>进入系统后再生成grub2配置文件<code>grub-mkconfig -o /boot/grub/grub.cfg</code></p><h2 id="后续配置"><a href="#后续配置" class="headerlink" title="后续配置"></a>后续配置</h2><h3 id="安装一些常用的包"><a href="#安装一些常用的包" class="headerlink" title="安装一些常用的包"></a>安装一些常用的包</h3><p><code>pacman -S vim bash-completion</code></p><h3 id="设置时区时间"><a href="#设置时区时间" class="headerlink" title="设置时区时间"></a>设置时区时间</h3><p><code>timedatectl set-timezone Asia/Shanghai</code></p><p><code>hwclock --systohc</code></p><h3 id="设置使用的区域"><a href="#设置使用的区域" class="headerlink" title="设置使用的区域"></a>设置使用的区域</h3><p>编辑<code>/etc/locale.gen</code>然后移除需要的 地区 前的注释符号 #</p><p>接着执行<code>locale-gen</code>以生成<code>locale</code>信息</p><p>编辑<code>/etc/locate.conf</code>配置文件，没有则新建:</p><p>文本内输入: <code>LANG=en_US.UTF-8</code></p><p>设置全局区域环境为美国英语环境。</p><h3 id="设置主机名"><a href="#设置主机名" class="headerlink" title="设置主机名"></a>设置主机名</h3><p><code>hostnamectl set-hostname 主机名</code></p><h3 id="开启BBR"><a href="#开启BBR" class="headerlink" title="开启BBR"></a>开启BBR</h3><p>Kernel 4.9 及以后已经合并了 BBR 的代码，BBR有可能默认安装。<br>使用<code>modinfo tcp_bbr</code>查看BBR内核模块。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">filename:       /lib/modules/5.13.7-arch1-1/kernel/net/ipv4/tcp_bbr.ko.zst</span><br><span class="line">description:    TCP BBR (Bottleneck Bandwidth and RTT)</span><br><span class="line">license:        Dual BSD/GPL</span><br><span class="line">author:         Soheil Hassas Yeganeh &lt;soheil@google.com&gt;</span><br><span class="line">author:         Yuchung Cheng &lt;ycheng@google.com&gt;</span><br><span class="line">author:         Neal Cardwell &lt;ncardwell@google.com&gt;</span><br><span class="line">author:         Van Jacobson &lt;vanj@google.com&gt;</span><br><span class="line">srcversion:     3ADF6435C60E99C5F186F19</span><br><span class="line">depends:</span><br><span class="line">retpoline:      Y</span><br><span class="line">intree:         Y</span><br><span class="line">name:           tcp_bbr</span><br><span class="line">vermagic:       5.13.7-arch1-1 SMP preempt mod_unload</span><br><span class="line">sig_id:         PKCS#7</span><br><span class="line">signer:         Build time autogenerated kernel key</span><br></pre></td></tr></table></figure><p>查看是否开启BBR:<br><code>sysctl net.ipv4.tcp_congestion_control</code></p><p>开启BBR:</p><p><code>sudo sysctl net.ipv4.tcp_congestion_control=bbr</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">$ sysctl net.ipv4.tcp_congestion_control</span><br><span class="line">net.ipv4.tcp_congestion_control = cubic</span><br><span class="line">$ sudo  modprobe tcp_bbr</span><br><span class="line">$ lsmod | grep tcp_bbr</span><br><span class="line">tcp_bbr                20480  0</span><br><span class="line">$ sudo sysctl net.ipv4.tcp_congestion_control=bbr</span><br><span class="line">net.ipv4.tcp_congestion_control = bbr</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>开启后效果可以立即看到，如果想在重启后依然使用BBR，则需要写入到文件系统:</p><p><code>echo &quot;tcp_bbr&quot; &gt; /etc/modules-load.d/80-bbr.conf</code></p><p><code>echo &quot;net.ipv4.tcp_congestion_control=bbr&quot; &gt; /etc/sysctl.d/80-bbr.conf</code></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;腾讯云-轻量云-安装ArchLinux的个人记录&quot;&gt;&lt;a href=&quot;#腾讯云-轻量云-安装ArchLinux的个人记录&quot; class=&quot;headerlink&quot; title=&quot;腾讯云/轻量云 安装ArchLinux的个人记录&quot;&gt;&lt;/a&gt;腾讯云/轻量云 安装Arch</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Arch" scheme="https://blog.yeefire.com/tags/Arch/"/>
    
  </entry>
  
  <entry>
    <title>记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程</title>
    <link href="https://blog.yeefire.com/2021_06/m720q_arch_setup.html"/>
    <id>https://blog.yeefire.com/2021_06/m720q_arch_setup.html</id>
    <published>2021-06-24T02:03:21.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="记录我的联想M720Q-Arch-Sway窗口管理器的安装和配置过程"><a href="#记录我的联想M720Q-Arch-Sway窗口管理器的安装和配置过程" class="headerlink" title="记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程"></a>记录我的联想M720Q Arch Sway窗口管理器的安装和配置过程</h1><h2 id="安装Arch-Linux基本过程纪录"><a href="#安装Arch-Linux基本过程纪录" class="headerlink" title="安装Arch Linux基本过程纪录"></a>安装Arch Linux基本过程纪录</h2><h3 id="下载并烧录镜像"><a href="#下载并烧录镜像" class="headerlink" title="下载并烧录镜像"></a>下载并烧录镜像</h3><p>本次下载2021.5.1日的镜像，写这篇文章的时候是六一儿童节，但是并没有看到这个月的镜像。好耶，都去过六一了！</p><p>应该是最后一次用东软维云的镜像站咯！下载Arch 2021.5.1 ISO走起。</p><h3 id="引导系统"><a href="#引导系统" class="headerlink" title="引导系统"></a>引导系统</h3><p>引导Arch ISO前在BIOS中关闭安全引导，借着还有Windows的时候，更新了一下BIOS到2021年三月份的版本。</p><h3 id="链接到互联网"><a href="#链接到互联网" class="headerlink" title="链接到互联网"></a>链接到互联网</h3><p>在 Arch ISO Live中安装了iwd来管理无线网络，因为本次安装过程只有无线网络，那么用iwctl工具来配置本次安装过程中使用的无线网络。</p><p>进入iwctl交互模式: <code>iwctl</code></p><p>罗列设备: <code>device list</code>，在列表中可以找到<em>wlan0</em>无线设备，记下来他的名字，接下来会使用到这个名称。</p><p>扫描无线网络: <code>station wlan0 scan</code></p><p>罗列已发现的网络 <code>station wlan0 get-networks</code></p><p>连接到无线网络 <code>station wlan0 connect SSID</code></p><h3 id="删除多余的引导"><a href="#删除多余的引导" class="headerlink" title="删除多余的引导"></a>删除多余的引导</h3><p>使用<code>efibootmgr</code>删除Windows引导。</p><p><code>efibootmgr -b 000X -B</code></p><h3 id="更新系统时间"><a href="#更新系统时间" class="headerlink" title="更新系统时间"></a>更新系统时间</h3><p>使用<code>timedatectl</code>更新时间，开启ntp。确保系统时间是准确的: <code>timedatectl set-ntp true</code></p><h3 id="建立硬盘分区"><a href="#建立硬盘分区" class="headerlink" title="建立硬盘分区"></a>建立硬盘分区</h3><p>使用<code>fdisk</code>工具对磁盘进行分区，我要将整个磁盘都空间都划分给Arch使用。</p><p><code>fdisk /dev/nvme0n1</code></p><ul><li>ESP分区 1G </li><li>SWAP分区 8G</li><li>根文件存储 剩余空间</li></ul><h3 id="格式化磁盘文件系统"><a href="#格式化磁盘文件系统" class="headerlink" title="格式化磁盘文件系统"></a>格式化磁盘文件系统</h3><p>将ESP被格式化成，ESP分区格式化成FAT32分区格式: <code>mkfs.vfat -F32 /dev/nvme0n1p1</code> </p><p>创建SWAP文件系统: </p><p><code>mkswap /dev/nvme0n1p2</code></p><p><code>swapon /dev/nvme0n1p2</code></p><p>创建根目录文件系统ext4: <code>mkfs.ext4 /dev/nvme0n1p3</code></p><h3 id="挂载分区"><a href="#挂载分区" class="headerlink" title="挂载分区"></a>挂载分区</h3><p>挂载根分区目录: <code>mount /dev/nvme0n1p3 /mnt</code></p><p>创建EFI目录并进行挂载: </p><p><code>mkdir /mnt/efi</code> </p><p><code>mount /dev/nvme0n1p1 /mnt/efi</code></p><h3 id="选择镜像源"><a href="#选择镜像源" class="headerlink" title="选择镜像源"></a>选择镜像源</h3><p>文件 <code>/etc/pacman.d/mirrorlist</code> 定义了软件包会从哪个镜像源下载。在 LiveCD 启动的系统上，在连接到因特网后，reflector 会通过选择 20 个最新同步的 HTTPS 镜像并按下载速率对其进行排序来更新镜像列表。</p><p>在列表中越前的镜像在下载软件包时有越高的优先权。您或许想检查一下文件，看看是否满意。如果不满意，可以相应的修改 /etc/pacman.d/mirrorlist 文件，并将地理位置最近的镜像源挪到文件的头部，同时也应该考虑一些其他标准。</p><p>这个文件接下来还会被 pacstrap 拷贝到新系统里，所以请确保设置正确。</p><h3 id="安装系统软件包"><a href="#安装系统软件包" class="headerlink" title="安装系统软件包"></a>安装系统软件包</h3><p><code>pacstrap /mnt base linux linux-firmware base-devel networkmanager</code></p><h3 id="写入引导"><a href="#写入引导" class="headerlink" title="写入引导"></a>写入引导</h3><p>用以下命令生成 fstab 文件 (用 -U 或 -L 选项设置UUID 或卷标)：</p><p><code>genfstab -U /mnt &gt;&gt; /mnt/etc/fstab</code></p><p>强烈建议在执行完以上命令后，后检查一下生成的 /mnt/etc/fstab 文件是否正确。</p><h3 id="切换根目录"><a href="#切换根目录" class="headerlink" title="切换根目录"></a>切换根目录</h3><p><code>Chroot</code>更当前进程及其子进程的可见根路径。变更后，程序无法访问可见根目录外文件和命令。</p><p><code>arch-chroot /mnt</code></p><h3 id="安装一些常用软件包"><a href="#安装一些常用软件包" class="headerlink" title="安装一些常用软件包"></a>安装一些常用软件包</h3><p><code>pacman -S vim bash-completion</code></p><h3 id="设置时区时间"><a href="#设置时区时间" class="headerlink" title="设置时区时间"></a>设置时区时间</h3><p><code>timedatectl set-timezone Asia/Shanghai</code></p><p><code>hwclock --systohc</code></p><h3 id="设置使用的区域"><a href="#设置使用的区域" class="headerlink" title="设置使用的区域"></a>设置使用的区域</h3><p>编辑<code>/etc/locale.gen</code>然后移除需要的 地区 前的注释符号 #</p><p>接着执行 <code>locale-gen</code> 以生成 locale 信息</p><p>编辑<code>/etc/locate.conf</code>:</p><p><code>LANG=en_US.UTF-8</code> </p><p>设置全局区域环境为美国英语环境。</p><p>稍后用户可以编辑自己的<code>~/.config/locale.conf</code>文件来设置使用的语言和特定的区域格式。如:</p><ul><li>LANG</li><li>LANGUAGE</li><li>LC_ADDRESS</li><li>LC_COLLATE</li><li>LC_CTYPE</li><li>LC_IDENTIFICATION</li><li>LC_MEASUREMENT</li><li>LC_MESSAGES</li><li>LC_MONETARY</li><li>LC_NAME</li><li>LC_NUMERIC</li><li>LC_PAPER</li><li>LC_TELEPHONE</li><li>LC_TIME</li></ul><p>LANG：默认的区域设置<br>这个变量的值会覆盖掉所有未设置的 LC_* 变量的值。</p><p>相关详情访问: <span class="exturl" data-url="aHR0cHM6Ly93aWtpLmFyY2hsaW51eC5vcmcvdGl0bGUvTG9jYWxlXyglRTclQUUlODAlRTQlQkQlOTMlRTQlQjglQUQlRTYlOTYlODcp" title="https://wiki.archlinux.org/title/Locale_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)">Arch Wiki - Locate（简体中文）<i class="fa fa-external-link"></i></span></p><h3 id="设置主机名"><a href="#设置主机名" class="headerlink" title="设置主机名"></a>设置主机名</h3><p><code>hostnamectl set-hostname Archxxxxxx</code></p><h3 id="设置用户及ROOT密码"><a href="#设置用户及ROOT密码" class="headerlink" title="设置用户及ROOT密码"></a>设置用户及ROOT密码</h3><p>设置root用户密码: <code>passwd</code></p><p>添加普通用户并设置密码: </p><p><code>useradd -m username</code></p><p><code>passwd username</code></p><p>将用户添加到管理员组(wheel): <code>usermod -aG wheel username</code></p><p>编辑<code>/etc/sudoers</code>文件允许<code>wheel</code>组中用户使用sudo提权到root级别权限。</p><h3 id="安装引导程序"><a href="#安装引导程序" class="headerlink" title="安装引导程序"></a>安装引导程序</h3><p>安装引导是安装的最后一步，使用GRUB配置本机引导，首先安装<code>grub</code>和<code>efibootmgr</code>两个包。</p><p><code>pacman -S grub efibootmgr</code></p><p>然后按照下列步骤安装 GRUB：</p><p>挂载 EFI 系统分区，在本节之后的内容里，挂载点为<code>/efi</code>。</p><p>选择一个启动引导器标识，这里叫做 GRUB。这将在 esp/EFI/ 中创建一个与标识同名的目录来储存 EFI 二进制文件，而且这个名字还会在 UEFI 启动菜单中表示 GRUB 启动项。</p><p>执行下面的命令来将 GRUB EFI 应用 grubx64.efi 安装到 esp/EFI/GRUB/，并将其模块安装到 /boot/grub/x86_64-efi/。</p><p><code>grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=GRUB</code></p><p>生成GRUB配置文件: <code>grub-mkconfig -o /boot/grub/grub.cfg</code></p><h2 id="安装后的一些系统服务配置"><a href="#安装后的一些系统服务配置" class="headerlink" title="安装后的一些系统服务配置"></a>安装后的一些系统服务配置</h2><h3 id="使用NetworkManager管理本机网络"><a href="#使用NetworkManager管理本机网络" class="headerlink" title="使用NetworkManager管理本机网络"></a>使用NetworkManager管理本机网络</h3><p>刚才在安装过程中使用<code>pacstrap</code>安装软件包时就已经将<code>networkmanager</code>软件包安装好了，接下来开启<code>NetworkManager</code>服务，并使用<code>nmcli</code>配置连接无线网络。</p><p><code>systemctl enable --now NetworkManager</code></p><p>罗列当前可用的无线网络: <code>nmcli device wifi list</code></p><p>连接到<code>SSID_NAME</code>无线网络<br><code>nmcli device wifi connect SSID_NAME ifname wlp3s0 password &lt;mypassword&gt; name XXXXX</code></p><p>若要交互式的输入密码，可以加<code>-a --ask</code>参数，避免在终端内输入密码留下痕迹。</p><p><code>nmcli device wifi connect SSID_NAME ifname wlp3s0 name XXXXX</code></p><p>此时缺省password参数，会在终端内进行交互式输入密码。</p><h4 id="PPPoE-DSL-support"><a href="#PPPoE-DSL-support" class="headerlink" title="PPPoE / DSL support"></a>PPPoE / DSL support</h4><p>若要使用PPPoE拨号，需要<code>rp-pppoe</code>软件包后，才可以用nmcli连接。</p><p><code>pacman -S rp-pppoe</code></p><p><code>nmcli connection add type pppoe pppoe.username &quot;myusername&quot; pppoe.password &quot;mypassword&quot; ifname &quot;enp1s0f1&quot; con-name &quot;NDR&quot; autoconnect yes</code></p><p><code>nmcli connection up NDR</code></p><h4 id="配置EAP-PEAP认证无线网络"><a href="#配置EAP-PEAP认证无线网络" class="headerlink" title="配置EAP PEAP认证无线网络"></a>配置EAP PEAP认证无线网络</h4><p>校内的无线网络使用EAP认证，通过查阅资料使用nmcli添加EAP无线网络方法如下：</p><p><code>nmcli connection add type wifi con-name my-CUCC ifname wlp3s0 ssid CUCC ipv4.method auto 802-1x.eap peap 802-1x.phase2-auth mschapv2 802-1x.identity yourusername 802-1x.password yourpassword wifi-sec.key-mgmt wpa-eap autoconnect yes</code></p><h3 id="桌面窗口服务"><a href="#桌面窗口服务" class="headerlink" title="桌面窗口服务"></a>桌面窗口服务</h3><p>使用Wayland图形显示服务，sway平铺窗口管理器。</p><p><strong>常见的环境配置文件所在地址</strong></p><p>对于特定用户，还可以在 <del>/.bashrc、</del>/.xinitrc 或 ~/.xprofile 中设置自己的用户环境。不同之处在于：</p><p>.bashrc：每次使用终端登录时读取并运用里面的设置。</p><p>.xinitrc：每次使用 startx 或 SLiM 启动 X 界面时读取并运用里面的设置。</p><p>.xprofile：每次使用 GDM 等显示管理器登录时读取并运用里面的设置。</p><h4 id="安装wayland和Sway以及依赖的一些包"><a href="#安装wayland和Sway以及依赖的一些包" class="headerlink" title="安装wayland和Sway以及依赖的一些包"></a>安装wayland和Sway以及依赖的一些包</h4><p><code>pacman -S wayland sway</code></p><p><code>pacman -S  alacritty swayidle</code></p><p>有关使用Wayland中的常见问题详见<span class="exturl" data-url="aHR0cHM6Ly93aWtpLmFyY2hsaW51eC5vcmcvdGl0bGUvV2F5bGFuZF8oJUU3JUFFJTgwJUU0JUJEJTkzJUU0JUI4JUFEJUU2JTk2JTg3KSNRdF81" title="https://wiki.archlinux.org/title/Wayland_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#Qt_5">Arch Wiki - Wayland<i class="fa fa-external-link"></i></span></p><ul><li>swayidle 在一定非活跃时间后执行操作 <a href="#%E5%BB%B6%E6%97%B6%E5%B7%A5%E5%85%B7swayidle%E9%85%8D%E7%BD%AE">swayidle与swaylock配置延时锁屏</a></li><li>swaylock-effects <a href="#%E9%94%81%E5%B1%8F%E5%B7%A5%E5%85%B7swaylock">Sway锁屏工具</a></li></ul><h4 id="配置Sway平铺窗口管理器"><a href="#配置Sway平铺窗口管理器" class="headerlink" title="配置Sway平铺窗口管理器"></a>配置Sway平铺窗口管理器</h4><p>配置在登录系统后自动启动sway，以及配置Sway的程序启动器，任务栏，和各种优化。</p><p><strong>配置tty登录后自动运行sway</strong></p><p><code>vim ~/.bash_profile</code></p><p>启动Sway时，设置环境变量，其中包含让firefox使用wayland的标记变量以及QT环境等变量信息。</p><p><code>vim ~/.local/bin/sway</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment">#!bin/sh</span></span><br><span class="line"><span class="built_in">set</span> -a</span><br><span class="line">[ -f <span class="variable">$HOME</span>/.config/sway/env ] &amp;&amp; . <span class="string">&quot;<span class="variable">$HOME</span>/.config/sway/env&quot;</span> </span><br><span class="line"><span class="built_in">set</span> +a</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> [ -z <span class="variable">$DISPLAY</span> ] &amp;&amp; [ <span class="string">&quot;<span class="subst">$(tty)</span>&quot;</span> = <span class="string">&quot;/dev/tty1&quot;</span> ]; <span class="keyword">then</span></span><br><span class="line">    <span class="built_in">exec</span> sway</span><br><span class="line"><span class="keyword">fi</span></span><br></pre></td></tr></table></figure><p>编辑环境变量文件：</p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="attr">MOZ_ENABLE_WAYLAND</span>=<span class="number">1</span></span><br><span class="line"><span class="attr">QT_QPA_PLATFORM</span>=wayland</span><br></pre></td></tr></table></figure><ul><li>MOZ_ENABLE_WAYLAND=1 : 火狐浏览器使用Wayland图形窗口服务标记</li><li>QT_QPA_PLATFORM=wayland : 在Wayland环境下使用Qt5需要安装<code>qt5-wayland</code>包，并设置<code>QT_QPA_PLATFORM=wayland</code>环境变量。</li></ul><p><strong>使用<code>wofi</code>作为程序启动坞</strong></p><p>安装wofi: <code>yay -S wofi</code></p><p>修改Sway配置文件</p><p><code>set $menu dmenu_path | wofi --show drun -i | xargs swaymsg exec --</code></p><p><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL01hbmdlL3JvZmktZW1vamk=" title="https://github.com/Mange/rofi-emoji">rofi-emoji<i class="fa fa-external-link"></i></span></p><h4 id="使用dex自动启动程序-Fcitx5（自启动fcitx5）"><a href="#使用dex自动启动程序-Fcitx5（自启动fcitx5）" class="headerlink" title="使用dex自动启动程序-Fcitx5（自启动fcitx5）"></a>使用dex自动启动程序-Fcitx5（自启动fcitx5）</h4><p>fcitx5等一些应用会创建XDG Autostart启动配置，通常以<code>.desktop</code>文件拓展名结尾。像fcitx5等一些程序包在安装时会在<code>/etc/xdg/</code>目录下生成配置文件，但是只有部分的窗口管理器支持xdg启动。在Sway中目前没有看到原生对它的支持，所以就需要一些其它工具辅助执行。</p><p>那么若要在进入桌面环境后自动启动fcitx5，则可以使用<code>dex</code>工具。它可以自动执行<code>/etc/xdg/autostart</code>目录下的<code>.desktop</code>程序启动配置文件。</p><p>安装dex: <code>yay -S dex</code></p><p>在Sway配置文件中配置自启动dex:</p><p>在 <code>~/.config/sway/config</code> 文件末尾处添加: <code>exec_always &quot;dex -a&quot; </code></p><p>之后在Sway启动后，会执行<code>dex</code>工具，<code>dex</code>工具又回去执行哪些在XDG自动启动目录下，但是在Sway中不会自动执行的程序启动配置文件<code>.desktop</code>，此时fcitx5已经可以自动启动了。</p><h4 id="安装中文字体"><a href="#安装中文字体" class="headerlink" title="安装中文字体"></a>安装中文字体</h4><p>推荐安装以下常用开源中文字体：</p><ul><li>wqy-microhei</li><li>wqy-microhei-lite</li><li>wqy-bitmapfont</li><li>wqy-zenhei</li><li>noto-fonts-cjk</li></ul><p><code>yay -S wqy-microhei wqy-microhei-lite wqy-bitmapfont wqy-zenhei noto-fonts-cjk</code></p><p>更新字体缓存: <code>fc-cache -fv</code></p><p>关于更多本土化中文字体设置详见</p><p><span class="exturl" data-url="aHR0cHM6Ly93aWtpLmFyY2hsaW51eC5vcmcvdGl0bGUvTG9jYWxpemF0aW9uXyglRTclQUUlODAlRTQlQkQlOTMlRTQlQjglQUQlRTYlOTYlODcpL1NpbXBsaWZpZWRfQ2hpbmVzZV8oJUU3JUFFJTgwJUU0JUJEJTkzJUU0JUI4JUFEJUU2JTk2JTg3KSMlRTQlQjglQUQlRTYlOTYlODclRTUlQUQlOTclRTQlQkQlOTM=" title="https://wiki.archlinux.org/title/Localization_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)/Simplified_Chinese_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#%E4%B8%AD%E6%96%87%E5%AD%97%E4%BD%93">Arch Wiki Simplified Chinese<i class="fa fa-external-link"></i></span></p><h4 id="锁屏工具swaylock"><a href="#锁屏工具swaylock" class="headerlink" title="锁屏工具swaylock"></a>锁屏工具swaylock</h4><p>我使用的是<span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL21vcnRpZS9zd2F5bG9jay1lZmZlY3Rz" title="https://github.com/mortie/swaylock-effects">swaylock-effects<i class="fa fa-external-link"></i></span></p><p>创建锁屏执行脚本文件: <code>sudo vim /usr/bin/lock-screen</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line">swaylock --screenshots --clock --indicator --indicator-radius 100 \</span><br><span class="line">         --indicator-thickness 7 --effect-blur 7x5 --effect-vignette 0.5:0.5 \</span><br><span class="line">         --ring-color bb00cc --key-hl-color 880033 --line-color 00000000 \</span><br><span class="line">         --inside-color 00000088 --separator-color 00000000 --grace 2 --fade-in 0.2</span><br></pre></td></tr></table></figure><p>赋予全体用户执行权限: <code>chmod u+x /usr/bin/lock-screen</code></p><p>接下里配置Sway配置文件: <code>vim .config/sway/config</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment">### Idle configuration</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="comment"># Example configuration:</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="built_in">exec</span> swayidle -w \</span><br><span class="line">    <span class="built_in">timeout</span> 300 <span class="string">&#x27;lock-screen &amp;&#x27;</span> \</span><br><span class="line">    <span class="built_in">timeout</span> 500 <span class="string">&#x27;swaymsg &quot;output * dpms off&quot;&#x27;</span> \</span><br><span class="line">       resume <span class="string">&#x27;swaymsg &quot;output * dpms on&quot;&#x27;</span> \</span><br><span class="line">    before-sleep <span class="string">&#x27;lock-screen &amp;&#x27;</span></span><br><span class="line"><span class="comment"># This will lock your screen after 300 seconds of inactivity, then turn off</span></span><br><span class="line"><span class="comment"># your displays after another 200 seconds, and turn your screens back on when</span></span><br><span class="line"><span class="comment"># resumed. It will also lock your screen before your computer goes to sleep.</span></span><br></pre></td></tr></table></figure><p>上面的部分配置为Sway默认配置，简单修改为上面的配置即可，修改好配置文件好需要重启Sway后才可以生效，因为使用的是<code>exec</code>，所以重新加载配置文件还不能生效，如果想要查看效果。可以: <code>killall -9 sway</code> ，之后重新登录系统等待查看效果。</p><h4 id="延时工具swayidle配置"><a href="#延时工具swayidle配置" class="headerlink" title="延时工具swayidle配置"></a>延时工具swayidle配置</h4><p><code>swayidle</code>我用来和<code>swaylock-effects</code>搭配使用，用于在一定时间内无操作后自动执行脚本或程序，所以可以用来解决一定时间哪无操作自动锁屏的需求。</p><h4 id="zsh"><a href="#zsh" class="headerlink" title="zsh"></a>zsh</h4><p>安装zsh: <code>yay -S zsh</code></p><p>更改用户默认Shell: <code>usermod --shell /usr/bin/zsh username</code></p><p>要注意bash_profile等文件是否有内容，如果有的话需要迁移为zsh相关的文件。</p><p>初始化默认配置文件:</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh</span><br><span class="line"><span class="built_in">cp</span> ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc</span><br><span class="line"><span class="built_in">source</span> .zshrc</span><br></pre></td></tr></table></figure><h2 id="常用软件包"><a href="#常用软件包" class="headerlink" title="常用软件包"></a>常用软件包</h2><p>这里会记录一些我常用的软件包</p><ul><li><code>git</code></li><li><code>vim</code> </li><li><code>bash-completion</code> bash自动补全</li><li><code>rp-pppoe</code> 对PPPoE的支持</li><li><code>openssh</code> openssh 需要开启服务</li><li><code>rclone</code> 挂载云盘</li><li><code>yay</code> 使用yay管理AUR源</li><li><code>proxychains-ng</code> 终端代理，可配置代理链</li><li><code>v2ray-core</code> 请珍惜眼前所拥有的一切</li><li><code>ntfs-3g</code> 挂载ntfs设备</li><li><code>qt5-wayland</code> 在Wayland下支持Qt5，需要<a href="#%E9%85%8D%E7%BD%AESway%E5%B9%B3%E9%93%BA%E7%AA%97%E5%8F%A3%E7%AE%A1%E7%90%86%E5%99%A8">配置环境变量</a></li></ul><h3 id="开启archlinuxcn源"><a href="#开启archlinuxcn源" class="headerlink" title="开启archlinuxcn源"></a>开启<code>archlinuxcn</code>源</h3><p>我使用清华大学archlinuxcn源</p><p>使用方法：</p><p>在 <code>/etc/pacman.conf</code> 文件末尾添加以下两行，并安装 <code>archlinuxcn-keyring</code> 包导入 GPG key。</p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[archlinuxcn]</span></span><br><span class="line"><span class="attr">Server</span> = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/<span class="variable">$arch</span></span><br></pre></td></tr></table></figure><h3 id="安装fcitx5-rime中文输入法"><a href="#安装fcitx5-rime中文输入法" class="headerlink" title="安装fcitx5-rime中文输入法"></a>安装fcitx5-rime中文输入法</h3><p>安装以下包：<code>yay -S fcitx5 fcitx5-qt fcitx5-gtk fcitx5-configtool fcitx5-rime qt5-wayland</code></p><p>若在Wayland环境下使用Qt5需要安装<code>qt5-wayland</code>包，并<a href="#%E9%85%8D%E7%BD%AESway%E5%B9%B3%E9%93%BA%E7%AA%97%E5%8F%A3%E7%AE%A1%E7%90%86%E5%99%A8">设置<code>QT_QPA_PLATFORM=wayland</code>环境变量</a>。</p><h3 id="yay安装"><a href="#yay安装" class="headerlink" title="yay安装"></a>yay安装</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://aur.archlinux.org/yay.git</span><br><span class="line"><span class="built_in">cd</span> yay</span><br><span class="line">makepkg -si</span><br></pre></td></tr></table></figure><p>或者在开启了archlinuxcn源后直接通过源安装。</p><p><code>pacman -S yay</code></p><p><strong>让yay通过proxychains使用代理</strong></p><p>go版本的yay不能使用proxychains进行代理，所以需要替换安装以下的软件包：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">yay -S gcc-go (代替go)</span><br><span class="line">yay -S yay (or yay-git)</span><br></pre></td></tr></table></figure><p>重新安装yay后还需要更改proxychains的配置文件：将52行附近的<code>proxy_dns</code>前使用#注释<code>#proxy_dns</code>。</p><h3 id="Edge浏览器"><a href="#Edge浏览器" class="headerlink" title="Edge浏览器"></a>Edge浏览器</h3><p>从AUR源中安装微软Edge浏览器: <code>yay -S microsoft-edge-dev-bin</code></p><p>在Wayland环境下，还需要对Edge浏览器的启动脚本做些手脚才能正式使用。</p><p><code>vim /usr/bin/microsoft-edge-dev</code></p><p>在exec指令中添加两个参数: </p><p><code>-enable-features=UseOzonePlatform</code></p><p><code>-ozone-platform=wayland</code></p><p><strong>目前没办法在EDGE浏览器中使用输入法，待解决</strong></p><h3 id="安装Wine"><a href="#安装Wine" class="headerlink" title="安装Wine"></a>安装Wine</h3><p>Wine目前原生不支持wayland，需要Xwayland支持。不过经过搜索后发现Wine的Git仓库中存在了wayland分支，并且在持续开发，截止到目前已经支持wayland环境与Wine运行的应用共享剪贴板。</p><p>接下来尝试使用wayland的分支尝试编译运行。</p><p>emmmm失败了，错误提示找不到显示驱动，先不折腾它，接下来试试Xwayland吧。</p><h4 id="安装Xwayland"><a href="#安装Xwayland" class="headerlink" title="安装Xwayland"></a>安装Xwayland</h4><p><code>yay -S xorg-xwayland</code></p><h4 id="安装wine"><a href="#安装wine" class="headerlink" title="安装wine"></a>安装wine</h4><p>Wine可通过开启<code>Multilib</code>仓库来安装<code>wine</code>包及依赖。</p><p><code>vim /etc/pacman.conf</code></p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[multilib]</span></span><br><span class="line"><span class="attr">Include</span> = /etc/pacman.d/mirrorlist</span><br></pre></td></tr></table></figure><p><code>yay -Sy</code></p><p><code>yay -S insatll wine</code></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;记录我的联想M720Q-Arch-Sway窗口管理器的安装和配置过程&quot;&gt;&lt;a href=&quot;#记录我的联想M720Q-Arch-Sway窗口管理器的安装和配置过程&quot; class=&quot;headerlink&quot; title=&quot;记录我的联想M720Q Arch Sway窗口管</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Arch" scheme="https://blog.yeefire.com/tags/Arch/"/>
    
  </entry>
  
  <entry>
    <title>Jenkins Linux安装</title>
    <link href="https://blog.yeefire.com/2021_02/jekins-install.html"/>
    <id>https://blog.yeefire.com/2021_02/jekins-install.html</id>
    <published>2021-02-06T06:28:45.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Jenkins-Linux-安装"><a href="#Jenkins-Linux-安装" class="headerlink" title="Jenkins Linux 安装"></a>Jenkins Linux 安装</h1><h2 id="在官网下载Jenkins"><a href="#在官网下载Jenkins" class="headerlink" title="在官网下载Jenkins"></a>在官网下载Jenkins</h2><p>下载当前最新的稳定版Jenkins保存到指定目录。</p><p><span class="exturl" data-url="aHR0cDovL21pcnJvcnMuamVua2lucy5pby93YXItc3RhYmxlL2xhdGVzdC9qZW5raW5zLndhcg==" title="http://mirrors.jenkins.io/war-stable/latest/jenkins.war">安装包下载<i class="fa fa-external-link"></i></span></p><p><code>wget -O ./jenkins.war http://mirrors.jenkins.io/war-stable/latest/jenkins.war</code></p><h2 id="配置Jenkins的JAVA运行环境"><a href="#配置Jenkins的JAVA运行环境" class="headerlink" title="配置Jenkins的JAVA运行环境"></a>配置Jenkins的JAVA运行环境</h2><p>Kenkins需要Java虚拟机才可以运行，在运行Jenkins前先配置JAVA虚拟机环境。</p><h3 id="下载-Java-JRE-Linux-X64"><a href="#下载-Java-JRE-Linux-X64" class="headerlink" title="下载 Java JRE Linux X64"></a>下载 Java JRE Linux X64</h3><p><span class="exturl" data-url="aHR0cHM6Ly9qYXZhZGwub3JhY2xlLmNvbS93ZWJhcHBzL2Rvd25sb2FkL0F1dG9ETD9CdW5kbGVJZD0yNDQwNThfODlkNjc4ZjJiZTE2NDc4NmIyOTI1Mjc2NThjYTE2MDU=" title="https://javadl.oracle.com/webapps/download/AutoDL?BundleId=244058_89d678f2be164786b292527658ca1605">Java JRE安装包下载<i class="fa fa-external-link"></i></span></p><p><code>wget -O ./jre-8u281-linux-x64.tar https://javadl.oracle.com/webapps/download/AutoDL?BundleId=244058_89d678f2be164786b292527658ca1605</code></p><h3 id="安装Java-JRE"><a href="#安装Java-JRE" class="headerlink" title="安装Java JRE"></a>安装Java JRE</h3><p>将下载好的Java JRE安装包移动你要安装的目录里，我想要安装在<code>/usr/java</code>目录下。</p><p>（ROOT）创建安装目录<code>sudo mkdir -p /usr/java</code></p><p>（ROOT）移动安装包<code>sudo mv ./jre-8u281-linux-x64.tar /usr/java</code></p><p>（ROOT）解压 <code>sudo tar -zxvf /usr/java/jre-8u281-linux-x64.tar</code></p><p>查看<code>/usr/java</code>目录你会发现除了安装包外新存在一个名字与<code>jre1.8.0_281</code>差不多相同的目录（这取决于你下载的JavaJRE版本）</p><p>那么现在你的Java JRE安装在了<code>/usr/java/jre1.8.0_281</code>内，现在可以将<code>/usr/java/</code>目录下的Java JRE安装包删除掉以节省空间</p><p>接下来配置环境变量，请根据自己Linux发行版的规则变通的配置<code>/etc/profile</code>！</p><p>在<code>/etc/profile</code>文件开始处填写：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> JAVA_HOME=/usr/java/jre1.8.0_281/</span><br><span class="line"><span class="built_in">export</span> JRE_HOME=/usr/java/jre1.8.0_281/</span><br><span class="line"><span class="built_in">export</span> CLASS_PATH=.:<span class="variable">$JAVA_HOME</span>/lib/rt.jar:<span class="variable">$JRE_HOME</span>/lib</span><br><span class="line"><span class="built_in">export</span> JAVA_PATH=<span class="variable">$JAVA_HOME</span>/bin:<span class="variable">$JRE_HOME</span>/bin</span><br></pre></td></tr></table></figure><p><strong>之后找到PATH，在PATH末尾填写上<code>$&#123;JAVA_PATH&#125;</code>。请根据自己的实际情况填写，否则可能会覆盖之前的环境变量哦！</strong></p><p>我的环境变量配置如下:</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">export</span> JAVA_HOME=/usr/java/jre1.8.0_281/</span><br><span class="line"><span class="built_in">export</span> JRE_HOME=/usr/java/jre1.8.0_281/</span><br><span class="line"><span class="built_in">export</span> CLASS_PATH=.:<span class="variable">$JAVA_HOME</span>/lib/rt.jar:<span class="variable">$JRE_HOME</span>/lib</span><br><span class="line"><span class="built_in">export</span> JAVA_PATH=<span class="variable">$JAVA_HOME</span>/bin:<span class="variable">$JRE_HOME</span>/bin</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> [ <span class="string">&quot;`id -u`&quot;</span> -eq 0 ]; <span class="keyword">then</span></span><br><span class="line">  PATH=<span class="string">&quot;/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:<span class="variable">$&#123;JAVA_PATH&#125;</span>&quot;</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  PATH=<span class="string">&quot;/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:<span class="variable">$&#123;JAVA_PATH&#125;</span>&quot;</span></span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"><span class="built_in">export</span> PATH</span><br></pre></td></tr></table></figure><p>激活环境变量 <code>source /etc/profile</code></p><p>查看配置是否成功则执行<code>java -version</code>，出现版本信息则配置成功:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">java version &quot;1.8.0_281&quot;</span><br><span class="line">Java(TM) SE Runtime Environment (build 1.8.0_281-b09)</span><br><span class="line">Java HotSpot(TM) 64-Bit Server VM (build 25.281-b09, mixed mode)</span><br></pre></td></tr></table></figure><h2 id="初始化Jenkins"><a href="#初始化Jenkins" class="headerlink" title="初始化Jenkins"></a>初始化Jenkins</h2><p>准备工作已经结束，接下来开始进行初始化Jenkins！</p><p>回到下载Jenkins的目录，执行<code>java -jar jenkins.war --httpPort=8080</code>命令。这里的8080是Web界面的端口号，你可以修改成自己需要的端口号，注意防火墙要放行该TCP端口。</p><p>首次运行Jenkins，首次运行Jenkins时会在当前用户家目录下生成一些配置文件<code>~/.jenkins</code>。</p><p>访问你的域名或IP地址加上端口号后，你可以看到这样的界面。</p><p><img src="https://cdn.yeefire.com/hexo/img/01-first-interface-2021-02-06-14-31-08.png" alt="01-first-interface-2021-02-06-14-31-08"></p><p>此时Jenkins会下载一些资源，需要等待5分钟左右。如果时间过长，结束掉现在运行的Jenkins，先需要更改国内下载源来加快速度:</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cd</span> ~/.jenkins</span><br><span class="line">vim hudson.model.UpdateCenter.xml</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将&lt;url&gt;标签内的网址改为清华源</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 将下面的内容</span></span><br><span class="line">&lt;url&gt;https://updates.jenkins.io/update-center.json&lt;/url&gt;</span><br><span class="line"><span class="comment"># 修改为</span></span><br><span class="line"></span><br><span class="line">&lt;url&gt;https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json&lt;/url&gt;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>之后回到Jenkins软件包的目录下重新执行<code>java -jar jenkins.war --httpPort=8080</code></p><p>稍后页面会让你输入管理员密码解锁安装Jenkins。管理员密码可以在运行Jenkins的终端上找到，也可以根据页面提示的文件中找到。</p><p><img src="https://cdn.yeefire.com/hexo/img/01-prepare-code-2021-02-06-14-31-38.png" alt="Jenkins安装解锁密码"></p><p>输入密码后下一步会安装基本常用插件，选择左侧的选项开始安装即可。</p><p><img src="https://cdn.yeefire.com/hexo/img/01-install-plugs-2021-02-06-14-31-57.png" alt="Jenkins安装常用插件"></p><p>此时需要一段时间等待……</p><p>如果出现插件安装失败，不用担心，很可能是Jenkins版本不支持当前下载的最新插件，稍后进入到Jenkins管理页面更新Jenkins版本即可。</p><p><img src="https://cdn.yeefire.com/hexo/img/01-install-plugs-error-2021-02-06-14-32-03.png" alt="Jenkins安装插件部分插件安装失败"></p><p>接下来根据你的个人需求配置管理员用户名密码等设置。</p><h2 id="配置开机自动启动-systemd-守护进程"><a href="#配置开机自动启动-systemd-守护进程" class="headerlink" title="配置开机自动启动 systemd 守护进程"></a>配置开机自动启动 systemd 守护进程</h2><p>以下内容使用于以war包形式部署Jenkins的方式来配置systemd守护进程服务，其它方式安装的Jenkins需要你自己变通。</p><p>以下内容参考<span class="exturl" data-url="aHR0cHM6Ly93d3cuY25ibG9ncy5jb20vYXJjaGl0ZWN0Zm9yZXN0L3AvMTM2ODcwMTQuaHRtbA==" title="https://www.cnblogs.com/architectforest/p/13687014.html">linux(centos8):用systemctl管理war包形式的jenkins(java 14 / jenkins 2.257)<i class="fa fa-external-link"></i></span>这篇文章。</p><h3 id="创建管理脚本"><a href="#创建管理脚本" class="headerlink" title="创建管理脚本"></a>创建管理脚本</h3><p><code>vim jenkins-control.sh</code>创建新文本文件，将以下内容写入到文件中。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">source</span> /etc/profile</span><br><span class="line"></span><br><span class="line">pid=`ps -ef | grep jenkins.war | grep -v <span class="string">&#x27;grep&#x27;</span>| awk <span class="string">&#x27;&#123;print $2&#125;&#x27;</span>| <span class="built_in">wc</span> -l`</span><br><span class="line"><span class="keyword">if</span> [ <span class="string">&quot;<span class="variable">$1</span>&quot;</span> = <span class="string">&quot;start&quot;</span> ];<span class="keyword">then</span></span><br><span class="line">   <span class="keyword">if</span> [ <span class="variable">$pid</span> -gt 0 ];<span class="keyword">then</span></span><br><span class="line">      <span class="built_in">echo</span> <span class="string">&#x27;jenkins is running...&#x27;</span></span><br><span class="line">   <span class="keyword">else</span></span><br><span class="line">      <span class="built_in">nohup</span> <span class="variable">$JAVA_HOME</span>/bin/java -jar /home/hackinsss/Jenkins/jenkins.war --enable-future-java --httpPort=8088  2&gt;&amp;1 &amp;</span><br><span class="line">   <span class="keyword">fi</span></span><br><span class="line"><span class="keyword">elif</span> [ <span class="string">&quot;<span class="variable">$1</span>&quot;</span> = <span class="string">&quot;stop&quot;</span> ];<span class="keyword">then</span></span><br><span class="line">   <span class="built_in">exec</span> ps -ef | grep jenkins | grep -v grep | awk <span class="string">&#x27;&#123;print $2&#125;&#x27;</span>| xargs <span class="built_in">kill</span> -9</span><br><span class="line">   <span class="built_in">echo</span> <span class="string">&#x27;jenkins is stop..&#x27;</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">   <span class="built_in">echo</span> <span class="string">&quot;Please input like this:&quot;</span>./jenkins.sh start<span class="string">&quot; or &quot;</span>./jenkins stop<span class="string">&quot;&quot;</span></span><br><span class="line"><span class="keyword">fi</span></span><br></pre></td></tr></table></figure><p>为脚本文件赋予执行权限 <code>chmod u+x jenkins-control.sh</code></p><p>启动Jenkins <code>./jenkins-control.sh start</code></p><p>关闭Jenkins <code>./jenkins-control.sh stop</code></p><p>上面两个操作没有问题，能正确开启或关闭Jenkins的话则脚本运行没有问题，开始编辑systemd服务文件。</p><h3 id="创建systemd服务文件"><a href="#创建systemd服务文件" class="headerlink" title="创建systemd服务文件"></a>创建systemd服务文件</h3><p><code>sudo vim /etc/systemd/system/jenkins.service</code></p><p>修改运行Jenkins的用户和脚本路径地址为你自己的。不推荐使用root权限运行Jenkins</p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[Unit]</span></span><br><span class="line"><span class="attr">Description</span>=Jenkins</span><br><span class="line"><span class="attr">After</span>=network.target</span><br><span class="line"></span><br><span class="line"><span class="section">[Service]</span></span><br><span class="line"><span class="attr">Type</span>=forking</span><br><span class="line"><span class="attr">User</span>=使用该用户运行Jenkins</span><br><span class="line"><span class="attr">Group</span>=使用该用户组运行Jenkins</span><br><span class="line"><span class="attr">ExecStart</span>=/home/hackinsss/Jenkins/jenkins-control.sh start</span><br><span class="line"><span class="attr">ExecReload</span>=</span><br><span class="line"><span class="attr">ExecStop</span>=/home/hackinsss/Jenkins/jenkins-control.sh stop</span><br><span class="line"><span class="attr">PrivateTmp</span>=<span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="section">[Install]</span></span><br><span class="line"><span class="attr">WantedBy</span>=multi-user.target</span><br></pre></td></tr></table></figure><p><code>sudo systemctl daemon-reload</code></p><p>设置开机自动运行Jenkins <code>sudo systemctl enable jenkins</code></p><p>运行Jenkins <code>sudo systemctl start jenkins</code></p><p>停止运行Jenkins <code>sudo systemctl start jenkins</code></p><p>安装Jenkins流程记录到此结束。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Jenkins-Linux-安装&quot;&gt;&lt;a href=&quot;#Jenkins-Linux-安装&quot; class=&quot;headerlink&quot; title=&quot;Jenkins Linux 安装&quot;&gt;&lt;/a&gt;Jenkins Linux 安装&lt;/h1&gt;&lt;h2 id=&quot;在官网下载Jenk</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Jenkins" scheme="https://blog.yeefire.com/tags/Jenkins/"/>
    
  </entry>
  
  <entry>
    <title>腾讯课堂、钉钉在线网课视频直播回放下载离线播放</title>
    <link href="https://blog.yeefire.com/2020_12/cloud_class_replay.html"/>
    <id>https://blog.yeefire.com/2020_12/cloud_class_replay.html</id>
    <published>2020-12-27T18:00:47.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="腾讯课堂、钉钉-在线网课视频直播回放下载离线播放"><a href="#腾讯课堂、钉钉-在线网课视频直播回放下载离线播放" class="headerlink" title="[腾讯课堂、钉钉]在线网课视频直播回放下载离线播放"></a>[腾讯课堂、钉钉]在线网课视频直播回放下载离线播放</h1><p>有些精品好课真的是百看不厌、教师精心准备、学习氛围也好。不过有些已购买的课程却只能在线观看…现在讲究的是一个环保、节能。如果能将已购买的课程离线下载好，那么会为各大平台节省多少带宽费用当然还有数据包在这世间重复的传输所浪费的电力资源。</p><p>本着环保、节能、减排的目的，开始了尝试对腾讯课堂网页版中自己购买了课程的视频回放进行下载。</p><p>然后顺便又看了下钉钉的回放。</p><p><span class="exturl" data-url="aHR0cHM6Ly9naXRodWIuY29tL3llZWZpcmUvY2xvdWQtY2xhc3MtcmVwbGF5" title="https://github.com/yeefire/cloud-class-replay">github直达项目：https://github.com/yeefire/cloud-class-replay<i class="fa fa-external-link"></i></span></p><h2 id="腾讯课堂"><a href="#腾讯课堂" class="headerlink" title="腾讯课堂"></a>腾讯课堂</h2><p>由于没有使用客户端，在网页上观看。使用浏览器中的开发者工具来寻找请求。</p><p><img src="https://cdn.yeefire.com/hexo/img/tencent_class_safari_devnet-2020-12-28-00-30-43.png" alt="tencent_class_safari_devnet-2020-12-28-00-30-43"></p><p>可以看到请求了很多视频片段，文件拓展名为ts，GET请求。于是直接复制求请求连接然后丢在浏览器地址栏播放，结果不行，是加密的。</p><p>因为看到了ts，那么八九不离十使用的是M3U文件存储分段多媒体信息。</p><blockquote><p>ts是日本高清摄像机拍摄下进行的封装格式文件,全称为MPEG2-TS。</p></blockquote><blockquote><p>M3U8是Unicode版本的M3U，用UTF-8编码。”M3U”和”M3U8”文件都是苹果公司使用的HTTP Live Streaming格式的基础，这种格式可以在iPhone和Macbook等设备播放。</p></blockquote><h3 id="寻找M3U"><a href="#寻找M3U" class="headerlink" title="寻找M3U"></a>寻找M3U</h3><p>在请求中搜索m3u，出现了几个m3u8拓展文件，选择资源文件最大的那个m3u8文件，获取cURL请求或者其他方式将其下载到本地方便进一步分析。</p><p>现在找到了m3u文件，我们可以获取到这节课的所有分段视频了。</p><p><img src="https://cdn.yeefire.com/hexo/img/tencent_class_safari_search_m3u8-2020-12-28-00-48-19.png" alt="tencent_class_safari_search_m3u8-2020-12-28-00-48-19"></p><h3 id="分析腾讯课堂M3U文件"><a href="#分析腾讯课堂M3U文件" class="headerlink" title="分析腾讯课堂M3U文件"></a>分析腾讯课堂M3U文件</h3><p>已经下载好了m3u8拓展文件，接下来打开文件进行分析！</p><p>可以看到腾讯课堂的每个分段视频是使用AES-128进行加密的，好在下载到的m3u8文件里给出了解密密钥的地址以及偏移量。</p><p>这下我们有了密钥和偏移量还有分段视频的请求参数（还不知道HTTP请求路径）</p><p><img src="https://cdn.yeefire.com/hexo/img/tencent_class_m3u8_file-2020-12-28-01-06-24.png" alt="tencent_class_m3u8_file-2020-12-28-01-06-24"></p><p><img src="https://cdn.yeefire.com/hexo/img/tencent_class_m3u8_check-2020-12-28-01-11-59.png" alt="tencent_class_m3u8_check-2020-12-28-01-11-59"></p><h3 id="整理总结"><a href="#整理总结" class="headerlink" title="整理总结"></a>整理总结</h3><p>现在可以尝试下载一个小的视频片段，不过目前还没有请求视频片段的完整路径，只有一个个的请求参数。这个好办，再回到浏览器中播放回放视频，观察浏览器开发者工具中的网络请求动态，找到’vxxxxxx.ts’请求，并查看获取该视频片段的完整HTTP请求路径。</p><p>发现和m3u8的请求路径与其相似。</p><p>m3u: <code>https://xxxxxxxxxx.vod2.myqcloud.com/xxxxxxxxxxxxxx/b4e0xxxxxxxxxxxxxx7/drm/voddrm.xxxxxxxxxxxxx</code></p><p>ts: <code>https://xxxxxxxxxx.vod2.myqcloud.com/xxxxxxxxxxxxxx/b4e0xxxxxxxxxxxxxx7/drm/v.fxxxx.ts?start=195027344&amp;end=195666559&amp;type=mpegtsxxxxxxxxxxxxx</code></p><p>在最后出现<code>/</code>斜杠位置前的所有请求路径都相同。并且斜杠后的请求参数正是m3u文件中的一个个分段视频的请求参数，看来仅仅需要简单的拼接就可以将这些分段视频下载好了。</p><p>那么现在我们有了全部分段视频的下载请求地址、解密算法、解密密钥及偏移量。有了这些就可以尝试下载分段视频并进行解密和合并了。</p><p>先尝试解密一个分段视频试试看:</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">with</span> aiofiles.<span class="built_in">open</span>(m3u8_encrypt_file, mode=<span class="string">&#x27;rb&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">       f = f.read()</span><br><span class="line">       content_video_part = AES.new(key, AES.MODE_CBC, iv).decrypt(f)</span><br><span class="line"><span class="keyword">with</span> aiofiles.<span class="built_in">open</span>(dest_decrypt_file, mode=<span class="string">&#x27;wb&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">       f.write(content_video_part)</span><br></pre></td></tr></table></figure><p>可以正常播放，没有问题。接下来下载全部的分段视频并解密，最后重新整合为一个mp4格式视频文件。剩下的交给脚本处理了！</p><h3 id="腾讯课堂回放下载脚本"><a href="#腾讯课堂回放下载脚本" class="headerlink" title="腾讯课堂回放下载脚本"></a>腾讯课堂回放下载脚本</h3><p>脚本使用异步进行请求下载分段视频和解密视频，尽可能的以最快的速度下载好全部的分段视频。</p><p>如果下载期间遇到网络波动，脚本可以自动重试下载。</p><p>若脚本意外停止，可以继续追加下载，不必全部重新开始下载分段视频。</p><p>使用方法：</p><ul><li>先安装依赖模块 <code>pip3 install pycrypto m3u8 aiofiles requests_async</code></li><li>命令行执行 <code>python3 tencent_class_m3u8.py 这节课的名称 这节课的M3U文件请求地址(网址或者本地路径都可以)</code></li></ul><p>例如: <code>python3 tencent_class_m3u8.py 【Python进阶】Python-上午 https://1dada217.vod2.myqcloud.com/fdadadada3kmdkfsxxxxxxxxxxxxxxxxx</code></p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line"><span class="keyword">import</span> requests_async <span class="keyword">as</span> requests</span><br><span class="line"><span class="keyword">import</span> aiofiles</span><br><span class="line"><span class="keyword">import</span> m3u8</span><br><span class="line"><span class="keyword">import</span> os, sys</span><br><span class="line"><span class="keyword">import</span> asyncio</span><br><span class="line"></span><br><span class="line">class_video_name = sys.argv[<span class="number">1</span>]</span><br><span class="line">m3u8_file_uri = sys.argv[<span class="number">2</span>]</span><br><span class="line">prefix_request_url = <span class="string">f&#x27;<span class="subst">&#123;m3u8_file_uri.rsplit(<span class="string">&quot;/&quot;</span>, <span class="number">1</span>)[<span class="number">0</span>]&#125;</span>/&#x27;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">download_m3u8_video</span>(<span class="params">index: <span class="built_in">int</span>, suffix_url: <span class="built_in">str</span></span>):</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/downloads/<span class="subst">&#123;index&#125;</span>.ts&#x27;</span>):</span><br><span class="line">        i = <span class="number">0</span></span><br><span class="line">        <span class="keyword">while</span> i &lt; <span class="number">3</span>:</span><br><span class="line">            <span class="keyword">try</span>:</span><br><span class="line">                download_video_ts = <span class="keyword">await</span> requests.get(url=prefix_request_url + suffix_url, timeout=<span class="number">30</span>)</span><br><span class="line">                <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/downloads/<span class="subst">&#123;index&#125;</span>.ts&#x27;</span>, <span class="string">&quot;wb&quot;</span>) <span class="keyword">as</span> ts:</span><br><span class="line">                    ts.write(download_video_ts.content)</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——已下载第 <span class="subst">&#123;index&#125;</span> 个片段/ 共 <span class="subst">&#123;<span class="built_in">len</span>(playlist.files)&#125;</span> 个片段&#x27;</span>)</span><br><span class="line">                <span class="keyword">return</span></span><br><span class="line">            <span class="keyword">except</span> requests.exceptions.RequestException:</span><br><span class="line">                <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——下载超时，正在重新下载第 <span class="subst">&#123;index&#125;</span> 个片段/ 共 <span class="subst">&#123;<span class="built_in">len</span>(playlist.files)&#125;</span> 个片段&#x27;</span>)</span><br><span class="line">                <span class="keyword">await</span> asyncio.sleep(i)</span><br><span class="line">                i += <span class="number">1</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">download_m3u8_all</span>():</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(class_video_name + <span class="string">&#x27;/downloads&#x27;</span>):</span><br><span class="line">        os.makedirs(class_video_name + <span class="string">&#x27;/downloads&#x27;</span>)</span><br><span class="line">    download_async_list = [asyncio.create_task(download_m3u8_video(i, video_suffix_url))</span><br><span class="line">                           <span class="keyword">for</span> i, video_suffix_url <span class="keyword">in</span> <span class="built_in">enumerate</span>(playlist.files, <span class="number">1</span>)]</span><br><span class="line">    <span class="keyword">await</span> asyncio.wait(download_async_list)</span><br><span class="line"></span><br><span class="line">    download_encrypt_list = [uri <span class="keyword">for</span> uri <span class="keyword">in</span> os.listdir(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/downloads&#x27;</span>) <span class="keyword">if</span> uri[<span class="number">0</span>] != <span class="string">&#x27;.&#x27;</span>]</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(download_encrypt_list) == <span class="built_in">len</span>(playlist.files):  <span class="comment"># 判断是否有漏下的分段视频没有下载</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——视频全部下载完成&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> download_encrypt_list</span><br><span class="line">    <span class="keyword">else</span>:  <span class="comment"># 有部分视频在三次重试后依旧没有下载成功</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——下载过程中出现问题，正在重试...&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">await</span> download_m3u8_all()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">decrypt_m3u8_video</span>(<span class="params">m3u8_encrypt_file_uri: <span class="built_in">str</span>, key: <span class="built_in">bytes</span>, iv: <span class="built_in">bytes</span></span>):</span><br><span class="line">    decrypt_name = <span class="string">f&#x27;<span class="subst">&#123;m3u8_encrypt_file_uri.split(<span class="string">&quot;/&quot;</span>)[-<span class="number">1</span>].split(<span class="string">&quot;.&quot;</span>)[<span class="number">0</span>]&#125;</span>&#x27;</span></span><br><span class="line">    dest_decrypt_uri = <span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/decryption/<span class="subst">&#123;decrypt_name&#125;</span>.de.ts&#x27;</span></span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(dest_decrypt_uri):</span><br><span class="line">        <span class="keyword">async</span> <span class="keyword">with</span> aiofiles.<span class="built_in">open</span>(m3u8_encrypt_file_uri, mode=<span class="string">&#x27;rb&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">            f = <span class="keyword">await</span> f.read()</span><br><span class="line">            content_video_part = AES.new(key, AES.MODE_CBC, iv).decrypt(f)</span><br><span class="line">        <span class="keyword">async</span> <span class="keyword">with</span> aiofiles.<span class="built_in">open</span>(dest_decrypt_uri, mode=<span class="string">&#x27;wb&#x27;</span>) <span class="keyword">as</span> f:</span><br><span class="line">            <span class="keyword">await</span> f.write(content_video_part)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——已解密第 <span class="subst">&#123;decrypt_name&#125;</span> 个片段/ 共 <span class="subst">&#123;<span class="built_in">len</span>(playlist.files)&#125;</span> 个片段&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">async</span> <span class="keyword">def</span> <span class="title function_">decrypt_m3u8_all</span>():</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">not</span> os.path.exists(class_video_name + <span class="string">&#x27;/decryption&#x27;</span>):</span><br><span class="line">        os.makedirs(class_video_name + <span class="string">&#x27;/decryption&#x27;</span>)</span><br><span class="line">    key = <span class="keyword">await</span> requests.get(playlist.keys[<span class="number">0</span>].uri)</span><br><span class="line">    key = key.content</span><br><span class="line">    iv = <span class="built_in">bytes</span>(playlist.keys[<span class="number">0</span>].iv, <span class="string">&#x27;UTF-8&#x27;</span>)[:<span class="number">16</span>]</span><br><span class="line">    decrypt_m3u8_list = [asyncio.create_task(decrypt_m3u8_video(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/downloads/<span class="subst">&#123;uri&#125;</span>&#x27;</span>, key, iv))</span><br><span class="line">                         <span class="keyword">for</span> uri <span class="keyword">in</span> os.listdir(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/downloads&#x27;</span>) <span class="keyword">if</span> uri[<span class="number">0</span>] != <span class="string">&#x27;.&#x27;</span>]  <span class="comment"># 忽略隐藏文件</span></span><br><span class="line">    <span class="keyword">await</span> asyncio.wait(decrypt_m3u8_list)</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——视频全部解密完成&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">merge_m3u8_all</span>():</span><br><span class="line">    download_decrypt_list = [uri <span class="keyword">for</span> uri <span class="keyword">in</span> os.listdir(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/decryption&#x27;</span>) <span class="keyword">if</span> uri[<span class="number">0</span>] != <span class="string">&#x27;.&#x27;</span>]</span><br><span class="line">    download_encrypt_list = [uri <span class="keyword">for</span> uri <span class="keyword">in</span> os.listdir(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/downloads&#x27;</span>) <span class="keyword">if</span> uri[<span class="number">0</span>] != <span class="string">&#x27;.&#x27;</span>]</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(download_decrypt_list) != <span class="built_in">len</span>(download_encrypt_list):  <span class="comment"># 判断是否有漏下的分段视频没有下载</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">&#x27;解密分段视频出现问题，可能是受限于类Unix系统文件句柄数量限制导致脚本不能获取足够的文件句柄。\n &#x27;</span></span><br><span class="line">              <span class="string">&#x27;如果你是 Linux 或 Macos 请尝试在运行本脚本的终端内执行 &quot;ulimit -n 5120&quot; 命令，以解除255(Macos)/1024(Linux)数量限制&#x27;</span>)</span><br><span class="line">        <span class="keyword">return</span></span><br><span class="line">    <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/<span class="subst">&#123;class_video_name&#125;</span>.mp4&#x27;</span>, <span class="string">&#x27;ab&#x27;</span>) <span class="keyword">as</span> final_file:</span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——开始拼接解密后的分段视频&#x27;</span>)</span><br><span class="line">        temp_file_uri_list = os.listdir(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/decryption&#x27;</span>)</span><br><span class="line">        temp_file_uri_list.sort(key=<span class="keyword">lambda</span> x: <span class="built_in">int</span>(x[:-<span class="number">6</span>]))</span><br><span class="line">        <span class="keyword">for</span> uri <span class="keyword">in</span> temp_file_uri_list:</span><br><span class="line">            <span class="keyword">if</span> uri[<span class="number">0</span>] == <span class="string">&#x27;.&#x27;</span>: <span class="keyword">continue</span>  <span class="comment"># 忽略隐藏文件</span></span><br><span class="line">            <span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">f&#x27;<span class="subst">&#123;class_video_name&#125;</span>/decryption/<span class="subst">&#123;uri&#125;</span>&#x27;</span>, <span class="string">&#x27;rb&#x27;</span>) <span class="keyword">as</span> temp_file:</span><br><span class="line">                final_file.write(temp_file.read())  <span class="comment"># 将ts格式分段视频追加到完整视频文件中</span></span><br><span class="line">        <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——合成视频成功&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">&#x27;__main__&#x27;</span>:</span><br><span class="line">    playlist = m3u8.load(m3u8_file_uri, verify_ssl=<span class="literal">False</span>)</span><br><span class="line">    <span class="keyword">del</span> playlist.files[<span class="number">0</span>]  <span class="comment"># 第一个文件为视频密钥，忽略这个文件。</span></span><br><span class="line">    asyncio.run(download_m3u8_all())</span><br><span class="line">    asyncio.run(decrypt_m3u8_all())</span><br><span class="line">    merge_m3u8_all()</span><br><span class="line">    <span class="built_in">print</span>(<span class="string">f&#x27;[<span class="subst">&#123;class_video_name&#125;</span>]——视频文件:<span class="subst">&#123;os.getcwd()&#125;</span>/<span class="subst">&#123;class_video_name&#125;</span>/<span class="subst">&#123;class_video_name&#125;</span>.mp4&#x27;</span>)</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="钉钉"><a href="#钉钉" class="headerlink" title="钉钉"></a>钉钉</h2><p>钉钉回放下载更简单，之后将腾讯课堂回放的脚本稍作删减就可以用于钉钉回放下载。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;腾讯课堂、钉钉-在线网课视频直播回放下载离线播放&quot;&gt;&lt;a href=&quot;#腾讯课堂、钉钉-在线网课视频直播回放下载离线播放&quot; class=&quot;headerlink&quot; title=&quot;[腾讯课堂、钉钉]在线网课视频直播回放下载离线播放&quot;&gt;&lt;/a&gt;[腾讯课堂、钉钉]在线网课</summary>
      
    
    
    
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
  </entry>
  
  <entry>
    <title>Ceph块设备对RBD块设备操作LVM创建PV时报错</title>
    <link href="https://blog.yeefire.com/2020_10/ceph_rbd_pvcreate_error.html"/>
    <id>https://blog.yeefire.com/2020_10/ceph_rbd_pvcreate_error.html</id>
    <published>2020-10-31T08:26:17.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ceph块设备-对RBD块设备操作LVM创建PV时报错"><a href="#Ceph块设备-对RBD块设备操作LVM创建PV时报错" class="headerlink" title="Ceph块设备 对RBD块设备操作LVM创建PV时报错"></a>Ceph块设备 对RBD块设备操作LVM创建PV时报错</h1><p>当映射好了RBD映像中后，要在其上创建LVM逻辑卷，在执行pvcreate时出错。报错如下：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[root@ceph-master ceph]# pvcreate /dev/rbd0</span><br><span class="line">  /dev/sdd: open failed: No medium found</span><br><span class="line">  Device /dev/rbd0 excluded by a filter.</span><br></pre></td></tr></table></figure><p>可以看到执行创建PV时被过滤器拦截掉了，这是因为默认情况下LVM不支持rbd设备类型，那么在LVM过滤器配置中手动添加RBD类型即可。</p><p>调试模式查看详细信息：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line"># pvcreate -vvvv /dev/rbd0 &amp;&gt; /tmp/out</span><br><span class="line"># less /tmp/out</span><br><span class="line">....</span><br><span class="line">#filters/filter-type.c:27            /dev/rbd0: Skipping: Unrecognised LVM device type 252</span><br><span class="line">....</span><br></pre></td></tr></table></figure><h2 id="查看设备类型ID"><a href="#查看设备类型ID" class="headerlink" title="查看设备类型ID"></a>查看设备类型ID</h2><p><code>cat /proc/devices</code></p><p>可以找到rbd设备类型ID编号为252，记住它后接下来在LVM过滤器配置文件中添加它。</p><h2 id="修改LVM过滤器配置文件"><a href="#修改LVM过滤器配置文件" class="headerlink" title="修改LVM过滤器配置文件"></a>修改LVM过滤器配置文件</h2><p><code>vim /etc/lvm/lvm.conf</code></p><p>找到<code>types</code>参数，将rbd和252修改为如下配置:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">...</span><br><span class="line"># Configuration section devices.</span><br><span class="line"># How LVM uses block devices.</span><br><span class="line">devices &#123;</span><br><span class="line">...</span><br><span class="line">        # Configuration option devices/types.</span><br><span class="line">        # List of additional acceptable block device types.</span><br><span class="line">        # These are of device type names from /proc/devices, followed by the</span><br><span class="line">        # maximum number of partitions.</span><br><span class="line">        # </span><br><span class="line">        # Example</span><br><span class="line">        types = [ &quot;rbd&quot;, 252 ]</span><br><span class="line">        # </span><br><span class="line">        # This configuration option is advanced.</span><br><span class="line">        # This configuration option does not have a default value defined.</span><br><span class="line">...</span><br></pre></td></tr></table></figure><p>现在尝试重新添加rbd设备作为PV：</p><p><code>pvcreate /dev/rbd0</code></p><p>现在可以成功在RBD块设备上执行创建PV操作了。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ceph块设备-对RBD块设备操作LVM创建PV时报错&quot;&gt;&lt;a href=&quot;#Ceph块设备-对RBD块设备操作LVM创建PV时报错&quot; class=&quot;headerlink&quot; title=&quot;Ceph块设备 对RBD块设备操作LVM创建PV时报错&quot;&gt;&lt;/a&gt;Ceph块</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>Ceph映射RBD块设备</title>
    <link href="https://blog.yeefire.com/2020_10/ceph_rbd_map.html"/>
    <id>https://blog.yeefire.com/2020_10/ceph_rbd_map.html</id>
    <published>2020-10-31T08:25:17.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ceph-映射RBD块设备"><a href="#Ceph-映射RBD块设备" class="headerlink" title="Ceph 映射RBD块设备"></a>Ceph 映射RBD块设备</h1><h2 id="前提准备"><a href="#前提准备" class="headerlink" title="前提准备"></a>前提准备</h2><p>你需要有一个运行着的Ceph集群，并且已创建好了一个Pool池，以此来创建新的RBD映像。</p><p>Pool池名称：rbd</p><p>Namespace命名空间名称：42team</p><p>要创建的RBD镜像名：<code>42team.dev.yeefire.com.100G.img</code></p><h2 id="新建块设备"><a href="#新建块设备" class="headerlink" title="新建块设备"></a>新建块设备</h2><p>创建块设备首先要创建Pool池，关于Pool池的创建如果你还不知道的话可以先看看这篇文章：<a href="https://blog.yeefire.com/2020_07/ceph_osd_pool_manage.html">OSD与Pool池的常见操作及管理</a></p><p>创建Pool池：<code>ceph osd pool create rbd 16 16</code></p><p>新创建的Pool池如果要用于RBD映像存储的话最好先对其初始化并对这个Pool池设置rbd应用：</p><ul><li>初始化Pool池用于RBD存储：<code>rbd pool init rbd</code></li><li>为rbd池设置app应用，并标记rbd应用：<code>ceph osd pool application enable rbd rbd</code></li></ul><h2 id="创建命名空间（非必要操作）"><a href="#创建命名空间（非必要操作）" class="headerlink" title="创建命名空间（非必要操作）"></a>创建命名空间（非必要操作）</h2><p>命名空间的存在是方便对一个存储池Pool进行更细化的用户访问控制，这样可以少创建一些存储池，使用池中命名空间来对用户进行隔离。</p><p>如果你想了解如何使用cephx认证配合命名空间对用户限制访问池中资源，请阅读：<a href="https://blog.yeefire.com/2020_07/ceph_user_manage.html">Ceph用户管理</a></p><p>为rbd池创建名为<code>42team</code>的命名空间：<code>namespace create -p rbd --namespace 42team</code></p><h2 id="创建RBD映像"><a href="#创建RBD映像" class="headerlink" title="创建RBD映像"></a>创建RBD映像</h2><p>到这一步为止，你已经做了如下操作：</p><ul><li>有一个正常状态的Ceph存储集群</li><li>创建了一个名为rbd的存储池</li><li>将rbd存储池的application应用设置为rbd</li><li>可选：（为rbd池创建名为42team的命名空间）</li><li>可选：（创建一个cephx认证用户，并将这个用户的osd能力限制在rbd池中的42team命名空间内）</li></ul><p>接下来开始创建一个RBD映像</p><p><code>rbd create -p rbd --namespace 42team --size 100G 42team.dev.yeefire.com.100G.img</code></p><p>查看创建的rbd映像</p><p><code>rbd ls -p rbd --namespace 42team</code></p><h2 id="映射RBD映像到内核模块"><a href="#映射RBD映像到内核模块" class="headerlink" title="映射RBD映像到内核模块"></a>映射RBD映像到内核模块</h2><p>用 rbd 把映像名映射为内核模块。必须指定映像名、存储池名、和用户名。若 RBD 内核模块尚未加载， rbd 命令会自动加载。</p><p>例如要将rbd池中42team命名空间的<code>42team.dev.yeefire.com.100G.img</code>RBD映像映射到本机：</p><p><code>rbd device map -p rbd --namespace 42team --image 42team.dev.yeefire.com.100G.img</code></p><p>至此挂载RBD映像成功，如果要查看本机已挂载的RBD映像可以执行：</p><p><code>rbd device ls</code></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ceph-映射RBD块设备&quot;&gt;&lt;a href=&quot;#Ceph-映射RBD块设备&quot; class=&quot;headerlink&quot; title=&quot;Ceph 映射RBD块设备&quot;&gt;&lt;/a&gt;Ceph 映射RBD块设备&lt;/h1&gt;&lt;h2 id=&quot;前提准备&quot;&gt;&lt;a href=&quot;#前提准备&quot;</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>2020年9月26日后端部门Python考核</title>
    <link href="https://blog.yeefire.com/2020_09/42team_test_20200926_python.html"/>
    <id>https://blog.yeefire.com/2020_09/42team_test_20200926_python.html</id>
    <published>2020-09-25T16:00:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <script id="hbeData" type="hbeData" data-hmacdigest="37f5cbf2dd8a1bcc395a003443f066d527d758acbb427bcca09bc3780e590327">62125583815e702202e6406178ced42d8b33ab6ae29ff092d542522cb313c770a26dfd00b6d102246e49714a4abee6d9f8a239d9e5af3a7f9943c0b27972f23691dba9b195e2a1518cc81916b957637f4ce59aa8ce3f0c04ecea43665f77458f4f8672b13e75018a7128e4b3373f3eb78b3a09ab3469d27623fdce0da9eafd9afdc8da055076b7c29bd8c2f54dd6e5b2a32609b585a1bc1b84383e2d2d4dff3ee4b55abb1d780f978e3ef3145fd9f9e615aab93b54d1621581a73be7ef86ac8d41632547fb641c541eef6e8c3d93d977871c2c45420b70abcbbda1252840692a1513abe4d3c4a5af8fd31d40dc6869fc9bf15fd0697c257339559d90823e4a81f16a66fec17ea9049f913c5f73d576c418d970bc148bd9de9bdbece8c71aac7a4758aff8a4959a24a4cbadb8411bc0e59f07a4e06549ef184e57d1982bf711dd2f94c77c9bf58e3edb6ab8ffbfee800b6ff7ac550503d2fc0d7453fcc5328a06354d30ae055c1ed96164dea090737691affe9f4a9c99b436265fb9ca2f6d9a523653a7f777f1a6df715d12d2bb1e8a28811c09d059dbcf95772d8d30fa9b659f46a72a9fd528b7abbee32adb5e3b60b9657cc9093c6dbfdd988c9e151ba12a322cc85e256295adc5eefb2b9c0ab924859013ba948cfc7519fb4570696fa3fe23862bca050a57ca1a460fca5e68c31ee3b68a48559eeb7e84c90b16b8fabf3781da59afe71ff305e25e13f31958ed86f021dcc96c0d4d22dc4dc1e288700dfdb7e0fb770ce5f19210a4641e221684aa22f350619b768ce488662b415dc119120923891eb3b99dbbe7fa46d1aec6360470795b3f42c01a8b1acbb14766e227bb37d415adfafd3d0fa47ef7039cf6cde22953de3e23170d1be6a797b365049da331470ca3f453ff36141ec999ddbab354f3276a340cab8e94710301a7c8fecdcb989bf58e8e0f0090ccc8bda8a65834482c3774bbce7b2f1a21c6a8bc72307b005f26b82fd4079d7fd97587636d25bc9df51b851dcfda009b1fb3f9159a95acd491db6ddd50f7105e86ce91506cf2a34ae8553b323334f7c405b4ced34c600707ebb7d90db986c8a7437001fb4be3a575b425549439050c835c65e369f85f205d57114f12628784288bc8a52103e6ff9620534ce5586f4cb87bc53c6e3e445f8266f5b1013229b51096fa59bc2b9b54b8d215d2860e12565a5c64c4d13170537610469b1448b82e02fab9e46f396da9f29f9fbca8e52ed3173cf78feb52a6c9a036903296fa212a7dbd81e07706120a65a920025d95456deb54e8fc54a68f87c06421bfba834df0c2e5cb4e492cd1b88f2157ee42689fa5d2da2fc411705b6333bc6727e1cffc78769bfd42311937b0df268d7404e9573c35afd022cd8fdd2c89b3abb2ca146d0cc53174151e847073abe13942e7c5c4fc26ca0393e2f786800a3f6ae3b2492a451924422a4b725e6b54c7413733857903c691539a9682262a5820c0e0365867fa73d19aba6cbbd36b95e8052c03ed8699a415f5ec54f54295f095cfb915aced64914092575fe1dc30834b3cbc24a25d9aeba2be00acaa241fc89fa344975a1640b553846d349a76d68866beddf9836c5cac03db819dd0ad7965d91676de48095bfd95cb2fc8d2bbe24c49db673e412ca933c172f09c7aac0a9b6ebcf439391cf2195c4072ab51cbd168f2e0ebafe9645397d1ad836e1b066a790ef9263c3064b3b5f58d97b59ef1eae4abf25661f15e49546d7a74103a771eaa3958015f226ac5e574d2315c18db0f45a3271f0fb6373c2cbd651e4edaf0dd495ff87e012bf95ed88d8f0740a8394282e2ebdbee7016771e9b69c41223011254514e82ff331022645e81043360508ff1ceffce06117d45f8833ba9648648f36747d342bd35d939ea079c66d2142d103d077e19331e009b21c7346591733a30550bd209ab80424595b78ac87f1bbda3251d9215621b65ff70fa46d9e228482292ff66eb95a9657e346fd2708308e4c3417561736055a9303edd175a5625e960070abf379162c6e95f1e6ce881602aae4873be44cffde128749f923427ad8196a9dcb4d1b08c5f66d509d4310bcb4d9c152fb4fe23236d17e9a0a92fe951e380ae8c9f15cb527b0fde558e67ae5d30f38da2f78f4201e2b9da796e0b1823e1d835f5f9a9ccece3a7790360e0a806886693c9a01378c977b480bd4b48262f0bf5d93f12cb664f7cff39be02132102f331982fb87fce020a805e89fe7bf92799440aa82c48f994631950c72d4041cadd1aa13247412b79bed39874c7a2d886fc7f7baa01d76fe551f1280562f37b7f43b67f5311f49b5bf4ee5dc6ed85b0a15932e929ac71ebe3361b334ebf7a3f4e6a397346b550909de372361c32b9e9da1e9bdad8ad54b5e1d0102e24b7213228b5a42a3f0390bf608580e41997a9fb4aeabf4eb52fbe1c38b6e6583189e99a1bd5930f998ba4440c72dd29bd5bcb2e5c9e3ade93b3ab3f8bbc25b77bcc99e3ea89694a22d28226e89c509bb44433f1ee8f97dbf0714e3111853cb282103c1e3629eb41c3f7fa5ed0703ba36147cf5bc6bd9ce8049ae33bcbf6a3700851862c3ee9b121251ffc387ca9737fcb4b0bb102935182e5d42e1ea1150d6702a73a40927aeae5277a05f5f0ce93960ff297189effd084939f987e1d6a2a9e6ec9455634a22f2916cd3802aef5512ca19663ece0bcfc6aeca91fb6048cebad41b1ab9f2556094aaf440256fa1a237734a8ea32a2299a7a6b609ceee1831ea3312fb0510b6eb22812eb88bb0a7c2eca06a86827dd7bbccf1d666bcb2a3df6450859c4ffe917c9b202ff6edddb3e4c9c8802d9d393868c366394a6fe19c3bffc9793b0a189f6ae302970c584e9fd5544c72df45264955a73f832bd893907fc20951afa399e7fd45353eae8cc64abfd31377308c6f8497f98e1714f2141742fd1862334ab67290b2cd7fda4a8315e56a724e1af81e2b42c80355cd06eacd5043e2a3f092aead02c116df009a86087f42872d5a4471ead5e5d29e51193df014e9230fe0d7053ce71f17570bca3b98ff518b66a1d0994f451862d46aa03340c431ccd8b25284b9c8b8228541257905338e5e40c4de502690fed85d54891cb362a666cd3575b0b7727b9f7971a2c7ad28f0cb1b8f64be202c7a78be53e592d1aaf3d1a902d76d9835af01317c019adfa4b1bd4e10a37ec592eda67a7755561da254645961ea9f0d1b43ac00cde5a970b549602e99f3b8f8150c6051da3fe117a3d27fdd1edfc956b50a633e43fc1acd993aa6da9a85bd5e01565ca16ea0474b66c552300ec89681fdf4978ef7146e503924c08acdf6e9af95984c55987398514f7f4be70ac2fcd03ffe7b4faceddbe09bb6f97acd0c7f2bf04cd5c589e29cd6f21f96f5e85776470f52fc61bdfb0e38c8d95cb23aef61a26c0c11a327297e77850122499553c7421ded7846a5f4f50f666ad42f23f42f71517a24af04dda3a944d217a414f1d2b96a58f785089cbda244ef8b07fb585f4038a8f3922293625ee0e64b204bba68338b6d1d199d6775c67e7dd95acccbc04361684f55de7f49a460a5175ec8816c4d5e1c00622c072f27612f5a27ce2528234fd21cbcacc0b7f4d1de8ed76807809c0ed8f017276c52548d40d60eabb5d102d4a5bf5cdfd001f0a622fce662103c4278f31c97008f60f9bb9c8323ac799f62e6d1f181fe57a3a19a89134b2ff13d64ca152aef40a796863eeb9d263855866ccd1977d7eb115a0f4f9626b45c1cd726d5d690274df2570ba7b8b9550918bd3bf73aff25b62ddde34da4517008f43ddffbc53c9f6f82d418ad987cf9894f1cac1c5c7a9c7143f313c0f60ed5620ffc67ce5b57e4e0b348dac267c03fb05c82dd7f665f7416d6a9ad0068522d2c98183a4812d70564302bb6cbe7d901684f10cb20a58f5b87751a52a9b109dfd80033834fadbe814da6cfe7c21d9a904c6b69f15bd1839971b489b5b53625aefe713ff99e139f64572e355ba1f69298c168280fe7e7ba5f37d856f1d1ae66cc07d3b6bdc0bf74fa30fde02c62a5db7b88c4692314b320cbb6149c664fd3b04ec4ac446758afb282b66a75ecb9b8f6d6b1e25eb9189589351c3761f2d029478c0bd42f9b1cdb909466aa6807c960287895050845846adb29352e69b83a271ea839057ae1e5e79f72ada59b4daef63dad3ac42558b47015485be0602f81579264a8288094d6e0154fd97ef8ea8f0b8dad8e81058ccdb892679dc661985127457cd31a0c15a01182d3ddca8845080cdf38cbffec6125692db285db28a915f0baf35a3952e371dd4e691ce73722eb0bb04c1984ef11708f01cfb2e16034a789c41781ca1efe0aa6482875191d5636700142c966eca9308aea437a494af1e56e360a0b6d9a563110cf3a13a85789e92a417095d10c2ef822f41cf54ea9d33124ff333b4aa67fffd9fea7c39994761025884659c6448b1b1b9253368bafba3fdabb98391afded50cbb7e1f6f38e08e6781dce1d99f1399b3808a96a225156f2bdb027615399b79d42e9b7f930674dc90ca5333af5a28e57e18ef4f6f620e65aab0aeea8b90e1acb037261039393b0f993323f0e7b3b58b06a6d03ec2513ade773ef24f47103c2e1c90c2077aa837b9d89972c88c196fd4fc4a2cc347a07053cbba838c76879e0060e8954dc4734867a78b1342ee7cba28c7ddbe965183eb2fbde06996122f06675e11b90d23ebef6b13d521418f1587874571fb6838635718d0d5a750453770484d0ece92ac9debc5c26bc396d651ed77ec53d80e7e5294df42486edfc2612915dc9109b74a2d0f9d22bda29064c268f71f6633c579213d8db831a9f38df083a99135a79843ee1936a99cd119f042da2898c5990b396750807d09c0066320a6cd783d9fe97fef324f0d35b4483fabd51b2610fff54553beffe1440c5d2a6f9eb4879656e67b159031185e00e68b2a0bccc41384577290af8c60c82ead061659edce7929159c647b766bb572061015157a24546e6a076ab82b1e50fa14dfbfe8e63930b77c2170b56741878b86b46992c6e3b0a9ac47cf5553a6e04f22f6b34a97d7022af28ec626ce5c89d6f596d75fadc21be0d8086a8be741f9f0834a5998b34340e6054035cba49bd6b27d7fe99691a1470f2fd80610345ccb164f89edbfdf5fed206bd240b87899beb636412d635162a55b973a676606dc6c7aacad7894d72e33d0ccc39cc81cb33e0e0f2f0a2a8c0bb53b37b0702c2a6c1c0711954436061a7ec5e90bdef43e164565ea367b10f19ab4fb926eac3809a431de810a47465c2f3497802f9d109a1107ba282cb328beb1c45489cf2ac790a7285935d4a20947775f6472cabb49314475c7078f783175d1eb04fcf6cc20e6eeb38f681a7bb7ae21b50d4c306af96c719b942033b56518e2d7042bb35dc8aec52dde2980844f26ca699646cf5e7b6bd5fc063d73563556a7cf39b2fb2cdef905fdcf1a3f54d0e743ed58f6892018bebf49f612c89018605bc2594553b6da5ff4d1886dafbe87065fc744cf72cd1162d67385bfc24448bf2b1b04d812f7ec09cf9e8d81dcf2666903b74e3ae0bcb3e30404e895f7492b54b81f96c208ceb86d444b95c978fce52526fd416b13901cc32d43576f35a27d4b2bb7b76c75b0ef4a87870c44f9f0f348b45929c5bf454e2eb00c3d8aaf08180bfc87dc89ade07abea20b07995d4e3257abd8b39cc085456e8bae4b6b882c4670375a74021c8ffd275a1a10fe9a0c5b957358465017a42597f96e85b5ee0737b279918c34cdc2ad9f5d66bb782b625931c42cba2ec31cb3a824673611b3844b4864b547a18550a6aa34ab585f2411cec151e958e71ce0cd8302ce6bab94790e42f6f422c19d9f15e9b61d2de482de86106490b5ad65fef2003bfc2d1cceac74cbf51c2a962a039129a7b7408bb072b19fe634d6f40db1f32888ab9a8b159f36727e7cfffd8b94d17b6fc66e81a8cd9d7edd8949cf55eb277cee267b82d4db60a01d45108d9e8a7c2518b15334d4d8aaff22b4d6e288d51918ac1b6a983608416b397faa240107ec31870b1e863d5cdfdfa74c421a6cdce424a69bab215c1fa6ade0365c96e6ddcbc247cd62d2bf2a783cca3bbb1925e933c754e86e09f37b8e9c6e750e060e2141c689b3564ef6c6e9815b901efb532274ddcc923ec191e4116c8cdda1b0e8c7fb535f6f911f0d763798c0a19cabb8237579dd2202ac13d2802934b9cb08828b1657aee3604b01e96f33614bb012cb3cc5cdd5bf6c246cd3d34fb755cabbbb44dd2bdbdf9e5839d91012acae7c60ea56b77b2bdf1f74e9afc61856cd04ba35838da86d2ccd5693fb3be7c33c5268d78e7431df87f86084d92ffe2d49d4f4ec4a2a22d7b6601b16eec260dae90e3fe85f31819312ccff0b7ef39e9409f1a72bfee7929a790c17db830b0f530ec30a3607d3ea318a5d328da5d55a5ac263986c69816f62d304d760e0ab7e894f937e21313c95d2bf808e6f1e4d074f48a901d3bee5620ccd39cdb3ba371e0ca6082ef98737f24c600456c63236a323d4395cafafe78bcabef1f4595b09919946b2cc7ca246b2c28714f43e76d442259fcea3117d8f087a0222112e5cd33838a7363fe8a00c6a1525a30f1517410667311bb38baad45e2474184a3f70314d4e0fcf8b0ed6f0af67b789d7ead58c4c02eeafd2f8b58db38b333c89b02aae66ccbbe522c7ceea3374c3e4ce7e241685df82eb87188eccc6784ecbbd42376cda72afdc7d7ae6ac390b1c17685cb1e13b012a1d1221fa41aea9e2390a8c122033e461d36c2747fa28b8fb3d116e01fac1a7ddd4aa864937019a8a26bb1e99d7af35d7baa301adea8d21b9adf5600b5eece01b682e2a1e4163fe5c881f355361515f2f0e86c0ee54ae754b6a81c8fe21947e5b372995e496454ac030b8280835ab26986f09847e46428d781723080241f0e7e0c27fcd9956b20ffae4c502e31f6e0860ba24c7080380882425788360db5177c76f4f001633ad6465958590178d2dc635c6a28568368683555e4ee591d407b1a9d568bdb5b5dc5d56964a87813e690ab6968e7b214285047dfef588746bf61d8bd6097abd0bb5adc0e2024bb1666aa3b14f2e493c5421b2f3a205b437fa7dd1ae5b63a3a771f66505b09342aff3a72c9be90a82aad0686d2e519c2c9b902d45ee9096389c686c831d7480c670b1981df0971f155028c0b84393251a013c79198df191ed280cdf1df1ff4e7ab17332c3e073ad7c2b8e70f41774bdfef1d321e041c53625515955c44d1c9096bc32c7f3d7e295191b37a266bdf5edd015c7af5be4a94591ccb8129501dc9bc5cbd11985a5d939ce380cb25922fb3bb1bba0c9936ef3c0f06c4fa439827c194a9cf6fdda2ef789be8b1933bd8f8f9a83241892b5a99d36e917044b7601a4d885081396e9bc2f6a4405a9736f9e794a71c0b5ae41cfc4c52590daa220a6c2ce92fcd7638c035bc899472f079555990fce9213fba597898ec6ea55c2364bb8cb6a11a993cacc6e8ad7bb47e26816c50887b78fcc60a03e7d25f0456756182459fcc0499510fb25ae6339b45f21b274202c1c9653a1526b2fa5e89a52c5c70e449a158e98a5448c1d7390cf0f50ca63687483219a0604d6f3619ae237f08aac80dc54f1d885d3375d8d5a801718d93734fac42312cbf42d0f7da3b60a10060f7f91ceb1d82b2905f9cf1ba572941a0f5174d4850535025bdc10642569d70650d57875d9ef3cba7c606bc8ec15762f62eea88297a3d76bc799c4488171c69bac3ec8df6d44edb8c744267f4036b6c938f703be6dda3e7f5ddb026d8081de3434c32ba585dfd69dec9a58b567daa1524e3e6993b07fe621c199b04bda7b79730b7353d5dc41c8180a74e26d0c94d323344785c6ed206b9069ab8cdc358b3d5bf7472a98b74bd3148eac3d72b09e2a24b30718087749a0eb3a21a31c050997e5171492a9e2b5b887a75061867ffcd2581a988e16cfb239714dd177517d5fd86bb519162478872be10c1e822100f345522969b6a90fa8cec0fbe258aefd91d8b87a96aa58ffcaee22b7b0ac65bec58828e6ea5ae2d00596e5f8a6552297df6a768c7d0cae99da724ef4d2f083deb0200d8fda4a4ac07c05b90215a55605f06e6f6c52dcd38576e9ec27804bf582bc9eb1d7689784a4854f707039d3032cf08ecd66cd590c66551a5053ca99678b1b42a92eed859e1a4001fa72ed50e18bf7979adf84d2c258417dc68260131de725d19777c55fde1223af0886882d63aec0a361538bc06a0be0effaec9da4908e11ce5a18801397b60eb94f085a60cafbb3ecd9925be39ad01e1a1f3a992e1ab3e63413c80d41e19091b3ae6c1170dbc8f6ccc32987e2ceb5dbdb6fb64d7f302735a67d59a7ecd49a6d462a5d7ce9d65f439c4719e13b9b3d73d5887d8396363c186b1ae497cb156800b077eb2d16e7e278205054a3f2f2ffd8ad507821b60ae797f74949d4ad7578cd3a524600f8477dbb44577ac4b6c866f72d56992db7c0700a0fa2fa3b83611ddcf32acb37c235903f1aaafe0680cc1934c4d16dd385532c9352b9c6307df80c7272685720613c77c4fc02def39f8aea5bb9364c2cc7c35aaf37b1fea2dde6fdacc1d71a4847d64035699dc52162d91483bd90ebeb45f2f0ab8f5fb4468833b72469847c1735fe93ddbc242fbbbb51dc6bbf2ddbe6603188344c2d56c6f67962483246b5dafd1a0fe27099861e0e3b4246fb460aa635be11518037068ebc584bcedc2494daf2cd2357769111552bee9a9163c1446254c4da059883b60adfd1eecbb7308293ef0ecc0022b0a074ddac74c57fa1360444a98668ed82ed4db395c3e16b6a7d5343b37768e0a4ee61cc572fa9f13db64980fe230518565af5f5ba7cbeadd85e88f50adacff95a0e40adae0d536ce6723fecbc93a22d2c675f95f98d3ab6b8f0ec99009d13660eb49fefce4270caf64a181b79917311d08a593dd9b5ea7bb35d82c0eead4889ad44694847e8a50cd1d9ee9133c4eff620517062655ca6f5e335f38a232770770a29164479bcf16aca0a35ac88eaaeab6a599426868ffc7cf94f9d0b2d4f7e3a5559da27d63582510cdba0e526db725dabb6b51059f8ad5d9e5c43ca7a42f0daa672a57bb0182b7a341cbccbe2c00308f1d5bb549bd2551d5b8ac4ae8f82209cbfc8ed96334c9a0b1e956cdb7df2ce9a9e6b354a33e1fce12f43824e6fd3449eefd38cf99cc5de20bff6994f3d71f812ca50cdf6d5228896abc9e72e785c192ce46c05c6ba2eb4e56cf1e85fb96747ddd5678f7d5113feca70f122735c2367f732ff3fa61c365f5bb77b19cb9c27290d43cdfdcd908b98701e53a0793fa59a1ed80a77e2a9a28df7759dd014c701f9fb2c988911afe1e6637d88b2d53db0a4f23564b63b8c8f53ad9375ec74d054550343a02f0d88c06a2a0a04ea6a21c97eb077fd3b488759d4ce7a3aa1dc5d21241cd0d291d8f67ee520d50ea0d5d69421717f6f015659ff5fdeb2ddcb5a7a312e4f2016fcf0a7fa875750bfa5f62943583132fe31f4145e423d3cb97b7a16ec9b03e5519f570db21288907e20a250c5d208f0fae7a8890e1c1d7391e131be46c1df0b4f0badd0a7b344649c1d571816b40126b7b7fec5e9aa0f9f05731870a6ff0d19c1da388f30e808835e3c4b03c3b74392d71287d5dee8a07cc2f638a77efcb07d913bf25a5dd0701043244220a6e44e14efc7660ca4bc8ab03b82c91ef5c6e24c5a1dcde5680f622cf8e0eb190be8d3c22e293f36c2c14534e2acaab0e2db2d9f550df8ea5e8cd23582e7cd05adbeed15c6009a6ff9fed122f4ea8047373cf778683657f82c426c26e42175a1cfb58f8a994605e5b1e32f8c7e47d9c5c44b4a0d6cd1a1113f3dfca2ac3cd13b9d96d19d82bd21fffc89409e0997475332163052888da6abab395fbdd055647f6cb3f3f6b697a8373a8fd120acbd035c5030f184f039625c140e81e035ce456cfd8f754a7b3b3dd4efe7d32dcfc4e42b2cdee1c59b78d49037345d605943c9bdc1ecd9837ff80a3b4cb677977d78a166ec687e7db0d91ccef2fc38b2e3ea7420e0f1f10d720e1ed140f15948fc68bcee8704a2aa8a4ed2b3ccad4a6b1da9c28e4aea2477556438f0d9a3ea5dcdda7ea95dfec25959c49baf40b32f61547875df2db18df5f62160f92f09ea91212b65ed986a5ad21408d5ca10369844535d37a2764835e0948ead4592dde6db69369465c91f32fa49c1eb932182bc57a2bfb542c6dc14d754a538b35f47bc12a8091e24eedae717a32e3c3adf658aff3c2c016ba12534557a1c5f30d6baac5da3dd29c5c34cb3401f861df9a8c2a062e3f06153507618d2291b289b36304aae7cbaf335951761d0199445710ba3dc0a45bd793370662b137fb359e2a2b8e1ebc79e7d410bfcc8a702a1fb5624ddddc465aa9874c295a84eb5a3eff53515c8d88a0bd4d77829c5169cea099f8abed372d80c019b5253978b21290fa66218f6e16fde3e71e15db11272dc976b0223255b0476192d9cbaddd6d18017393cb085629d8f9d18802955b654284c9ff2554d5607374afa4e49648e45d95b0f46df45a27b4b4a5dc65079c12d087797c958a78a85e28f52f47c14770044eaec9c377bef2c8cdf7275fc677829fa4aba5c635fbcc1ca10d4a1758167dc9533aed16f081f2d5b515329444dfd174e8a3b93468daca0509001adbe61153f33bac13f6ac1795d14e27f32eb562ced56f5195f8fc79c510d0043a38f03d05b043bdf9b6f2b4f9dd9cb0fafd1f03ff34b142681fd6df733c635d6a852b540a0579c6288f090adf41aa228721df32415a5cf6a51206ba3334330a555b4e866d91a3dec50914d4eedb70028835e3e11ffd15638a6ccab27c374c46f4f28a94e29bbbb6984bf64ccbb7e3c3194899f6f7dc4b1be285d2a464c96df3969aca5e5f5a430de72516b5a1aaf2b5e96a8c86a629b94ee8c344781781433460777b196a9d2047e73b85b7a29614f9abe5a3729db95648da6eaa050e44c79ae5249c6b8b50753901b3216b35a08a593c1e5bbe5f9264d2ce66c1b9d4099a5f19ef5f1bfed297838a5e69784b727940f4f21f57c3fbb552d7904ce0c8684a25a01c99174635e2ea61f19ea319f8357651b90dfe408fe9d2e749a0ed52dd229124a551ebf612a35c08cf25662917f59486a794707f36b9d23cf93ebcba7489a1855688970801438cd898f0e96e6736eb046ded9fe9a3e40766ec50c66dc7a78a1ceb3c29344fa3d18166d0868c574042775c7a305b104de37e4562285ec0c8a3e2bf508d0b625a23b852441c0fcbffd91feda0f378e203b0c299969d418a3261376bd6f3971fb387f78d8a1de43a80388a42a68a4869ffaa425f74ea8a8cc983d08b218b405be73827a49b5ddf5eef8527a29db13e65b6b25f7e38afe215e24a2773bf1a64b1fe0ee488988f0dc767fdb291532adbefcf676ecc9227d17ed11b173ed7a9b1f145fd5551f0a960727d479c70b5c4e4a7ced5be18d7c474b014496d888bc3af035a8796f6c0036dbada5e2275a1ebdec3088ed32c01d165c4525c65868e3858e9c9de94b3efa0de6f1adfff7f1c84e6b220f9d34085987aac7300acc08edc2980c11330ee0be9ac9cbbe47e8ad0129cce12501c5829f84ffcc86748f89f8d28cd3d1525ba61a84fd8afbe5346336f983d2263624cb60901a4ad226d16ab03a67566e4cc36ab7c9a4cce065dc06f2e896d16994a8139b88ed8392091f18221981954c12d9a72a366e769dc81ee67b9f73854602e53226c0ba10068e6a64a32fa1802be82a160901033c0ef202da35839202955f10752bfb16e5adf4846ea151683d844a1b9c4a2279ed8189b77b3b312305708413190c7cfa76183a8f994b98136aa7e74ef6fb1feb109657ed3e37be44546a8086785660d2399eb4c713d6e5d59b247038a4dd508ed3c9c2fb211298e2de4eac32f87fe657204b458994891ced4bca8c7f976ac4d991d46a8e7a2bcc707b005cfdcc4150e1e4d7b29b523f98756ca676e236a974726c73dde9e53b108fa315c71913803100e1aa08bccf45a6d1834ad43cd24c637be1b9ff58bf2867d4ce5ec8eb9be338a009381aea0471a371938ea3708ee4d2571c6621e0bfe963e0cdc22f02d58893dff3bb5263432b0f288d0b0d9713a83fdc4e3ca5933eae402b593caec445992110ce1d5eb2c5409986f17b3b6a3e5e4b5e878cf4edc78f9a67cb4d830586c8505ec26f1674aa50509c255e32af0bf576c134580272b5ececdad5dae9be24f5832f74afe070fbb5f9805c98d9f77f56cf6480675d474ffc60ace0719bd7f6e89ef9c7f46eed8bd178b3bcfd95ac239f6d27f26d2e883d3678329b766152d59352928a18d5466b431f3fb4b2c50420c4f8a4f8f358ed22bd9ccd1a60cbb46a156bc181449563d635934b2066c74ad700017815ad349a6c1b04977bcd1bd2eee88ac21ed65474d05f0ec4fb6d527746b259d025dcd96a585d0b1d0cf2d73328ac25e6b4b6d4ee1eeac9b2a7e9b525463afa66eafe0541a2838eab675b9785800a1c9903fd2ebde9b8200a2e5a9287c8652152326a331fb4e8a70236be65ef63a30c25bf19bccbebd8d2c581cc8fc3b5db731e67e9a0bdece88717a0e46dace9942dfa16731e775cbffd1339bf325c64c9ba2b3aecbe0e6ce017dd48bdbd977ecd1e45e6110a336b59e92aa808d4a7614a6f05a6e92b9559c5a1454374521adc59c25d64dd14ca735494e7562b129d3ded4fcf2ca449a805ec9b8eda9fee05010b3cb7070cc28fa3deae87bc78515f8851fed77805dfef3358405cdbb43d0a1d164503bd24230c06a2dda4c03dbff5f55e0f49a504032e205215a71daed0d667880c7014785eeecb8c9136c9d03153f955b12e0d8e74e6eadde6ef6fe08244140f4469720b7cd149f1ea537758058f1bfedd75aa1b2d93797b4dcbbb6263b41fb51da6bb6f1d8a5648c4849034d9188a9593f3721b5ee49a5b1d03b3e6695e8cac15146f0a0fd6a7ee70ab7f1ac9a45873c5fd44673ab8b0fbb802958fbf5f5c45b5c86357f3fbbbc83abbac02cf29f6bfadf39d01205ba047bd175a7d5f6c56ff098007d4b0d18ec97a3d363be81c05622c803733facc04c861f38fd5b5cc2ed6cfe8400f8fb228bc6715b3bb27dce2623ffaeeed462e243dabcc501a9623752b5086299462911e6c0b6c94707739bcd83a3909517be09fe95da7e68b2a82f351378d668fbfa60f85f7abcf45c57db1740bfae02cf39689b387594e73fe908c1dc8b60045207b9bd8d151acbf996bba0f56494e3aa94482e9dfcca8fe72ad5c3454cd2c6160a87617d4fe7ce062551c614927de259c818c8745125f6320b7bf9a3506bc6afa6c35f8c7ef1278bf1cad7e6cc1fbb564c126c194648d0d3ae9a5c02b58e9502b49934752a4c2aa36e27343e344819c4dd6bfc866dd56f4b9a04aea5e04d31640dc73a52a83ee4d97e6ce88904514cf00086039b72942213546bf14117b3074c25a08f80e8264dc17a5ef72336fc46d87057779e55732b806d1a4c6c0b3d2d23b31e5c1fbb805efb0868a39a0932da9cf511600b692cfbf6a2c89c81ca9665555efad30b9827bdb2d9cf11036cefd2b5ea46d8dba7940934eb482046bf737035597be1ac933d02a3ed464fbfcf2204ec9702d1698f3466d314058e8ab29d11b6c01c9e070839721fcb0376a6b3af0e3ff1311a9ca118f5389697fb44c63facd6800ef10cf929098e60b2cd8e12a06093917d38e936970f97a5b9e399795ab644d0f6e85b2389efce3695b10dade293285057badbc7330ed95507a1fec6eb71336820e3a2caae1e0596599354d69d7cc4c2c583a64ccd221d079e806f58feee4be451ce510c2713a67a253f72f842a8c212db2153b4f487d32cab28463b823454a5f76b470efe3cf5b2ce0b8219b084e0bcd6a200464658bb749450650cd630f31951334d1a13eafac402dad680d30630a190e1de2c6610b0d0242eac99087ba2c20984c41b7353a59d56f40b4cb242304671febdfb3fd170f06fdab1710f53a8e129a76b062907aee3a18dbe76ee2fd095bb9478fe9783fa8cd2b3d372a0b627c33b089f5f4c0dd057863797c43dcf74795d24cfe40a6145b8946112ab04956be4ad6946b5ff55f11ba839103bf7abd71634220e9f10db32ecfd2843ecbbcb6c51bccf465db24e5f028bb9d93f8c673ee5509e9bfe41e3779d0f485b6f4c694f2fffb884fab3306f5eaf27fe41018883ae375c2843a48108c6da02d23a0e4ee2478582088729dd8d2aa6eafb873bd3f7ce63a0aee5dff6dc2d3f0c97d6ef45f9a695804982a0582af821c43b2b3a46231f165b2189adfdf7ba868254599dfad12106bd1827f3a84d76e0e5ac534f5b16d1f9e0a05d62d2de73cf8f88a15d2ad02184e3999ed5aa612e273d0673164c634563f677b3b7d813caf0cab8252dcfe4416dd070abc299fe6e48307cf9cc6209c360714687c2fb7f4e5232e5814ff36c6a831c9c33b262a81602a460fe19d0b3c22ac2eb2cf80085037213a5875b2bf4865967a069059830bc0f2d3831a51a531bf6f8d22e751c9e5b062956ac745cd5c818deef374f117d031ec118b9c634103631277e04e69945a56a913d5a7f7466935e935b4d439cb16483d47d8b2d4cb7f4f069beff6d4e642d6eb6a7ffe333a43fa578f9e40ff55c78314089aa859fa717e30588fb03c05131495d0d011a06654c846a768ebc3d9cc25febe5b1cb6e9085351a975bb47897d64689ee835bfe90a9f3abac96151cb8d553fc80a9750b7faba39ca0983dd1aef542b3d0b08e2845576a0930835120c386512cf8064a7d8e5eed30412af56ac3cd9f39af49d9e8c6dbb614028597b719f28cb8f6a549bb668296e626126accfa6e46a28fba93dd4c4680353332a04f3bb6bd1f9b1e05ee7437185afcf1c2e9a27b344ef6be3ffcd40394f454ccf973706433078ee6a78558100e5f515e8d746fcd928ff25146525a6e704230ee60613d73f7e0c156fee456e2c1db6de7b58f96215db486da0e566ebefb8d4a32574405684eea96e1c2c6836c9b5d56578435654f1c7d3ecf28a35d5e6e5413d6c183aa12e794e13edf717748e5d7efd65077ec9ee769025d0c61018b57214e3f3d937dc639286066920c1a568d7c5d803096bf3936b199ff6d8ce3f8d653c71671050e6c8c1348e1d06f313920f33e803e56b8823a34302e244db00c2ece59ea728e0d5d89936b8674a570f8622cbaf5bdfba3ee2713085f168c964f08f9f3b9eb406fab031bdf11d59d60c8f1462ed84feb9c3290620b50ac6eb0ffd2ca16d3cf91b82f2257f537dd23f4083c1fa36c914ff174fe334fa7653cad72edc3a1917653483ac8bed2633f8e91d3602c9250b1d2a0031d5c20efb52f9052f726c5113dcb8ac51d3dc1f89e446540a28c4b86e4cebd10ee152a0558569552f3ae7cfac3d05cd7495c07acea0bfdb0c5c9df778b9eac5e0e536421a03070328e8a82d0cc5a345b35a35a05c6988be03103b1185cdea35ba0eeef90d7786fec130db9d0c16d0bc076f5b33ec2ff133de9353d0ee59a5f8ea9919b5d28a8e20f12e14c6cee39b16bba8b758e51f87aacf40f13b4f5546e6cc5b9b8f08a37522545677879116dc1061d6966197ec104de83f5b5e1ba8e134926147f9ba44af6fce52df0a9ab6750a30d8327c354dd5f50d3abaad3fd78d0d176e3f2b49c5e2af27c38239294075f876e6d06f60aff463cf8047730f1d07065eb9ccf04f858f04a626adfc17a19d0a47c5322c621b8666073fbaac94070dd6ad3301eb539866a79618e92c2591fa06a497095d53994082758895fde4a4e767b907610d52a01baaa18009e5ceb5bd663c3a23a755f3d1a73bbf7b3fe7cfb4d5874c0f2fb8c85ed7bb1f663d2826cf5e246c6bd4b69a8db2ab197f82141f177d867cc27201fa2a74bd8fe8ad0884d3194176a682000ccb6cb22e05a01b00ce9fcf98ae3879fa38d6836d363caaf6c4ce5e4126d0591e06841faa1ad6dddff68f3cb04440aa19db6d633e09283c7842abda508a5c88caa8c71796eead484958ff992951f9ec78ee5798842de93ff75b1bee26341481dc7435b46806ca8f44fefd2e41ed3f71d80be8c2d32bd252c70cbddc76a52047776e874af5ec2d6e0831316d4024e424a24214d294d44753c3dbf98ce43f202e3a58939d2c985f927410b21812a08e2b0a702a8536c52e46d88c7a96bc7def873b0107fc8de51a93b50b8c727992c30003dbf9a03d8e4f87a96cb3e0353538896730eb0b7529381c4cbfece13e7d4f8123139cd382db8a4975698f74d2d72253d3d230c6c2ffd9590e2e98028b08562c95282884545787277054922c061929fd240689bf4d706bf0978e19588574a3e92b21988abe10fd2af8bb9394601a781fa6a38b55a6f4a91a90d85b56e946ddd0449372aa8207ba02bd129ff36f686d1c1c9ee74d635c552038fd48be4ec3e8504ae5a1e80761e54dd34bbd2d68c8647660d2df995a2ba37df3fc09ac5587d27d2fcc87c81b1a246ae7fa059738c039acb136fa6b30db031263cb0f44dc8ab3ac1de59193abdf5e1bc88c290ac3e29c6affc5169693e77e4945b1c02bd05224f230a286c9891fcfab2879f8ffa8ac0f6207f4e1b476fd7629210eb6e671b28eeeb026d63a21e4c4a123709c1f85f9be0f74ea26b5bb2784198e4d2e332dfe3bbf2df70f00c5d9f720a0b4259a3331dd6e9789255647cee462aecaecd49fd80182fc7e5d0503c1fd6c2eece60a35d1af6190c08a56cba4a603116e99fec459a1a7fe625dd1c9ebd88ad7499d65c07fd2e2570c924f7db8f63edf993026d220415e0c6e3eec75a068d3383871c6d9da391be9aa49459f4229f21e4190a561362002fd824a3122699fc3726d2c4cf1c77b01ea8f8d6f3cb80bb1ec8085c45c05976d1fdef4d1f773034e343c0e9274e1c2dde0960f69cfbe444c703f6eedcb0187fc934bfb979a1c07aedadd97b486b68017e0c418e738ae189757be059da38bd580302ca0b61625793da50c9816ffe2a9044521de56bad87eb739d0cbc7ada6471de873aed1af3a604af7079621c2ab9796a76715eb42d8d601f819c42f97a7cdce5906c2471c7708ce27be032d48f7e7bfd2d4cf6c2af36d57b1b7df30fc9188f58c1e64cdf98cd1f23e7e5d7eca5faf81fc0e80418746a0b7119c13469753a07dc19ae8a6c71a19379f6e58631014491322c467490141485089d3756749fcacd5c14d067d04c818f66fa202309bbe82fc2644ee328cf0c1e721b6962f088e39f13ec2f3b9a6c0f475fda1177f4e3dfb9ae12f9d967cf1d4201b20dac9999c68802e4b7cfca4067f85128891d3a1ed42b659a3b1e53f61d2abaf58c43fc220ecf6105d71af5c680caf9727b318ee710f234579d841130b18dfa3dd7e30d69fd4bf41906d3d14f5c7dc14e8de359ac0c1a0</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-default">      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-default">42Team内部考核试题访问需要密码，请输入密码。</span>      </label>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">考核试题，需要密码访问。</summary>
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>2020年9月26日前端部门Vue考核</title>
    <link href="https://blog.yeefire.com/2020_09/42team_test_20200926_vue.html"/>
    <id>https://blog.yeefire.com/2020_09/42team_test_20200926_vue.html</id>
    <published>2020-09-25T16:00:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <script id="hbeData" type="hbeData" data-hmacdigest="6597ff40b01287dcc19f59b3721393418577e8394297684512230b85bef92837">bd6554463cebacfa8c1f4ea2c9224e52a1e359a74b0b8b339428c73c50ccb6f1def67fa4fe08eb9093f63cfc5aa58399c30876a2ff6bb922698c17072c95d6032962f645a16b92efd730f8eec21d8993bdf672f6707e74311fcd81ed6aee53f72407c79ef4bf46dccd33baae4a04d874251e53280ddd2efee1a8f5e450b8d56f2894bf957cc3ff2564bd0f3f8c97921fa9769a0566f71bac9949b96c94b809cd8c97a7e551a77395303223cbf48f16410d05ad593576e14b385c9775619057a70130e0d25ddcfb2a1c5db0a90a4decb7b449eec87a9e256fe2ed8aef74bdc75169d11667081c5d8360f3b0d5aa96db821c5d4eb1387c400fb3304385d0d2cc649e912f68522923e6db8f4f980fdad170d0643840899133866c2c862dc6804aebf375d007ad06815ce803a8a55c7c97446fbf040a3508ee19d11bc6533bfad7c25bc9416a88263b44eb85697c4b6f78ce025547aa93536667e3c8cd58aea4b545c79eb15b60239cd7e5739a3fd22dc8195ce3c8e85bdfeae9e97a054f250bf9ea2ac235509205620c3ba5bd5092387b5f7d8a71e831851d88a7c3f0799286fc7ad15062001aa8c49aad020fa6e73fbc9774d830aa1cb77722394963d4b8fcc3370c4eaed4d31f6c394e7baaa1d1c6bece0e98d62ee75f666adc1321c79aff6b9dcba27f7a9f85e79ae75586c286f0b8b79e2d81601c54273e19c2281dbacd6fd94f289c75e9c29e22cfed306e13c9998087e4146327d4e0e687bd12488009410e95033ffab68384c1062c0fd9216639e51daa74e588ce8da3db41975a3a2a27d4dd3f5f8c8dc2b3d3d8944d815e2d614d0a9015e80a8a0e991006e42783fdd71033c75c1b91bbe9028b688dc3211b9f2d4acd837780ee482286cecfdbedadeb82971212e7d04df3b19c6d4f1b8a10c894ee6091a991cc914a369fe804270c456d2d533f84cf55215803aa72e0f480589130fc8b7104963a1f2b3327f1924ef0a0d5fffe84a97991ca0f154fb0b130c05089e83f5304e66dbf7fabf03bc4097290abd874fdbe0f0a5af4db27e6ea2738e83ae214d8d14199578cbeace5f48b5f71bb6cd704b2cd722b054e8f8df3324049563f0583ea649b297eea04325a7d93b0a205f99a23ee26b3244038a21459975f5187865a6dc9a569be8e042261c263b40091a02b439334747412e14b189115915a30699c152e2adf4d80ab2f86b2d9f382acbccd389cf028d5b1ba2406a65313d81eeb37205cab24976dbe701b3c410fc211d9a160999724d2fc098f9c3eb1eea4d407020d6ce1cb39c0c98ff612fd6d72bcbf7962c32cb5e344532591ff89ae11698ea3b8a54739f07d8d7675046e5d44bc1c567ac211053cf1f6b7c02718be2763bae45afc9c74e5a060312f4a85d1cde17842ea05d970917dd66f415e88692b65fe09f72d9ef7048becacda09ccc1789b58af411cbb47359a16b2dc6463492eddb6aa3cd1f2a82988dfb39309fd72069d488d8afa83700b2723a6060766880a20d842b67884fae2bc975e1a8ac97d162f85b938224880a059b376dba10ff9c030cc892a84d3367841f30bdb820552ce90cad3b75fe378ba0631c65430a6b9c3d2068c9ae1eb5594464746e329b0f5dff31e8cbdf0d7f1258bed7e0ff96edd9db10a27e5e36fc8f49cf876dede91799b317bf9cebe05eb3c1f263c2b218de80e719c22f5ec1308d2eb5b3fef02dca7d4abea2a39c5fe17de5edc7052fa3315cfcc15325c4b25d91b7a8b3a7a943b08d931e3ece7a325da6be941fdafb0c4c6c83f7e0232c937c634965b0686c0b0026395aca6a0eba7118bf7d532e96ad0e99bff4b47f0cacec980051e0d2f8de567f1941788f0d2bfb02f28f0be4a1a868ed8c83df3ecb23acfb2c787df9400c496702758214481d7b850712cd0608682af4568ba6de63f56b0a9afe7dfba639dda4e91fdadf7ec4985c4f84f7102212b86e12e3f683c36dce8a70607c2855af6b7fbd2f909c2066d4b217a51b8a43c2fae16ef7e5b46e52df7c340581372bbf092744664b5fdba3ed193706b2ef15b7f75d552a4342a88b79e357109ac2066d9aa8f45d1b0c1111119adf36b144eb542014c673b0c8b4d7d2e4d008db603501b99f9f999b4ad6f8b4a776520b96bef8961cd620028d8bc83c1107c09210c1a7a658c8c107116f08eebc6b63cb6cd5760cc1732ffa484eb728191490f74eff6205ba7e66972e249dc2b8e7f0d44c80780ed5683f71fa330a98cbe301207ed547d6e3a6d5ddca199720685db98f11b44d58b2e1962f685e2181edd0f664f1cbbc633eeccf39f3040b34c440f9ada41ab654bae0d98087b3d77b69b888ea1a4865002d841ec5bc16274e0c94d0e09e9b48166a62ab10c208427e4753948e8b5032c41fd54a85e698c810b56f7e84c3a8fe370deb4b5e9f12ae1dc9d85c9ff1814e08c4db5424f96255a5df0014031493176d040d5c264c2453cdbf30af24a78f85d9c602f2efa156f915376d7c5fc4f62d86630f10e81a1aa7d3e616cf7687f4b0826d31c5b3936af24eff72a9f27cfb05c95a1097eaa46222ff831a7fbf5e7054303bc631592d22601f37fa1bbbe567add5a919fcbf9c30d8d4017595a3d9c6ac13daa586a377320f203df274874cee01827eb4e3ce66f8f5e1624adfe80e82c15980d92dd9e768be8506d95661f1db37d9f797995e1bb94db3d1184734c23c629e50eb73df6cd41f4adf603fac7b5b157aabcb5f0f6de53988386707d020d68d6648aa94dc854c07e14a587dacedc0a2f936237a67df011a536b8462fc13f0a94c85adc0079309d323093538dc52adc7c6643acab5aecc5f8a88e387c40d8bb0f4bf00be910aa1f95056e95cf9e2aa5705dcb0ccb73c4411f0b89be9fc35000b31f310cc158ce6b60a57a0090607f653a878a646fdc7cf7b75f63f5a38f472dcd4ed6a960e040c865705c17f6734b320fce621923dcbc1d231e1a89c0a1ee3fe8f3ec339c9ef15f93358906eee3fe95435fc239e7a392da93181e3784f4ce63832afb824fdb36fd30c8cfab512e0f272b7e6b43bba67a31257858445e57636e0efce94deffca8001b913895656b31fdea7d74c6da32f501311c0db6502b8650772bfab83cae75ce5a8d795079be832fbb85c9d5131070bb5ffc7439b81875ada61c1695269943fa551691a8c28bdb593a9e0edc99197ecd0417d0b8d81117cc3158131b0a3e0fc301aa17837c5373acc12b1434a5a42e93bd3c84ee078d557fd50b11a3c67b1c5308a1b8216588bd1d5e0c7c94a50e2681e654cae70c825e0acbb46ad95f7765b7e833a013e4d535a142d02cca633957f21f2e1814961956fa636bd90b18e77fbf1767d959f6c21166a097b28b2ce06b132bfd325527461fc8a95378784b93d84632f4d4c0ef6b4536526bc13c06ec29decdabcbe9e4ccf56eb2d561796f5b25f9447b29d94efabc5b93714002b75189a3703b30a2e7278ed6f4e048d2babf0e31ae6fc0239936b23b67dc50cd2c14cf040dd1ce522cd4f21ffa3ba331971c180867ab146c2afeaf1b422801c052a0a6d9f2fe7e6c3c0dded8d6e902f433b10bab9319a1a6f36d52185f2db1d647da96c5bfd224c82eefeff10245ca7287a9a8732c384546c353b8801969a61260d3b21fd5fa71b91d08cbad55bcb7f79ca3f823e49d2c32ff66977e4ee31f0b26eecbd8cb9299af96fb12c56a35b4317ae90c17f69ef0f05526f479ce76295579290a8f4f74359cca6f9d615b9b55dd91fb2862552d735d6542791babc8e16da7f20f18afab2b466a02393da7798181a79cf16067b8d4b2e4561a112fd5c368d6d3cf22cc6464c280f1b68c69834ba6189291bb189aa66aab244b7f1579f106d0c2ffa3d81ee39d82700d9f29faa904cf73e5e89663673784ef5d1f70bbe133545b9f31ef31b6cf2d656f472517f763bd2f908c9bbc9c1009e69c9b5f6a591c2420bc4be40047f0afc5c9fcddd9214583dcce24216f1c8a7d24507062084d6c8b03e3113e1f82fdebc84781a1c1278325c5d9f2ecffad5c964793ac714d5e4c8cb4436c2485c737f981a349cfa4fcbf2e3f258e7fae69ec140cc6c8233e20160a2761927faf4a3ab27a08a0d55aaf3478ffce39d17de965180c8078cefaf16233609f3e68c8755c3eb3643e94ead66af577e16a3776b619cd2437c4c07846043d587620c4d04f91ec8cc990b5286197c059faa7a44ba1975d1fbc5b957982120c404fc3775f4b343282bb69490d61390238f8d8deea17aef0232d3ff06f63eea088d663fed65f491dac054775549ad456fb42ee5516cf4bdf946d5f47bff068d6658fe53efedeaa56afe8b20a0caf2ae5fabac925ce3bfedec529e095f29688a314e95f4ac98fd29cc60e925c33cd5dbef80d6d3f6bc378d9ff2cafbb6c5cf012154fda2614813233c42e221ebdeec14cda24518cef6709134603788329e9b69c2bd51af312cb04203a0043fd47b525618ed2173a3b1fe8be29fe5f76764bceb484bc77a27c1277288619675908cfc36b7b357b420de30da76d0dd6d527383f5727cfd39d5aa738b767dd3bc17827ca405e2b5a840794aee6c750f3d7386f08a195d912a38ac636e4b8f79c67567bcb1341eafc880f6a1ea33d06822dfea4bee24d0807b56c64a7b0caad0ac5fa473edad27bd909414f1967d7ea511111c4156734439364931c30a969865ac1c825fede465b6f533870d2d4b345c69e90151834220b556d81af025b28d666ad4504a1bede146b19332da6f418f30cd952ddef92bc76e3704c6d73de0f808dbab97c1ab34d98261d5f410c0a3a8da54989a1168455ea9ff2b6d65f3dcef83145da0e64d0121dfb23547768b71ac2fe7b36daac9e1492ac251abb67d180e94f29194e6bbeff403d538c82d42a6873729d95d7ea8f64143ef2d846f64a968d3cd9450ca07e4f804c3293132b44c8ef86f1ccc3cb1c32226fa06ea5c5af093e6a0d7a44d111aad9dfb442fe9beba1286a380bb05ee1cfb805cb42ad2c01a3a284a4e76f930f2091d57053819a8380e3ac165d08e66d81afea044d8d49de24c18c361fcde46f9ddc3cdbc497e78367ceb03fd411320b737b6bb1bbea2c04b86b56a8a7a252edcda03efdb62cf0793579568b26a1438e50047b315953001dd979d8d0d8da161adf2777eac4718fdf64cd49ace94cf529782d22d6a1d75f8174aa3eac7bada678275c08621453f4c35ab1f8f6642291d363d33e04d9d2bea758296e1d05f34bb1880865a8eaadc4bf678ae571b8d26d9988483544459510d86cad45995849413188745f8f85b7c81d7ee419b99cdc95f1d7bbd3bcf06f6fce13e618f5e8482427b44434c59d75a6e4ee5b723d0722a25d643fd7f42740a06375f1bb1747d6d85c65163993bab4f82647b4324e664399c6c1df1f511db9b0c61255b759032d07c0d3878da42f82a3738674c9b4a4547c6d9e4664e9fd6fb303104760ad496c9922ca05c287822d9b89ba709fb6ed4a53086bd30691b3d64b384a829133ac4bca68dadf7ba69d99087a9384b9f8755380a806df336e1b293defcb44970d0894a28fc4ac8a6b5b38609d94a805b704b375d589204126e3bc95a9a40bd5b942229a504e224f9aace791ccf2372dfcb1e7beb97baa4570067303a5b0a9ee7c9ef6d588e8d11b2a54b8505f6abc91ff4c2c4211c207d8852942cf6a9d659c78e990533140b11d902c81f23cb2f12172116d1f50b9e629e3e1b25943b5877b2d6ee761141ad95c0f7dadc31d03e9dcade155ed9991439450c7f4d0463254a5a5eb179e0d8b8e40651b51e4b8f61d1b16d483ff70134e86a9a7934fb609393de872ed6e97c33dafb04e4eac1394aafaed701762a06178d03112e399e0cedf2b85edacf7082caa9a4e1f9d9a8a406541acc4be060545b3b7411fdce779cea9f0f79f24449f838479cc54a3fb35fa4227a228650c351d6e6a25ee14ac12117e862827c554bc73391ddf90781b41c653f23f95961d345d2055a20fcdeb045cc9c16f6c61311066b488dea1bfb3cb9179ba211de45a170f266b741f10a8b4fd551acacf9c571457a39e6adaabb388ff05d68e6e54118fd7d882c9c2c30e8fd2f8de06de14bfac32bd5156bfc67117e1ab0a19d75eb220696eba67f8d06b791c04be48248ceab932aea9b61c35206ad89cc7fdc3a843b38f8a0e6e2f492056860207524ed07032b744b3fb67feb1518ea396b69fa1f6c95fca664951773f9234828f594ae27cf33ebe82814d2597f7c91b7a93cc5a505be8f61d0c7bafb045fd5a2685c80970127be399751d1166efde139675ab0fb33a75b02d80b412d2637a1272c839d93005fee79f500ba7ccbef6d5414b34cdfc0a2ba075ad344a4bdb1185a5ec003d2179fca2e5f47eb25d0cf112cd050ea7daa6c788d6bc3c1cc4973c745e416dd4f2963444a36baebf19d6d446ea514bc351625d4efd1dce6cf7564b9b0f5ab80e337c7a31503149dec4d2c21a965373da102a891ca1e53863d490e17c8f04a529aa369e6cf9cdc1f85b7cc14befa3af49d9253d6534738bb4015df07f097d0410cc5b0621c02d413a40c352e58b3dd03b4655a5da61bc7218958a8876283951bb0eac45fa9e14495219d2492fd0bb12faa33a548ea705a81238984691c6f94a563ef8f7df4cdf99de3593b48a87ab2c36d778d8eee28f7234a79a8b53810d9b04326bd6f5a4a0008ea66b6ec80a41ce69321ce04a15ed8ef4023f248b98c96287eb2da884826c8a14bcdbde9e6da58a88153a77740aaafbef6d28a7da481c5a9287ac74e1d4d2ce5a2a4a25719c0a80fd53335a0ae32f3b8675e8297fed428981326b5cc44a4a118a6c8328cd1afe439b7c0f9ab1e4e181bd2bd25a5699219c7c7025d2e3b9863465e9dd46ef4bf057e61d94f38381d515913305ecb4f38dfcb4a3c484fea6186ec98a472825fdb4a6d3717e4999b91ff9b24754ab3869345c9462025cb39e2d0f5a2296db36cf3cbe21295f6f14188e429a43f9b629e9701bd01926c7b7d8af725298b853299f0ad9ad51a8c282a04305d976c3e906820a6408906b8bb40868761b2f54a4d9b961a2de6f87d88282f35bdc96dd43cd715db527de14ce4de30b2cca3c2dc6ebdd107c5d8d13116d89e0066629951280209e962c0f79d2954313f3d9a0cfda1899fec387d830497ea0eb432abd1b0f58b8e89ae49aa99d41a186276a47c68d73d56007544791dc010862ca9e8112f6238ff640a78fcf29cbafb3f8364194066fa6f563054a9077d6676374f5f492a8849c5251180a24e41c4a7eef2ab30b233a0d238e379b24af8b72a2a4daa42a0df911c87329af9d38e4bb9701a074e449f3d5fc5c1a9af367b83321087f7a12b4197543f651c7ca8cf9dcb5a4b7aa80e28f58ec0153ce8241dab19c29d153c4d458391a37f13fc812259e966f50caf667e30f95d64dd8a723246100a5e9ce11efc8358ebe0fe9e98fae95d7d92e97ca49062322b4d68e1912cacc6d6b8f6a741f6eb7013e65b3f9b81818348c0f221048e3151c40e3aab7d50340f873b772015302306fafc5d3b9dbdafbf220c3f1b7bbfbcee7085edaf6bd5c2fdc7cb87bb4275a854b8d838b7299e457c72f470c5dc4f941771065b59c0923933dcc986ec04f96116551be14736de07540abfa8ec4c5c6c82d02b26a1a886448704ce4de82da4fec95319e0757c482fd0eb2986a62cc8a5623bf7b791c50d6db7e9b1da590bafaa921bf3f189cc9f3fa7162adec9401dc211b0f80b682e9b3f87f09dfe82f1b0b38cb7694c9a26b70f43fb3c50053a61755cbf55568eb2752b08d225328f7312156c1c9f9ca5315d065ef27095bd6212ebdb1feeb1e3ee6499a8cd6c1662de6524450031940bfd413c0df81927436c163952158c66c4d64873f77df0b47401dba210fc8aa5c236246fc1b7330554004b3df74d9065e9f7da86caef474456e7604bdb2166900b2e5658f2cbc09e50aa59dbebe75e5acbda8d7ae269a18c21c1b3bc3e3feff255df91c0de3f75b1318847052bb8d181d0bd19344a70189f668d9fa2a35f9ff8e0ee2925cdbc5592a5da898b5816d61cf8564a051286ef5e02f602648f79138e62820a551327f5d2b5a5d56e1627555525095ef89204eb55a9f4f5f3bb3dc910386013c37d85468676ebe7a2c319b97147191b0afed4d7ea1f8146106f3997643d4e71b4c51ca82c938a949d82aead94785bee79ccf8f6911d54c345de5fc287dd7f0386ff236da0a60ba672b8ece554a04242ea780fb7190008ef3a08fdd3255d41278d27e5d8c9c29c811c42877d02048bf40b427548b1c9108c60f04aaa46c448262bbe18e5c29f9ac7186445e1d0cbbfa781d6cba0920701473ae1438f1c3430e920200d9b07aedd7eb62afd15a8ba45b675bb34395d3eb240737f392f0b568f30fa73117d08a3305c11cf167aab7bd067e25935e9c5ebdd74633e25270b3e979c731eba1f64705e649cb4f8576aad6c7e81bf006d355903a6add08e550dba45853c7edfbac4018bab467b1cf8fd1ddac3d2af4f20e668821edee50da36e35c9e302c471695376e535f8061104eade3704200fd1caff6b7648e19c5cd3127fdd972ce40507dd7a60c1b75952c57c70313f987c0b36a6318a90c3c7cb3136d85804b29b4fb2927a43731df197c76340aac45de997f493d9eb542f7124f584bd6b10797babd26701655bef31c34b54bf58fff60b6907832e8ba4edbf393dd88f606fa4a63dff34be25b2fa6ede1ad9fc3e9b78a7f43a9dda386990cdc204daa3a55553b12f9fe5fe730a4602fd63e8c39cccd78b7a50cd931237e3b1980d107ac837d33eda6e47331ff14a562a71de00d46c0dd59cb6c375ffcdafe5e77194abba35ac3feb35ed792f28fc04f553f960a97f3937fa6f8038543c111c8f8146529c05125b3c46977c7f7f0cd4d3a87d73f6784c1460c7518615173f3ae9dffa177eb736c53850087778740a727c958236149fb2bd217c8345dd603d4f1d632a8ff90aef6623b551ea5c6ea5789806401ecd9d6b6f546d274e2be8cc039ba62bdca2e3f18638c240610c8e4cbce9b83f186e65789b8842487ae3119aadd24e96a9ec15a380f6541448d8516db9abdd90ee0ee35e4f9a9bd4ed7da17a2e3de8711962bdb9ace6f1c6134a8e937d4db5086993b4bdb6f137c5bfc316953340006562868aa8155996a83ab357c2e2da9562d94679379efe201d13869287168be313e38e4d8749a97ad0ea421649022bdb96a4b145d0faf7cf2a8325c10483c7d26f95b7ab094e6f921b50b4623f16372dd60e36aca9cf1f69fe4cc68eee5082258dbaec21dbd591240b74bac0ec22060d3a46fa90a10ecbfe75c817ce8ddae9fc51a208be10679dee47eab5868e3bc3ec645419f0d1a406a3deef77ab9bd2dce2c6bd8ae651794e261095adb5139cc920b7e695ce6409823485e9e6384a4b79189316a0482c1b7b8b2cc4dddc461ef428842f193f5bbd25acd966658892f408e6432002f49532577413d2452bb21d613978020d9cfe02b81ee64e35dcd1ccef46fb49c79c54085466ca116afec9f18886a4fae6afa7b4a89a706f619ac909780b8b809f28bb09716ece6bf59b8f6ae03f7e05e4be07281ad0189b215bd3c859c7fa1d943db7fc1eaf1507b8aca502a29a21ffc50684baab49d4a6541c41c2df7c82428f184015efe088a0b0d5a383ce988b1c775e27a773d5b7c4ff275e8a86df8bb83622f5c4fc6f4e577582330a682f9150457b93d1ab981787d055e2c650f8ba3655a61189db69f52f750fe636091a6df8cc96cb066b17f6e93667939767e8d2a823b2f024e993436d0fc4f5b586efdcb8370701ee00a0482451ac940d1d20818f56abf1c8417d2721f9e0dfb69f6ad2da6fc12e91be44b97ba76b7e915311f7f6a6442983e186774c261a1847ec9865872c3a3dd5110ef3b2da4fd988711dd277545ff1bff818a19c21cfb55fc5b3433743d586cc8d0e809c0d30f76ce611b6bf40d7b11d33f698cf7bd87063295e3f0bb4b696a6e03807cb26c8aa3a4bfde68926342daff81eac9d66c101f908bf62bc71098a3b84e1fb1b3df126dde91ff78efd26029c99eaed39e3d063b25e1b1f49c94f157b6e00fc490941fc9eb0d1c4f9fd24bc081bb86daa36b4cd25e73b439dce014667922098dec81380de1a3ab9fa4f3254c511e37f52cf710ef31915457866f588f90d5eaebbdaeaf44d0645730b76c61303e2c9252912ab4496c44b74d5cd280ce659abdfcb6b34b550a9e94324219c1be4cc8b48a39672115e438d46e13efc6a294ee921ac9279699af2c707c53a61c4e7f12ea6f901f0742b245a2cea2ed89764f072c660ccce71b4e5a2dbd8275d5b03107df12fd5fa594af389900db7af04082f83e7d6e359c1a55c36e521170b6c2f4865d638e75cadd19ec781651f77df24beffd494cf536abcacd5141789d93f34277e97369e0a0a7f6445c4dcada2e82ffa8fcac09af0067dcf7b7bfef36052925746469583c91a3c97f1c8b14252afb0f1f2d462070ebf859400ca6903d3f3cf1c5f926102bccfe62f4c065bec10c909a2b1e0ea4cffe9974c7</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-default">      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-default">42Team内部考核试题访问需要密码，请输入密码。</span>      </label>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">考核试题，需要密码访问。</summary>
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>Nginx反向代理下载传输超过1G大文件时断开问题</title>
    <link href="https://blog.yeefire.com/2020_09/nginx_forward_proxy_big_file_issue.html"/>
    <id>https://blog.yeefire.com/2020_09/nginx_forward_proxy_big_file_issue.html</id>
    <published>2020-09-25T02:37:48.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Nginx反向代理下载传输超过1G大文件时断开问题"><a href="#Nginx反向代理下载传输超过1G大文件时断开问题" class="headerlink" title="Nginx反向代理下载传输超过1G大文件时断开问题"></a>Nginx反向代理下载传输超过1G大文件时断开问题</h1><h2 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h2><p>42Team社团上线下载站，使用Nginx反向代理为用户提供服务。问题的现象是当用户下载文件超过1G大小时出现断开下载连接的情况导致下载失败。</p><h2 id="问题分析"><a href="#问题分析" class="headerlink" title="问题分析"></a>问题分析</h2><p>一开始以为是Flask的流传输出了问题，调试并跟踪代码后并没有发现问题，而且直接在本地代码调试下载大文件不会出现断开情况。那么开发环境与生产环境中只相差了中间有一层Nginx反向代理，那么初步问题定位到Nginx的反向代理配置上。</p><p>经过在网上进行搜索“反向代理下载大文件失败断开连接”等关键字后找到了一篇其他人写的博文，遇到过类似的问题。</p><p>发现可能是因为超时的原因导致，因为反向代理服务器和部署下载站服务的服务器之间的网络传输速度和磁盘性能非常好，所以他们之间传递1G以上的大文件仅仅有几秒的时间，而Nginx反向代理服务器将文件传输到用户端可能需要数分钟或数十分钟，由于这之间的时间差非常大，所以超过了Nginx的默认连接超时时间，导致此问题发生</p><h2 id="问题解决"><a href="#问题解决" class="headerlink" title="问题解决"></a>问题解决</h2><h3 id="禁用缓存"><a href="#禁用缓存" class="headerlink" title="禁用缓存"></a>禁用缓存</h3><p>禁用缓存，客户端的每次清求都转发到被代理服务器，做法是在代理服务器的Nginx配置里面添加：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">proxy_pass http://172.17.8.88:5050/;</span><br><span class="line">proxy_redirect default;</span><br><span class="line">proxy_buffering off;</span><br></pre></td></tr></table></figure><h3 id="加大Nginx服务器与另一服务器之间的超时等待时间"><a href="#加大Nginx服务器与另一服务器之间的超时等待时间" class="headerlink" title="加大Nginx服务器与另一服务器之间的超时等待时间"></a>加大Nginx服务器与另一服务器之间的超时等待时间</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">keepalive_timeout 15;</span><br><span class="line">send_timeout 3600;</span><br></pre></td></tr></table></figure><hr><p><span class="exturl" data-url="aHR0cDovL2x1bmEyb29vLmJsb2cuY2hpbmF1bml4Lm5ldC91aWQtMjAzMzI1MTktaWQtNTc1NTcyNC5odG1s" title="http://luna2ooo.blog.chinaunix.net/uid-20332519-id-5755724.html">Nginx反向代理导致大文件下载失败<i class="fa fa-external-link"></i></span></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Nginx反向代理下载传输超过1G大文件时断开问题&quot;&gt;&lt;a href=&quot;#Nginx反向代理下载传输超过1G大文件时断开问题&quot; class=&quot;headerlink&quot; title=&quot;Nginx反向代理下载传输超过1G大文件时断开问题&quot;&gt;&lt;/a&gt;Nginx反向代理下载</summary>
      
    
    
    
    
    <category term="Splunk" scheme="https://blog.yeefire.com/tags/Splunk/"/>
    
    <category term="日志" scheme="https://blog.yeefire.com/tags/%E6%97%A5%E5%BF%97/"/>
    
  </entry>
  
  <entry>
    <title>Windows Server 2019 Datacenter M720q 安装记录</title>
    <link href="https://blog.yeefire.com/2020_08/win_server_2019_m720q.html"/>
    <id>https://blog.yeefire.com/2020_08/win_server_2019_m720q.html</id>
    <published>2020-08-31T13:50:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Windows-Server-2019-Datacenter-M720q-安装记录"><a href="#Windows-Server-2019-Datacenter-M720q-安装记录" class="headerlink" title="Windows Server 2019 Datacenter M720q 安装记录"></a>Windows Server 2019 Datacenter M720q 安装记录</h1><span id="more"></span><h2 id="基操"><a href="#基操" class="headerlink" title="基操"></a>基操</h2><h3 id="修改IE浏览器安全策略"><a href="#修改IE浏览器安全策略" class="headerlink" title="修改IE浏览器安全策略"></a>修改IE浏览器安全策略</h3><p>默认的IE浏览器安全策略不允许访问任何不受信任的域，这让我打开百毒-下载Chrome浏览器的过程变得无比艰难。</p><p>关闭限制的方法是在服务器管理器中选择本地服务器。</p><p><img src="https://cdn.yeefire.com/hexo/img/Snipaste_2020-08-31_21-42-28-2020-08-31.png" alt="Snipaste_2020-08-31_21-42-28-2020-08-31"></p><h3 id="打开一些功能"><a href="#打开一些功能" class="headerlink" title="打开一些功能"></a>打开一些功能</h3><p>在Windows Server中为了保障系统运行的稳定性最大限度的关闭了不需要的功能。但是要把它作为一台使用的系统最好将他的实用性更改得好一些。</p><p>在服务器管理器中选择选择添加角色和功能，手动打开一些常见功能，比如WIFI、游戏图形API支持等。</p><table><thead><tr><th align="left">功能名</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">Direct Play</td><td align="left">游戏图形支持API</td></tr><tr><td align="left">Windows Search服务</td><td align="left">Windows搜索索引</td></tr><tr><td align="left">Windows Server备份</td><td align="left">备份服务</td></tr><tr><td align="left">媒体基础</td><td align="left">包含Windows媒体文件格式之间转换</td></tr><tr><td align="left">适用于 Linux 的 Windows 子系统</td><td align="left">提供环境和服务在Windows中运行Linux shell及程序</td></tr><tr><td align="left">无线LAN服务</td><td align="left">开启对WLAN的支持</td></tr></tbody></table><h3 id="开启一些服务"><a href="#开启一些服务" class="headerlink" title="开启一些服务"></a>开启一些服务</h3><p>声音服务：<code>Windows Audio</code>和<code>Windows Audio Endpoint Builder</code>设置为自动。</p><p><code>Windows移动热点服务</code>，如果需要开热点可以开启。</p><p><code>无线电管理服务</code></p><h3 id="组策略设置"><a href="#组策略设置" class="headerlink" title="组策略设置"></a>组策略设置</h3><p>WIN键+R键，输入gpedit.msc，进入组策略设置。</p><p>1、计算机配置，Windows设置，安全设置，帐户策略，密码策略：“密码必须符合复杂性要求”，设置为”已禁用”。<br>解决问题：设置帐号密码，默认必须是字母、数字、特殊字符都必须有，否则会提示不符合条件。</p><p>2、计算机配置，Windows设置，安全设置，帐户策略，密码策略：“密码最短使用期限”，设置为”0”（无期限）。<br>解决问题：密码有有效期，快到期会提示修改密码。修改后密码永久有效。</p><p>3、计算机配置，Windows设置，安全设置，本地策略，安全选项，“无需按 Ctrl+Alt+Del”，设置为”已启用”。<br>解决问题：登录系统，需要先按Ctrl+Alt+Del，才能显示登录界面。修改后不再需要。</p><p>4、计算机配置，管理模板，系统，显示”关闭事件跟踪程序”，设置为”已禁用”。<br>解决问题：关机时，需要输入关机原因。设置后不再需要。</p><p>5、计算机配置，管理模板，系统，登录时不显示”管理你的服务器”页，设置为”已启用”。<br>解决问题：Administrators组下的用户每次登录，会自动启动server manager，设置该策略后，会不再自动启动。<br>另外一种设置方式：通过设置server manager，下次启动时不再自动启动。</p><p>6、最好是新建一个用户。也可以使用Administrator（内置管理员），但要启用批准模式，组策略，计算机配置，Windows设置，安全设置，本地策略，安全选项，“用于内置管理员帐户的管理员批准模式”，设置为”已启用”，重启后生效。<br>解决问题：Administrator也使用UAC，如果想要超级权限，该策略可不设置。</p><p>7、标准帐户类型的用户允许关机，重启<br>解决问题：标准帐户类型的用户，默认无法关机、重启，是没有这些按钮的，按如下设置可以解决该问题。<br>Computer Configuration &gt; Windows Settings &gt; Security Settings &gt; Local Policies &gt; User Rights Assignment &gt; Shutdown the system<br>添加Users组即可。<br>工作站默认的组（指windows 10）：Administrators, Backup Operators, Users.<br>服务器默认的组（指windows server 2019）: Administrators, Backup Operators.</p><p>以上参考自互联网，由于找不到谁是第一个撰写该博文的网友，所以此处不添加引用来源，请谅解。</p><h2 id="开启备份"><a href="#开启备份" class="headerlink" title="开启备份"></a>开启备份</h2><p>默认情况下，Windows Server不启动系统备份，也不会创建系统还原点。如果像我一样Windows绝缘体经常遇到“蓝屏”的话导致系统无法启动等问题还真是很让人崩溃。所以很有必要开启Windows备份，在先前已经安装了Windows Server备份功能，所以搜索 <code>Windows Server 备份</code>应用，即可配置备份设置。</p><h2 id="驱动问题"><a href="#驱动问题" class="headerlink" title="驱动问题"></a>驱动问题</h2><p>先用联想官方驱动助手过一边，之后会发现有两个驱动打不上，一个还是非常重要的板载驱动。（4网口千兆网卡可以免驱直接被识别，所以一开始的时候我将网线插到了这张卡上来上网23333）</p><h3 id="板载有线网卡"><a href="#板载有线网卡" class="headerlink" title="板载有线网卡"></a>板载有线网卡</h3><p>正常情况下板载有线网卡并不能被驱动，在官网下载对应的驱动也无法进行安装，所以只能手动修改inf驱动信息来安装。<br>参考<span class="exturl" data-url="aHR0cDovL2Jsb2cueml2ZXJzLmNvbS9wb3N0LzIxNTcuaHRtbA==" title="http://blog.zivers.com/post/2157.html">Windows Server 2019安装Intel I219-V I211网卡驱动<i class="fa fa-external-link"></i></span></p><h3 id="蓝牙驱动异常"><a href="#蓝牙驱动异常" class="headerlink" title="蓝牙驱动异常"></a>蓝牙驱动异常</h3><p>在任务管理器中，可见一个未知设备。点击详情后提示与蓝牙有关。查看设备硬件ID为：<code>BTH \ MS_BTHPAN</code>，在Intel官网支持找到一篇文章，解决了此问题。</p><p><span class="exturl" data-url="aHR0cHM6Ly93d3cuaW50ZWwuY24vY29udGVudC93d3cvY24vemgvc3VwcG9ydC9hcnRpY2xlcy8wMDAwNTY3NTgvaW50ZWwtbnVjLmh0bWw=" title="https://www.intel.cn/content/www/cn/zh/support/articles/000056758/intel-nuc.html">在英特尔® NUC8i3PN、NUC8v5PN、NUC8v7PN 上安装 Windows * Server 2019 时，使用硬件 ID BTH \ MS_BTHPAN 解决未知设备<i class="fa fa-external-link"></i></span></p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Windows-Server-2019-Datacenter-M720q-安装记录&quot;&gt;&lt;a href=&quot;#Windows-Server-2019-Datacenter-M720q-安装记录&quot; class=&quot;headerlink&quot; title=&quot;Windows Server 2019 Datacenter M720q 安装记录&quot;&gt;&lt;/a&gt;Windows Server 2019 Datacenter M720q 安装记录&lt;/h1&gt;</summary>
    
    
    
    
    <category term="macos" scheme="https://blog.yeefire.com/tags/macos/"/>
    
  </entry>
  
  <entry>
    <title>Ceph块设备基础及快照、克隆操作</title>
    <link href="https://blog.yeefire.com/2020_08/ceph_block_basic.html"/>
    <id>https://blog.yeefire.com/2020_08/ceph_block_basic.html</id>
    <published>2020-08-03T08:47:43.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ceph块设备"><a href="#Ceph块设备" class="headerlink" title="Ceph块设备"></a>Ceph块设备</h1><p>块是一个字节序列（例如，一个512字节的一块数据），基于块的存储接口是最常见的存储数据方法，他们基于旋转媒体，类似于硬盘、CD、软盘、甚至传统的磁带。无处不在的块设备接口使得虚拟块设备成为与Ceph这样海量存储系统交互的理想之选。</p><p>Ceph块设备是瘦接口、大小可以调整且数据被条带化存储在Ceph集群内的多个OSD上。Ceph块设备均衡多个RADOS的能力，快照、复制和一致性，Ceph的RADOS块设备用内核模块或librbd库与各个OSD交互。</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-block-rados-2020-08-03.png" alt="ceph-block-rados-2020-08-03"></p><p>Ceph 块设备靠无限伸缩性提供了高性能，如向内核模块、或向 abbr:KVM (kernel virtual machines) （如 QEMU 、依赖 libvirt 和 QEMU 的 OpenStack 和 CloudStack 云计算系统都可与 Ceph 块设备集成）。可以用同一个集群同时运营 Ceph RADOS 网关、 CephFS 文件系统、和 Ceph 块设备。</p><h2 id="块设备的基本操作"><a href="#块设备的基本操作" class="headerlink" title="块设备的基本操作"></a>块设备的基本操作</h2><p><code>rbd</code>命令可以用于创建、罗列、自检和删除块设备的映像。当然也可以对映像进行克隆、创建快照并支持回滚等。</p><h3 id="创建一个块设备存储池"><a href="#创建一个块设备存储池" class="headerlink" title="创建一个块设备存储池"></a>创建一个块设备存储池</h3><p>在管理节点上，用ceph命令创建一个Pool池。了解更多关于Pool池可以访问<a href="https://blog.yeefire.com/2020_07/ceph_osd_pool_manage.html">OSD与Pool池的常见操作及管理</a>。</p><p><code>ceph osd pool create rbd 64 64</code></p><p>成功创建一个Pool后使用rbd工具再对这个Pool池进行初始化用于RBD。</p><p><code>rbd pool init &lt;pool-name&gt;</code></p><p>此处将新创建的<code>rbd</code>Pool池进行初始化</p><blockquote><p>注意：在接下来使用rbd的命令时如果需要填写<code>&lt;pool-name&gt;</code>参数的地方为空没有填写，那么默认会查找Pool池名为<code>rbd</code>并使用它。</p></blockquote><h3 id="创建块设备用户（非必须）"><a href="#创建块设备用户（非必须）" class="headerlink" title="创建块设备用户（非必须）"></a>创建块设备用户（非必须）</h3><p>如果不指定用户的话，使用<code>rbd</code>命令会默认使用admin管理员访问Ceph集群，admin的用户权限最大，不应该分配给其他机器。所以最好创建一个权限尽可能小的用户访问块设备池。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">osd &#x27;allow &#123;access-spec&#125; [&#123;match-spec&#125;] [network &#123;network/prefix&#125;]&#x27;</span><br><span class="line"></span><br><span class="line">osd &#x27;profile &#123;name&#125; [pool=&#123;pool-name&#125; [namespace=&#123;namespace-name&#125;]] [network &#123;network/prefix&#125;]&#x27;</span><br></pre></td></tr></table></figure><p>如果要了解更多Ceph用户有关信息，可以访问阅读<a href="https://blog.yeefire.com/2020_07/ceph_user_manage.html">Ceph用户管理</a></p><h3 id="创建块设备映像"><a href="#创建块设备映像" class="headerlink" title="创建块设备映像"></a>创建块设备映像</h3><p>如果想要将块设备添加到某一节点，你需要先在Pool中创建一个映像文件。</p><p><code>rbd create --size &#123;megabytes&#125; &#123;pool-name&#125;/&#123;image-name&#125;</code></p><p>例如，在rbd这个Pool池中创建一个名为<code>42team-webnode.img</code>，大小为20G的一个映像：</p><p><code>rbd create --size 20G --pool rbd --image 42team-webnode.img</code></p><h3 id="罗列磁盘映像"><a href="#罗列磁盘映像" class="headerlink" title="罗列磁盘映像"></a>罗列磁盘映像</h3><p>要罗列<code>rbd</code>Pool存储池中的全部映像，使用下面的命令：</p><p><code>rbd ls &#123;poolname&#125;</code></p><blockquote><p><code>&#123;poolname&#125;</code>如果不填写，则默认使用<code>rbd</code>存储池。</p></blockquote><h3 id="检索映像信息"><a href="#检索映像信息" class="headerlink" title="检索映像信息"></a>检索映像信息</h3><p>使用下面的命令来检索某一个映像的信息：</p><p><code>rbd info &#123;pool-name&#125;/&#123;image-name&#125;</code></p><blockquote><p><code>&#123;poolname&#125;</code>如果不填写，则默认使用<code>rbd</code>存储池。</p></blockquote><p><code>rbd info rbd/42team-webnode.img</code></p><p>返回结果：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[root@vm1 ~]# rbd info rbd/42team-webnode.img</span><br><span class="line">rbd image &#x27;42team-webnode.img&#x27;:</span><br><span class="line">size 20 GiB in 5120 objects</span><br><span class="line">order 22 (4 MiB objects)</span><br><span class="line">snapshot_count: 0</span><br><span class="line">id: 17382bc345839</span><br><span class="line">block_name_prefix: rbd_data.17382bc345839</span><br><span class="line">format: 2</span><br><span class="line">features: layering, exclusive-lock, object-map, fast-diff, deep-flatten</span><br><span class="line">op_features:</span><br><span class="line">flags:</span><br><span class="line">create_timestamp: Mon Aug  3 11:03:56 2020</span><br><span class="line">access_timestamp: Mon Aug  3 11:03:56 2020</span><br><span class="line">modify_timestamp: Mon Aug  3 11:03:56 2020</span><br></pre></td></tr></table></figure><h3 id="调整块设备映像大小"><a href="#调整块设备映像大小" class="headerlink" title="调整块设备映像大小"></a>调整块设备映像大小</h3><p>Ceph块设备是瘦接口设备，只有真正写入了数据后才开始占据物理空间，直到限制到它最大的存储大小，他们的最大存储容量就是设置的<code>--size</code>选项的值。如果需要增加或减少Ceph块设备的存储最大尺寸，使用下面的命令：</p><h4 id="缩小映像最大尺寸"><a href="#缩小映像最大尺寸" class="headerlink" title="缩小映像最大尺寸"></a>缩小映像最大尺寸</h4><p>如果要缩小块设备的映像最大存储尺寸，需要添加<code>--allow-shrink</code>选项，才允许缩小映像尺寸。</p><p><code>rbd resize -p rbd --image 42team-webnode.img -s 5G --allow-shrink</code></p><blockquote><p>如果已使用的存储尺寸大于要缩减之后的尺寸，强行缩减块设备映像尺寸会导致数据丢失！</p></blockquote><h4 id="扩大映像最大尺寸"><a href="#扩大映像最大尺寸" class="headerlink" title="扩大映像最大尺寸"></a>扩大映像最大尺寸</h4><p><code>rbd resize -p rbd --image 42team-webnode.img -s 25G</code></p><h3 id="删除块设备映像"><a href="#删除块设备映像" class="headerlink" title="删除块设备映像"></a>删除块设备映像</h3><p>你可以直接将块设备中的映像删除，或者先将他们移动到垃圾桶中，等待一段时间删除或者手动进行清理。</p><h4 id="直接删除块设备映像"><a href="#直接删除块设备映像" class="headerlink" title="直接删除块设备映像"></a>直接删除块设备映像</h4><p><code>rbd rm &#123;pool-name&#125;/&#123;image-name&#125;</code></p><p><code>rbd rm 42team-webnode.img</code></p><blockquote><p><code>&#123;poolname&#125;</code>如果不填写，则默认使用<code>rbd</code>存储池。</p></blockquote><h4 id="延期删除映像"><a href="#延期删除映像" class="headerlink" title="延期删除映像"></a>延期删除映像</h4><p>延期删除可以现将要删除的映像存放到垃圾池中，即便他有快照或者正被克隆的镜像引用者也可以被放入到垃圾桶池中，但是不能将他们从垃圾池中删掉。</p><p>你可以用 <code>–expires-at</code> 设置延期时间（默认为 now ），并且，它的延期时间没到的话是不能删除的，除非你用 <code>–force</code> 选项。</p><p><code>rbd trash mv &#123;pool-name&#125;/&#123;image-name&#125;</code></p><p><code>rbd trash mv rbd/42team-webnode.img</code></p><p><code>rbd trash mv restore-42team-webnode.img --expires-at &quot;20200805&quot;</code></p><p>之后可以通过<code>rbd trash ls --long</code>查看放入到垃圾池的映像有哪些，如果设立日期保护的话还可以看到保护到期的时间。</p><h4 id="还原块设备映像"><a href="#还原块设备映像" class="headerlink" title="还原块设备映像"></a>还原块设备映像</h4><p>当你突然醒悟不该放弃某个映像时，你当然可以从垃圾池中将映像还原！但是前提时你将它放入到了垃圾池而不是直接删除掉他们。</p><p><code>rbd trash restore &#123;pool-name&#125;/&#123;image-id&#125;</code></p><p>在还原映像时需要使用<code>image-id</code>进行还原。可以使用<code>rbd trash ls</code>查看image映像id。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[root@vm1 ~]# rbd trash ls</span><br><span class="line">17382bc345839 42team-webnode.img</span><br><span class="line">[root@vm1 ~]#</span><br></pre></td></tr></table></figure><p><code>rbd trash restore 17382bc345839 --image restore-42team-webnode.img</code></p><p>在还原的同时，还可以指定<code>--image</code>选项对垃圾池内的映像重命名。</p><h4 id="彻底删除在垃圾池中的映像"><a href="#彻底删除在垃圾池中的映像" class="headerlink" title="彻底删除在垃圾池中的映像"></a>彻底删除在垃圾池中的映像</h4><p><code>rbd trash rm &#123;pool-name&#125;/&#123;image-id&#125;</code></p><p>使用<code>rbd trash rm</code>命令可以将在垃圾池中的映像彻底删除，如果你设置了延期时间<code>–expires-at</code> ，那么没到延期时间内直接删除是不可以的，除非使用 <code>–force</code> 选项强制删除。</p><h2 id="拍摄镜像快照"><a href="#拍摄镜像快照" class="headerlink" title="拍摄镜像快照"></a>拍摄镜像快照</h2><p>快照是某映像在一个特定时间点的一份只读副本。Ceph块设备的一个高级功能是可以为映像创建快照来保留历史。Ceph也支持分层快照，这样可以更快速的的克隆一个映像（如VM映像）。Ceph的快照功能还支持rbd命令和多种高级接口，包括 <code>QEMU 、 libvirt 、 OpenStack 和 CloudStack</code>。</p><p>因为RBD不关心文件系统，如果没有与map挂载着的计算机协调的话，快照就是<code>crash-consistent</code>的。所以，在拍摄快照前应该将这个映像的I/O操作暂停，如果这个映像还包含文件系统，在拍摄这个包含文件系统的映像前系统还必须处于一致性状态，否则就要用<code>fsck</code>来修复它了…</p><p>可以使用<code>fsfreeze</code>命令冻结I/O。对于虚拟机来说，<code>qemu-guest-agent</code> 可在创建快照时自动冻结文件系统。</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-snap-ins-2020-08-06.png" alt="ceph-snap-ins-2020-08-06"></p><h3 id="快速操作快照"><a href="#快速操作快照" class="headerlink" title="快速操作快照"></a>快速操作快照</h3><p>接下来的过程演示了如何用 rbd 命令创建、罗列、和删除快照。</p><h4 id="创建快照"><a href="#创建快照" class="headerlink" title="创建快照"></a>创建快照</h4><p>用<code>rbd snap create</code>命令创建快照，需要声明存储池名和映像名。</p><p><code>rbd snap create &#123;pool-name&#125;/&#123;image-name&#125;@&#123;snap-name&#125;</code></p><p>如为<code>rbd/5G.img</code>拍摄快照：</p><p><code>rbd snap create 5G.img@2008050810</code></p><h4 id="罗列快照"><a href="#罗列快照" class="headerlink" title="罗列快照"></a>罗列快照</h4><p>要列出某一个映像的快照，需要指定存储池名和映像名。</p><p><code>rbd snap ls &#123;pool-name&#125;/&#123;image-name&#125;</code></p><p>例如：</p><p><code>rbd snap ls 5G.img</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[root@vm1 ~]# rbd snap ls 5G.img</span><br><span class="line">SNAPID  NAME        SIZE   PROTECTED  TIMESTAMP</span><br><span class="line">     4  2008050810  5 GiB             Wed Aug  5 08:10:55 2020</span><br></pre></td></tr></table></figure><h4 id="回滚快照"><a href="#回滚快照" class="headerlink" title="回滚快照"></a>回滚快照</h4><p>要用rbd回滚到某一快照，使用<code>rbd snap rollback</code>命令。回滚快照时要求该映像不能处于map状态！不应该有任何资源占用这个映像。</p><p><code>rbd snap rollback &#123;pool-name&#125;/&#123;image-name&#125;@&#123;snap-name&#125;</code></p><p>例如：</p><p><code>rbd snap rollback 5G.img@2008050810</code></p><blockquote><p>把映像回滚到一快照的意思是，用快照中的数据覆盖映像的当前版本，此过程花费的时间随映像尺寸增长。从快照克隆要快于回滚到某快照。这也是回到先前状态的首选方法。</p></blockquote><h4 id="删除快照"><a href="#删除快照" class="headerlink" title="删除快照"></a>删除快照</h4><p><strong>删除某映像的一个快照</strong></p><p>使用<code>rbd snap rm</code>命令删除某一映像的快照：</p><p><code>rbd snap rm rbd/5G.img@2008050810</code></p><p>删除后可以再查看一下当前快照，检查是否成功删除：</p><p><code>rbd snap ls rbd/5G.img</code></p><p><strong>删除某映像的全部快照</strong></p><p>当你要删除一个映像的全部快照时，使用<code>rbd snap purge</code>命令：</p><p><code>rbd snap purge &#123;pool-name&#125;/&#123;image-name&#125;</code></p><p><code>rbd snap purge rbd/5G.img</code></p><h3 id="克隆快照映像"><a href="#克隆快照映像" class="headerlink" title="克隆快照映像"></a>克隆快照映像</h3><p>可以克隆一个映像，在原有映像基础之上建立新的分支。不过需要了解分层的概念，想要克隆一个快照必须先创建快照，并且将其保护，之后才能克隆快照。</p><h4 id="了解分层"><a href="#了解分层" class="headerlink" title="了解分层"></a>了解分层</h4><p><img src="https://cdn.yeefire.com/hexo/img/ceph-clone-2020-08-06.png" alt="ceph-clone-2020-08-06"></p><p>Ceph 块设备的分层是个简单的过程。你必须有个映像、必须为它创建快照、必须保护快照，执行过这些步骤后，你才能克隆快照。</p><p>克隆出的映像包含到父快照的饮用、存储池ID、映像ID和快照ID。包含存储池ID意味着你可以把存储池内的快照克隆到别的存储池中。</p><p>分层可以应用于以下方面：</p><ul><li>映像模版：块设备分层的一个常见用法是创建一个主映像及其快照，并作为模版以供克隆。例如管理员会创建一个Linux发行版的映像，之后周期性的升级维护（比如执行了dnf update操作之后等）。等映像文件稳定可用后，用户可以克隆任意快照。</li><li>拓展模板：更高级的用法包括拓展映像模板，让它包含比基础映像更多的信息。例如，首先可以克隆一个基础映像，然后再此基础之上安装新的软件包（如数据库、博客平台、内容管理系统等），之后在此拓展上再次创建快照，拍下的快照可以像基础映像一样更新。</li><li>模版存储池：块设备分层的一种用法是创建一个存储池，其中包含作为模版的主映像和那些模版快照。然后把只读权限分给用户，这样他们就可以克隆快照了，而无需分配此存储池内的写和执行权限。</li><li>映像迁移/恢复：块设备分层的一种用法是把以存储池内的数据迁移或恢复到另一个存储池。</li></ul><h4 id="保护快照"><a href="#保护快照" class="headerlink" title="保护快照"></a>保护快照</h4><p>克隆的映像要访问父快照。如果那个用户不小心删除掉了父快照，那么所有依赖这个父快照的克隆映像都会损坏。为了防止数据丢失，必须先保护快照，然后再当作父快照进行克隆。</p><p><code>rbd snap protect &#123;pool-name&#125;/&#123;image-name&#125;@&#123;snapshot-name&#125;</code></p><p>如下：</p><p><code>rbd snap protect 5G.img@202008051308</code></p><p>之后查看该映像的所有快照：</p><p><code>rbd snap ls 5G.img</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[root@vm1 ~]# rbd snap ls 5G.img</span><br><span class="line">SNAPID  NAME           SIZE   PROTECTED  TIMESTAMP</span><br><span class="line">    10  202008051308   5 GiB  yes        Wed Aug  5 13:08:03 2020</span><br><span class="line">    11  202008051309   5 GiB             Wed Aug  5 13:08:05 2020</span><br><span class="line">    12  2020080513010  5 GiB             Wed Aug  5 13:08:10 2020</span><br></pre></td></tr></table></figure><p>可以看到刚刚被保护的快照，在此处有了标记，接下来尝试能否删除这个快照：</p><p><code>rbd snap rm 5G.img@202008051308</code></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-snap-protect-rm-2020-08-06.png" alt="ceph-snap-protect-rm-2020-08-06"></p><p>结果显而易见，当快照被保护的情况下是不允许被删除的。这样我们就可以在这个快照的基础上进行克隆全新的映像！</p><h4 id="克隆映像快照"><a href="#克隆映像快照" class="headerlink" title="克隆映像快照"></a>克隆映像快照</h4><p>要克隆快照，你得指定父存储池、映像、和快照，还有子存储池和映像名。克隆前必须先保护快照，否则不允许克隆。</p><p><code>rbd clone &#123;pool-name&#125;/&#123;parent-image&#125;@&#123;snap-name&#125; &#123;pool-name&#125;/&#123;child-image-name&#125;</code></p><p>例如克隆我们刚刚保护的那个快照，并且把克隆后的映像叫做<code>5G_new.img</code>:</p><p><code>rbd clone 5G.img@202008051308 rbd/5G_new.img</code></p><blockquote><p>你可以把一存储池中的映像的快照克隆到另一个存储池。例如，你可以把一存储池中的只读映像及快照当作模版进行维护，之后（比如映像调试完毕后）可以将其克隆到另一个存储池中进行发布使用。</p></blockquote><p>现在，可以查看以下刚刚克隆的新映像的信息：</p><p><code>rbd ls --long</code></p><p><code>rbd info 5G_new.img</code></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-clone-ls-2020-08-06.png" alt="ceph-clone-ls-2020-08-06"><br><img src="https://cdn.yeefire.com/hexo/img/ceph-clone-rbd-info-2020-08-06.png" alt="ceph-clone-rbd-info-2020-08-06"></p><h4 id="罗列快照的后代"><a href="#罗列快照的后代" class="headerlink" title="罗列快照的后代"></a>罗列快照的后代</h4><p><code>rbd children &#123;pool-name&#125;/&#123;image-name&#125;[@&#123;snapshot-name&#125;]</code></p><p>例如：</p><p><code>rbd children rbd/5G.img</code></p><h4 id="取消快照保护"><a href="#取消快照保护" class="headerlink" title="取消快照保护"></a>取消快照保护</h4><p>删除快照前，必须先需要快照保护。另外如果有其他的子映像使用着这个快照，那么你不能删除这个快照。除非你将引用这个快照的子映像执行拍平的操作。</p><p><code>rbd snap unprotect &#123;pool-name&#125;/&#123;image-name&#125;@&#123;snapshot-name&#125;</code></p><blockquote><p>无法取消保护一个被克隆的子映像使用的快照，除非你将克隆后的映像拍平。<br><img src="https://cdn.yeefire.com/hexo/img/ceph-snap-unprotect-1-2020-08-06.png" alt="ceph-snap-unprotect-1-2020-08-06"></p></blockquote><h4 id="拍平克隆的映像"><a href="#拍平克隆的映像" class="headerlink" title="拍平克隆的映像"></a>拍平克隆的映像</h4><p>克隆的映像一直保留着对父快照的引用，所以你无法取消保护一个被引用的父快照。如果你要从子克隆删除到父快照的这些引用，你可以把引用的父快照信息完整的复制到子克隆中，也就是拍平它。拍平克隆品的时间因快照尺寸而不同，要删除快照或者取消保护快照，必须将子映像拍平。</p><p><code>rbd flatten &#123;pool-name&#125;/&#123;image-name&#125;</code></p><p>例如：</p><p><code>rbd flatten rbd/5G_new.img</code></p><p>拍平子映像后，就不会再引用父快照的信息了。此时，你可以将父快照解除保护并删除。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ceph块设备&quot;&gt;&lt;a href=&quot;#Ceph块设备&quot; class=&quot;headerlink&quot; title=&quot;Ceph块设备&quot;&gt;&lt;/a&gt;Ceph块设备&lt;/h1&gt;&lt;p&gt;块是一个字节序列（例如，一个512字节的一块数据），基于块的存储接口是最常见的存储数据方法，他们基于</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>从Ceph集群中删除OSD节点</title>
    <link href="https://blog.yeefire.com/2020_08/ceph_osd_rm.html"/>
    <id>https://blog.yeefire.com/2020_08/ceph_osd_rm.html</id>
    <published>2020-07-31T15:50:43.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="从集群中删除OSD节点"><a href="#从集群中删除OSD节点" class="headerlink" title="从集群中删除OSD节点"></a>从集群中删除OSD节点</h1><p>使用<code>cephadm</code>部署的Ceph集群，再尝试从集群中删除OSD节点的时候遇到了各种问题……</p><p>既然自动化工具目前不太完善（或者说在文档里目前还没看到使用cephadm删除OSD节点的方法），那么就手动删除吧！记录一次使用<code>cephadm</code>搭建的集群如何删除OSD节点。当然使用其他方式部署的OSD要删除的话也是大同小异的。</p><p>ceph版本:<code>ceph version 15.2.4 (7447c15c6ff58d7fce91843b705a268a1917325c) octopus (stable)</code></p><h2 id="查看集群OSD状态"><a href="#查看集群OSD状态" class="headerlink" title="查看集群OSD状态"></a>查看集群OSD状态</h2><p>先查看集群内OSD的状态，并找到要删除的OSD节点。现在准备删除<code>osd.4</code>和<code>osd.5</code>这两个节点，他们都在<code>vm2</code>这台主机上。</p><p><code>ceph osd tree</code></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-rm-osd-tree-2020-07-31.png" alt="ceph-rm-osd-tree-2020-07-31"></p><p><code>ceph osd dump</code></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-rm-osd-dump-2020-07-31.png" alt="ceph-rm-osd-dump-2020-07-31"></p><p>可以留意一下ID，之后便于确认ID所对应的块设备名(如：/dev/sdx或/dev/nvmex)</p><h2 id="删除OSD节点节点"><a href="#删除OSD节点节点" class="headerlink" title="删除OSD节点节点"></a>删除OSD节点节点</h2><h3 id="使用cephadm删除OSD节点"><a href="#使用cephadm删除OSD节点" class="headerlink" title="使用cephadm删除OSD节点"></a>使用<code>cephadm</code>删除OSD节点</h3><p>目前使用<code>cephadm</code>删除OSD节点后也需要手动的<a href="#%E8%A7%A3%E9%99%A4ceph%E5%AF%B9%E7%A3%81%E7%9B%98%E7%9A%84%E5%8D%A0%E7%94%A8">释放磁盘占用</a>。</p><p><code>ceph orch osd rm &lt;svc_id&gt;... [--replace] [--force]</code></p><p>要删除<code>osd.4</code>和<code>osd.5</code>节点则执行：<code>ceph orch osd rm 4 5</code></p><p>删除的过程需要一段时间，会重新分配集群内的PG，删除CRUSH图节点信息，删除这两个OSD所对应的用户和密钥环。</p><p>查看自动删除状态进度<code>ceph orch osd rm status</code>，如果长时间无响应或者依旧没有删除，可以开始尝试<a href="#%E6%89%8B%E5%8A%A8%E5%88%A0%E9%99%A4osd%E8%8A%82%E7%82%B9">手动删除OSD节点</a></p><h3 id="手动删除OSD节点"><a href="#手动删除OSD节点" class="headerlink" title="手动删除OSD节点"></a>手动删除OSD节点</h3><h4 id="移除daemon守护进程"><a href="#移除daemon守护进程" class="headerlink" title="移除daemon守护进程"></a>移除daemon守护进程</h4><p>接下来的操作请确保你对整个集群拥有<code>admin</code>权限并且对要删除OSD节点的主机有<code>root</code>权限。</p><p>登录到拥有Ceph集群<code>admin</code>权限的主机，执行如下命令：</p><p><code>ceph orch daemon rm osd.4 osd.5 --force</code></p><p>返回结果如下，已经移除他们容器的守护进程：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Removed osd.4 from host &#x27;vm2&#x27;</span><br><span class="line">Removed osd.5 from host &#x27;vm2&#x27;</span><br></pre></td></tr></table></figure><p>此时查看集群中这两个OSD的状态：</p><p>要删除<code>osd.4</code>和<code>osd.5</code>这两个节点的状态变成了<strong>DOWN</strong>。接下来就可以从<code>crush</code>表中将他们移除。</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-rm-osd-tree-2-2020-07-31.png" alt="ceph-rm-osd-tree-2-2020-07-31"></p><blockquote><p>如果还没有使用<code>cephadm</code>管理集群，此处你可以登录到<code>vm2</code>这台主机中手动的将他们的<code>systemd</code>守护进程<code>disable</code>。<br>    <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">systemctl disable --now  ceph-osd@4</span><br><span class="line">systemctl disable --now  ceph-osd@5</span><br></pre></td></tr></table></figure></p></blockquote><h4 id="删除CRUSH图中所对应的OSD节点"><a href="#删除CRUSH图中所对应的OSD节点" class="headerlink" title="删除CRUSH图中所对应的OSD节点"></a>删除CRUSH图中所对应的OSD节点</h4><p>删除CRUSH图中的OSD节点信息</p><p><code>ceph osd crush remove osd.4</code></p><p><code>ceph osd crush remove osd.5</code></p><p>执行成功返回结果：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">removed item id 4 name &#x27;osd.4&#x27; from crush map</span><br><span class="line">removed item id 5 name &#x27;osd.5&#x27; from crush map</span><br></pre></td></tr></table></figure><p>此时再次手动检查集群内的OSD节点中是否还包含<code>osd.4</code>和<code>osd.5</code>：</p><p>已经从CRUSH图标中删除，此处已经看不到这两个OSD节点。</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-rm-osd-tree-3-2020-07-31.png" alt="ceph-rm-osd-tree-3-2020-07-31"></p><h4 id="删除osd节点"><a href="#删除osd节点" class="headerlink" title="删除osd节点"></a>删除osd节点</h4><p><code>ceph osd rm osd.4 osd.5</code></p><p>返回执行成功结果：<code>removed osd.4, osd.5</code></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-osd-rm-2020-07-31.png" alt="ceph-osd-rm-2020-07-31"></p><h4 id="删除osd用户"><a href="#删除osd用户" class="headerlink" title="删除osd用户"></a>删除osd用户</h4><p><code>ceph auth ls | grep ^osd -A4</code></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-auth-ls-2020-07-31.png" alt="ceph-auth-ls-2020-07-31"></p><p>发现Ceph的OSD用户未被删除，残留在此处（会影响下一次添加OSD时，导致密钥环不匹配的错误）。执行如下命令删除：</p><p><code>ceph auth rm osd.4</code></p><p><code>ceph auth rm osd.5</code></p><h4 id="删除OSD配置（如果有的话）"><a href="#删除OSD配置（如果有的话）" class="headerlink" title="删除OSD配置（如果有的话）"></a>删除OSD配置（如果有的话）</h4><p>如果额外对OSD进行了额外配置的话需要手动删除当时的配置信息。登录到这台被删除OSD节点的主机上，修改配置文件：<code>vim /etc/ceph/ceph.conf</code>，将对该OSD节点额外配置的信息删除。</p><p><strong>之后把更新过的ceph.conf文件要拷贝到其他集群主机的<code>/etc/ceph/</code>目录下。</strong></p><h2 id="解除Ceph对磁盘的占用"><a href="#解除Ceph对磁盘的占用" class="headerlink" title="解除Ceph对磁盘的占用"></a>解除Ceph对磁盘的占用</h2><p>之后的操作都需要在移除OSD节点的主机(<code>vm2</code>)上通过<code>root</code>用户特权执行操作。</p><p>当删除了OSD之后，由于先前的配置，Ceph仍然对磁盘进行占用。需要移除这块OSD磁盘的DM状态，并之后对其格式化，这样才完整的手动移除一个OSD节点(磁盘)。</p><h3 id="查询磁盘DM状态并移除编码"><a href="#查询磁盘DM状态并移除编码" class="headerlink" title="查询磁盘DM状态并移除编码"></a>查询磁盘DM状态并移除编码</h3><p><code>dmsetup status</code></p><p><img src="https://cdn.yeefire.com/hexo/img/dmset-status-2020-07-31.png" alt="dmset-status-2020-07-31"></p><p>注意在一开始要留意的哪个ID，在这里用来识别要删除哪个磁盘的DM标记。</p><p><code>dmsetup remove ceph--14c75e65--a33e--459a--8bc7--c95add15d8a3-osd--block--d2af5a38--54b9--4112--9bbf--8ea313c673f1</code></p><p><code>dmsetup remove ceph--6ceb7c60--8b90--44fc--b159--34bd3d8c8e0f-osd--block--5f1d52fa--e50c--4915--b059--f672684ce571</code></p><p>执行完上面的命令后，再检查一下DM状态，发现已经成功被删除DM标记：</p><p><img src="https://cdn.yeefire.com/hexo/img/dmset-status-2-2020-07-31.png" alt="dmset-status-2-2020-07-31"></p><h3 id="wipefs格式化文件系统"><a href="#wipefs格式化文件系统" class="headerlink" title="wipefs格式化文件系统"></a><code>wipefs</code>格式化文件系统</h3><p>在使用<code>wipefs</code>工具清除文件系统前，要找到所对应的块设备名称。</p><p>执行<code>lsblk -f</code>命令：</p><p>下面的图片中可以看到，<code>nvme0n2</code>和<code>nvme0n3</code>这两个块设备已经<strong>没有了像<code>nvme0n4</code>下方的ID标记</strong>，所以可以判定<code>nvme0n2</code>和<code>nvme0n3</code>和两块磁盘是我们移除的OSD节点所使用的磁盘。</p><p><img src="https://cdn.yeefire.com/hexo/img/fdisk-f-2020-07-31.png" alt="fdisk-f-2020-07-31"></p><p>接下来对<code>nvme0n2</code>和<code>nvme0n3</code>两个块设备格式他们的文件系统，执行命令：</p><p><code>wipefs -a  /dev/nvme0n2 /dev/nvme0n3</code></p><p><img src="https://cdn.yeefire.com/hexo/img/wipefs-2020-07-31.png" alt="wipefs-2020-07-31"></p><p>到此，完成的将OSD节点从集群中移除。你可以使用lsblk工具或<strong>稍后一段时间后</strong>在拥有集群admin权限的主机上执行<code>ceph orch device ls</code>命令查看这两个OSD节点所使用的磁盘是否是可以用的状态了。现在你可以将这两个磁盘取出或者在这两块磁盘上重新部署OSD节点…</p><p><img src="https://cdn.yeefire.com/hexo/img/fdisk-f-clean-2020-07-31.png" alt="fdisk-f-clean-2020-07-31"></p><h2 id=""><a href="#" class="headerlink" title=""></a><img src="https://cdn.yeefire.com/hexo/img/ceph-orch-device-ls-2020-07-31.png" alt="ceph-orch-device-ls-2020-07-31"></h2>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;从集群中删除OSD节点&quot;&gt;&lt;a href=&quot;#从集群中删除OSD节点&quot; class=&quot;headerlink&quot; title=&quot;从集群中删除OSD节点&quot;&gt;&lt;/a&gt;从集群中删除OSD节点&lt;/h1&gt;&lt;p&gt;使用&lt;code&gt;cephadm&lt;/code&gt;部署的Ceph集群，再尝</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>Centos8配置 chrony NTP服务端及客户端</title>
    <link href="https://blog.yeefire.com/2020_07/chrony_ntp.html"/>
    <id>https://blog.yeefire.com/2020_07/chrony_ntp.html</id>
    <published>2020-07-28T03:55:07.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Centos8配置-chrony-NTP服务端及客户端"><a href="#Centos8配置-chrony-NTP服务端及客户端" class="headerlink" title="Centos8配置 chrony NTP服务端及客户端"></a>Centos8配置 chrony NTP服务端及客户端</h1><p>现在有一台服务器想作为NTP服务器，3台客户端想作为NTP服务器的客户端，保证客户端机器上的时间与服务器端保持同步。清单如下：</p><table><thead><tr><th align="left">类型</th><th align="left">IP地址</th></tr></thead><tbody><tr><td align="left">server</td><td align="left">192.168.1.30</td></tr><tr><td align="left">client</td><td align="left">192.168.1.[31:33]</td></tr></tbody></table><h2 id="部署服务端chrony"><a href="#部署服务端chrony" class="headerlink" title="部署服务端chrony"></a>部署服务端chrony</h2><p>ssh登录到server机器后放行防火墙、安装chrony服务、配置chrony服务器端。</p><h3 id="放行防火墙端口"><a href="#放行防火墙端口" class="headerlink" title="放行防火墙端口"></a>放行防火墙端口</h3><p>Centos8使用<code>firewalld</code>服务对防火墙进行管理。放行ntp服务(123/udp)</p><p><code>firewall-cmd --add-service=ntp --permanent &amp;&amp; firewall-cmd --reload</code></p><h3 id="安装chrony服务"><a href="#安装chrony服务" class="headerlink" title="安装chrony服务"></a>安装chrony服务</h3><p>默认情况下Centos8中已经安装好chrony的软件包。如果发现没有安装，使用下面的命令安装即可：</p><p><code>sudo dnf install chrony -y</code></p><h3 id="配置chrony服务端"><a href="#配置chrony服务端" class="headerlink" title="配置chrony服务端"></a>配置chrony服务端</h3><p><code>sudo vim /etc/chrony.conf</code></p><p>不习惯<code>vi/vim</code>编辑器的小伙伴可以替换为自己喜爱的编辑器如<code>nano</code>。</p><p>把原有自带的上游NTP服务器地址删除。之后手动配置国内阿里云的NTP服务器地址。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">server time1.aliyun.com iburst     #添加上游NTP服务器</span><br><span class="line">server time2.aliyun.com iburst</span><br><span class="line">server time3.aliyun.com iburst</span><br><span class="line"></span><br><span class="line">allow 192.168.1.0/24               #允许IP端内的客户端通过这台服务器获取时间</span><br></pre></td></tr></table></figure><p>配置无误后，重启chrony服务，并配置开机自启动：</p><p><code>systemctl restart chronyd.service &amp;&amp; systemctl enable chronyd.service --now</code></p><p>使用<code>ss -tlunp | grep chrony</code>命令检查，发现chrony服务已经在监听<code>123/udp</code>端口，服务端配置成功。</p><h2 id="配置chrony客户端"><a href="#配置chrony客户端" class="headerlink" title="配置chrony客户端"></a>配置chrony客户端</h2><p>配置chrony客户端需要将三台客户端都安装chrony并且配置好他们的配置文件。如果说客户端数量较少可以手动配置，当数量为成百上千台机器时使用Ansible自动化配置是一个不错的选择。所以在这里有两种配置方法供大家参考，一种是普通手动配置，一种是使用Ansible-Galaxy角色配置。</p><h3 id="手动配置chrony客户端"><a href="#手动配置chrony客户端" class="headerlink" title="手动配置chrony客户端"></a>手动配置chrony客户端</h3><p>配置客户端同样的需要放行防火墙、安装chrony软件包、配置chrony客户端。</p><h4 id="安装chrony软件包"><a href="#安装chrony软件包" class="headerlink" title="安装chrony软件包"></a>安装chrony软件包</h4><p><code>dnf install chrony -y</code></p><h4 id="修改客户端chrony配置文件"><a href="#修改客户端chrony配置文件" class="headerlink" title="修改客户端chrony配置文件"></a>修改客户端chrony配置文件</h4><p><code>sudo vim /etc/chrony.conf</code></p><p>不习惯<code>vi/vim</code>编辑器的小伙伴可以替换为自己喜爱的编辑器如<code>nano</code>。</p><figure class="highlight sh"><table><tr><td class="code"><pre><span class="line"><span class="comment"># Use public servers from the pool.ntp.org project.</span></span><br><span class="line"><span class="comment"># Please consider joining the pool (http://www.pool.ntp.org/join.html).</span></span><br><span class="line"><span class="comment"># pool 2.centos.pool.ntp.org iburst </span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 把原有的NTP服务器地址注释掉或者直接删除。添加下面刚刚搭建好的NTP服务器地址。</span></span><br><span class="line">server 192.168.1.30 iburst</span><br></pre></td></tr></table></figure><p>注释默认的NTP服务器地址，之后添加上我们自己刚刚搭建好的NTP服务器地址即可完成chrony客户端的手动配置。</p><h4 id="重启chrony客户端服务"><a href="#重启chrony客户端服务" class="headerlink" title="重启chrony客户端服务"></a>重启chrony客户端服务</h4><p>重启chrony服务，并配置开机自启动：</p><p><code>systemctl restart chronyd.service &amp;&amp; systemctl enable chronyd.service --now</code></p><h4 id="查看同步状态"><a href="#查看同步状态" class="headerlink" title="查看同步状态"></a>查看同步状态</h4><p><code>chronyc sources -v</code></p><figure class="highlight sh"><table><tr><td class="code"><pre><span class="line">[root@vm1 ~]# chronyc sources -v</span><br><span class="line">210 Number of sources = 1</span><br><span class="line"></span><br><span class="line">  .-- Source mode  <span class="string">&#x27;^&#x27;</span> = server, <span class="string">&#x27;=&#x27;</span> = peer, <span class="string">&#x27;#&#x27;</span> = <span class="built_in">local</span> clock.</span><br><span class="line"> / .- Source state <span class="string">&#x27;*&#x27;</span> = current synced, <span class="string">&#x27;+&#x27;</span> = combined , <span class="string">&#x27;-&#x27;</span> = not combined,</span><br><span class="line">| /   <span class="string">&#x27;?&#x27;</span> = unreachable, <span class="string">&#x27;x&#x27;</span> = <span class="keyword">time</span> may be <span class="keyword">in</span> error, <span class="string">&#x27;~&#x27;</span> = <span class="keyword">time</span> too variable.</span><br><span class="line">||                                                 .- xxxx [ yyyy ] +/- zzzz</span><br><span class="line">||      Reachability register (octal) -.           |  xxxx = adjusted offset,</span><br><span class="line">||      Log2(Polling interval) --.      |          |  yyyy = measured offset,</span><br><span class="line">||                                \     |          |  zzzz = estimated error.</span><br><span class="line">||                                 |    |           \</span><br><span class="line">MS Name/IP address         Stratum Poll Reach LastRx Last sample</span><br><span class="line">===============================================================================</span><br><span class="line">^* 192.168.1.30                  3   6    17    16  +3424ns[ +110us] +/-   31ms</span><br></pre></td></tr></table></figure><p>可以看到，输出结果里已经有我们搭建好的NTP服务器了。并且在服务器地址前有<code>^*</code>标记，证明已经正确同步时间。</p><p>至此一台客户端的chrony已经搭建完毕。剩下的两台同理部署即可。</p><h3 id="使用Ansible自动化配置chrony客户端"><a href="#使用Ansible自动化配置chrony客户端" class="headerlink" title="使用Ansible自动化配置chrony客户端"></a>使用Ansible自动化配置chrony客户端</h3><p>相关Ansible基础默认你已经了解，不再赘述。如果你不了解Ansible请从<a href="https://blog.yeefire.com/2020_06/ansible_index.html">Ansible文档</a>入门学习。</p><p><code>mkdir Chrony &amp;&amp; cd Chrony</code></p><h4 id="配置ansible-cfg"><a href="#配置ansible-cfg" class="headerlink" title="配置ansible.cfg"></a>配置ansible.cfg</h4><p><code>vim ansible.cfg</code></p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[defaults]</span></span><br><span class="line"><span class="attr">inventory</span> = inventory</span><br><span class="line"><span class="attr">remote_user</span> = root</span><br><span class="line"><span class="attr">roles_path</span>=./roles:/usr/share/ansible/roles:/etc/ansible/roles</span><br><span class="line"></span><br><span class="line"><span class="section">[privilege_escalation]</span></span><br><span class="line"><span class="attr">become</span>=<span class="literal">True</span></span><br><span class="line"><span class="attr">become_method</span>=sudo</span><br><span class="line"><span class="attr">beome_user</span>=root</span><br><span class="line"><span class="attr">become_ask_pass</span>=<span class="literal">False</span></span><br></pre></td></tr></table></figure><h4 id="配置主机清单"><a href="#配置主机清单" class="headerlink" title="配置主机清单"></a>配置主机清单</h4><p><code>vim inventory</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[client]</span><br><span class="line">192.168.1.3[1:3]</span><br></pre></td></tr></table></figure><h4 id="配置ssh免密登陆客户端"><a href="#配置ssh免密登陆客户端" class="headerlink" title="配置ssh免密登陆客户端"></a>配置ssh免密登陆客户端</h4><p><a href="https://blog.yeefire.com/2020_02/Linux_sshd.html#%E9%85%8D%E7%BD%AESSH%E5%85%8D%E5%AF%86%E7%99%BB%E5%BD%95">配置SSH免密登录</a></p><h4 id="下载chrony角色"><a href="#下载chrony角色" class="headerlink" title="下载chrony角色"></a>下载chrony角色</h4><p><code>ansible-galaxy install ericsysmin.chrony</code></p><h4 id="编写Playbok"><a href="#编写Playbok" class="headerlink" title="编写Playbok"></a>编写Playbok</h4><p><code>vim playbook.yml</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">---</span><br><span class="line">- name: Config Chrony Client</span><br><span class="line">  hosts: client</span><br><span class="line">  roles:</span><br><span class="line">    - role: ericsysmin.chrony</span><br><span class="line">      chrony_config_server:</span><br><span class="line">        - 192.168.1.30</span><br><span class="line">...</span><br></pre></td></tr></table></figure><p>执行结果如下，全部OK即为成功：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">PLAY RECAP **************************</span><br><span class="line">192.168.1.31               : ok=7    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0</span><br><span class="line">192.168.1.32               : ok=7    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0</span><br><span class="line">192.168.1.33               : ok=7    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0</span><br></pre></td></tr></table></figure><p>之后可以登录几台机器进行手动验证，查看是否已经以NTP服务器保持同步。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Centos8配置-chrony-NTP服务端及客户端&quot;&gt;&lt;a href=&quot;#Centos8配置-chrony-NTP服务端及客户端&quot; class=&quot;headerlink&quot; title=&quot;Centos8配置 chrony NTP服务端及客户端&quot;&gt;&lt;/a&gt;Cento</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
  </entry>
  
  <entry>
    <title>搭建Ceph集群</title>
    <link href="https://blog.yeefire.com/2020_07/ceph_cluster.html"/>
    <id>https://blog.yeefire.com/2020_07/ceph_cluster.html</id>
    <published>2020-07-26T11:13:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="搭建Ceph集群"><a href="#搭建Ceph集群" class="headerlink" title="搭建Ceph集群"></a>搭建Ceph集群</h1><h2 id="部署前准备"><a href="#部署前准备" class="headerlink" title="部署前准备"></a>部署前准备</h2><h3 id="机器清单"><a href="#机器清单" class="headerlink" title="机器清单"></a>机器清单</h3><table><thead><tr><th align="left">host</th><th align="left">ip地址</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">centos8</td><td align="left">192.168.1.30(外网)/10.10.1.10(内网)</td><td align="left">为其他机器运行Ansible脚本（部署）、Ceph客户端</td></tr><tr><td align="left">vm1</td><td align="left">192.168.1.31/10.10.1.11</td><td align="left">Ceph OSD节点</td></tr><tr><td align="left">vm2</td><td align="left">192.168.1.32/10.10.1.12</td><td align="left">Ceph OSD节点</td></tr><tr><td align="left">vm3</td><td align="left">192.168.1.33/10.10.1.13</td><td align="left">Ceph OSD节点</td></tr></tbody></table><h3 id="hosts文件"><a href="#hosts文件" class="headerlink" title="hosts文件"></a>hosts文件</h3><p>把机器清单编写为hosts文件。</p><p><code>vim /etc/hosts</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">192.168.1.30    centos8</span><br><span class="line">192.168.1.31    vm1</span><br><span class="line">192.168.1.32    vm2</span><br><span class="line">192.168.1.33    vm3</span><br></pre></td></tr></table></figure><h3 id="防火墙放行"><a href="#防火墙放行" class="headerlink" title="防火墙放行"></a>防火墙放行</h3><table><thead><tr><th align="left">服务名</th><th align="left">端口号</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">Monitor监视器</td><td align="left">6789/tcp</td><td align="left">与Ceph集群通信</td></tr><tr><td align="left">Manager</td><td align="left">7000/tcp</td><td align="left">Ceph管理面板</td></tr><tr><td align="left"></td><td align="left">8003/tcp</td><td align="left">Ceph Restful API管理 with HTTPS</td></tr><tr><td align="left"></td><td align="left">9283/tcp</td><td align="left">Prometheus插件通信接口</td></tr><tr><td align="left">OSD</td><td align="left">6800-7300/tcp</td><td align="left">每个OSD在这个范围内使用3个端口，一个用来与客户端和监视器进行通信，一个用来与集群中其他的OSD进行通信<del>或者在公网上传输数据</del>，最后一个用来在集群中发送心跳包</td></tr><tr><td align="left">RADOS 网关</td><td align="left">7480/tcp</td><td align="left">默认RADOS网管端口为7480，你可以修改为80/443（如果使用TLS）</td></tr></tbody></table><p>如果你使用firewalld来管理你的防火墙，可以执行下面的命令放行端口：</p><p><code>firewall-cmd --add-service=ceph --add-service=ceph-mon --permanent &amp;&amp; firewall-cmd --reload</code></p><h3 id="创建部署Ceph的用户"><a href="#创建部署Ceph的用户" class="headerlink" title="创建部署Ceph的用户"></a>创建部署Ceph的用户</h3><p><code>ceph-deploy</code> 工具必须以普通用户登录，且此用户拥有无密码使用 sudo 的权限，因为它需要安装软件及配置文件，中途不能输入密码。</p><p>较新版的 <code>ceph-deploy</code> 支持用 <code>--username</code> 选项提供可无密码使用 sudo 的用户名（包括 root ，虽然不建议这样做）。要用 <code>ceph-deploy --username &#123;username&#125;</code> 命令，指定的用户必须能够通过无密码 SSH 连接到 Ceph 节点，因为 ceph-deploy 不支持中途输入密码。</p><blockquote><p>从 Infernalis 版起，用户名 “ceph” 保留给了 Ceph 守护进程。如果 Ceph 节点上已经有了 “ceph” 用户，升级前必须先删掉这个用户。</p></blockquote><p><strong>在各个Ceph节点创建新用户</strong></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh username@ceph-server</span><br><span class="line"><span class="built_in">sudo</span> useradd -d /home/&#123;username&#125; -m &#123;username&#125;</span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;password&quot;</span> | passwd &#123;username&#125; --stdin</span><br></pre></td></tr></table></figure><p><strong>配置sudo权限</strong></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">echo &quot;&#123;username&#125; ALL = (root) NOPASSWD:ALL&quot; | sudo tee /etc/sudoers.d/&#123;username&#125;</span><br><span class="line">sudo chmod 0440 /etc/sudoers.d/&#123;username&#125;</span><br></pre></td></tr></table></figure><h3 id="配置ssh-key免密登录"><a href="#配置ssh-key免密登录" class="headerlink" title="配置ssh-key免密登录"></a>配置ssh-key免密登录</h3><p>在centos8机器中创建密钥对，但是不要用sudo或root用户。口令为空。</p><p><code>ssh-keygen</code></p><p>全部默认配置，直接回车生成key。</p><p>现在将centos8机器的ssh公钥发送到vm[1:3]的机器上。</p><p>把公钥拷贝到各 Ceph 节点，把下列命令中的 <code>&#123;username&#125;</code> 替换成前面创建部署 Ceph 的用户里的用户名。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> 1 2 3</span><br><span class="line"><span class="keyword">do</span></span><br><span class="line">    ssh-copy-id &#123;username&#125;@vm<span class="variable">$i</span> </span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></table></figure><p><strong>如果使用<code>ceph-deploy</code>工具部署集群推荐使用以下方式配置免密登录</strong></p><p>修改 <code>ceph-deploy</code> 管理节点上的 <code>~/.ssh/config</code> 文件，这样 <code>ceph-deploy</code> 就能用你所建的用户名登录 Ceph 节点了，无需每次执行 <code>ceph-deploy</code> 都指定 <code>--username &#123;username&#125;</code> 。这样做同时也简化了 ssh 和 scp 的用法。把 <code>&#123;username&#125;</code> 替换成你创建的用户名。注意要将<code>~/.ssh/config</code> 文件权限修改为0600。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Host node1</span><br><span class="line">   Hostname node1</span><br><span class="line">   User &#123;username&#125;</span><br><span class="line">Host node2</span><br><span class="line">   Hostname node2</span><br><span class="line">   User &#123;username&#125;</span><br><span class="line">Host node3</span><br><span class="line">   Hostname node3</span><br><span class="line">   User &#123;username&#125;</span><br></pre></td></tr></table></figure><h3 id="配置NTP"><a href="#配置NTP" class="headerlink" title="配置NTP"></a>配置NTP</h3><p>集群之间机器的时间应该保持同步，需要使用NTP服务同步时间。</p><p>如果不了解NTP服务及搭建，请参考<a href="https://blog.yeefire.com/2020_07/chrony_ntp.html">搭建NTP服务和配置客户端</a></p><h3 id="配置SELinux"><a href="#配置SELinux" class="headerlink" title="配置SELinux"></a>配置SELinux</h3><p>在 CentOS 和 RHEL 上， SELinux 默认开启为 <code>Enforcing</code> 。为简化安装，我们建议把 SELinux 设置为 <code>Permissive</code> 或者完全禁用，也就是在加固系统配置前先确保集群的安装、配置没问题。用下列命令把 SELinux 设置为 <code>Permissive</code> ：</p><p><code>sudo setenforce 0</code></p><p>要使 SELinux 配置永久生效，需修改其配置文件<code>/etc/selinux/config</code>。</p><h2 id="使用Ansible部署Ceph集群"><a href="#使用Ansible部署Ceph集群" class="headerlink" title="使用Ansible部署Ceph集群"></a>使用Ansible部署Ceph集群</h2><p>使用centos8作为Ansible部署节点，为其他机器安装服务。</p><h3 id="使用ceph-ansible来部署集群"><a href="#使用ceph-ansible来部署集群" class="headerlink" title="使用ceph-ansible来部署集群"></a>使用ceph-ansible来部署集群</h3><p>在centos8机器上执行 <code>yum install ceph-ansible -y</code></p><p>复制ceph-ansible目录到家目录下 <code>cp -r /usr/share/ceph-ansible /home/student/ &amp;&amp; cd /home/student/ceph-ansible</code></p><h4 id="配置ansible-cfg-vim-ansible-cfg"><a href="#配置ansible-cfg-vim-ansible-cfg" class="headerlink" title="配置ansible.cfg vim ansible.cfg"></a>配置ansible.cfg <code>vim ansible.cfg</code></h4><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[defaults]</span></span><br><span class="line"><span class="attr">inventory</span> = ./inventory</span><br><span class="line"><span class="comment"># 因为该Ansible脚本目前比较老，脚本中使用的语法在新版本的Ansible上运行会有警告提示，提示部分语法即将被弃用。但是目前还可以继续使用，暂时忽略警告即可</span></span><br><span class="line"><span class="attr">deprecation_warnings</span> = <span class="literal">false</span></span><br><span class="line"><span class="attr">ansible_managed</span> = Please do not change this file directly since it is managed by Ansible and will be overwritten</span><br><span class="line"><span class="attr">action_plugins</span> = plugins/actions</span><br><span class="line"><span class="attr">roles_path</span> = ./roles</span><br><span class="line"><span class="attr">log_path</span> = /tmp/ansible.log</span><br><span class="line"></span><br><span class="line"><span class="comment"># Disable them in the context of https://review.openstack.org/#/c/469644</span></span><br><span class="line"><span class="attr">retry_files_enabled</span> = <span class="literal">False</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># This is the default SSH timeout to use on connection attempts</span></span><br><span class="line"><span class="comment"># CI slaves are slow so by setting a higher value we can avoid the following error:</span></span><br><span class="line"><span class="comment"># Timeout (12s) waiting for privilege escalation prompt:</span></span><br><span class="line"><span class="attr">timeout</span> = <span class="number">30</span></span><br><span class="line"></span><br><span class="line"><span class="section">[ssh_connection]</span></span><br><span class="line"><span class="comment"># see: https://github.com/ansible/ansible/issues/11536</span></span><br><span class="line"><span class="attr">control_path</span> = %(directory)s/%%h-%%r-%%p</span><br></pre></td></tr></table></figure><h4 id="配置inventory-vim-inventory"><a href="#配置inventory-vim-inventory" class="headerlink" title="配置inventory vim inventory"></a>配置inventory <code>vim inventory</code></h4><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[mons]</span></span><br><span class="line">server<span class="section">[c:e]</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mgrs]</span></span><br><span class="line">server<span class="section">[c:e]</span></span><br><span class="line"></span><br><span class="line"><span class="section">[osds]</span></span><br><span class="line">server<span class="section">[c:e]</span></span><br></pre></td></tr></table></figure><p>测试一下连通性 <code>ansible all -m ping</code>，返回结果如下：</p><figure class="highlight json"><table><tr><td class="code"><pre><span class="line">vm3 | SUCCESS =&gt; <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;changed&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;failed&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ping&quot;</span><span class="punctuation">:</span> <span class="string">&quot;pong&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line">vm2 | SUCCESS =&gt; <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;changed&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;failed&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ping&quot;</span><span class="punctuation">:</span> <span class="string">&quot;pong&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line">vm1 | SUCCESS =&gt; <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;changed&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;failed&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">false</span></span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ping&quot;</span><span class="punctuation">:</span> <span class="string">&quot;pong&quot;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><h4 id="配置group-vars变量："><a href="#配置group-vars变量：" class="headerlink" title="配置group_vars变量："></a>配置group_vars变量：</h4><h5 id="配置-all-yml-group-vars变量"><a href="#配置-all-yml-group-vars变量" class="headerlink" title="配置 all.yml group_vars变量:"></a>配置 all.yml group_vars变量:</h5><p>拷贝all.yml变量 <code>cp group_vars/all.yml.sample group_vars/all.yml</code></p><p>编辑变量文件 <code>vim group_vars/all.yml</code></p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">fetch_directory:</span> <span class="string">~/ceph-ansible-keys</span></span><br><span class="line"></span><br><span class="line"><span class="attr">ntp_service_enabled:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">ceph_origin:</span> <span class="string">repository</span></span><br><span class="line"></span><br><span class="line"><span class="attr">ceph_repository:</span> <span class="string">rhcs</span></span><br><span class="line"></span><br><span class="line"><span class="attr">ceph_rhcs_version:</span> <span class="string">&quot;3&quot;</span></span><br><span class="line"><span class="attr">ceph_repository_type:</span> <span class="string">&quot;cdn&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">rbd_cache:</span> <span class="string">&quot;true&quot;</span></span><br><span class="line"><span class="attr">rbd_cache_writethrough_until_flush:</span> <span class="string">&quot;false&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">rbd_client_directories:</span> <span class="literal">false</span> <span class="comment"># this will create rbd_client_log_path and rbd_client_admin_socket_path directories with proper permissions</span></span><br><span class="line"></span><br><span class="line"><span class="attr">monitor_interface:</span> <span class="string">eth0</span></span><br><span class="line"></span><br><span class="line"><span class="attr">journal_size:</span> <span class="number">1024</span> <span class="comment"># OSD journal size in MB</span></span><br><span class="line"><span class="attr">public_network:</span> <span class="number">172.25</span><span class="number">.250</span><span class="number">.0</span><span class="string">/24</span></span><br><span class="line"><span class="attr">cluster_network:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; public_network &#125;&#125;</span>&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">ceph_conf_overrides:</span></span><br><span class="line">  <span class="attr">global:</span></span><br><span class="line">    <span class="attr">mon_osd_allow_primary_affinity:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">mon_clock_drift_allowed:</span> <span class="number">0.5</span></span><br><span class="line">    <span class="attr">osd_pool_default_size:</span> <span class="number">2</span></span><br><span class="line">    <span class="attr">osd_pool_default_min_size:</span> <span class="number">1</span></span><br><span class="line">    <span class="attr">mon_pg_warn_min_per_osd:</span> <span class="number">0</span></span><br><span class="line">    <span class="attr">mon_pg_warn_max_per_osd:</span> <span class="number">0</span></span><br><span class="line">    <span class="attr">mon_pg_warn_max_object_skew:</span> <span class="number">0</span></span><br><span class="line">  <span class="attr">client:</span></span><br><span class="line">    <span class="attr">rbd_default_features:</span> <span class="number">1</span></span><br></pre></td></tr></table></figure><h5 id="配置-osds-yml-group-vars变量"><a href="#配置-osds-yml-group-vars变量" class="headerlink" title="配置 osds.yml group_vars变量:"></a>配置 osds.yml group_vars变量:</h5><p>在这里配置OSD存储相关设置</p><p><code>cp group_vars/osds.yml.sample group_vars/osds.yml</code></p><p>先来查看server[c:e]中空闲磁盘的名称，发现在这三台机器中都有/dev/vd[b:d]三块21.5G空闲磁盘未被使用。所以在配置OSD时使用这三台机器的/dev/vd[b:d]空闲磁盘作为OSD存储空间。</p><p><code>ssh ceph@vm1</code></p><p><code>sudo fdisk -l</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Disk /dev/vdb: 21.5 GB, 21474836480 bytes, 41943040 sectors</span><br><span class="line">Units = sectors of 1 * 512 = 512 bytes</span><br><span class="line">Sector size (logical/physical): 512 bytes / 512 bytes</span><br><span class="line">I/O size (minimum/optimal): 512 bytes / 512 bytes</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/vdc: 21.5 GB, 21474836480 bytes, 41943040 sectors</span><br><span class="line">Units = sectors of 1 * 512 = 512 bytes</span><br><span class="line">Sector size (logical/physical): 512 bytes / 512 bytes</span><br><span class="line">I/O size (minimum/optimal): 512 bytes / 512 bytes</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Disk /dev/vdd: 21.5 GB, 21474836480 bytes, 41943040 sectors</span><br><span class="line">Units = sectors of 1 * 512 = 512 bytes</span><br><span class="line">Sector size (logical/physical): 512 bytes / 512 bytes</span><br><span class="line">I/O size (minimum/optimal): 512 bytes / 512 bytes</span><br></pre></td></tr></table></figure><p><code>vim group_vars/osds.yml</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">copy_admin_key: true</span><br><span class="line"></span><br><span class="line">devices:</span><br><span class="line">  - /dev/vdb</span><br><span class="line">  - /dev/vdc</span><br><span class="line">  - /dev/vdd</span><br><span class="line"></span><br><span class="line">osd_scenario: &quot;collocated&quot;</span><br></pre></td></tr></table></figure><h4 id="配置site-yml-Playbook"><a href="#配置site-yml-Playbook" class="headerlink" title="配置site.yml Playbook"></a>配置site.yml Playbook</h4><p><code>cp site.yml.sample site.yml</code></p><h4 id="运行Playbook开始部署"><a href="#运行Playbook开始部署" class="headerlink" title="运行Playbook开始部署"></a>运行Playbook开始部署</h4><p>请确保当前目录在<code>ceph-ansible</code>目录下。</p><p>执行 <code>ansible-playbook site.yml</code> 开始部署Ceph基础集群。</p><p>等待一段时间后Ansible返回执行结束结果，没有机器存在failed则表明配置成功。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">PLAY RECAP ******************************</span><br><span class="line">vm1                    : ok=203  changed=32   unreachable=0    failed=0</span><br><span class="line">vm2                    : ok=185  changed=26   unreachable=0    failed=0</span><br><span class="line">vm3                    : ok=187  changed=27   unreachable=0    failed=0</span><br></pre></td></tr></table></figure><p>之后可以<a href="#%E9%AA%8C%E8%AF%81%E9%83%A8%E7%BD%B2%E7%BB%93%E6%9E%9C">验证部署结果</a></p><h3 id="部署Ceph客户端"><a href="#部署Ceph客户端" class="headerlink" title="部署Ceph客户端"></a>部署Ceph客户端</h3><p>如果要控制Ceph集群，现在只能通过在部署了Ceph集群节点上区管理集群。注意，我们最开始是从centos8上搭建的，那么现在也想要在centos8上部署Ceph客户端以此能够在centos8上就可以控制整个Ceph集群。</p><p>复制group_vars变量 <code>cp group_vars/clients.yml.sample group_vars/clients.yml</code></p><p>编辑复制好的clients.yml变量，开启<code>copy_admin_key</code>即可：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="attr">copy_admin_key:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>编辑inventory主机清单文件，在其中加入clients项。</p><p><code>vim inventory</code></p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line">server<span class="section">[c:e]</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mgrs]</span></span><br><span class="line">server<span class="section">[c:e]</span></span><br><span class="line"></span><br><span class="line"><span class="section">[osds]</span></span><br><span class="line">server<span class="section">[c:e]</span></span><br><span class="line"></span><br><span class="line"><span class="section">[clients]</span></span><br><span class="line">centos8</span><br></pre></td></tr></table></figure><p>运行Playbook：</p><p><code>ansible-playbook site.yml --limit=clients</code></p><p>仅限制运行主机清单中clients组即可！节省时间。</p><blockquote><p>如果一切部署顺利，Playbook执行结束后会在结果处返回failed=0。</p></blockquote><p>现在切换到centos8上的ceph用户，尝试执行<code>ceph -s</code>命令，没有异常的情况下可以正常读取到Ceph集群的信息了。我们没有在centos8上配置OSD或者MON，仅仅是把它作为控制Ceph的客户端，目前centos8具有admin的权限。</p><h3 id="验证部署结果"><a href="#验证部署结果" class="headerlink" title="验证部署结果"></a>验证部署结果</h3><p>现在ssh登陆vm1这台机器上，接下来执行ceph的相关命令来检测刚刚的配置详情。</p><p><code>ssh ceph@vm1</code></p><p><code>ceph -s</code>查看集群概况及状态</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@vm1 ~]$ ceph -s</span><br><span class="line">  cluster:</span><br><span class="line">    id:     ca5c8e66-e427-4adb-86c1-83b0eb5983cb</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 vm1,vm2,vm3</span><br><span class="line">    mgr: vm2(active), standbys: vm1, vm3</span><br><span class="line">    osd: 9 osds: 9 up, 9 in</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:   966 MB used, 169 GB / 170 GB avail</span><br><span class="line">    pgs:</span><br></pre></td></tr></table></figure><p>如果配置成功，此时执行 <code>ceph -s</code> 命令后。可以看到<code>health: HEALTH_OK</code>字样，这表明集群现在是健康的状态。</p><p>输出结果的<code>services</code>中可以看到<code>osd: 9 osds: 9 up, 9 in</code>，表明这三台机器一共9个OSD都在正常的运行着。</p><p>输出结果<code>data</code>中包含<code>usage:   966 MB used, 169 GB / 170 GB avail</code>，可以看得到我们一共有170G的存储空间，目前剩余169GB空间可用，已经使用966MB空间。</p><p>如果此时停止vm1这台机器上的ceph-mon.target服务，会发现集群状态变成了HEALTH_WARN状态。重启ceph-mon.target服务后不久集群状态又会恢复。</p><p>刚刚搭建好了Ceph OSD集群，如果停止掉一个OSD进程看看有什么效果？</p><p>在vm1上使用<code>ceph osd tree</code>查看vm1上osd信息</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-osd-tree-1-2020-07-26.png" alt="ceph-osd-tree-1"></p><p>发现在vm1上运行3个osd进程，分别是osd.0,osd.3,osd.8 。现在我们人为干预宕掉vm1上的osd.3之后看看集群有什么反应。</p><p><code>sudo systemctl stop ceph-osd@8.service</code></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-osd-tree-down-2020-07-26.png" alt="ceph-osd-tree-down-2020-07-26"></p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-s-osd-down-1-2020-07-26.png" alt="ceph-s-osd-down-1-2020-07-26"></p><p>恢复osd.8运行 <code>sudo systemctl start ceph-osd@8.service</code></p><h2 id="使用ceph-deploy搭建集群"><a href="#使用ceph-deploy搭建集群" class="headerlink" title="使用ceph-deploy搭建集群"></a>使用<code>ceph-deploy</code>搭建集群</h2><p>使用<code>ceph-deploy</code>搭建集群前，请确保已经完成<a href="#%E9%83%A8%E7%BD%B2%E5%89%8D%E5%87%86%E5%A4%87">准备工作</a>，并且<a href="#%E5%88%9B%E5%BB%BA%E9%83%A8%E7%BD%B2ceph%E7%9A%84%E7%94%A8%E6%88%B7">创建了一个Ceph集群用户</a></p><h3 id="安装ceph-deploy"><a href="#安装ceph-deploy" class="headerlink" title="安装ceph-deploy"></a>安装<code>ceph-deploy</code></h3><p>注意：如果是在Centos8上，要开启epel源。这里是用阿里的镜像源加速。</p><p><code>wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo</code></p><p><code>yum install ceph-deploy</code></p><h3 id="配置Ceph国内源"><a href="#配置Ceph国内源" class="headerlink" title="配置Ceph国内源"></a>配置Ceph国内源</h3><p><code>vim /etc/yum.repos.d/ceph.repo</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph]</span><br><span class="line">name=Ceph packages for $basearch</span><br><span class="line">baseurl=http://mirrors.aliyun.com/ceph/rpm-octopus/el8/$basearch</span><br><span class="line">enabled=1</span><br><span class="line">gpgcheck=1</span><br><span class="line">type=rpm-md</span><br><span class="line">gpgkey=https://download.ceph.com/keys/release.asc</span><br></pre></td></tr></table></figure><blockquote><p>注意：当使用<code>ceph-deploy install</code>的时候，务必这样用：<code>ceph-deploy install –repo-url http://mirrors.aliyun.com/ceph/rpm-octopus/el8/</code> <code>ceph-deploy install centos8 vm1 vm2 vm3</code>（官方的方法是：<code>ceph-deploy install admin-node node1 node2 node3</code>）因为这个ceph-deploy在安装过程中会自动帮你修改repo，所以需要用–repo-url来拒绝这个改动，我安装的是jewel发行版，可根据实际需要修改为最新的</p></blockquote><h2 id="查看安装的Ceph版本"><a href="#查看安装的Ceph版本" class="headerlink" title="查看安装的Ceph版本"></a>查看安装的Ceph版本</h2><p><code>ceph -v</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@vm1 ~]$ ceph -v</span><br><span class="line">ceph version 12.2.1-40.el7cp (c6d85fd953226c9e8168c9abe81f499d66cc2716) luminous (stable)</span><br></pre></td></tr></table></figure><h2 id="使用Cephadm部署集群"><a href="#使用Cephadm部署集群" class="headerlink" title="使用Cephadm部署集群"></a>使用<code>Cephadm</code>部署集群</h2><p>Cephadm通过在单个主机上的引导，再拓展其他的主机加入集群，部署所欲要的服务来达到创建一个新的Ceph集群。</p><p>cephadm使用容器的方式部署Ceph集群，所以需要额外准备以下要求与环境：</p><ul><li>systemd</li><li>Podman或Docker容器支持</li><li>时间同步（NTP）</li><li>用于供应存储设备的LVM2</li></ul><h3 id="安装Cephadm"><a href="#安装Cephadm" class="headerlink" title="安装Cephadm"></a>安装Cephadm</h3><p>cephadm可以引导一个全新的集群，控制容器化下的Ceph集群，以及调试Ceph守护程序。</p><p>如果是RHEL系系统使用yum或dnf即可安装cephadm：</p><p><code>dnf install -y cephadm</code></p><h3 id="引导部署一个全新的集群"><a href="#引导部署一个全新的集群" class="headerlink" title="引导部署一个全新的集群"></a>引导部署一个全新的集群</h3><p>此时，需要知道Ceph集群中提供第一个监视器mon的服务器IP地址。通常来说这是第一台的主机IP，如果有多个网络和接口，应该选择一个确保能连接到所有集群内主机的一个网络接口。</p><p><strong>引导集群</strong></p><p><code>mkdir -p /etc/ceph</code></p><p><code>cephadm bootstrap --mon-ip *&lt;mon-ip&gt;*</code></p><p>执行这条命令后会执行如下操作：</p><ol><li>为本地集群创建监视器和管理器的守护进程</li><li>为集群生成一个新的SSH Key文件并且在<code>/root/.ssh/authorized_keys</code>文件中添加一个root认证用户</li><li>生成一个与新集群通信的最小化配置文件<code>/etc/ceph/ceph.conf</code></li><li>写入Ceph用户认证用户<code>client.admin</code>的密钥环到<code>/etc/ceph/ceph.client.admin.keyring</code></li><li>将公钥副本写入<code>/etc/ceph/ceph.pub</code></li></ol><p>如上，执行引导命令：</p><p><code>cephadm bootstrap --mon-ip 192.168.1.30</code></p><p>完成部署Ceph容器后，会生成如下信息。其中包括了Dashboard的登录地址以及随机生成的用户信息</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">INFO:cephadm:Ceph Dashboard is now available at:</span><br><span class="line"></span><br><span class="line">     URL: https://centos8:8443/</span><br><span class="line">    User: admin</span><br><span class="line">Password: g1ohoef3t9</span><br><span class="line"></span><br><span class="line">INFO:cephadm:You can access the Ceph CLI with:</span><br><span class="line"></span><br><span class="line">sudo /usr/sbin/cephadm shell --fsid c50990c4-d1b9-11ea-9884-000c29c91658 -c /etc/ceph/ceph.conf -k /etc/ceph/ceph.client.admin.keyring</span><br><span class="line"></span><br><span class="line">INFO:cephadm:Please consider enabling telemetry to help improve Ceph:</span><br><span class="line"></span><br><span class="line">ceph telemetry on</span><br><span class="line"></span><br><span class="line">For more information see:</span><br><span class="line"></span><br><span class="line">https://docs.ceph.com/docs/master/mgr/telemetry/</span><br><span class="line"></span><br><span class="line">INFO:cephadm:Bootstrap complete.</span><br></pre></td></tr></table></figure><p>现在一个简单的基础Ceph集群建立完成，接下来会添加其他机器节点并分别部署Ceph任务 。</p><h3 id="使用-Ceph-命令行"><a href="#使用-Ceph-命令行" class="headerlink" title="使用 Ceph 命令行"></a>使用 Ceph 命令行</h3><p>Cephadm并不会在主机上安装任何Ceph软件包，因为它会使用容器管理工具创建容器，将Ceph部署在容器中。那么如果在机器上想要访问Ceph容器并执行Ceph命令的话有如下几种方式可以实现：</p><ul><li><p><code>cephadm shell</code>命令可以在安装了Ceph的容器中启动一个shell。默认情况下，如果在<code>/etc/ceph</code>目录下找到配置文件和密钥环文件，他们就会被传入到Ceph容器环境中，这样可以使用Ceph shell的功能。注意：如果在<code>cephadm shell</code>在部署了MON节点的机器上安装，那么它会使用Ceph MON容器内的配置文件来代替默认默认配置文件。<br><code>cephadm shell</code></p></li><li><p>创建alias别名：<code>alias ceph=&#39;cephadm shell -- ceph&#39;</code><br><code>echo &quot;alias ceph=&#39;cephadm shell -- ceph&#39;&quot; &gt;&gt; /etc/profile.d/colorls.sh</code></p><p><code>source /etc/profile.d/colorls.sh</code></p></li></ul><p>现在可以直接使用<code>ceph</code>命令进行操作：</p><p><code>ceph -v</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">INFO:cephadm:Inferring fsid c50990c4-d1b9-11ea-9884-000c29c91658</span><br><span class="line">INFO:cephadm:Inferring config /var/lib/ceph/c50990c4-d1b9-11ea-9884-000c29c91658/mon.centos8/config</span><br><span class="line">INFO:cephadm:Using recent ceph image docker.io/ceph/ceph:v15</span><br><span class="line">ceph version 15.2.4 (7447c15c6ff58d7fce91843b705a268a1917325c) octopus (stable)</span><br></pre></td></tr></table></figure><p>确认ceph命令可以连接到集群并且可以查看他们的状态：</p><p><code>ceph status</code></p><h3 id="将主机添加到集群"><a href="#将主机添加到集群" class="headerlink" title="将主机添加到集群"></a>将主机添加到集群</h3><p>添加主机到集群中需要两步：</p><ol><li><p>在新主机的root用户的<code>authorized_keys</code>文件中添加添加SSH公钥。</p><p><code>ssh-copy-id -f -i /etc/ceph/ceph.pub root@vm1</code></p><p><code>ssh-copy-id -f -i /etc/ceph/ceph.pub root@vm2</code></p><p><code>ssh-copy-id -f -i /etc/ceph/ceph.pub root@vm3</code></p></li><li><p>告知Ceph集群添加新节点主机：</p><p><code>ceph orch host add vm1</code></p><p><code>ceph orch host add vm2</code></p><p><code>ceph orch host add vm3</code></p></li></ol><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[root@centos8 ~]# ceph orch host add vm3</span><br><span class="line">INFO:cephadm:Inferring fsid c50990c4-d1b9-11ea-9884-000c29c91658</span><br><span class="line">INFO:cephadm:Inferring config /var/lib/ceph/c50990c4-d1b9-11ea-9884-000c29c91658/mon.centos8/config</span><br><span class="line">INFO:cephadm:Using recent ceph image docker.io/ceph/ceph:v15</span><br><span class="line">Added host &#x27;vm3&#x27;</span><br></pre></td></tr></table></figure><h3 id="添加MON监控节点"><a href="#添加MON监控节点" class="headerlink" title="添加MON监控节点"></a>添加MON监控节点</h3><p>一个Ceph集群应该有1、3、5奇数个MON监控节点（投票选举）分布在不同的主机上。如果集群中有5个或以上的主机节点，推荐部署5个MON监控节点。</p><p>当指定给Ceph告知MON监视器使用哪个IP子网时，那么在添加新的集群MON节点时会自动使用该子网自动部署。在默认情况下，Ceph假定其他监视器的子网与集群内第一台监视器MON节点的IP在同一个子网下。</p><p>如果Ceph的mon监视器在单个子网中，cephadm会在添加节点时默认自动的在集群中最多部署5个MON节点，不需要人工干预。</p><ul><li><p>如果你指定MON监视器使用的子网，那么可以执行下面的命令配置：</p><p><code>ceph config set mon public_network 192.168.1.0/24</code></p><p>之后添加的MON节点会自动的在该子网内工作。</p></li><li><p>调整默认的MON监视器数量（默认为5个）：</p><p><code>ceph orch apply mon 3</code></p></li><li><p>指定在一组主机桑拿部署Ceph的mon监视器：</p><p><code>ceph orch apply mon *&lt;host1,host2,host3,...&gt;*</code></p><p><code>ceph orch apply mon vm1,vm2,vm3</code></p><blockquote><p>确保此处mon部署节点中包括了引导节点(本机节点)</p></blockquote></li><li><p>罗列当前集群内的全部主机</p><p><code>ceph orch host ls</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">HOST  ADDR  LABELS  STATUS</span><br><span class="line">vm1   vm1</span><br><span class="line">vm2   vm2</span><br><span class="line">vm3   vm3</span><br></pre></td></tr></table></figure></li><li><p>你可以为某个主机这只标签进行标记，比如在此处就可以编辑合适的标签给刚刚添加的那三台主机。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">orch host label add &lt;hostname&gt; &lt;label&gt;</span><br><span class="line">orch host label rm &lt;hostname&gt; &lt;label&gt;</span><br></pre></td></tr></table></figure><p><code>ceph orch host label add vm1 mon</code></p><p><code>ceph orch host label add vm1 cephadm</code></p><p>添加标签后再重新罗列集群内主机节点：</p><p><code>ceph orch host ls</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">HOST  ADDR  LABELS       STATUS</span><br><span class="line">vm1   vm1   mon cephadm</span><br><span class="line">vm2   vm2   mon</span><br><span class="line">vm3   vm3   mon</span><br></pre></td></tr></table></figure></li></ul><h3 id="添加OSD节点"><a href="#添加OSD节点" class="headerlink" title="添加OSD节点"></a>添加OSD节点</h3><p>显示当前主机集群内主机可用的存储设备列表，添加主机到节点中请参考<a href="#%E5%B0%86%E4%B8%BB%E6%9C%BA%E6%B7%BB%E5%8A%A0%E5%88%B0%E9%9B%86%E7%BE%A4">将主机添加到集群</a>：</p><p><code>ceph orch device ls</code></p><p>在我当亲添加的三台主机中，存储设备列表如下，其中包含了可以用作OSD部署的设备以及他们的容量等基本信息：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">HOST  PATH          TYPE   SIZE  DEVICE                                     AVAIL  REJECT REASONS</span><br><span class="line">vm1   /dev/nvme0n2  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm1   /dev/nvme0n3  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm1   /dev/nvme0n4  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm1   /dev/nvme0n5  ssd   10.0G  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm1   /dev/nvme0n1  ssd   20.0G  VMware Virtual NVMe Disk_VMWare NVME_0000  False  LVM detected, Insufficient space (&lt;5GB) on vgs, locked</span><br><span class="line">vm2   /dev/nvme0n2  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm2   /dev/nvme0n3  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm2   /dev/nvme0n4  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm2   /dev/nvme0n1  ssd   20.0G  VMware Virtual NVMe Disk_VMWare NVME_0000  False  Insufficient space (&lt;5GB) on vgs, locked, LVM detected</span><br><span class="line">vm3   /dev/nvme0n2  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm3   /dev/nvme0n3  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm3   /dev/nvme0n4  ssd   5120M  VMware Virtual NVMe Disk_VMWare NVME_0000  True</span><br><span class="line">vm3   /dev/nvme0n1  ssd   20.0G  VMware Virtual NVMe Disk_VMWare NVME_0000  False  Insufficient space (&lt;5GB) on vgs, locked, LVM detected</span><br></pre></td></tr></table></figure><p>如果满足以下所有条件，则认为存储设备可以部署OSD：</p><ul><li>设备必须没有分区。</li><li>设备不得具有任何LVM状态。</li><li>不得安装设备。</li><li>该设备不得包含文件系统。</li><li>该设备不得包含Ceph BlueStore OSD。</li><li>设备必须大于5GB</li></ul><p><strong>部署OSD节点</strong>：</p><ul><li><p>自动发现可用的存储设备：</p><p><code>ceph orch apply osd --all-available-devices</code></p><p>不过我自己在使用上面这个命令时并没有得到任何输出…</p></li><li><p>在特定主机上创建OSD：</p><p><code>ceph orch daemon add osd *&lt;host&gt;*:*&lt;device-path&gt;*</code></p><p><code>ceph orch daemon add osd vm2:/dev/nvme0n2,/dev/nvme0n2</code></p></li></ul><p>  或者写一个脚本批量添加某一节点上的OSD节点：</p>  <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">for i in 2 3 4</span><br><span class="line">&gt; do</span><br><span class="line">&gt; ceph orch daemon add osd vm3:/dev/nvme0n$i</span><br><span class="line">&gt; done</span><br></pre></td></tr></table></figure><p>查看已添加的Ceph的OSD节点：</p><p><code>ceph osd tree</code></p><p><strong>删除OSD节点</strong></p><p><code>ceph orch osd rm &lt;svc_id&gt;... [--replace] [--force]</code></p><p>如果要删除1234这四个OSD节点则执行下面的命令：</p><p><code>ceph orch osd rm 1 2 3 4</code></p><p>之后可以执行<code>ceph orch osd rm status</code>查询删除状态。当被移除的OSD中没有PG时，则会将它正式的下架。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;搭建Ceph集群&quot;&gt;&lt;a href=&quot;#搭建Ceph集群&quot; class=&quot;headerlink&quot; title=&quot;搭建Ceph集群&quot;&gt;&lt;/a&gt;搭建Ceph集群&lt;/h1&gt;&lt;h2 id=&quot;部署前准备&quot;&gt;&lt;a href=&quot;#部署前准备&quot; class=&quot;headerlink</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>Ceph硬件准备</title>
    <link href="https://blog.yeefire.com/2020_07/ceph_hardware_prepare.html"/>
    <id>https://blog.yeefire.com/2020_07/ceph_hardware_prepare.html</id>
    <published>2020-07-26T11:12:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ceph硬件准备"><a href="#Ceph硬件准备" class="headerlink" title="Ceph硬件准备"></a>Ceph硬件准备</h1><p>大部分的推荐配置来源于<span class="exturl" data-url="aHR0cDovL2RvY3MuY2VwaC5vcmcuY24v" title="http://docs.ceph.org.cn/">http://docs.ceph.org.cn/<i class="fa fa-external-link"></i></span>。</p><p>Ceph为普通硬件设计，这可以让维护构建PB级别的数据集群的费用相对来说更低廉。在搭建集群前最初的硬件架构设计极为重要。你需要均衡几个方面的因素，包括区域实效和潜在的性能问题。硬件规划包含要把使用Ceph集群的Ceph守护进程和其他进程所需要的资源恰当合理分布。</p><p>通常只推荐在一台机器上运行一种类型的守护进程。我们推荐把使用数据集群的进程（如 Openstack、CloudStack等）安装在别的机器上。</p><h2 id="CPU"><a href="#CPU" class="headerlink" title="CPU"></a>CPU</h2><p>Ceph元数据服务器对CPU敏感，他会动态地重分布他们的负载，所以你的元数据服务器应该有足够的处理能力（如4核或更强悍的CPU）。Ceph的OSD运行着RADOS服务，用CRUSH算法计算着数据存放位置、复制数据、维护它自己的集群运行图副本，因此OSD需要一定的处理能力（如双核心CPU）。Ceph监视器只简单地维护者集群运行图的副本，因此对CPU不敏感。</p><p>但是需要考虑是否未来会在Ceph监视器的机器会运行其他的CPU密集型任务。比如运行用于计算的虚拟机（Openstack NOVA），你就要确保给Ceph进程保留足够的处理能力，所以推荐在其他机器上运行CPU密集型任务。</p><h3 id="内存"><a href="#内存" class="headerlink" title="内存"></a>内存</h3><p>元数据服务器和监视器必须尽可能快的提供他们的数据，所以元数据服务器与监视器至少每个进程分配1G内存。</p><p>OSD的日常运行不需要那么多的内存，但是也要确保每个进程能分配到500M的内存，通常来说在进行数据恢复的期间他们占用的内存比较大，每TB级数据需要1GB的内存。</p><p>通常内存越多越好。</p><h2 id="数据存储"><a href="#数据存储" class="headerlink" title="数据存储"></a>数据存储</h2><p>谨慎的规划数据和数据存储架构，因为期间涉及明显的成本和性能折衷。</p><p>来自操作系统的并行操作和到单个硬盘的多个守护进程的并发读写会极大的降低性能。同时文件系统局限性也要考虑，btrfs尚未稳定到可以用于生产环境的程度，但它可以同时记录日志并写入数据，而xfs和ext4不能。</p><blockquote><p>Ceph发送ACK前必须把所有数据写入日志（至少对xfs和ext4来说是），因此均衡日志和OSD性能相当重要。</p></blockquote><h2 id="磁盘驱动器"><a href="#磁盘驱动器" class="headerlink" title="磁盘驱动器"></a>磁盘驱动器</h2><p>OSD应该有足够的空间用于存储对象数据。考虑到大硬盘的没GB成本，建议使用容量大于1TB的硬盘。建议用GB数除以硬盘价格来计算每GB的成本，因为较大的硬盘通常会对每GB成本有较大影响。</p><p>值得注意的是，单个驱动器的容量越大，其对应的OSD进程所需要的内存就越大，特别是在重均衡、回填、恢复期间。1TB的存储空间大约需要1GB内存。</p><blockquote><p>在单个硬盘上运行多个OSD，这样不太妙！<br>在运行了OSD的磁盘上又同时运行着监视器或者云数据服务器这样也不太妙！</p></blockquote><p>磁盘驱动器受限于寻道时间、访问时间、读写时间、还有吞吐量这些磁盘的物理局限影响着整体系统的性能，特别是在出现故障系统恢复期间。因此推荐独立的磁盘用于安装操作系统和软件，避免增加OSD存储磁盘的负担以提升性能。</p><p>Ceph可以在每块硬盘上运行多个OSD，但这会导致资源竞争并降低总体吞吐量；Ceph也允许把日志和对象数据存储在相同的磁盘驱动器上，但这会增加记录写日志并回应客户端的延迟，因为Ceph必须先写入日志才会回应确认了写动作。btrfs文件胸能同时写入日志数据和对象数据，而xfs、etx4不能。</p><p>Ceph最佳实践指示，应该分别在单独的硬盘运行操作系统、OSD和OSD日志。</p><h2 id="固态硬盘"><a href="#固态硬盘" class="headerlink" title="固态硬盘"></a>固态硬盘</h2><p>一种提升性能的方法是使用固态硬盘SSD来降低随机访问时间和读延时，同时增加吞吐量。SSD和硬盘相比每GB的成本通常要高出10倍以上，但访问时间至少比硬盘快100倍！</p><p>SSD没有可移动机械部件，所以不存在和硬盘一样的局限性。但是SSD也有其他的局限性，评估SSD时，<strong>顺序读写</strong>的性能很重要，在为多个OSD存储日志时，有着400MB/s顺序读写吞吐量的SSD性能远高于120MB/s的。</p><blockquote><p>建议发觉SSD的用法来提升性能，在大量投入SSD前，强烈建议核实SSD的性能指标，并在测试环境下衡量性能。相对廉价的SSD虽然价格很诱人，但是要谨慎使用！一分钱一分货的道理是永恒不变的。</p></blockquote><p>正是因为SSD没有移动机械部件，所以它很适合Ceph里不需要太多存储空间的地方。可接受的IOPS指标对选择用于Ceph的SSD还不够，用于日志和SSD时还有几个重要考量：</p><ul><li>写密集语意：写日志数据涉及密集语意，所以要确保选用的SSD写入性能和硬盘相当或者好于硬盘。廉价SSD可能在加速访问的同时引入写延时，有时候高性能的硬盘的写入速度可以和便宜的SSD硬盘相媲美。</li><li>顺序写入：在一个SSD上为多个OSD存储多个日志时也必须考虑SSD的顺序写入极限，因为它们要同时处理多个OSD日志的写入请求。</li><li>分区对齐：采用SSD的一个常见问题是人们喜欢分区，却常常忽略了分区对齐，这会导致SSD的数据传输速率慢很多，所以请确保分区对齐了。</li></ul><p>SSD用于对象存储太昂贵了，但是把OSD的日志存到SSD、把对象数据存储到独立的硬盘可以明显提升性能。osd journal选项的默认值是<code>/var/lib/ceph/osd/$cluster-$id/journal</code>，所以说可以把目录存储的位置更改到SSD磁盘或SSD的分区上，这样它就不再是和对象数据一样存储在同一个硬盘上的文件了。</p><p>提升CephFS文件系统性能的一种方法是从CephFS文件内容中分离出元数据。Ceph提供了默认的metadata存储池来存储CephFS元数据，所以你不需要给CephFS元数据创建存储池，但是可以给它创建一个仅指向某主机SSD的CRUSH运行图。具体详情见<a href="https://blog.yeefire.com/2020_07/ceph_osd_pool_manage.html">OSD与Pool池的常见操作及管理</a></p><h2 id="硬盘控制器"><a href="#硬盘控制器" class="headerlink" title="硬盘控制器"></a>硬盘控制器</h2><p>硬盘控制器也会对吞吐量有显著影响，要谨慎的选择控制器，以免产生性能瓶颈。</p><h2 id="网络"><a href="#网络" class="headerlink" title="网络"></a>网络</h2><p>建议每台机器最少两个千兆网卡，现在大多数的机械硬盘都能达到100MB/s的吞吐量，网卡应该能处理所有的OSD硬盘总吞吐量，所以推荐最少两个千兆网卡分别用于公网和集群网络。集群网络用来处理数据复制产生的额外负载，而且可以防止拒绝服务攻击，拒接服务攻击会干扰数据归置组，使OSD数据复制时不能回到active+clean状态。所以最好考虑使用两个万兆网卡。</p><p>通过 1Gbps 网络复制 1TB 数据耗时 3 小时，而 3TB （典型配置）需要 9 小时，相比之下，如果使用 10Gbps 复制时间可分别缩减到 20 分钟和 1 小时。在一个 PB 级集群中， OSD 磁盘失败是常态，而非异常；在性价比合理的的前提下，系统管理员想让 PG 尽快从 degraded （降级）状态恢复到 active + clean 状态。</p><p>增加的硬件成本可用节省的运营（网络安装、维护）成本抵消。使用 VLAN 来处理集群和计算栈（如 OpenStack 、 CloudStack 等等）之间的 VM 流量时，采用 10G 网卡仍然值得。每个网络的机架路由器到核心路由器应该有更大的带宽，如 40Gbps 到 100Gbps 。</p><h2 id="其他要注意的点"><a href="#其他要注意的点" class="headerlink" title="其他要注意的点"></a>其他要注意的点</h2><p>可以在同一台主机上运行多个OSD，但是要确保OSD硬盘总吞吐量不超过客户端提供读写服务所需的网络带宽；还要考虑集群在每台主机上所存储的数据占总体的百分比，如果一台主机所占百分比太大而它宕机了，就可能导致诸如超过full ratio的问题，此问题会使Ceph中止运作以防止数据丢失。</p><p>保证内核是最新的，确保硬件性能可以达到期望值。</p><p>OSD数量比较多的主机会产生大量OSD线程，尤其是在恢复和重均匀期间。很多Linux内核默认的最大线程数较小（如 32K 个），如果遇到了这类问题，可以把<code>kernel.pid_max</code> 值调高些。理论最大值是 4194303 。例如把下列这行加入 <code>/etc/sysctl.conf</code> 文件：</p><p><code>kernel.pid_max = 4194303</code></p><h2 id="故障域"><a href="#故障域" class="headerlink" title="故障域"></a>故障域</h2><p>故障域指任何导致不能访问一个或多个 OSD 的故障，可以是主机上停止的进程、硬盘故障、操作系统崩溃、有问题的网卡、损坏的电源、断网、断电等等。规划硬件需求时，要在多个需求间寻求平衡点，像付出很多努力减少故障域带来的成本削减、隔离每个潜在故障域增加的成本。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ceph硬件准备&quot;&gt;&lt;a href=&quot;#Ceph硬件准备&quot; class=&quot;headerlink&quot; title=&quot;Ceph硬件准备&quot;&gt;&lt;/a&gt;Ceph硬件准备&lt;/h1&gt;&lt;p&gt;大部分的推荐配置来源于&lt;span class=&quot;exturl&quot; data-url=&quot;aHR0</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>OSD与Pool池的常见操作及管理</title>
    <link href="https://blog.yeefire.com/2020_07/ceph_osd_pool_manage.html"/>
    <id>https://blog.yeefire.com/2020_07/ceph_osd_pool_manage.html</id>
    <published>2020-07-26T11:10:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="OSD与Pool池的常见操作及管理"><a href="#OSD与Pool池的常见操作及管理" class="headerlink" title="OSD与Pool池的常见操作及管理"></a>OSD与Pool池的常见操作及管理</h1><h2 id="查看osd状态"><a href="#查看osd状态" class="headerlink" title="查看osd状态"></a>查看osd状态</h2><h3 id="ceph-s"><a href="#ceph-s" class="headerlink" title="ceph -s"></a>ceph -s</h3><p>通过ceph -s可以查看集群的概况，其中包括了部分osd相关的健康信息。</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-s-osd-down-1-2020-07-26.png" alt="ceph-s-osd-down-1-2020-07-26"></p><h3 id="ceph-osd-stat"><a href="#ceph-osd-stat" class="headerlink" title="ceph osd stat"></a>ceph osd stat</h3><p><code>ceph osd stat</code>可以验证当前集群内的状态。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph osd stat</span><br><span class="line">9 osds: 9 up, 9 in</span><br></pre></td></tr></table></figure><p>当前集群内共有9个OSD，目前这9个OSD的状态均为OK！</p><h3 id="ceph-osd-tree"><a href="#ceph-osd-tree" class="headerlink" title="ceph osd tree"></a>ceph osd tree</h3><p><code>ceph osd tree</code> 显示所有的OSD列表</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-osd-tree-1-2020-10-23.png" alt="ceph-osd-tree-1-2020-10-23"></p><p>在ID列，可以看到每一个OSD的ID均为正数，并且每个OSD的ID顺序是打乱、分散的。3台机器共9个OSD的ID被随机分配了。</p><p>值得注意的点是所有的主机和集群也被进行了ID编号，只不过它们的编号为负数。</p><h3 id="ceph-osd-df"><a href="#ceph-osd-df" class="headerlink" title="ceph osd df"></a>ceph osd df</h3><p>如果要查看每个OSD的使用情况以及数据所占用OSD空间的百分比，可以使用<code>ceph osd df</code>命令查看。</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-osd-df-1-2020-07-26.png" alt="ceph-osd-df-1-2020-07-26"></p><h3 id="删除Pool"><a href="#删除Pool" class="headerlink" title="删除Pool"></a>删除Pool</h3><p><code>ceph osd pool delete rbd rbd --yes-i-really-really-mean-it</code></p><p>想要删除一个Pool你需要按照上面的格式进行确认，但是即便是一再确认，默认情况下MON节点还是不允许你删除Pool池。会提示<code>Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool</code>。</p><p>那么有下面两种方式可以删除Pool：</p><h4 id="修改MON配置文件"><a href="#修改MON配置文件" class="headerlink" title="修改MON配置文件"></a>修改MON配置文件</h4><p>修改配置文件，在配置文件中标记允许删除Pool，这样在重启集群所有的MON节点后会重新读取到这条配置文件，在删除Pool的时候不会进行阻拦。</p><p><code>vim /etc/ceph/ceph.conf</code></p><p>在<strong>所有的</strong>MON节点下的配置文件中添加下面的配置：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[mon]</span><br><span class="line">mon allow pool delete = true</span><br></pre></td></tr></table></figure><p>修改后保存设置，重启集群内<strong>所有的MON节点服务</strong>。</p><p>之后执行<code>ceph osd pool delete rbd rbd --yes-i-really-really-mean-it</code>就可以删除掉。</p><p>这种方式要登录到所有的MON节点机器中修改配置，并且需要重启MON节点服务，如果你是单节点集群或者对集群的稳定性有严格需求，这种方式不太友好。</p><h4 id="使用ceph-tell运行时注入配置"><a href="#使用ceph-tell运行时注入配置" class="headerlink" title="使用ceph tell运行时注入配置"></a>使用<code>ceph tell</code>运行时注入配置</h4><p>Ceph支持运行时注入配置，那么可以进行下面的操作：</p><p><code>ceph tell mon.* injectargs --mon_allow_pool_delete true</code></p><p>之后会看到输出：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">mon.vm1: &#123;&#125;</span><br><span class="line">mon.vm2: &#123;&#125;</span><br><span class="line">mon.vm3: &#123;&#125;</span><br><span class="line">mon.vm1: mon_allow_pool_delete = &#x27;true&#x27;</span><br><span class="line">mon.vm2: mon_allow_pool_delete = &#x27;true&#x27;</span><br><span class="line">mon.vm3: mon_allow_pool_delete = &#x27;true&#x27;</span><br></pre></td></tr></table></figure><p>此时执行<code>ceph osd pool delete rbd rbd --yes-i-really-really-mean-it</code>就可以删除掉刚才不能删除的Pool。</p><h2 id="Pool池"><a href="#Pool池" class="headerlink" title="Pool池"></a>Pool池</h2><p>Pool是一个抽象的存储池，它是PG之上的一层逻辑。它规定了数据冗余的类型以及对应的副本分布策略。</p><p>目前有两种pool类型：replicated类型和Erasure Code类型。</p><ul><li>一个pool由多个PG构成，一个PG只能属于一个Pool</li><li>同一个Pool中的PG具有相同的类型，比如，如Pool为副本类型，则Pool中所有的PG都是多副本的</li></ul><blockquote><p>注意：在ceph 12.2.1(luminous)版本中，目前还不支持缩减PG、PGP数量，但是可以增加它们的数量，这适用于OSD存储节点的扩容，但是却不利于缩减OSD存储节点……<br>不过在</p></blockquote><h3 id="创建副本Pool"><a href="#创建副本Pool" class="headerlink" title="创建副本Pool"></a>创建副本Pool</h3><p>使用副本Pool时，每个对象都会被复制到n个osd上进行存储。复制几份由pool的size属性决定，默认情况下会有3个副本，在生产环境下应该至少存在3个副本才可以保证数据可靠性。</p><p><code>ceph osd pool create &lt;poolname&gt; &lt;int[0-]&gt; &#123;&lt;int[0-]&gt;&#125; &#123;replicated|erasure&#125; &#123;&lt;erasure_code_profile&gt;&#125; &#123;&lt;rule&gt;&#125; &#123;&lt;int&gt;&#125;</code></p><p>现在来创建一个名字叫rbd的Pool，使用默认的<code>replicated</code>模式创建并且默认的副本数量为3，将它的PG和PGP数量设置为64。</p><p><code>ceph osd pool create rbd 64 64</code></p><h3 id="创建纠删码Pool"><a href="#创建纠删码Pool" class="headerlink" title="创建纠删码Pool"></a>创建纠删码Pool</h3><p>使用纠删码Pool可以减少副本的磁盘占用并且能与副本Pool得到同等的数据保护效果。它可以减少集群为了保护数据而而外付出的存储开销。</p><p>不过使用纠删码虽然与副本类型相比会减少很多存储空间，但是需要对数据进行较多的运算。在回复数据时会占用大量的计算资源如CPU、内存。</p><p>创建一个名字为reapool的PG、PGP数为50的纠删码类型Pool：</p><p><code>ceph osd pool create reapool 50 50 erasure</code></p><p>纠删码由配置定义，在创建纠删码存储池及其相关的 CRUSH 规则时用到。</p><p>创建 Ceph 集群时初始化的、名为 default 的纠删码配置可提供与两副本相同的冗余水平，却能节省 25% 的磁盘空间。在此配置中 k=2 和 m=1 ，其含义为数据分布于 3 个 OSD （ k+m==3 ）且允许一个失效。</p><p>为了在不增加原始存储空间需求的前提下提升冗余性，你可以新建配置。例如，一个 k=10 且 m=4 的配置可容忍 4 个 OSD 失效，它会把一对象分布到 14 个（ k+m=14 ） OSD 上。此对象先被分割为 10 块（若对象为 10MB ，那每块就是 1MB ）、并计算出 4 个用于恢复的编码块（各编码块尺寸等于数据块，即 1MB ）；这样，原始空间仅多占用 10% 就可容忍 4 个 OSD 同时失效、且不丢失数据。</p><p>详见<a href="#%E6%9B%B4%E6%94%B9%E5%89%AF%E6%9C%AC%E6%95%B0%E7%BA%A0%E5%88%A0%E7%A0%81%E4%B8%AA%E6%95%B0">修改纠删码副本及冗余数量</a></p><h3 id="管理和操作Pool"><a href="#管理和操作Pool" class="headerlink" title="管理和操作Pool"></a>管理和操作Pool</h3><h4 id="为Pool设置应用"><a href="#为Pool设置应用" class="headerlink" title="为Pool设置应用"></a>为Pool设置应用</h4><p>在创建一个pool之后，你应该把这个pool分配一个application对这个pool进行标记。可以设置的应用有<code>cephfs</code>、<code>rbd</code>、<code>rgw</code>。</p><p><code>ceph osd pool application enable &lt;poolname&gt; &lt;app&gt;</code></p><p>现在将刚刚创建名字为<code>rbd</code>这个Pool设置为用于rbd应用。</p><p><code>ceph osd pool application enable rbd rbd</code></p><p>在没有设置应用之前，使用<code>ceph -s</code>查看集群状态可能会有警告提示。设置之后再次查询，警告消失。</p><p><code>ceph -s</code> 或 <code>ceph health detail</code></p><p>通过<code>eph osd pool application get rbd</code>命令查看application发现已激活rbd应用在这个pool上。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph osd pool application get rbd</span><br><span class="line">&#123;</span><br><span class="line">    &quot;rbd&quot;: &#123;&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h4 id="查看Pool信息"><a href="#查看Pool信息" class="headerlink" title="查看Pool信息"></a>查看Pool信息</h4><p>查看集群内的Pool</p><p><code>ceph osd lspools</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph osd lspools</span><br><span class="line">7 rbd,8 testpool,</span><br></pre></td></tr></table></figure><p><code>ceph osd pool ls</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph osd pool ls</span><br><span class="line">rbd</span><br><span class="line">testpool</span><br></pre></td></tr></table></figure><p>查看集群内Pool的资源使用情况</p><p><code>ceph df</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph df</span><br><span class="line">GLOBAL:</span><br><span class="line">    SIZE     AVAIL     RAW USED     %RAW USED</span><br><span class="line">    170G      169G        1071M          0.61</span><br><span class="line">POOLS:</span><br><span class="line">    NAME         ID     USED     %USED     MAX AVAIL     OBJECTS</span><br><span class="line">    rbd          7         0         0        82552M           0</span><br><span class="line">    testpool     8         0         0        82552M           0</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>查看每个OSD资源使用情况</p><p><code>ceph osd df</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph osd df</span><br><span class="line">ID CLASS WEIGHT  REWEIGHT SIZE   USE   AVAIL  %USE VAR  PGS</span><br><span class="line"> 0   hdd 0.01849  1.00000 19444M  117M 19327M 0.61 0.99 197</span><br><span class="line"> 3   hdd 0.01849  1.00000 19444M  117M 19327M 0.61 0.99 213</span><br><span class="line"> 8   hdd 0.01849  1.00000 19444M  117M 19327M 0.60 0.99 204</span><br><span class="line"> 2   hdd 0.01849  1.00000 19444M  127M 19317M 0.66 1.08 206</span><br><span class="line"> 4   hdd 0.01849  1.00000 19444M  117M 19327M 0.61 0.99 185</span><br><span class="line"> 6   hdd 0.01849  1.00000 19444M  117M 19327M 0.60 0.99 205</span><br><span class="line"> 1   hdd 0.01849  1.00000 19444M  117M 19327M 0.61 0.99 181</span><br><span class="line"> 5   hdd 0.01849  1.00000 19444M  117M 19327M 0.60 0.99 200</span><br><span class="line"> 7   hdd 0.01849  1.00000 19444M  117M 19327M 0.60 0.99 209</span><br><span class="line">                    TOTAL   170G 1068M   169G 0.61</span><br><span class="line">MIN/MAX VAR: 0.99/1.08  STDDEV: 0.02</span><br></pre></td></tr></table></figure><p>查看Pool当前执行的任务，可以使用<code>ceph osd pool stats</code>来查看Pool当前正在执行的任务和写入、读取速度。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph osd pool stats</span><br><span class="line">pool rbd id 7</span><br><span class="line">  nothing is going on</span><br><span class="line"></span><br><span class="line">pool testpool id 8</span><br><span class="line">  nothing is going on</span><br></pre></td></tr></table></figure><h4 id="重命名Pool"><a href="#重命名Pool" class="headerlink" title="重命名Pool"></a>重命名Pool</h4><p>你可以使用<code>ceph osd pool rename</code>命令重新命名你不满意的名字。</p><p><code>osd pool rename &lt;current_poolname&gt; &lt;new_poolname&gt;</code></p><h4 id="对Pool进行快照"><a href="#对Pool进行快照" class="headerlink" title="对Pool进行快照"></a>对Pool进行快照</h4><p>你可以创建或者删除一个Pool的快照。</p><p><code>ceph osd pool mksnap/rmsnap &lt;poolname&gt; &lt;snap&gt;</code></p><p>对当前的<code>rbd</code>Pool进行创建快照操作：</p><p><code>ceph osd pool mksnap rbd rbd@snap-20200721</code></p><p>查看该Pool中创建的Pool快照：</p><p><code>rados lssnap -p rbd</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ rados lssnap -p rbd</span><br><span class="line">1       rbd@snap-20200721       2020.07.21 15:26:39</span><br><span class="line">1 snaps</span><br></pre></td></tr></table></figure><p>删除刚刚创建的快照：</p><p><code>ceph osd pool rmsnap rbd rbd@snap-20200721</code></p><p>还原快照：</p><p><code>rados -p &lt;poolname&gt; rollback &lt;obj-name&gt; &lt;snap-name&gt;</code></p><p><code>rados -p &lt;poolname&gt; -s &lt;snap-name&gt; get &lt;obj-name&gt; file</code></p><blockquote><p>Ceph支持两种类型的快照，一种是pool snaps，也就是Pool级别的快照，是给整个pool中的对象整体做一个快照。另一个是self managed snaps，rbd使用的就是这种类型的快照。<br>要注意的是：这两种快照类型是互斥的，不能同时存在。如果你要是用Pool快照那么默认情况下就不能在这个Pool下创建RBD了。</p></blockquote><h4 id="更改Pool参数"><a href="#更改Pool参数" class="headerlink" title="更改Pool参数"></a>更改Pool参数</h4><p>对Pool进行调整可以设置副本数、纠删码份数，还可以限制该Pool所使用的资源大小等。</p><p><code>ceph osd pool set &lt;poolname&gt; &lt;parameter&gt; &lt;value&gt;</code></p><h5 id="限制Pool所用资源数量"><a href="#限制Pool所用资源数量" class="headerlink" title="限制Pool所用资源数量"></a>限制Pool所用资源数量</h5><p>管理员可以对Pool设置限额(quotas)来限制最大使用的存储量和对象(object)数量。</p><p><code>ceph osd pool set-quota &lt;poolname&gt; max_objects|max_bytes &lt;val&gt;</code></p><p>限制<code>rbd</code>Pool最大仅能使用1GB存储空间：</p><p><code>ceph osd pool set-quota rbd max_bytes 1073741824</code></p><h5 id="更改副本数-纠删码个数"><a href="#更改副本数-纠删码个数" class="headerlink" title="更改副本数/纠删码个数"></a>更改副本数/纠删码个数</h5><p><strong>修改副本数</strong></p><p>在实际生产环境中副本数通常在3个或以上。默认的副本数是两个，不过保险起见生产环境下应越多越保险。</p><p><code>ceph osd pool set rbd size 3</code></p><p><strong>修改纠删码副本及冗余数量</strong></p><p>使用纠删码创建的Pool可以配置纠删码算法及相应规则，你可以自己新建一个纠删码规则适用于当前的业务需求。</p><p>和副本模式相比纠缠码可以大幅减少存储成本，但当集群内的其他OSD遇到数据盘损坏时会重新计算丢失的数据。这会对计算资源和网络资源造成较大的负担！</p><p>合理的配置纠删码文件可以带来更好的效率。</p><p>使用<code>ceph osd erasure-code-profile get default</code>查看创建一个纠删码模式的Pool时默认的的配置信息。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">k=2</span><br><span class="line">m=1</span><br><span class="line">plugin=jerasure</span><br><span class="line">technique=reed_sol_van</span><br></pre></td></tr></table></figure><ul><li>k 对对象分割的数量，k=2为默认值。对一个对象分割成两部分。</li><li>m 纠删码数量，默认m=1。假如k=2时，一个对象文件被分割成了两份存在了不同的OSD上，此时有一个OSD坏掉了的话通过纠删码就可以计算出坏掉的那个OSD磁盘中的数据。</li></ul><p><strong>创建一个新的纠删码配置</strong></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ceph osd erasure-code-profile <span class="built_in">set</span> &#123;name&#125; \</span><br><span class="line">     [&#123;directory=directory&#125;] \</span><br><span class="line">     [&#123;plugin=plugin&#125;] \</span><br><span class="line">     [&#123;stripe_unit=stripe_unit&#125;] \</span><br><span class="line">     [&#123;key=value&#125; ...] \</span><br><span class="line">     [--force]</span><br></pre></td></tr></table></figure><ul><li>directory 设置纠删码插件的路径，需是目录。</li><li>plugin 指定纠删码插件来计算编码块、及恢复丢失块。</li><li>stripe_unit 每一个条带中、一个数据块的数据量。例如，在一个配置中，数据块为 2 且 stripe_unit=4K ，数据进来时会把 0-4K 放入块 0 ， 4K-8K 放入块 1 ；然后 8K-12K 又是块 0 。为实现最佳性能，这里应该设置成 4K 的倍数。默认值是在存储池创建时从监视器配置选项 osd_pool_erasure_code_stripe_unit 获取的。一个使用着这个配置的存储池，其 stripe_width 值（条带宽度）就是数据块的数量乘以这里的 stripe_unit 值。</li><li>key 纠删码插件所定义的键/值对含义。</li></ul><p>创建一个k=6,m=3的纠删码配置文件:</p><p><code>ceph osd erasure-code-profile set test k=6 m=3</code></p><p>查看test纠删码配置信息</p><p><code>ceph osd erasure-code-profile get test</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ ceph osd erasure-code-profile get test</span><br><span class="line">crush-device-class=</span><br><span class="line">crush-failure-domain=host</span><br><span class="line">crush-root=default</span><br><span class="line">jerasure-per-chunk-alignment=false</span><br><span class="line">k=6</span><br><span class="line">m=3</span><br><span class="line">plugin=jerasure</span><br><span class="line">technique=reed_sol_van</span><br><span class="line">w=8</span><br></pre></td></tr></table></figure><p>创建一个新的纠删码类型Pool并使用刚刚创建的test纠删码配置进行创建。</p><p><code>ceph osd pool create erasurepool 10 10 erasure test</code></p><p>查看Pool信息</p><p><code>ceph osd pool ls detail</code></p><p><code>pool 12 &#39;erasurepool&#39; erasure size 9 min_size 7 crush_rule 2 object_hash rjenkins pg_num 10 pgp_num 10 last_change 618 flags hashpspool stripe_width 24576</code></p><h3 id="删除Pool-1"><a href="#删除Pool-1" class="headerlink" title="删除Pool"></a>删除Pool</h3><p><code>ceph osd pool delete rbd rbd --yes-i-really-really-mean-it</code></p><p>想要删除一个Pool你需要按照上面的格式进行确认，但是即便是一再确认，默认情况下MON节点还是不允许你删除Pool池。会提示<code>Error EPERM: pool deletion is disabled; you must first set the mon_allow_pool_delete config option to true before you can destroy a pool</code>。</p><p>那么有下面两种方式可以删除Pool：</p><h4 id="修改MON配置文件-1"><a href="#修改MON配置文件-1" class="headerlink" title="修改MON配置文件"></a>修改MON配置文件</h4><p>修改配置文件，在配置文件中标记允许删除Pool，这样在重启集群所有的MON节点后会重新读取到这条配置文件，在删除Pool的时候不会进行阻拦。</p><p><code>vim /etc/ceph/ceph.conf</code></p><p>在<strong>所有的</strong>MON节点下的配置文件中添加下面的配置：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[mon]</span><br><span class="line">mon allow pool delete = true</span><br></pre></td></tr></table></figure><p>修改后保存设置，重启集群内<strong>所有的MON节点服务</strong>。</p><p>之后执行<code>ceph osd pool delete rbd rbd --yes-i-really-really-mean-it</code>就可以删除掉。</p><p>这种方式要登录到所有的MON节点机器中修改配置，并且需要重启MON节点服务，如果你是单节点集群或者对集群的稳定性有严格需求，这种方式不太友好。</p><h4 id="使用ceph-tell运行时注入配置-1"><a href="#使用ceph-tell运行时注入配置-1" class="headerlink" title="使用ceph tell运行时注入配置"></a>使用<code>ceph tell</code>运行时注入配置</h4><p>Ceph支持运行时注入配置，那么可以进行下面的操作：</p><p><code>ceph tell mon.* injectargs --mon_allow_pool_delete true</code></p><p>之后会看到输出：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">mon.vm1: &#123;&#125;</span><br><span class="line">mon.vm2: &#123;&#125;</span><br><span class="line">mon.vm3: &#123;&#125;</span><br><span class="line">mon.vm1: mon_allow_pool_delete = &#x27;true&#x27;</span><br><span class="line">mon.vm2: mon_allow_pool_delete = &#x27;true&#x27;</span><br><span class="line">mon.vm3: mon_allow_pool_delete = &#x27;true&#x27;</span><br></pre></td></tr></table></figure><p>此时执行<code>ceph osd pool delete rbd rbd --yes-i-really-really-mean-it</code>就可以删除掉刚才不能删除的Pool。</p><h3 id="Pool命名空间"><a href="#Pool命名空间" class="headerlink" title="Pool命名空间"></a>Pool命名空间</h3><p>命名空间是Pool池的逻辑组。可以设置一个命名空间限制个个用户能访问到该Pool的范围，限制用户只访问到该Pool的部分范围。当然也可以按照不同应用应用的方式进行分组。</p><p>要存储一个对象到命名空间时客户端需要指明Pool和命名空间。</p><p>默认情况下每个Pool包括一个孔明成的命名空间作为默认的命名空间使用。</p><h4 id="放置对象到命名空间"><a href="#放置对象到命名空间" class="headerlink" title="放置对象到命名空间"></a>放置对象到命名空间</h4><p>使用rados命令可以将Object对象放置在Pool上的指定命名空间内。</p><p><code>rados -p &lt;poolname&gt; [-N &lt;namespace&gt;] put &lt;obj-name&gt; [infile] [--offset offset]</code></p><p><code>rados -p rbd -N system put release /etc/redhat-release</code></p><p>上面这个命令是将<code>/etc/redhat-release</code>这个文件放在了rbd存储池的system命名空间里，并且文件名为<code>release</code>。</p><h4 id="列出命名空间内的对象"><a href="#列出命名空间内的对象" class="headerlink" title="列出命名空间内的对象"></a>列出命名空间内的对象</h4><p><code>rados -p &lt;poolname&gt; [-N &lt;namespace&gt;] ls [--all]</code></p><p>列出rbd存储池中system命名空间下的对象：</p><p><code>rados -p rbd -N system ls</code></p><p>返回列表如下，返回的这些object都是属于system这个命名空间下的对象。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">services-name</span><br><span class="line">release</span><br></pre></td></tr></table></figure><p>不过，在不指明命名空间的情况下，只能看得到默认命名空间里的对象，如果要显示出该Pool内全部命名空间的对象的话如何操作？</p><p><code>rados -p rbd ls --all</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">system  services-name</span><br><span class="line">system  release</span><br><span class="line">        release</span><br></pre></td></tr></table></figure><p>这样就可以显示出全部命名空间里的对象名称了，那么没有名字的release对象就是存放在默认的命名空间下。</p><p>还可以以JSON的格式进行输出：</p><p><code>rados -p rbd ls --all --format=json | python -m json.tool</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@servera ~]$ rados -p rbd ls --all --format=json | python -m json.tool</span><br><span class="line">[</span><br><span class="line">    &#123;</span><br><span class="line">        &quot;name&quot;: &quot;services-name&quot;,</span><br><span class="line">        &quot;namespace&quot;: &quot;system&quot;</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        &quot;name&quot;: &quot;release&quot;,</span><br><span class="line">        &quot;namespace&quot;: &quot;system&quot;</span><br><span class="line">    &#125;,</span><br><span class="line">    &#123;</span><br><span class="line">        &quot;name&quot;: &quot;release&quot;,</span><br><span class="line">        &quot;namespace&quot;: &quot;&quot;</span><br><span class="line">    &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;OSD与Pool池的常见操作及管理&quot;&gt;&lt;a href=&quot;#OSD与Pool池的常见操作及管理&quot; class=&quot;headerlink&quot; title=&quot;OSD与Pool池的常见操作及管理&quot;&gt;&lt;/a&gt;OSD与Pool池的常见操作及管理&lt;/h1&gt;&lt;h2 id=&quot;查看osd</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>Ceph用户管理</title>
    <link href="https://blog.yeefire.com/2020_07/ceph_user_manage.html"/>
    <id>https://blog.yeefire.com/2020_07/ceph_user_manage.html</id>
    <published>2020-07-26T11:10:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ceph用户管理"><a href="#Ceph用户管理" class="headerlink" title="Ceph用户管理"></a>Ceph用户管理</h1><p>本文档叙述了Ceph客户端的用户身份，以及Ceph存储集群的认证和授权。用户可以是个人或是系统角色（像应用程序），它们用Ceph客户端和Ceph服务器守护进程进行交互。</p><p><img src="https://cdn.yeefire.com/hexo/img/ceph-user-auth-2020-07-26.png" alt="ceph-user-auth-2020-07-26"></p><p>当Ceph开启用户认证时（默认开启），你必须指定一个用户名和密钥环来证明一个用户认证通过后才可以对Ceph进行相关操作。如果不指明用户名和密钥环，Ceph将会使用client.admin作为用户名，通过查找Ceph keyring设置搜索名称匹配的密钥环。</p><p>假如我们执行<code>ceph health</code>命令时没有指明任何用户名和密钥环文件存放地址。那么Ceph会自动的将其解析为如下命令并执行：</p><p><code>ceph -n client.admin --keyring=/etc/ceph/ceph.client.admin.keyring health</code>。</p><p>另外也可以用<code>CEPH_ARGS</code>环境变量来避免多次输入用户名和密钥。</p><h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>不论Ceph是从块设备、对象存储、文件系统、还是API中接收数据，最后都会将它们作为对象存储在Pool池中。</p><p>Ceph用户必须有权访问池才能读取和写入数据。此外，Ceph用户还应该具有执行权限才能使用Ceph的管理命令。下面的更多概念将会帮助了解Ceph用户管理。</p><h3 id="用户"><a href="#用户" class="headerlink" title="用户"></a>用户</h3><p>一个用户可以是一个个体，也可以是一个应用程序。通过创建用户，您可以控制哪些人（或什么人）可以访问您的Ceph存储集群以及Pool池中的数据。</p><p>Ceph有一个<code>type</code>的用户观念，这是出于用户管理的目的，类型总是<code>client</code>，并且以(.)分割标识不同的用户，以<code>Type.ID</code>这种形式表现。例如<code>client.admin</code>或<code>client.user1</code>。</p><p>区分用户类型有助于区分客户端和其他用户的访问控制，更方便的进行用户监控和可追溯用户。</p><p>有时候Ceph的用户type类型会让你感到很迷惑，因为既可以指定Type来执行Ceph命令，也可以只使用用户名来进行访问。其实这取决于执行Ceph命令行时所使用的选项。当你使用<code>--user</code>或者 <code>--id</code>来指明一个用户时，此时<code>client.user1</code>可以省略为<code>user1</code>。如果使用<code>--name</code>或<code>-n</code>来指定用户时，你就必须要加上Type类型了。</p><p>推荐使用<code>--name</code>或<code>-n</code>提供Type类型和名称的方式进行用户访问。</p><h3 id="授权"><a href="#授权" class="headerlink" title="授权"></a>授权</h3><p>Ceph用能力(capabilities,caps)这个term术语来描述给某个已认证用户的授权。有一定权限后才可以使用mon、osd和元数据服务器等功能。能力也用于限制对一存储池内的数据、存储池内命名空间、或由应用标签所标识的一系列存储池的访问。</p><p>Ceph管理用户可以在创建或更新某一用户时赋予、更新他的能力。</p><p>能力的语法符合下面的形式：</p><p><code>&#123;daemon-type&#125; &#39;&#123;cap-spec&#125;[, &#123;cap-spec&#125; ...]&#39;</code></p><ul><li><p>mon 监视器能力：监视器能力包括r 、 w 、 x 访问选项或 <code>profile &#123;name&#125;</code>，例如:</p>  <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">mon &#x27;allow &#123;access-spec&#125; [network &#123;network/prefix&#125;]&#x27;</span><br><span class="line">mon &#x27;profile &#123;name&#125;&#x27;</span><br></pre></td></tr></table></figure><p>  {access-spec} 语法如下：</p><p>  <code>* | all | [r][w][x]</code></p><p>  可选项 <code>&#123;network/prefix&#125;</code> 是个标准网络名和前缀长度（ CIDR 表示法，如 10.3.0.0/16 ）。如果设置了，此能力就仅限于从这个网络连接过来的客户端。</p></li><li><p>OSD 能力：OSD能力包括 r 、 w 、 x 、 class-read 、 class-write 访问选项和 profile {name} 。此外，OSD能力还支持存储池和命名空间的配置。</p>  <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">osd &#x27;allow &#123;access-spec&#125; [&#123;match-spec&#125;] [network &#123;network/prefix&#125;]&#x27;</span><br><span class="line">osd &#x27;profile &#123;name&#125; [pool=&#123;pool-name&#125; [namespace=&#123;namespace-name&#125;]] [network &#123;network/prefix&#125;]&#x27;</span><br></pre></td></tr></table></figure><p>  其中， {access-spec} 语法是下列之一：</p>  <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">* | all | [r][w][x] [class-read] [class-write]</span><br><span class="line"></span><br><span class="line">class &#123;class name&#125; [&#123;method name&#125;]</span><br></pre></td></tr></table></figure><p>  可选的 {match-spec} 语法是下列之一：</p>  <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">pool=&#123;pool-name&#125; [namespace=&#123;namespace-name&#125;] [object_prefix &#123;prefix&#125;]</span><br><span class="line"></span><br><span class="line">[namespace=&#123;namespace-name&#125;] tag &#123;application&#125; &#123;key&#125;=&#123;value&#125;</span><br></pre></td></tr></table></figure><p>  可选的 {network/prefix} 是一个标准网络名、且前缀长度遵循 CIDR 表示法（如 10.3.0.0/16 ）。如果配置了，对此能力的使用就仅限于从这个网络连入的客户端。</p></li><li><p>元数据服务器能力：对于管理员，设置 allow * 。对于其它的所有用户，如 CephFS 客户端，参考 <a href="">CephFS 客户端用户</a> 。</p></li></ul><h3 id="存储池"><a href="#存储池" class="headerlink" title="存储池"></a>存储池</h3><p>存储池是用户存储数据的逻辑分区。在Ceph部署中，经常创建存储池作为逻辑分区、用以归类相似的数据。例如，用Ceph作为Openstack的后端时，典型的部署通常会创建多个存储池，分别用于存储卷宗、映像、备份和虚拟机。</p><h3 id="应用程序标签"><a href="#应用程序标签" class="headerlink" title="应用程序标签"></a>应用程序标签</h3><p>可以将访问限定于指定存储池，正如其应用程序元数据所定义的那样。通配符 * 可以用于key参数、value参数或者二者全部。<code>all</code> 与 <code>*</code> 同义。</p><h3 id="命名空间"><a href="#命名空间" class="headerlink" title="命名空间"></a>命名空间</h3><p>对象Object在Pool池中可以关联到命名空间，他是池中对象的逻辑组。用户对Pool池的访问可以与命名空间想关联，比如限制一个用户在命名空间内的读写权限。</p><blockquote><p>命名空间主要适用于 librados 之上的应用程序，逻辑分组可减少新建存储池的必要。 Ceph 对象网关（从 luminous 起）就把命名空间用于各种元数据对象。</p></blockquote><p>用 namespace 能力可以把访问权限局限于特定的 RADOS 命名空间。命名空间支持有限的通配；如果指定的命名空间最后一个字符是 * ，那就把访问权限授予所有以所提供参数打头的命名空间。</p><h2 id="管理用户"><a href="#管理用户" class="headerlink" title="管理用户"></a>管理用户</h2><p>用户管理功能赋予Ceph存储集群管理员直接从Ceph存储集群中间、更新和删除用户及能力。</p><p>挡在Ceph存储集群中创建或删除用户的时候，可能得把密钥文件分发到各客户端，一边加入他们的密钥环。详见<a href="#%E7%AE%A1%E7%90%86%E5%AF%86%E9%92%A5%E7%8E%AF">密钥环管理</a></p><h3 id="罗列显示用户"><a href="#罗列显示用户" class="headerlink" title="罗列显示用户"></a>罗列显示用户</h3><p>罗列显示集群内的用户，使用<code>ceph auth ls</code>命令。Ceph将罗列出集群内的所有用户。例如，在一个上节点示例集群中，<code>ceph auth ls</code>会显示类似如下的内容：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">installed auth entries:</span><br><span class="line"></span><br><span class="line">osd.0</span><br><span class="line">        key: AQCvCbtToC6MDhAATtuT70Sl+DymPCfDSsyV4w==</span><br><span class="line">        caps: [mon] allow profile osd</span><br><span class="line">        caps: [osd] allow *</span><br><span class="line">osd.1</span><br><span class="line">        key: AQC4CbtTCFJBChAAVq5spj0ff4eHZICxIOVZeA==</span><br><span class="line">        caps: [mon] allow profile osd</span><br><span class="line">        caps: [osd] allow *</span><br><span class="line">client.admin</span><br><span class="line">        key: AQBHCbtT6APDHhAA5W00cBchwkQjh3dkKsyPjw==</span><br><span class="line">        caps: [mds] allow</span><br><span class="line">        caps: [mon] allow *</span><br><span class="line">        caps: [osd] allow *</span><br><span class="line">client.bootstrap-mds</span><br><span class="line">        key: AQBICbtTOK9uGBAAdbe5zcIGHZL3T/u2g6EBww==</span><br><span class="line">        caps: [mon] allow profile bootstrap-mds</span><br><span class="line">client.bootstrap-osd</span><br><span class="line">        key: AQBHCbtT4GxqORAADE5u7RkpCN/oo4e5W0uBtw==</span><br><span class="line">        caps: [mon] allow profile bootstrap-osd</span><br></pre></td></tr></table></figure><blockquote><p>Type.ID 这种表示方法对于用户来说，如osd.0标示用户类型是osd，其ID是0；client.admin表示用户类型是client，ID是admin（即默认的client.admin）用户。还有，每条都有一行 key: <value> 条目、和一或多行 caps: 条目。</p></blockquote><p>你可以给 <code>ceph auth ls</code>加上<code>-o &#123;filename&#125;</code>选项，把输出保存到一个文件。</p><h3 id="获取用户"><a href="#获取用户" class="headerlink" title="获取用户"></a>获取用户</h3><p>想要获取一个用户的key和能力，执行下面的命令：</p><p><code>ceph auth get &#123;Type.ID&#125;</code></p><p><code>ceph auth get client.admin</code></p><p>得到如下结果：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@serverc ~]$ ceph auth get client.admin</span><br><span class="line">exported keyring for client.admin</span><br><span class="line">[client.admin]</span><br><span class="line">        key = AQDtYxJf2UeZHRAAZmPGLhLr3kLzHXh3Glba6g==</span><br><span class="line">        caps mds = &quot;allow *&quot;</span><br><span class="line">        caps mgr = &quot;allow *&quot;</span><br><span class="line">        caps mon = &quot;allow *&quot;</span><br><span class="line">        caps osd = &quot;allow *&quot;</span><br></pre></td></tr></table></figure><p>如果想要保存输出结果到文本文件中，可以使用-o 选项，和上面的一样。</p><p><code>ceph auth export &#123;Type.ID&#125;</code> 使用export命令等价于get。它会把auid显示到终端上。</p><h3 id="新增用户"><a href="#新增用户" class="headerlink" title="新增用户"></a>新增用户</h3><p>添加一个用户，让其拥有密钥和应该有的能力。</p><p>用户的密钥是用户可以通过Ceph存储集群进行身份认证。可以对用户的能力进行授予，使他们拥有在Ceph监视器mon，Ceph OSD，或者Ceph元数据mds上的读取、写入或执行权限。</p><p>有下面几种方式添加用户：</p><ul><li><code>ceph auth add</code>：这种添加用户的方式是最规范的方法。它将创建用户，生成密钥并添加任何指定的能力。</li><li><code>ceph get-or-create-key</code>：这个命令添加用户后并返回用户密钥环文件信息。这对于需要密钥的客户端非常方便。如果用户已经存在，那么会返回密钥文件格式，并不会重新生成一个新的用户去替换重名用户。使用-o选项将密钥环保存在本地文件。</li><li><code>ceph auth get-or-create-key</code>：这种方式创建用户后会输出到控制台密钥，仅仅是密钥而不包括更多的钥匙环格式。</li><li>如果需要批量新建用户，可以尝试<a href="#%E9%80%9A%E8%BF%87%E9%92%A5%E5%8C%99%E7%8E%AF%E5%88%9B%E5%BB%BA%E7%94%A8%E6%88%B7">使用密钥环批量创建用户</a></li></ul><p>当创建了用户之后，可能没有给用户赋予任何的能力。一个用户如果没有任何能力就是一个毫无卵用的用户，因为客户端无法从监视器mon中获得任何集群信息。当然，你可以先创建一个没有能力的用户，之后再使用<code>ceph auth caps</code>命令赋予能力给用户。</p><p>标准的用户至少要用用Ceph监视器mon的可读的能力，并且在Ceph osd上具有读写的能力。此外，用户的OSD权限通常会限定至一个特定的Pool池中。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ceph auth add client.yeefire mon <span class="string">&#x27;allow r&#x27;</span> osd <span class="string">&#x27;allow rw pool=rbd&#x27;</span></span><br><span class="line">ceph auth get-or-create client.paul mon <span class="string">&#x27;allow r&#x27;</span> osd <span class="string">&#x27;allow rw pool=liverpool&#x27;</span></span><br><span class="line">ceph auth get-or-create client.yeefire mon <span class="string">&#x27;allow r&#x27;</span> osd <span class="string">&#x27;allow *  pool=rbd namespace=system&#x27;</span> -o ceph.client.yeefire.keyring</span><br><span class="line">ceph auth get-or-create client.george mon <span class="string">&#x27;allow r&#x27;</span> osd <span class="string">&#x27;allow rw pool=liverpool&#x27;</span> -o george.keyring</span><br><span class="line">ceph auth get-or-create-key client.ringo mon <span class="string">&#x27;allow r&#x27;</span> osd <span class="string">&#x27;allow rw pool=liverpool&#x27;</span> -o ringo.key</span><br><span class="line"></span><br></pre></td></tr></table></figure><blockquote><p>如果你给用户分配了访问 OSD 的能力，但是没有限制他可以访问哪些存储池，那么他可以访问集群内的所有存储池！最好对用户能力再进行namespace上的限制，以达到最小能力。</p></blockquote><h3 id="更改用户能力"><a href="#更改用户能力" class="headerlink" title="更改用户能力"></a>更改用户能力</h3><p><code>ceph auth caps</code> 命令可以用来修改指定用户的能力。设置新能力时会覆盖当前能力。</p><p><code>ceph auth caps USERTYPE.USERID &#123;daemon&#125; &#39;allow [r|w|x|*|...] [pool=&#123;pool-name&#125;] [namespace=&#123;namespace-name&#125;]&#39; [&#123;daemon&#125; &#39;allow [r|w|x|*|...] [pool=&#123;pool-name&#125;] [namespace=&#123;namespace-name&#125;]&#39;]</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ceph auth get client.john</span><br><span class="line">ceph auth caps client.john mon &#x27;allow r&#x27; osd &#x27;allow rw pool=liverpool&#x27;</span><br><span class="line">ceph auth caps client.paul mon &#x27;allow rw&#x27; osd &#x27;allow rwx pool=liverpool&#x27;</span><br><span class="line">ceph auth caps client.brian-manager mon &#x27;allow *&#x27; osd &#x27;allow *&#x27;</span><br></pre></td></tr></table></figure><h3 id="删除用户"><a href="#删除用户" class="headerlink" title="删除用户"></a>删除用户</h3><p>要删除一用户，使用<code>ceph auth del &#123;Type&#125;.&#123;ID&#125;</code>命令：</p><p><code>ceph auth del client.yeefire</code></p><h3 id="查看用户密钥"><a href="#查看用户密钥" class="headerlink" title="查看用户密钥"></a>查看用户密钥</h3><p>要想查看用户的密钥，可以通过以下方式进行获取：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ceph auth print-key client.yeefire</span><br><span class="line">ceph auth get-key client.yeefire</span><br><span class="line">ceph auth get-or-create-key client.yeefire -o key</span><br></pre></td></tr></table></figure><p>他们都可以使用-o选项将标准输出内容输出到文件中。</p><p>使用<code>auth print-key</code>、<code>auth get-key</code>和<code> auth get-or-create-key</code>返回的结果基本都是一样的。只不过<code> auth get-or-create-key</code>在输出key的时候会在行末尾添加一个换行符。</p><h3 id="导入用户"><a href="#导入用户" class="headerlink" title="导入用户"></a>导入用户</h3><p>通过<code>ceph auth get</code>或<code>ceph auth export</code>导出的用户文件可以通过<code>ceph auth import</code>导入的方式恢复用户及他们的能力。</p><p>要导入一个或多个用户，可以用 <code>ceph auth import</code> 命令，并指定一个密钥环：</p><p><code>ceph auth import -i /path/to/all.keyring</code></p><p>Ceph 存储集群会新增用户、他们的密钥以及其能力，也会更新已有的用户们、他们的密钥和他们的能力。</p><h2 id="管理密钥环"><a href="#管理密钥环" class="headerlink" title="管理密钥环"></a>管理密钥环</h2><p>当你访问Ceph使，你的客户端会在一些目录下寻找当前用户的keyring。Ceph默认情况下会使用下面四个路径来搜索与当前用户对应的密钥环。</p><ul><li>/etc/ceph/$cluster.$name.keyring</li><li>/etc/ceph/$cluster.keyring</li><li>/etc/ceph/keyring</li><li>/etc/ceph/keyring.bin</li></ul><p><code>$cluster</code>是你的集群名称，如<code>client</code>。<code>$name</code>是你的用户类型和用户ID，如<code>client.admin</code>。因此合起来的话是<code>/etc/ceph/ceph.client.admin.keyring</code>。</p><p>用户管理部分详细介绍了如何直接在Ceph存储群集中列出，获取，添加，修改和删除用户。Ceph还提供了<code>ceph-authtool</code>实用程序，使您可以从Ceph客户端管理密钥环。</p><h3 id="把用户加入到密钥环"><a href="#把用户加入到密钥环" class="headerlink" title="把用户加入到密钥环"></a>把用户加入到密钥环</h3><p>当你在 Ceph 存储集群中创建用户后，你可以用获取用户里面的方法获取此用户、及其密钥、能力，并存入一个密钥环文件。</p><p>当你希望每个密钥环中只有一个用户时，使用<code>ceph auth get</code>命令与<code>-o</code>选项搭配，将该用户的钥匙环保存在文件中。</p><p><code>ceph auth get client.yeefire -o ceph.client.admin.keyring</code></p><p>当你想把其他用户的钥匙环导入到一个目标钥匙环里，为了方便import的话，可以使用<code>ceph-authtool</code>工具进行导入：</p><p><code>ceph-authtool ceph.client.yeefire.keyring --import-keyring ceph.client.yeefire.sirius.keyring</code></p><h3 id="通过钥匙环创建用户"><a href="#通过钥匙环创建用户" class="headerlink" title="通过钥匙环创建用户"></a>通过钥匙环创建用户</h3><p>Ceph提供了创建用户的功能，可以直接在集群中创建用户。但是如果要是批量新建用户，先在密钥环上创建用户之后再导入到Ceph集群中也是一个不错的选择！</p><p>可以将用户导入Ceph存储集群。例如：</p><p><code>ceph-authtool -C ceph.42team.keyring -n client.42team.admin --cap mon &#39;allow *&#39; --cap  osd &#39;allow *&#39; --cap  mgr &#39;allow *&#39; --gen-key</code></p><p>可以继续创建新的用户，然后导入到<code>ceph.42team.keyring</code>密钥环文件中：</p><p><code>ceph-authtool -n client.42team.sirius --cap mon &#39;allow r&#39; --cap osd &#39;allow rw pool=42team&#39; ceph.42team.keyring -g</code></p><p>现在查看<code>ceph.42team.keyring</code>密钥环文件中的内容：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">[ceph@serverc ~]$ <span class="built_in">cat</span> ceph.42team.keyring</span><br><span class="line">[client.42team.admin]</span><br><span class="line">        key = AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==</span><br><span class="line">        caps mgr = <span class="string">&quot;allow *&quot;</span></span><br><span class="line">        caps mon = <span class="string">&quot;allow *&quot;</span></span><br><span class="line">        caps osd = <span class="string">&quot;allow *&quot;</span></span><br><span class="line">[client.42team.sirius]</span><br><span class="line">        key = AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==</span><br><span class="line">        caps mon = <span class="string">&quot;allow r&quot;</span></span><br><span class="line">        caps osd = <span class="string">&quot;allow rw pool=42team&quot;</span></span><br></pre></td></tr></table></figure><p>将密钥环文件导入到Ceph中创建用户：</p><p><code>ceph auth import -i ceph.42team.keyring</code></p><p>导入完成后使用<code>ceph auth ls</code>命令进行验证：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@serverc ~]$ ceph auth ls | grep client.42team -A5</span><br><span class="line">installed auth entries:</span><br><span class="line"></span><br><span class="line">client.42team.admin</span><br><span class="line">        key: AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==</span><br><span class="line">        caps: [mgr] allow *</span><br><span class="line">        caps: [mon] allow *</span><br><span class="line">        caps: [osd] allow *</span><br><span class="line">client.42team.sirius</span><br><span class="line">        key: AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==</span><br><span class="line">        caps: [mon] allow r</span><br><span class="line">        caps: [osd] allow rw pool=42team</span><br></pre></td></tr></table></figure><p>成功将2个用户导入到Ceph集群。</p><p>接下来将钥匙环放置到<code>/etc/ceph/ceph.keyring</code>：</p><p><code>cp ceph.42team.keyring /etc/ceph/ceph.keyring</code></p><p>尝试使用<code>client.42team.admin</code>用户去执行Ceof osd命令：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@serverc ~]$ ceph osd tree -n client.42team.admin</span><br><span class="line">ID CLASS WEIGHT  TYPE NAME        STATUS REWEIGHT PRI-AFF</span><br><span class="line">-1       0.16644 root default</span><br><span class="line">-3       0.05548     host serverc</span><br><span class="line"> 0   hdd 0.01849         osd.0        up  1.00000 1.00000</span><br><span class="line"> 3   hdd 0.01849         osd.3        up  1.00000 1.00000</span><br><span class="line"> 8   hdd 0.01849         osd.8        up  1.00000 1.00000</span><br><span class="line">-7       0.05548     host serverd</span><br><span class="line"> 2   hdd 0.01849         osd.2        up  1.00000 1.00000</span><br><span class="line"> 4   hdd 0.01849         osd.4        up  1.00000 1.00000</span><br><span class="line"> 6   hdd 0.01849         osd.6        up  1.00000 1.00000</span><br><span class="line">-5       0.05548     host servere</span><br><span class="line"> 1   hdd 0.01849         osd.1        up  1.00000 1.00000</span><br><span class="line"> 5   hdd 0.01849         osd.5        up  1.00000 1.00000</span><br><span class="line"> 7   hdd 0.01849         osd.7        up  1.00000 1.00000</span><br></pre></td></tr></table></figure><h3 id="修改密钥环中用户能力"><a href="#修改密钥环中用户能力" class="headerlink" title="修改密钥环中用户能力"></a>修改密钥环中用户能力</h3><p>要修改密钥环中用户的能力，请指定密钥环，然后再指定用户，<strong>修改用户的能力不会重置用户的key</strong>。</p><p><code>ceph-authtool ceph.42team.keyring -n client.42team.sirius --cap mon &#39;allow r&#39;</code></p><p>撤销<code>client.42team.sirius</code>用户对osd的所有权限，目前该用户仅可以查看mon信息。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[client.42team.sirius]</span><br><span class="line">        key = AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==</span><br><span class="line">        caps mon = &quot;allow r&quot;</span><br></pre></td></tr></table></figure><p>要将刚刚在密钥环上的修改应用到ceph集群，必须将密钥环的用户更新到Ceph集群中的用户条目。</p><p><code>ceph auth import -i ceph.42team.keyring</code></p><p>成功导入后对修改进行验证：</p><p><code>ceph auth ls | grep ^client.42team -A5</code></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[ceph@serverc ~]$ ceph auth ls | grep ^client.42team -A5</span><br><span class="line">installed auth entries:</span><br><span class="line"></span><br><span class="line">client.42team.admin</span><br><span class="line">        key: AQCmVB1fTffGIBAAoBiwyBPEgggX+UtPzsnFoQ==</span><br><span class="line">        caps: [mgr] allow *</span><br><span class="line">        caps: [mon] allow *</span><br><span class="line">        caps: [osd] allow *</span><br><span class="line">client.42team.sirius</span><br><span class="line">        key: AQDLVx1fxsuyOBAAvLtLw6vqnAqTLu5uND+LgQ==</span><br><span class="line">        caps: [mon] allow r</span><br></pre></td></tr></table></figure><p>对导入用户不了解可以参见<a href="#%E5%AF%BC%E5%85%A5%E7%94%A8%E6%88%B7">导入用户</a></p><p>不想使用<code>ceph-authtool</code>工具或者不想以密钥环方式添加用户可以参见<a href="#%E6%9B%B4%E6%94%B9%E7%94%A8%E6%88%B7%E8%83%BD%E5%8A%9B">更改用户能力</a>和<a href="#%E6%96%B0%E5%A2%9E%E7%94%A8%E6%88%B7">新增用户</a></p><h2 id="身份验证命令行"><a href="#身份验证命令行" class="headerlink" title="身份验证命令行"></a>身份验证命令行</h2><p>Ceph命令行几乎全局支持用户名和密钥的下列用法：</p><ul><li><code>--id | --user</code>：Ceph 用一个类型和 ID（ 如 TYPE.ID 或 client.admin 、 client.user1 ）来标识用户， id 、 name 、和 -n 选项可用于指定用户名（如 admin 、 user1 、 foo 等）的 ID 部分，你可以用 –id 指定用户并忽略类型，例如可用下列命令指定 client.foo 用户：  <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ceph --id foo --keyring /path/to/keyring health</span><br><span class="line">ceph --user foo --keyring /path/to/keyring health</span><br></pre></td></tr></table></figure></li><li><code>--name | -n</code>：Ceph 用一个类型和 ID （如 TYPE.ID 或 client.admin 、 client.user1 ）来标识用户， –name 和 -n 选项可用于指定完整的用户名，但必须指定用户类型（一般是 client ）和用户 ID ，例如：  <figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ceph --name client.foo --keyring /path/to/keyring health</span><br><span class="line">ceph -n client.foo --keyring /path/to/keyring health</span><br></pre></td></tr></table></figure></li><li><code>--keyring</code>：包含一或多个用户名、密钥的密钥环路径。 <code>--secret</code> 选项提供了相同功能，但它不能用于 RADOS 网关，其 <code>--secret</code> 另有用途。你可以用 ceph auth get-or-create 获取密钥环并保存在本地，然后您就可以改用其他用户而无需重指定密钥环路径了。<br>  <code>ceph --id 42team.admin --keyring /etc/ceph/ceph.keyring  health</code></li></ul><h2 id="Ceph认证的局限性"><a href="#Ceph认证的局限性" class="headerlink" title="Ceph认证的局限性"></a>Ceph认证的局限性</h2><p><code>cephx</code>协议提供Ceph客户端和服务器间的相互认证，并没打算认证人类用户或者应用程序。如果有访问控制需求，那必须用另外一种机制，他对于前端用户访问Ceph对象存储可能是特定的，其任务是确保只有此机器上可接受的用户和程序才能访问Ceph的对象存储。</p><p>用于认证Ceph客户端和服务器的密钥通常以纯文本存储在权限合适的文件里，并保存于可信主机上。</p><blockquote><p>密钥存储为纯文本文件有安全缺陷，但很难避免，它给了 Ceph 可用的基本认证方法，设置 Ceph 时应该注意这些缺陷。</p></blockquote><p>尤其是任意用户、特别是移动机器不应该和 Ceph 直接交互，因为这种用法要求把明文认证密钥存储在不安全的机器上，这些机器的丢失、或盗用将泄露可访问 Ceph 集群的密钥。</p><p>相比于允许潜在的欠安全机器直接访问 Ceph 对象存储，应该要求用户先登录安全有保障的可信机器，这台可信机器会给人们存储明文密钥。未来的 Ceph 版本也许会更彻底地解决这些特殊认证问题。</p><p>当前，没有任何 Ceph 认证协议保证传送中消息的私密性。所以，即使物理线路窃听者不能创建用户或修改它们，但可以听到、并理解客户端和服务器间发送过的所有数据。此外， Ceph 没有可加密用户数据的选项，当然，用户可以手动加密、然后把它们存在对象库里，但 Ceph 没有自己加密对象的功能。在 Ceph 里存储敏感数据的用户应该考虑存入 Ceph 集群前先加密。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ceph用户管理&quot;&gt;&lt;a href=&quot;#Ceph用户管理&quot; class=&quot;headerlink&quot; title=&quot;Ceph用户管理&quot;&gt;&lt;/a&gt;Ceph用户管理&lt;/h1&gt;&lt;p&gt;本文档叙述了Ceph客户端的用户身份，以及Ceph存储集群的认证和授权。用户可以是个人或是系</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Ceph" scheme="https://blog.yeefire.com/tags/Ceph/"/>
    
  </entry>
  
  <entry>
    <title>MacOS睡眠管理——让你的Mac睡的更香</title>
    <link href="https://blog.yeefire.com/2020_07/mac_sleep.html"/>
    <id>https://blog.yeefire.com/2020_07/mac_sleep.html</id>
    <published>2020-07-15T10:01:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="让你的Mac睡的更香"><a href="#让你的Mac睡的更香" class="headerlink" title="让你的Mac睡的更香"></a>让你的Mac睡的更香</h1><p>最近Mac的睡眠让我感到不太舒服，明明已经合上盖子拔掉电源，可是它还在熬着夜！不好好睡觉真让人生气！</p><p>所以得好好调教一下，让他该睡觉的时候老老实实趴下，该干活的时候就得全力以赴工作。</p><h2 id="Mac是怎么睡觉的"><a href="#Mac是怎么睡觉的" class="headerlink" title="Mac是怎么睡觉的"></a>Mac是怎么睡觉的</h2><p>Mac有两种睡觉有两个阶段，一开始是<strong>睡眠</strong>，在一定条件之后会从睡眠进入<strong>休眠</strong>。这两种睡觉方式就像我们人的小憩和睡大觉。小憩醒得快，睡大觉醒的就会慢一些。</p><p>在长时间无操作，或者把Macbook的盖子合上时以及手动点击进入睡眠时则进入<strong>睡眠状态</strong>，在睡眠状态下数据存储在内存中，此时的系统可以被快速唤醒，快速恢复到睡眠前的状态。</p><p>如果<strong>睡眠</strong>持续了一段时间之后，Mac会根据设定进入更深一层的<strong>休眠状态</strong>，此时Mac要根据你的配置来决定要不要把内存中的数据写入到磁盘中，然后会放弃对内存及设备的大部分供电，达到更加节省电量的目的。如果在休眠模式下唤醒，则Mac会将保存在硬盘中的数据再重新写入到内存之中并恢复程序运行，这样的话耗时比较长，速度比较慢。</p><h2 id="pmset工具"><a href="#pmset工具" class="headerlink" title="pmset工具"></a>pmset工具</h2><p>Apple 提供了一个工具叫pmset来管理Apple 设备的电源选项。<code>pmset</code>这个工具的名字来源于 <strong>Power Manager Setting（pmset）</strong> ，通过调整macos的睡眠计划，可以让Mac睡的更香。</p><h3 id="pmset用法"><a href="#pmset用法" class="headerlink" title="pmset用法"></a>pmset用法</h3><p><code>sudo pmset [-选项] &lt;参数&gt;</code></p><p>实例：</p><ul><li>pmset -g cap: 查看当前供电方式下可以调节的参数</li><li>pmset -g custom : 查看全部供电方式下的电源参数信息</li><li>pmset restoredefaults : 还原自定义的设置</li></ul><h3 id="pmset常用选项"><a href="#pmset常用选项" class="headerlink" title="pmset常用选项"></a>pmset常用选项</h3><ul><li>pmset -a : 全局调整睡眠电源计划</li><li>pmset -c : 仅调整<strong>外部供电</strong>时睡眠计划</li><li>pmset -b : 仅调整<strong>电池供电</strong>时睡眠计划</li><li>pmset -g : 查看当前供电方式下的睡眠计划</li></ul><h3 id="常用参数"><a href="#常用参数" class="headerlink" title="常用参数"></a>常用参数</h3><ul><li>sleep: 睡眠计时器，进入睡眠所需要的时间</li><li>hibernatemode: 睡眠模式<ul><li>hibernatemode = 0 将数据保存在内存中持续为内存供电 非笔记本机器默认配置</li><li>hibernatemode = 3 safe sleep模式，数据保存在内存中并写入内存镜像到硬盘中备份。笔记本默认模式</li><li>hibernatemode = 25 将内存镜像直接写入到硬盘中</li></ul></li><li>standby: 休眠计时器</li><li>highstandbythreshold: highstandbythreshold(电池剩余电量百分比)它是standbydelay模式选择阈值，默认 50% 电量。<ul><li>高于阈值，采用<code>standbydelayhigh</code>计算时间。</li><li>低于阈值，采用<code>standbydelaylow</code>计算时间。</li></ul></li><li>gpuswitch: 这个参数用来管理独立显卡的选择<ul><li>gpuswitch=0 只使用集成显卡</li><li>gpuswitch=1 只使用独立显卡</li><li>gpuswitch=2 自动切换显卡</li></ul></li></ul><h3 id="其他参数"><a href="#其他参数" class="headerlink" title="其他参数"></a>其他参数</h3><ul><li>lidwake:开盖时是否唤醒</li><li>tcpkeepalive:合盖时是否保存网络连接</li><li>displaysleep:屏幕休眠时间</li><li>disksleep:硬盘休眠时间</li><li>acwake:被同一 iCloud ID 下的设备唤醒</li></ul><h2 id="我的个人参数"><a href="#我的个人参数" class="headerlink" title="我的个人参数"></a>我的个人参数</h2><h3 id="外部供电环境下："><a href="#外部供电环境下：" class="headerlink" title="外部供电环境下："></a>外部供电环境下：</h3><p>外部供电睡眠设置使用的是默认参数。</p><p><img src="https://cdn.yeefire.com/hexo/img/%E5%A4%96%E9%83%A8%E7%94%B5%E6%BA%90%E4%BE%9B%E7%94%B5-2020-07-15.png" alt="外部电源供电-2020-07-15"></p><h3 id="电池供电："><a href="#电池供电：" class="headerlink" title="电池供电："></a>电池供电：</h3><p><img src="https://cdn.yeefire.com/hexo/img/%E7%94%B5%E6%B1%A0%E4%BE%9B%E7%94%B5-2020-07-15.png" alt="电池供电-2020-07-15"></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">// 20分钟后睡眠</span><br><span class="line">sudo pmset -b sleep 20</span><br><span class="line"></span><br><span class="line">// 休眠模式使用3，在给内存供电的同时写入内存的镜像备份到磁盘中</span><br><span class="line">sudo pmset -b hibernatemode 3</span><br><span class="line"></span><br><span class="line">// 显示器15分钟后关闭</span><br><span class="line">sudo pmset -b displaysleep 15</span><br><span class="line"></span><br><span class="line">// 硬盘30分钟后休眠</span><br><span class="line">sudo pmset -b disksleep 30</span><br><span class="line"></span><br><span class="line">// 休眠后断网</span><br><span class="line">sudo pmset -b tcpkeepalive 0</span><br><span class="line"></span><br><span class="line">// 开盖唤醒</span><br><span class="line">sudo pmset -b lidwake 1</span><br><span class="line"></span><br><span class="line">// 关闭被同一 iCloud 下的设备唤醒</span><br><span class="line">sudo pmset -b acwake 0</span><br><span class="line"></span><br><span class="line">// gpuswitch 0 在使用电池的情况下只使用核心显卡</span><br><span class="line">sudo pmset -b gpuswitch 0</span><br><span class="line"></span><br><span class="line">// 在电池剩余电量高于75%的情况时，休眠计时器设定为2小时。低于75%的情况下1小时后进入休眠。</span><br><span class="line">sudo pmset -b highstandbythreshold 75</span><br><span class="line">sudo pmset -b standbydelayhigh 7200</span><br><span class="line">sudo pmset -b standbydelaylow 3600</span><br></pre></td></tr></table></figure><h1 id="参考文章："><a href="#参考文章：" class="headerlink" title="参考文章："></a>参考文章：</h1><p><span class="exturl" data-url="aHR0cHM6Ly9zc3BhaS5jb20vcG9zdC82MTM3OQ==" title="https://sspai.com/post/61379">https://sspai.com/post/61379<i class="fa fa-external-link"></i></span></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;让你的Mac睡的更香&quot;&gt;&lt;a href=&quot;#让你的Mac睡的更香&quot; class=&quot;headerlink&quot; title=&quot;让你的Mac睡的更香&quot;&gt;&lt;/a&gt;让你的Mac睡的更香&lt;/h1&gt;&lt;p&gt;最近Mac的睡眠让我感到不太舒服，明明已经合上盖子拔掉电源，可是它还在熬着夜</summary>
      
    
    
    
    
    <category term="macos" scheme="https://blog.yeefire.com/tags/macos/"/>
    
  </entry>
  
  <entry>
    <title>初中古诗文必背篇目</title>
    <link href="https://blog.yeefire.com/2020_07/chinese_handsome.html"/>
    <id>https://blog.yeefire.com/2020_07/chinese_handsome.html</id>
    <published>2020-07-14T06:21:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="语文古诗默写清单"><a href="#语文古诗默写清单" class="headerlink" title="语文古诗默写清单"></a>语文古诗默写清单</h1><ul><li><p><a href="#%E5%AF%92%E9%A3%9F">寒食    唐代-韩翃</a></p></li><li><p><a href="#%E9%A9%AC%E8%AF%97">马诗    唐代-李贺</a></p></li><li><p><a href="#%E7%9F%B3%E7%81%B0%E5%90%9F">石灰吟    明代-于谦</a></p></li><li><p><a href="#%E5%8D%81%E4%BA%94%E5%A4%9C%E6%9C%9B%E6%9C%88%E5%AF%84%E6%9D%9C%E9%83%8E%E4%B8%AD">十五夜望月寄杜郎中    唐代（中）-王健</a></p></li><li><p><a href="#%E8%BF%A2%E8%BF%A2%E7%89%B5%E7%89%9B%E6%98%9F">迢迢牵牛星    东汉-???</a></p></li><li><p><a href="#%E6%97%A9%E6%98%A5%E5%91%88%E6%B0%B4%E9%83%A8%E5%BC%A0%E5%8D%81%E5%85%AB%E5%91%98%E5%A4%96">早春呈水部张十八员外    唐代-韩愈</a></p></li><li><p><a href="#%E6%98%A5%E5%A4%9C%E5%96%9C%E9%9B%A8">春夜喜雨    唐代-杜甫</a></p></li><li><p><a href="#%E9%80%81%E5%85%83%E4%BA%8C%E4%BD%BF%E5%AE%89%E8%A5%BF">送元二使安西    唐代-王维</a></p></li><li><p><a href="#%E6%B1%9F%E4%B8%8A%E6%B8%94%E8%80%85">江上渔者    北宋-范仲淹</a></p></li><li><p><a href="#%E5%B0%8F%E9%9B%85%E9%87%87%E8%96%87">小雅·采薇    西周-《诗经》</a></p></li><li><p><a href="#%E7%AB%B9%E7%9F%B3">竹石    清代-郑燮（郑板桥）</a></p></li><li><p><a href="#%E6%B3%8A%E8%88%B9%E7%93%9C%E6%B4%B2">泊船瓜洲    宋代-王安石</a></p></li><li><p><a href="#%E5%A4%9C%E9%9B%A8%E5%AF%84%E5%8C%97">夜雨寄北    唐代（晚）-李商隐</a></p><h2 id="寒食"><a href="#寒食" class="headerlink" title="寒食"></a>寒食</h2></li></ul><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">寒 食</span><br><span class="line">        唐代-韩翃(hóng)</span><br><span class="line">春城无处不飞花①，寒食东风御柳斜②。</span><br><span class="line">日暮汉宫传蜡烛③，轻烟散入五侯家④。</span><br></pre></td></tr></table></figure><h3 id="注解"><a href="#注解" class="headerlink" title="注解"></a>注解</h3><p>①春城：暮春时的长安城。<br>②寒食：古代在清明节前两天的节日，禁火三天，只吃冷食，所以称寒食。御柳：御苑之柳，皇城中的柳树。<br>③汉宫：这里指唐朝皇宫。传蜡烛：寒食节普天下禁火，但权贵宠臣可得到皇帝恩赐而得到燃烛。《唐辇下岁时记》“清明日取榆柳之火以赐近臣”。<br>④五侯：汉成帝时封王皇后的五个兄弟王谭、王商、王立、王根、王逢时皆为候，受到特别的恩宠。这里泛指天子近幸之臣。<br>⑤飞花：指柳絮</p><h3 id="白话文译文"><a href="#白话文译文" class="headerlink" title="白话文译文"></a>白话文译文</h3><p><code>暮春时节，长安城处处柳絮飞舞、落红无数，寒食节的东风吹拂着皇家花园的柳枝。夜色降临，宫里忙着传蜡烛，点蜡烛的轻烟散入王侯贵戚的家里。</code></p><h3 id="创作背景"><a href="#创作背景" class="headerlink" title="创作背景"></a>创作背景</h3><p>寒食是中国古代一个传统节日，一般在冬至后一百零五天，清明前两天。古人很重视这个节日，按风俗家家禁火，只吃现成食物，故名寒食。唐代制度，到清明这天，皇帝宣旨取榆柳之火赏赐近臣，以示皇恩。这仪式用意有二：一是标志着寒食节已结束，可以用火了；二是藉此给臣子官吏们提个醒，让大家向有功也不受禄的介子推学习，勤政为民。唐代诗人窦叔向有《寒食日恩赐火》诗纪其实：“恩光及小臣，华烛忽惊春。电影随中使，星辉拂路人。幸因榆柳暖，一照草茅贫。”正可与韩翃这一首诗参照。<br>中唐以后，几任昏君都宠幸宦官，以致他们的权势很大，败坏朝政，排斥朝官，正直人士对此都极为愤慨。有意见认为此诗正是因此而发。</p><h2 id="马诗"><a href="#马诗" class="headerlink" title="马诗"></a>马诗</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">马诗·大漠沙如雪（《马诗二十三首》的第五篇）</span><br><span class="line">        唐代-李贺</span><br><span class="line">大漠沙如雪⑴，燕山月似钩⑵。</span><br><span class="line">何当金络脑⑶，快走踏清秋⑷。</span><br></pre></td></tr></table></figure><h3 id="注释"><a href="#注释" class="headerlink" title="注释"></a>注释</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">⑴大漠：广大的沙漠。</span><br><span class="line">⑵燕山：在河北省。一说为燕然山，即今之杭爱山，在蒙古人民共和国西部。钩：古代兵器。</span><br><span class="line">⑶何当：什么时候。金络脑：即金络头，用黄金装饰的马笼头。</span><br><span class="line">⑷踏：走，跑。此处有“奔驰”之意。清秋：清朗的秋天。</span><br></pre></td></tr></table></figure><h3 id="白话文译文-1"><a href="#白话文译文-1" class="headerlink" title="白话文译文"></a>白话文译文</h3><p><code>平沙覆盖着大漠，犹如无边的积雪，月亮高悬在燕山上，恰似一把弯钩。什么时候我能给它带上金络头，飞快奔驰着，踏遍这清爽秋日时的原野！</code></p><h3 id="创作背景-1"><a href="#创作背景-1" class="headerlink" title="创作背景"></a>创作背景</h3><p>作者所处的贞元（785～805）、元和（806～820）之际，正是藩镇极为跋扈的时代，诗中“燕山”暗示的幽州蓟门一带又是藩镇肆虐为时最久、为祸最烈的地带，作者希望能扫除战乱，建功立业，但终是不被赏识。对马有所偏爱的作者或许受伯乐识马所启，结合自己怀才不遇的现实，带着愤懑之情创作了此诗。</p><h2 id="石灰吟"><a href="#石灰吟" class="headerlink" title="石灰吟"></a>石灰吟</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">石灰吟</span><br><span class="line">        明代-于谦</span><br><span class="line">千锤万凿出深山，烈火焚烧若等闲。</span><br><span class="line">粉骨碎身浑不怕，要留清白在人间。</span><br></pre></td></tr></table></figure><h3 id="注释-1"><a href="#注释-1" class="headerlink" title="注释"></a>注释</h3><figure class="highlight plaintext"><table><tr><td class="code"><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></tr></table></figure><h3 id="白话文译文-2"><a href="#白话文译文-2" class="headerlink" title="白话文译文"></a>白话文译文</h3><p><code>石灰石只有经过千万次锤打才能从深山里开采出来，它把熊熊烈火的焚烧当作很平常的一件事。即使粉身碎骨也毫不惧怕，甘愿把一身清白留在人世间。</code></p><h3 id="创作背景-2"><a href="#创作背景-2" class="headerlink" title="创作背景"></a>创作背景</h3><p>于谦从小学习刻苦，志向远大。相传有一天，他信步走到一座石灰窑前，观看师傅们煅烧石灰。只见一堆堆青黑色的山石，经过熊熊的烈火焚烧之后，都变成了白色的石灰。他深有感触，略加思索之后便写下了此诗。据说此时的于谦才十二岁，他写下这首诗不只是石灰形象的写照，更是他日后的人生追求。</p><h2 id="十五夜望月寄杜郎中"><a href="#十五夜望月寄杜郎中" class="headerlink" title="十五夜望月寄杜郎中"></a>十五夜望月寄杜郎中</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">十五夜望月寄杜郎中⑴</span><br><span class="line">        中唐-王建</span><br><span class="line">中庭地白树栖鸦⑵，冷露无声湿桂花⑶。</span><br><span class="line">今夜月明人尽望⑷，不知秋思落谁家⑸</span><br></pre></td></tr></table></figure><h3 id="注解-1"><a href="#注解-1" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">⑴十五夜：指农历八月十五的晚上，即中秋夜。杜郎中：即杜元颖。</span><br><span class="line">⑵中庭：即庭中，庭院中。地白：指月光照在庭院的样子。</span><br><span class="line">⑶冷露：秋天的冰冷的露水。</span><br><span class="line">⑷尽：都。</span><br><span class="line">⑸秋思（sī）：秋天的情思，这里指怀人的思绪。落：在，到</span><br></pre></td></tr></table></figure><h3 id="白话译文"><a href="#白话译文" class="headerlink" title="白话译文"></a>白话译文</h3><p><code>庭院地面雪白树上栖息着鹊鸦，秋露点点无声打湿了院中桂花。今夜明月当空世间人人都仰望，不知道这秋日情思可落到谁家？</code></p><h3 id="创作背景-3"><a href="#创作背景-3" class="headerlink" title="创作背景"></a>创作背景</h3><p>此诗是诗人在中秋佳节与朋友相聚时所作。诗题为“十五夜望月寄杜郎中”，可见是寄友人杜元颖的。原诗诗题下注云：“时会琴客”，说明佳节良友相聚，并非独吟。</p><h2 id="迢迢牵牛星"><a href="#迢迢牵牛星" class="headerlink" title="迢迢牵牛星"></a>迢迢牵牛星</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">迢迢牵牛星</span><br><span class="line">        东汉-???</span><br><span class="line">迢迢牵牛星，皎皎河汉女。</span><br><span class="line">纤纤擢素手，札札弄机杼。</span><br><span class="line">终日不成章，泣涕零如雨。</span><br><span class="line">河汉清且浅，相去复几许？</span><br><span class="line">盈盈一水间，脉脉不得语。</span><br></pre></td></tr></table></figure><h3 id="注解-2"><a href="#注解-2" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">迢（tiáo）迢：遥远的样子。牵牛星：河鼓三星之一，隔银河和织女星相对，俗称“牛郎星”，是天鹰星座的主星，在银河东。</span><br><span class="line">皎皎：明亮的样子。河汉女：指织女星，是天琴星座的主星，在银河西，与牵牛星隔河相对。河汉，即银河。</span><br><span class="line">纤纤：纤细柔长的样子。擢（zhuó）：引，抽，接近伸出的意思。素：洁白。</span><br><span class="line">札（zhá）札：象声词，机织声。弄：摆弄。杼（zhù）：织布机上的梭子。</span><br><span class="line">章：指布帛上的经纬纹理，这里指整幅的布帛。此句是用《诗经·小雅·大东》语意，说织女终日也织不成布。《诗经》原意是织女徒有虚名，不会织布。而这里则是说织女因相思，而无心织布。</span><br><span class="line">涕：眼泪。零：落下。</span><br><span class="line">清且浅：清又浅。</span><br><span class="line">相去：相离，相隔。去，离。复几许：又能有多远。</span><br><span class="line">盈盈：水清澈、晶莹的样子。一说形容织女，《文选》六臣注：“盈盈，端丽貌。”一水：指银河。间（jiàn）：间隔。</span><br><span class="line">脉（mò）脉：含情相视的样子。一作“默默”，默默地用眼神或行动表达情意。</span><br></pre></td></tr></table></figure><h3 id="白话译文-1"><a href="#白话译文-1" class="headerlink" title="白话译文"></a>白话译文</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">那遥远而亮洁的牵牛星，那皎洁而遥远的织女星。</span><br><span class="line">织女正摆动柔长洁白的双手，织布机札札地响个不停。</span><br><span class="line">因为相思而整天也织不出什么花样，她哭泣的泪水零落如雨。</span><br><span class="line">只隔了道清清浅浅的银河，两界相离也没有多远。</span><br><span class="line">相隔在清清浅浅的银河两边，含情脉脉(mò)相视无言地痴痴凝望。</span><br></pre></td></tr></table></figure><h3 id="创作背景-4"><a href="#创作背景-4" class="headerlink" title="创作背景"></a>创作背景</h3><p>在中国关于牵牛和织女的民间故事起源很早。《古诗十九首》中的这首《迢迢牵牛星》写牵牛织女夫妇的离隔，它的时代在东汉后期，略早于曹丕和曹植。将这首诗和曹氏兄弟的作品加以对照，可以看出，在东汉末年到魏这段时间里牵牛和织女的故事大概已经定型了。</p><h2 id="早春呈水部张十八员外"><a href="#早春呈水部张十八员外" class="headerlink" title="早春呈水部张十八员外"></a>早春呈水部张十八员外</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">早春呈水部张十八员外（一）</span><br><span class="line">        唐代-韩愈</span><br><span class="line">天街小雨润如酥⑵，草色遥看近却无。</span><br><span class="line">最是一年春好处⑶，绝胜烟柳满皇都⑷。</span><br></pre></td></tr></table></figure><h3 id="注解-3"><a href="#注解-3" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">⑴呈：恭敬地送给。水部张十八员外：指张籍（766—830年）唐代诗人。在同族兄弟中排行第十八，曾任水部员外郎。</span><br><span class="line">⑵天街：京城街道。润如酥：细腻如酥。酥，动物的油，这里形容春雨的细腻。</span><br><span class="line">⑵最是：正是。处：时。</span><br><span class="line">⑷绝胜：远远胜过。皇都：帝都，这里指长安。</span><br><span class="line">⑸官忙身老大：韩愈写此诗时任吏部侍郎，公务繁忙，故云“官忙”；韩愈时年56岁，故云“身老大”。身老大，年纪大。</span><br><span class="line">⑹即：已经。</span><br><span class="line">⑺凭：这里作“请”讲。江：曲江，位于唐代京城东南角，为游览胜地，遗址在今陕西西安东南部。</span><br></pre></td></tr></table></figure><h3 id="白话译文-2"><a href="#白话译文-2" class="headerlink" title="白话译文"></a>白话译文</h3><p><code>京城大道上空丝雨纷纷，它像酥油般细密而滋润，远望草色依稀连成一片，近看时却显得稀疏零星。这是一年中最美的季节，远胜过绿柳满城的春末。</code></p><h3 id="创作背景-5"><a href="#创作背景-5" class="headerlink" title="创作背景"></a>创作背景</h3><p>此诗作于唐穆宗长庆三年（823年）早春。当时韩愈已经56岁，任吏部侍郎。虽然时间不长，但此时心情很好。此前不久，镇州（今河北正定）藩镇叛乱，韩愈奉命前往宣抚，说服叛军，平息了一场叛乱。穆宗非常高兴，把他从兵部侍郎任上调为吏部侍郎。在文学方面，他早已声名大振。同时在复兴儒学的事业中，他也卓有建树。因此，虽然年近花甲，却不因岁月如流而悲伤，而是兴味盎然地迎接春天。<br>此诗是写给当时任水部员外郎的诗人张籍的。张籍在兄弟辈中排行十八，故称“张十八”。大约韩愈约张籍游春，张籍因以事忙年老推辞，韩愈于是作这首诗寄赠，极言早春景色之美，希望触发张籍的游兴。</p><h2 id="春夜喜雨"><a href="#春夜喜雨" class="headerlink" title="春夜喜雨"></a>春夜喜雨</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">春夜喜雨</span><br><span class="line">        唐代-杜甫</span><br><span class="line">好雨知时节⑴，当春乃发生⑵。</span><br><span class="line">随风潜入夜⑶，润物细无声⑷。</span><br><span class="line">野径云俱黑⑸，江船火独明⑹。</span><br><span class="line">晓看红湿处⑺，花重锦官城⑻。</span><br></pre></td></tr></table></figure><h3 id="注解-4"><a href="#注解-4" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">⑴知：明白，知道。说雨知时节，是一种拟人化的写法。</span><br><span class="line">⑵乃：就。发生：萌发生长。</span><br><span class="line">⑶潜：暗暗地，悄悄地。这里指春雨在夜里悄悄地随风而至。</span><br><span class="line">⑷润物：使植物受到雨水的滋养。</span><br><span class="line">⑸野径：田野间的小路。</span><br><span class="line">⑹“江船”句：意谓连江上的船只都看不见，只能看见江船上的点点灯火，暗示雨意正浓。</span><br><span class="line">⑺晓：天刚亮的时候。红湿处：雨水湿润的花丛。</span><br><span class="line">⑻花重（zhòng）：花因为饱含雨水而显得沉重。锦官城：故址在今成都市南，亦称锦城。三国蜀汉时管理织锦之官驻此，故名。后人有用作成都的别称。此句是说露水盈花的美景。</span><br></pre></td></tr></table></figure><h3 id="白话译文-3"><a href="#白话译文-3" class="headerlink" title="白话译文"></a>白话译文</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">好雨是知道该下雨的时节的，正好下在春天植物萌发生长的时候。</span><br><span class="line">它随着春风在夜里悄悄地落下，悄然无声地滋润着大地万物。</span><br><span class="line">在雨夜，野外的小路和乌云都是黑茫茫的，只有江船上的灯火格外明亮。</span><br><span class="line">天亮后，去看这带着雨的娇美红艳的花朵，整个锦官城变成了沉甸甸的鲜花盛开的世界。</span><br></pre></td></tr></table></figure><h3 id="创作背景-6"><a href="#创作背景-6" class="headerlink" title="创作背景"></a>创作背景</h3><p>这首诗写于唐肃宗上元二年（761）春。杜甫在经过一段时间的流离转徙的生活后，终因陕西旱灾而来到四川成都定居，开始了在蜀中的一段较为安定的生活。作此诗时，他已在成都草堂定居两年。他亲自耕作，种菜养花，与农民交往，对春雨之情很深，因而写下了这首描写春夜降雨、润泽万物的美景诗作。</p><h2 id="送元二使安西"><a href="#送元二使安西" class="headerlink" title="送元二使安西"></a>送元二使安西</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">送元二使安西</span><br><span class="line">        唐代-王维</span><br><span class="line">渭城朝雨浥轻尘⑵，客舍青青柳色新⑶。</span><br><span class="line">劝君更尽一杯酒⑷，西出阳关无故人⑸。</span><br></pre></td></tr></table></figure><h3 id="注解-5"><a href="#注解-5" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">⑴元二：姓元，排行第二，作者的朋友。使：出使。安西：指唐代安西都护府，治所在龟兹城（今新疆库车）。</span><br><span class="line">⑵渭城：即秦代咸阳古城，汉改渭城。朝（zhāo）雨：早晨下的雨。浥（yì）：湿。</span><br><span class="line">⑶客舍：驿馆，旅馆。柳色：柳树象征离别。</span><br><span class="line">⑷更尽：再喝干，再喝完。</span><br><span class="line">⑸阳关：在今甘肃省敦煌西南，为古代通西域的要道。故人：老朋友。</span><br></pre></td></tr></table></figure><h3 id="白话译文-4"><a href="#白话译文-4" class="headerlink" title="白话译文"></a>白话译文</h3><p><code>渭城清晨的细雨打湿了路边尘土，客舍边的杨柳愈发显得翠绿清新。 劝君再饮下这杯离别的美酒，向西出了阳关就再难遇到故人。</code></p><h3 id="创作背景-7"><a href="#创作背景-7" class="headerlink" title="创作背景"></a>创作背景</h3><p>此诗是王维送朋友去西北边疆时作的诗，后有乐人谱曲，名为“阳关三叠”，又名“渭城曲”，大约作于安史之乱前。其送行之地是渭城。诗人送友人元二远赴安西都护府，从长安一带送到渭城客舍，到了最后分手之地，作这首七绝送别。</p><h2 id="江上渔者"><a href="#江上渔者" class="headerlink" title="江上渔者"></a>江上渔者</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">江上渔者</span><br><span class="line">        北宋-范仲淹</span><br><span class="line">江上往来人，但2爱3鲈鱼4美。</span><br><span class="line">君5看一叶舟6，出没7风波8里。</span><br></pre></td></tr></table></figure><h3 id="注解-6"><a href="#注解-6" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><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></tr></table></figure><h3 id="白话译文-5"><a href="#白话译文-5" class="headerlink" title="白话译文"></a>白话译文</h3><p><code>江上来来往往的人们，只喜爱鲈鱼的美味。你看那渔人驾着像树叶一样的小舟，在大风大浪里时出时没。</code></p><h2 id="小雅·采薇"><a href="#小雅·采薇" class="headerlink" title="小雅·采薇"></a>小雅·采薇</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">小雅·采薇</span><br><span class="line">        西周-《诗经》</span><br><span class="line">采薇采薇，薇亦作止2。曰归曰归3，岁亦莫止4。 靡室靡家5，猃狁之故6。不遑启居7，猃狁之故。</span><br><span class="line">采薇采薇，薇亦柔止8。曰归曰归，心亦忧止。 忧心烈烈9，载饥载渴10。我戍未定11，靡使归聘12。</span><br><span class="line">采薇采薇，薇亦刚止13。曰归曰归，岁亦阳止14。 王事靡盬15，不遑启处16。忧心孔疚17，我行不来18！</span><br><span class="line">彼尔维何？维常之华19。彼路斯何20？君子之车21。 戎车既驾22，四牡业业23。岂敢定居24？一月三捷25。</span><br><span class="line">驾彼四牡，四牡骙骙26。君子所依，小人所腓27。 四牡翼翼28，象弭鱼服29。岂不日戒30？猃狁孔棘31！</span><br><span class="line"></span><br><span class="line">昔我往矣32，杨柳依依33。今我来思34，雨雪霏霏35。 行道迟迟36，载渴载饥。我心伤悲，莫知我哀！</span><br></pre></td></tr></table></figure><h3 id="注解-7"><a href="#注解-7" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">小雅：《诗经》中“雅”部分，分为大雅、小雅，合称“二雅”。雅，雅乐，即正调，指当时西周都城镐京地区的诗歌乐调。小雅部分今存七十四篇。薇：豆科野豌豆属的一种，学名救荒野豌豆，又叫大巢菜，种子、茎、叶均可食用。</span><br><span class="line"></span><br><span class="line">作：指薇菜冒出地面。止：句末助词，无实义。</span><br><span class="line"></span><br><span class="line">曰：句首、句中助词，无实义。</span><br><span class="line"></span><br><span class="line">莫（mù）：通“暮”，此指年末。</span><br><span class="line"></span><br><span class="line">靡（mǐ）室靡家：没有正常的家庭生活。靡，无。室，与“家”义同。</span><br><span class="line"></span><br><span class="line">猃（xiǎn）狁（yǔn）：中国古代少数民族名。</span><br><span class="line"></span><br><span class="line">不遑（huáng）：不暇。遑，闲暇。启居：跪、坐，指休息、休整。启，跪、跪坐。居，安坐、安居。古人席地而坐，两膝着席，危坐时腰部伸直，臀部与足离开；安坐时臀部贴在足跟上。</span><br><span class="line"></span><br><span class="line">柔：柔嫩。“柔”比“作”更进一步生长。指刚长出来的薇菜柔嫩的样子。</span><br><span class="line"></span><br><span class="line">烈烈：炽烈，形容忧心如焚。</span><br><span class="line"></span><br><span class="line">载（zài）饥载渴：则饥则渴，又饥又渴。载，又。</span><br><span class="line"></span><br><span class="line">戍：防守，这里指防守的地点。</span><br><span class="line"></span><br><span class="line">聘（pìn）：问候的音信。</span><br><span class="line"></span><br><span class="line">刚：坚硬。</span><br><span class="line"></span><br><span class="line">阳：农历十月，小阳春季节。今犹言“十月小阳春”。</span><br><span class="line"></span><br><span class="line">靡：无。盬（gǔ）：止息，了结。</span><br><span class="line"></span><br><span class="line">启处：休整，休息。</span><br><span class="line"></span><br><span class="line">孔：甚，很。疚：病，苦痛。</span><br><span class="line"></span><br><span class="line">我行不来：我不能回家。一说我从军出发后还没有人来慰问过。</span><br><span class="line"></span><br><span class="line">常：常棣（棠棣），既芣苡，植物名。</span><br><span class="line"></span><br><span class="line">路：高大的战车：斯何，犹言维何。斯，语气助词，无实义。</span><br><span class="line"></span><br><span class="line">君子：指将帅。</span><br><span class="line"></span><br><span class="line">戎：车，兵车。</span><br><span class="line"></span><br><span class="line">牡：雄马。业业：高大的样子。</span><br><span class="line"></span><br><span class="line">定居：犹言安居。</span><br><span class="line"></span><br><span class="line">捷：胜利。谓接战、交战。一说邪出，指改道行军。此句意谓，一月多次行军。</span><br><span class="line"></span><br><span class="line">骙（kuí）：雄强，威武。这里的骙骙是指马强壮的意思。</span><br><span class="line"></span><br><span class="line">小人：指士兵。腓（féi）：庇护，掩护。</span><br><span class="line"></span><br><span class="line">翼翼：整齐的样子。谓马训练有素。</span><br><span class="line"></span><br><span class="line">象弭（mǐ）：以象牙装饰弓端的弭。弭，弓的一种，其两端饰以骨角。一说弓两头的弯曲处。鱼服：鲨鱼鱼皮制的箭袋。</span><br><span class="line"></span><br><span class="line">日戒：日日警惕戒备。</span><br><span class="line"></span><br><span class="line">孔棘（jí）：很紧急。棘，急。</span><br><span class="line"></span><br><span class="line">昔：从前，文中指出征时。往：当初从军。</span><br><span class="line"></span><br><span class="line">依依：形容柳丝轻柔、随风摇曳的样子。</span><br><span class="line"></span><br><span class="line">思：用在句末，没有实在意义。</span><br><span class="line"></span><br><span class="line">雨（yù）雪：下雨。雨，这里作动词。霏（fēi）霏：雪花纷落的样子。</span><br><span class="line"></span><br><span class="line">迟迟：迟缓的样子。</span><br></pre></td></tr></table></figure><h3 id="白话译文-6"><a href="#白话译文-6" class="headerlink" title="白话译文"></a>白话译文</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">采薇采薇一把把，薇菜新芽已长大。说回家呀道回家，眼看一年又完啦。有家等于没有家，为跟玁狁去厮杀。没有空闲来坐下，为跟玁狁来厮杀。</span><br><span class="line"></span><br><span class="line">采薇采薇一把把，薇菜柔嫩初发芽。说回家呀道回家，心里忧闷多牵挂。满腔愁绪火辣辣，又饥又渴真苦煞。防地调动难定下，书信托谁捎回家！</span><br><span class="line"></span><br><span class="line">采薇采薇一把把，薇菜已老发杈枒。说回家呀道回家，转眼十月又到啦。王室差事没个罢，想要休息没闲暇。满怀忧愁太痛苦，生怕从此不回家。</span><br><span class="line"></span><br><span class="line">什么花儿开得盛？棠棣花开密层层。什么车儿高又大？高大战车将军乘。驾起兵车要出战，四匹壮马齐奔腾。边地怎敢图安居？一月要争几回胜！</span><br><span class="line"></span><br><span class="line">驾起四匹大公马，马儿雄骏高又大。将军威武倚车立，兵士掩护也靠它。四匹马儿多齐整，鱼皮箭袋雕弓挂。哪有一天不戒备，军情紧急不卸甲！</span><br><span class="line"></span><br><span class="line">回想当初出征时，杨柳依依随风吹；如今回来路途中，大雪纷纷满天飞。道路泥泞难行走，又渴又饥真劳累。满心伤感满腔悲。我的哀痛谁体会！</span><br></pre></td></tr></table></figure><h3 id="创作背景-8"><a href="#创作背景-8" class="headerlink" title="创作背景"></a>创作背景</h3><p>《采薇》是出自《诗经·小雅·鹿鸣之什》中的一篇。历代注者关于它的写作年代说法不一。但据它的内容和其它历史记载的考订大约是周宣王时代的作品的可能性大些。周代北方的猃狁(即后来的匈奴)已十分强悍，经常入侵中原，给当时北方人民生活带来不少灾难。历史上有不少周天子派兵戍守边外和命将士出兵打败猃狁的记载。从《采薇》的内容看，当是将士戍役劳还时之作。诗中唱出从军将士的艰辛生活和思归的情怀。</p><p>有关《采薇》这一首诗的背景，历来众说纷纭。据毛序为：“《采薇》，遣戍役也。文王之时，西有昆夷之患，北有猃狁之难。以天子之命，命将率遣戍役，以守卫中国。故歌《采薇》以遣之。”其实，真正的经典，无一例外都有着穿越时空的魅力。它曾经如此真切细微地属于一个人，但又如此博大深厚地属于每一个人。所以，纵然这首诗背后的那一场战争的烽烟早已在历史里淡去，而这首由戍边战士唱出来的苍凉的歌谣却依然能被每一个人编织进自己的生命里，让人们在这条民歌的河流里看见时间，也看到自己的身影。所以面对《采薇》，与其观世，不如观思;与其感受历史，不如感受生命。</p><h2 id="竹石"><a href="#竹石" class="headerlink" title="竹石"></a>竹石</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">竹石</span><br><span class="line">        清代-郑燮（郑板桥）</span><br><span class="line">咬定青山不放松1，立根原在破岩中2。</span><br><span class="line">千磨万击还坚劲3，任尔东西南北风4。</span><br></pre></td></tr></table></figure><h3 id="注解-8"><a href="#注解-8" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">咬定：咬紧</span><br><span class="line">立根：扎根。破岩：裂开的山岩，即岩石的缝隙。</span><br><span class="line">千磨万击：指无数的磨难和打击。坚劲：坚强有力。</span><br><span class="line">任：任凭，无论，不管。尔：你</span><br></pre></td></tr></table></figure><h3 id="白话译文-7"><a href="#白话译文-7" class="headerlink" title="白话译文"></a>白话译文</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">紧紧咬定青山不放松，原本深深扎根石缝中。</span><br><span class="line">千磨万击身骨仍坚劲，任凭你刮东西南北风。</span><br></pre></td></tr></table></figure><h3 id="创作背景-9"><a href="#创作背景-9" class="headerlink" title="创作背景"></a>创作背景</h3><p>这是一首题画诗，原题《竹石》，是郑板桥题自己画的竹石图的。</p><p><img src="https://cdn.yeefire.com/hexo/img/09fa513d269759ee59fe9836b0fb43166c22dfa5-2020-07-14.jpeg" alt="竹石"></p><h2 id="泊船瓜洲"><a href="#泊船瓜洲" class="headerlink" title="泊船瓜洲"></a>泊船瓜洲</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">泊船瓜洲</span><br><span class="line">        宋代-王安石</span><br><span class="line">京口瓜洲一水间，钟山只隔数重山。</span><br><span class="line">春风又绿江南岸，明月何时照我还？</span><br></pre></td></tr></table></figure><h3 id="注解-9"><a href="#注解-9" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">泊船：停船。泊，停泊。指停泊靠岸。</span><br><span class="line"></span><br><span class="line">京口：古城名。故址在江苏镇江市。</span><br><span class="line"></span><br><span class="line">瓜洲：镇名，在长江北岸，扬州南郊，即今扬州市南部长江边,京杭运河分支入江处。</span><br><span class="line"></span><br><span class="line">一水：一条河。古人除将黄河特称为“河”，长江特称为“江”之外，大多数情况下称河流为“水”，如汝水、汉水、浙水、湘水、澧水等。这里的“一水”指长江。一水间指一水相隔之间。</span><br><span class="line"></span><br><span class="line">间：根据平仄来认读jiàn四声。</span><br><span class="line"></span><br><span class="line">钟山：今南京市紫金山。</span><br><span class="line"></span><br><span class="line">绿：吹绿，拂绿。</span><br><span class="line"></span><br><span class="line">还：回。</span><br></pre></td></tr></table></figure><h3 id="白话译文-8"><a href="#白话译文-8" class="headerlink" title="白话译文"></a>白话译文</h3><p>京口和瓜洲之间只隔着一条长江，我所居住的钟山隐没在几座山峦的后面。暖和的春风啊，吹绿了江南的田野，明月什么时候才能照着我回到钟山下的家里？</p><h2 id="夜雨寄北"><a href="#夜雨寄北" class="headerlink" title="夜雨寄北"></a>夜雨寄北</h2><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">夜雨寄北</span><br><span class="line">        唐代（晚）-李商隐</span><br><span class="line">君2问归期3未有期，</span><br><span class="line">巴山4夜雨涨秋池5。</span><br><span class="line">何当6共7剪西窗烛8，</span><br><span class="line">却话9巴山夜雨时。</span><br></pre></td></tr></table></figure><h3 id="注解-10"><a href="#注解-10" class="headerlink" title="注解"></a>注解</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">寄北：写诗寄给北方的人。诗人当时在巴蜀（现在四川省），他的亲友在长安，所以说“寄北”。这首诗表达了诗人对亲友的深刻怀念。</span><br><span class="line">君：对对方的尊称，等于现代汉语中的“您”。 [2] </span><br><span class="line">归期：指回家的日期。</span><br><span class="line">巴山：指缙云山 [3]  ，在陕西南部和四川东北交界处。这里泛指巴蜀一带。 [2] </span><br><span class="line">秋池：秋天的池塘。</span><br><span class="line">何当：什么时候。</span><br><span class="line">共：副词，用在谓语前，表示动作行为是由两个或几个施事者共同发生的。可译为“一起”。 [2] </span><br><span class="line">剪西窗烛：剪烛，剪去燃焦的烛芯，使灯光明亮。这里形容深夜秉烛长谈。“西窗话雨”“西窗剪烛”用作成语，所指也不限于夫妇，有时也用以写朋友间的思念之情。 [2] </span><br><span class="line">却话：回头说，追述。</span><br></pre></td></tr></table></figure><h3 id="白话译文-9"><a href="#白话译文-9" class="headerlink" title="白话译文"></a>白话译文</h3><p><code>你问我何时回家，我回家的日期定不下来啊！我此时唯一能告诉你的，就是这正在盛满秋池的绵绵不尽的巴山夜雨了。如果有那么一天，我们一齐坐在家里的西窗下，共剪烛花，相互倾诉今宵巴山夜雨中的思念之情，那该多好！</code></p><h3 id="创作背景-10"><a href="#创作背景-10" class="headerlink" title="创作背景"></a>创作背景</h3><p>这首诗选自《玉溪生诗》卷三，是李商隐留滞巴蜀（今四川省）时寄怀长安亲友之作。因为长安在巴蜀之北，故题作《夜雨寄北》。</p><p>在南宋洪迈编的《万首唐人绝句》里，这首诗的题目为《夜雨寄内》，意思是诗是寄给妻子的。他们认为，李商隐于大中五年（851）七月赴东川节度使柳仲郢梓州幕府，而王氏是在这一年的夏秋之交病故，李商隐过了几个月才得知妻子的死讯。</p><p>现传李诗各本题作《夜雨寄北》，“北”就是北方的人，可以指妻子，也可以指朋友。有人经过考证认为它作于作者的妻子王氏去世之后，因而不是“寄内”诗，而是写赠长安友人的。</p><p>就诗的内容看，按“寄内”解，便情思委曲，悱恻缠绵；作“寄北”看，便嫌细腻恬淡，未免纤弱。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;语文古诗默写清单&quot;&gt;&lt;a href=&quot;#语文古诗默写清单&quot; class=&quot;headerlink&quot; title=&quot;语文古诗默写清单&quot;&gt;&lt;/a&gt;语文古诗默写清单&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;#%E5%AF%92%E9%A3%9F&quot;&gt;寒食    唐</summary>
      
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 技巧之场</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_sexy.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_sexy.html</id>
    <published>2020-06-22T09:22:20.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible-技巧之场"><a href="#Ansible-技巧之场" class="headerlink" title="Ansible 技巧之场"></a>Ansible 技巧之场</h1><p>看到技巧之场，我就想起来被百万<del>氪金</del>王支配的恐惧！</p><h2 id="拼接主机与http或其他字符串"><a href="#拼接主机与http或其他字符串" class="headerlink" title="拼接主机与http或其他字符串"></a>拼接主机与http或其他字符串</h2><p>有时候我们有一个列表，里面是IP地址。但是有时候我们要将<code>http://</code>拼接在每个IP地址的开头，可以利用Jinja2语法进行操作。</p><p>在模版中:</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;% set http_hosts=[] %&#125; # 定一个list变量</span><br><span class="line">&#123;% set hosts_list = discovery_seed_hosts | flatten %&#125;   # 将列表扁平化，因为这个变量列表里面存在嵌套的情况</span><br><span class="line">&#123;% for host in hosts_list %&#125;</span><br><span class="line">  &#123;% set _ = http_hosts.append(&quot;http://%s:%s&quot; % (host,9200)) %&#125; #使用Python语法进行操作。</span><br><span class="line">&#123;% endfor %&#125;</span><br></pre></td></tr></table></figure><p>在Plybook中（从网上找到的未经过测试，理论可行）:</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">set_fact:</span></span><br><span class="line">    <span class="attr">cluster_address:</span> <span class="string">|</span></span><br><span class="line"><span class="string">       [</span></span><br><span class="line"><span class="string">         &#123;% set pxc_hosts = groups.pxc %&#125;</span></span><br><span class="line"><span class="string">         &#123;% for host in pxc_hosts %&#125;</span></span><br><span class="line"><span class="string">           &#123;% set pxc_ip = hostvars[host].inventory_hostname | default(host) %&#125;</span></span><br><span class="line"><span class="string">           &#123;% set pxc_port = group_port %&#125;</span></span><br><span class="line"><span class="string">           &quot;&#123;&#123; pxc_ip &#125;&#125;:&#123;&#123; pxc_port &#125;&#125;&quot;  </span></span><br><span class="line"><span class="string">         &#123;% endfor -&#125;</span></span><br><span class="line"><span class="string">       ]</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="comment"># 使用的时候</span></span><br><span class="line">&#123;&#123; <span class="string">cluster_address</span> <span class="string">|</span> <span class="string">join(&#x27;</span>,<span class="string">&#x27;) &#125;&#125;&#x27;</span>  <span class="comment"># 使用join 过滤器可生成&#x27;,&#x27; 分隔的字符串，分隔符自己定义</span></span><br></pre></td></tr></table></figure><h2 id="对字符串的操作"><a href="#对字符串的操作" class="headerlink" title="对字符串的操作"></a>对字符串的操作</h2><p>得益于Python特性，在Ansible中可以使用Python中处理字符串的语法。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">你可以对字符串进行取单个字符等操作: &#123;&#123; vars[2] &#125;&#125;</span><br><span class="line"></span><br><span class="line">也可以切片: &#123;&#123; vars[3:6]&#125;&#125;</span><br><span class="line"></span><br><span class="line">判断某些字符是否在字符串中: when: &quot;&#x27;haha&#x27; in vars&quot;</span><br><span class="line"></span><br><span class="line">使用加号连接两个字符串: &#123;&#123; var1+var2 &#125;&#125;</span><br><span class="line"></span><br><span class="line">使用乘号*连续输出字符串: &#123;&#123; var1*3 / &#x27;la&#x27;*nums &#125;&#125;</span><br><span class="line"></span><br><span class="line">使用find函数查找: </span><br><span class="line"></span><br><span class="line">when: &#123;&#123; vars.find(&#x27;test&#x27;) == -1 &#125;&#125; # 值为</span><br><span class="line"></span><br><span class="line">find函数的语法是find(string,begin,end)</span><br><span class="line"></span><br><span class="line">when: &#123;&#123; vars.find(&#x27;test&#x27;,5) == -1 &#125;&#125;  # 从第5位开始查找</span><br></pre></td></tr></table></figure><h2 id="任务委派"><a href="#任务委派" class="headerlink" title="任务委派"></a>任务委派</h2><p>有时候你想让某一个tasks在指定的某一个受控主机上运行而不是要在Play中指定的组或主机中全部运行这个tasks。</p><p>这种情况下可以新写一个Play，然后将hosts和tasks进行指定。但是这样要新建一个Play，有点麻烦。</p><p>可以使用<code>delegate_to</code>关键字来让某一个tasks指定运行在某一台主机上，<strong>任务委派时不会去看目标主机是否在inventory主机清单中</strong>。可以指定代码块进行任务委派。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">&quot;only host&quot;</span></span><br><span class="line">      <span class="attr">delegate_to:</span> <span class="number">192.168</span><span class="number">.1</span><span class="number">.196</span></span><br><span class="line"></span><br><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="attr">ok:</span> [<span class="number">192.168</span><span class="number">.1</span><span class="number">.39</span> <span class="string">-&gt;</span> <span class="number">192.168</span><span class="number">.1</span><span class="number">.196</span>] <span class="string">=&gt;</span> &#123;</span><br><span class="line">    <span class="attr">&quot;msg&quot;:</span> <span class="string">&quot;only host&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="仅在主机上执行"><a href="#仅在主机上执行" class="headerlink" title="仅在主机上执行"></a>仅在主机上执行</h2><p>如果指向让某一个任务在本主机上运行。你可以使用刚刚的任务委派，来指向Ansible控制节点。也可以尝试<code>connection: local</code>关键字。</p><p>connection关键字也可以用于代码块和任务。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">block:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">systemd:</span></span><br><span class="line">            <span class="attr">name:</span> <span class="string">elasticsearch</span></span><br><span class="line">            <span class="attr">state:</span> <span class="string">restarted</span></span><br><span class="line">          <span class="attr">connection:</span> <span class="string">local</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="仅运行一遍任务"><a href="#仅运行一遍任务" class="headerlink" title="仅运行一遍任务"></a>仅运行一遍任务</h2><p>在某些情况下，下载资源到本地时，你只需要下载一次就可以。但是任务却执行和主机清单中相同的次数。得益于Ansible模块幂等性，虽然说任务运行很多次，但只有第一次真正进行了下载，对我们的影响不大。但是能否继续减少性能开支呢。</p><p>使用<code>run_once: true</code>关键字让任务或代码块只运行一次。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="string">-</span> <span class="string">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="string">gather_facts:</span> <span class="literal">no</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">  <span class="string">-</span> <span class="attr">get_url:</span></span><br><span class="line">      <span class="string">url:</span> <span class="string">&quot;https://github.com/rofl0r/proxychains-ng/archive/v4.14.tar.gz&quot;</span></span><br><span class="line">      <span class="string">dest:</span> <span class="string">&quot;/tmp&quot;</span></span><br><span class="line">    <span class="string">connection:</span> <span class="string">local</span></span><br><span class="line">    <span class="string">run_once:</span> <span class="literal">true</span></span><br><span class="line"> </span><br><span class="line">  <span class="string">-</span> <span class="attr">copy:</span></span><br><span class="line">      <span class="string">src:</span> <span class="string">&quot;/tmp/v4.14.tar.gz&quot;</span></span><br><span class="line">      <span class="string">dest:</span> <span class="string">&quot;/tmp&quot;</span></span><br></pre></td></tr></table></figure><h2 id="遇到过的错误…"><a href="#遇到过的错误…" class="headerlink" title="遇到过的错误…"></a>遇到过的错误…</h2><h3 id="在when关键字中使用了Jinja2语法"><a href="#在when关键字中使用了Jinja2语法" class="headerlink" title="在when关键字中使用了Jinja2语法"></a>在when关键字中使用了Jinja2语法</h3><p><code>[WARNING]: conditional statements should not include jinja2 templating delimiters such as &#123;&#123; &#125;&#125; or &#123;% %&#125;. Found:XXX</code></p><p>在when关键字中不应该包含Jinja2语法。在使用循环或者变量时不小心就会顺手把花括号加上。此时会发出警告。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="string">错误用法：</span></span><br><span class="line"><span class="attr">when:</span> <span class="string">&quot;&#x27;<span class="template-variable">&#123;&#123;item.hosts&#125;&#125;</span>&#x27; in group_names&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="string">正确用法：</span></span><br><span class="line"><span class="attr">when:</span> <span class="string">item.hosts</span> <span class="string">in</span> <span class="string">group_names</span></span><br></pre></td></tr></table></figure><h3 id="没有获取事实就要使用hostvars获取变量"><a href="#没有获取事实就要使用hostvars获取变量" class="headerlink" title="没有获取事实就要使用hostvars获取变量"></a>没有获取事实就要使用<code>hostvars</code>获取变量</h3><p>在主机没有gether facts事实之前，是无法通过hostvars来获取它的事实变量的。这个错误在生成hosts文件时出现过一次，折腾了好久。难受的是没有指向正确的报错位置，这导致我在错误的方向研究了好久都没有解决。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="string">错误用法：</span></span><br><span class="line"><span class="attr">when:</span> <span class="string">&quot;&#x27;<span class="template-variable">&#123;&#123;item.hosts&#125;&#125;</span>&#x27; in group_names&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="meta"></span></span><br><span class="line"><span class="string">正确用法：</span></span><br><span class="line"><span class="attr">when:</span> <span class="string">item.hosts</span> <span class="string">in</span> <span class="string">group_names</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ansible-技巧之场&quot;&gt;&lt;a href=&quot;#Ansible-技巧之场&quot; class=&quot;headerlink&quot; title=&quot;Ansible 技巧之场&quot;&gt;&lt;/a&gt;Ansible 技巧之场&lt;/h1&gt;&lt;p&gt;看到技巧之场，我就想起来被百万&lt;del&gt;氪金&lt;/del&gt;王支</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 包含和导入文件</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_include.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_include.html</id>
    <published>2020-06-16T12:29:36.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible-包含和导入文件"><a href="#Ansible-包含和导入文件" class="headerlink" title="Ansible 包含和导入文件"></a>Ansible 包含和导入文件</h1><p>如果Playbook很长或很复杂，可以尝试将其分成较小的文件以便与管理。适宜食用模块化方式将多个Playbook组合成一个主要的Playbook，或者将文件中的任务列表插入到Play中。和杨可以更轻便、更加便于管理的操作项目中的Play和任务序列。</p><h2 id="包含与导入文件概念区别"><a href="#包含与导入文件概念区别" class="headerlink" title="包含与导入文件概念区别"></a>包含与导入文件概念区别</h2><p>Ansible支持两种方式将内容带入到Playbook，可以使用包含内容，也可以使用导入内容。</p><p>包含内容(include)是一个动态的过程。在playbook运行期间，Ansible会在内容到达时再去处理所包含的内容。</p><p>导入内容(import)是一个静态操作。在最开始的时候Ansible运行Playbook时就将它解析好并导入到要执行的这个Playbook中了。</p><h2 id="导入Playbook"><a href="#导入Playbook" class="headerlink" title="导入Playbook"></a>导入Playbook</h2><p>使用<code>import_playbook</code>指令可以将外部的Playbook导入到当前的Playbook中。</p><p>导入的Playbook是一个完成的playbook，因此要使用<code>import_playbook</code>指令需要在Play的位置导入，而不能在tasks处进行导入Playbook。如果你导入了多喝playbook，则将按照导入的顺序一次运行.</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Play1</span></span><br><span class="line">  <span class="attr">import_playbook:</span> <span class="string">web.yml</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Play2</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">localhost</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">This</span> <span class="string">is</span> <span class="string">Play</span> <span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Play3</span></span><br><span class="line">  <span class="attr">import_playbook:</span> <span class="string">db.yml</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>在上面的例子中，会一次执行三个Play，并且导入操作可以和展开的Play穿插使用。</p><h2 id="导入和包含任务"><a href="#导入和包含任务" class="headerlink" title="导入和包含任务"></a>导入和包含任务</h2><p>可以将任务文件中的任务列表导入或包含在Play中。任务文件是包含一个任务平面列表的文件:</p><p><code>vim tasks_firewalld.yml</code></p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">the</span> <span class="string">firewall</span></span><br><span class="line">  <span class="attr">yum:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">firewalld</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">latest</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Start</span> <span class="string">the</span> <span class="string">firewall</span></span><br><span class="line">  <span class="attr">service:</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">firewalld</span></span><br><span class="line">    <span class="attr">enabled:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><h3 id="导入任务文件"><a href="#导入任务文件" class="headerlink" title="导入任务文件"></a>导入任务文件</h3><p>使用<code>import_tasks</code>功能将任务文件静态导入Playbook的Play中。在一开始解析Playbook时就会将该任务文件插入到Play中。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Play</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">localhost</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">This</span> <span class="string">is</span> <span class="string">Play</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">I&#x27;m</span> <span class="string">Import</span> <span class="string">Task</span></span><br><span class="line">      <span class="attr">import_tasks:</span> <span class="string">db.yml</span></span><br></pre></td></tr></table></figure><ul><li>使用import_tasks功能时，导入时设置的when等条件语句将应用于导入的每个任务。</li><li>使用import_tasks功能时，无法将loop循环应用在上面。</li><li>如果使用变量来指定要导入的文件的名称，则无法使用主机或组清单变量。</li></ul><h3 id="包含任务文件"><a href="#包含任务文件" class="headerlink" title="包含任务文件"></a>包含任务文件</h3><p>使用<code>include_tasks</code>可以将任务文件动态包含进Tasks中。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Play</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">localhost</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">      <span class="attr">include_tasks:</span> <span class="string">db.yml</span></span><br></pre></td></tr></table></figure><p>在Play运行到达该Tasks前，Ansible不会处理该任务文件的任何内容。使用<code>include_tasks</code>时，包含时设置的<code>when</code>等条件语句将确定任务是否包含在Play中。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ansible-包含和导入文件&quot;&gt;&lt;a href=&quot;#Ansible-包含和导入文件&quot; class=&quot;headerlink&quot; title=&quot;Ansible 包含和导入文件&quot;&gt;&lt;/a&gt;Ansible 包含和导入文件&lt;/h1&gt;&lt;p&gt;如果Playbook很长或很复杂，可</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 学习文档</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_index.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_index.html</id>
    <published>2020-06-16T12:28:36.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible-学习文档"><a href="#Ansible-学习文档" class="headerlink" title="Ansible 学习文档"></a>Ansible 学习文档</h1><p>Ansible自动化运维学习。大部分操作及示例基于RHEL8实现。</p><p>文档未进行过任何校对和查错，目前仅用于个人学习使用。文档中可能会包含错误，请您雅正，谢谢。</p><p>最近一次的更新日期：2020年6月27日</p><p><a href="#2020%E5%B9%B46%E6%9C%8827%E6%97%A5">本次更新内容</a>：继续完成《Ansible 常用模块》 ⭕️</p><p>近期持续更新Ansible常用模块。</p><h2 id="文档列表"><a href="#文档列表" class="headerlink" title="文档列表"></a>文档列表</h2><ul><li><a href="https://blog.yeefire.com/2020_05/ansible_basic.html">Ansible 基础概念</a> 介绍Ansible主机清单、模块、配置文件</li><li><a href="https://blog.yeefire.com/2020_06/ansible_playbook.html">Ansible Playbook</a> 介绍Ansible Playbook编写、格式、如何检查语法错误</li><li><a href="https://blog.yeefire.com/2020_06/ansible_vars.html">Ansible 变量和事实</a> 如何定义变量、使用变量。魔法变量、Facts事实、加密敏感变量</li><li><a href="https://blog.yeefire.com/2020_06/ansible_mod.html">Ansible 常用模块</a> 对文件、网络、磁盘等模块操作、Jinja2模板（持续更新）、软件包管理、系统调度</li><li><a href="https://blog.yeefire.com/2020_06/ansible_control.html">Ansible 任务控制</a> 如何进行循环控制、条件控制、代码块、错误处理以及处理程序</li><li><a href="https://blog.yeefire.com/2020_06/ansible_include.html">Ansible 包含和导入文件</a> 包含、导入 任务或Play</li><li><a href="https://blog.yeefire.com/2020_06/ansible_forks.html">Ansible 调整连接数量</a> 设置连接数、批次执行任务</li><li><a href="https://blog.yeefire.com/2020_06/ansible_inventory.html">Ansible 主机模式</a> 深入Ansible 受控主机清单</li><li><a href="https://blog.yeefire.com/2020_06/ansible_role.html">Ansible 角色</a> 创建、使用角色框架、角色内部处理任务的顺序、使用角色安装V2ray-core示例</li><li><a href="https://blog.yeefire.com/2020_06/ansible_sexy.html">Ansible 技巧之场</a> 神尼玛技巧之场？你以为是亚瑟王？</li></ul><h2 id="更新日志"><a href="#更新日志" class="headerlink" title="更新日志"></a>更新日志</h2><h3 id="2020年6月27日"><a href="#2020年6月27日" class="headerlink" title="2020年6月27日"></a>2020年6月27日</h3><ul><li>继续完成《Ansible 常用模块》 ⭕️</li></ul><h3 id="2020年6月22日"><a href="#2020年6月22日" class="headerlink" title="2020年6月22日"></a>2020年6月22日</h3><ul><li>完成《Ansible 技巧之场》✅</li></ul><h3 id="2020年6月18日"><a href="#2020年6月18日" class="headerlink" title="2020年6月18日"></a>2020年6月18日</h3><ul><li>修复《Ansible 任务控制》中部分Markdown解析错误</li></ul><h3 id="2020年6月16日"><a href="#2020年6月16日" class="headerlink" title="2020年6月16日"></a>2020年6月16日</h3><ul><li>Ansible角色 ✅</li><li>添加部分刚刚没有同步到文档中的内容</li><li>添加软件包管理模块使用</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ansible-学习文档&quot;&gt;&lt;a href=&quot;#Ansible-学习文档&quot; class=&quot;headerlink&quot; title=&quot;Ansible 学习文档&quot;&gt;&lt;/a&gt;Ansible 学习文档&lt;/h1&gt;&lt;p&gt;Ansible自动化运维学习。大部分操作及示例基于RHEL8</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 主机模式</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_inventory.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_inventory.html</id>
    <published>2020-06-16T12:28:36.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible-主机模式"><a href="#Ansible-主机模式" class="headerlink" title="Ansible 主机模式"></a>Ansible 主机模式</h1><p>通过主机模式，可以更高效地为play或命令选择受控主机。除了常规的使用组名或清单中的IP地址以及all、ungrouped外，你还可以使用以下方式匹配受控主机。</p><h2 id="使用通配符匹配"><a href="#使用通配符匹配" class="headerlink" title="使用通配符匹配"></a>使用通配符匹配</h2><p>使用<code>&#39;*&#39;</code>匹配模式会与<code>all</code>主机模式具有相同的效果，它会匹配任意字符串，会使用清单中的全部主机。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">&#x27;*&#x27;</span></span><br></pre></td></tr></table></figure><p>也可以使用*与文字进行匹配，使用通配符匹配以<code>.example.com</code>结尾的全部主机例子如下：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">&#x27;*.example.com&#x27;</span></span><br></pre></td></tr></table></figure><p>匹配192.168开头的全部主机或主机组的名称：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">&#x27;192.168*&#x27;</span></span><br></pre></td></tr></table></figure><blockquote><p>⚠️注意：使用匹配模式匹配时，Ansible不会区分它是主机还是组的名字。如果主机的域名和组名有被匹配到，那么不管是主机还是主机组中全部的主机都会被匹配。</p></blockquote><h2 id="使用逗号匹配多个主机和组"><a href="#使用逗号匹配多个主机和组" class="headerlink" title="使用逗号匹配多个主机和组"></a>使用逗号匹配多个主机和组</h2><p>使用逗号可以来匹配多个主机和组，可以混合使用受控主机、主机组和通配符。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">&#x27;server1.com,*.example.com,192.168.1.1&#x27;</span></span><br></pre></td></tr></table></figure><blockquote><p>也可以使用<code>:</code>冒号作为分隔符进行分隔，特别是将IPv6地址用作受管主机名称时。不过在较老的例子中依旧可以见到使用冒号进行分隔。</p></blockquote><h2 id="使用-amp-和"><a href="#使用-amp-和" class="headerlink" title="使用&amp;和!"></a>使用<code>&amp;</code>和<code>!</code></h2><p>如果在使用逗号的列表中某一项与<code>&amp;</code>结合，则主机必须与该项也匹配才会匹配主机模式。</p><p>如下例子，主机模式匹配同时出现在lab组和datacenter组中的主机才能作为受控主机。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">&#x27;lab,&amp;datacenter&#x27;</span></span><br></pre></td></tr></table></figure><p>也可以通过在主机模式前面使用感叹号<code>!</code>，从列表中排除匹配某以模式的主机。他的工作方式类似于逻辑NOT。</p><p>如下例子：主机模式匹配datacenter中的所有主机，但是server1.example.com主机除外！</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">&#x27;datacenter,!server1.example.com&#x27;</span></span><br></pre></td></tr></table></figure><h2 id="管理动态清单"><a href="#管理动态清单" class="headerlink" title="管理动态清单"></a>管理动态清单</h2><p>目前为止使用静态清单很容易编写，对于管理小型的主机架构很方便。但是如果要操作一个大型的集群中许许多多的计算机，或者在机器交替非常快的环境工作，在面对维护主机静态清单想必是不太好受。</p><blockquote><p>在大型IT环境下，通常会有系统来跟踪服务器资产，比如有外部目录服务通过Zabbix等监控系统维护，或者位于FreeIPA或Active Directory服务器上。Cobbler等安装服务器或红帽卫星等管理服务可能跟踪部署的逻辑系统。</p></blockquote><p>Ansible支持动态清单脚本，这些清单脚本在Ansible执行时会执行脚本并检索当前信息，时清单能够得到实时的更新。这些脚本时可以执行的程序，能够从一些外部来源收集信息，并以JSON格式输出清单。</p><p>动态清单脚本的使用和静态清单一样。清单的位置可以直接在ansible.cfg中配置，也可以通过-i选型指定。如果清单文件可以执行，则会被视作动态清单程序，Ansible会尝试运行脚本来生成清单。如果文件不可执行，则它会被视作静态清单。</p><blockquote><p>在使用动态清单时要确保该脚本具有执行权限并且返回值为JSON数据类型。</p></blockquote><h2 id="管理多个清单"><a href="#管理多个清单" class="headerlink" title="管理多个清单"></a>管理多个清单</h2><p>Ansible支持在同一运行中使用多个清单，如果配置清单的地址是一个目录，那么会使用该目录下所有的清单文件，如果可执行文件会作为动态清单文件对待。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ansible-主机模式&quot;&gt;&lt;a href=&quot;#Ansible-主机模式&quot; class=&quot;headerlink&quot; title=&quot;Ansible 主机模式&quot;&gt;&lt;/a&gt;Ansible 主机模式&lt;/h1&gt;&lt;p&gt;通过主机模式，可以更高效地为play或命令选择受控主机。除了</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 角色</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_role.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_role.html</id>
    <published>2020-06-16T12:28:36.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible角色"><a href="#Ansible角色" class="headerlink" title="Ansible角色"></a>Ansible角色</h1><p>使用Ansible角色可以有更多的机会去重用以前便携的Playbook中的代码。可以在标准化目录结构中打包所有任务、变量、文件、模版以及调配基础架构或部署应用其他资源。</p><p>除了自行编写、使用角色外，也可从其他来源获取角色。常用红帽企业Linux管理角色包含在<code>rhel-system-roles</code>软件包中可以方便的去使用。也可以从Ansible Galaxy网站获取由社区提供的其他角色。</p><p>使用<code>ansible-galaxy list</code>可以看到在在当前Ansible配置环境下找到了Role角色列表。</p><p>那么Ansible怎么发现这些Role呢？这些Role的路径在ansible.cfg配置文件中已经定义好了，每个目录之间通过冒号分隔：</p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[defaults]</span></span><br><span class="line"><span class="attr">inventory</span>=./inventory</span><br><span class="line"><span class="attr">remote_user</span>=devops</span><br><span class="line"><span class="attr">roles_path</span>=./roles:/usr/share/ansible/roles:/etc/ansible/roles</span><br></pre></td></tr></table></figure><h2 id="Ansible角色子目录"><a href="#Ansible角色子目录" class="headerlink" title="Ansible角色子目录"></a>Ansible角色子目录</h2><table><thead><tr><th align="left">子目录</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">defaults</td><td align="left">此目录中的main.yml文件包含角色变量的默认值，使用角色时可以覆盖这些默认值。这些变量的优先级较低，应该在Play中更改和定义。</td></tr><tr><td align="left">files</td><td align="left">此目录包含由角色要处理的全部静态文件</td></tr><tr><td align="left">handles</td><td align="left">此目录中的main.yml文件包含角色的处理程序</td></tr><tr><td align="left">meta</td><td align="left">main.yml中包含角色相关信息，如作者、许可证、平台、角色依赖项</td></tr><tr><td align="left">tasks</td><td align="left">main.yml中包含角色任务的定义</td></tr><tr><td align="left">templates</td><td align="left">此目录包含角色引用的template模板</td></tr><tr><td align="left">tests</td><td align="left">此目录包含清单和test.yml Playbook，用于进行测试</td></tr><tr><td align="left">vars</td><td align="left">此目录的main.yml文件定义角色的变量值。这些变量通常用于角色内部用途。这些变量的优先级较高，不应在Playbook中覆盖修改</td></tr></tbody></table><h2 id="定义变量和默认值"><a href="#定义变量和默认值" class="headerlink" title="定义变量和默认值"></a>定义变量和默认值</h2><p>对于角色变量可以通过在vars目录下的main.yml文件来定义。与其他变量一样，使用这些变量需要在角色文件中引入<code>&#123;&#123; VARS_NAME &#125;&#125;</code>。这些变量具有较高的优先级，无法被Ansible中清单变量覆盖。</p><p>默认变量在defaults目录下的main.yml文件中定义。它们的变量优先级是最低的，任何定义变量的形式都会将其覆盖，所以更改默认变量可以使Play操作更精准、更适合受控主机。</p><p>可以在vars/main.yml或defaults/main.yml中定义具体的变量，但没必要在两者中都定义变量。</p><h2 id="在Playbook中使用Ansible角色"><a href="#在Playbook中使用Ansible角色" class="headerlink" title="在Playbook中使用Ansible角色"></a>在Playbook中使用Ansible角色</h2><p>可以在Play中引入roles即可使用。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">hosts:</span> <span class="string">remote</span> <span class="string">server</span></span><br><span class="line">  <span class="attr">roles:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">role1</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">role2</span></span><br></pre></td></tr></table></figure><p>角色中使用的任何copy、script、template或include_tasks/import_tasks任务都可以引用角色中相关的文件、模版或任务文件，并且无需使用相对路径或绝对路径，因为Ansible会自动在角色的files、templates、tasks子目录下去寻找他们。</p><h2 id="控制执行顺序"><a href="#控制执行顺序" class="headerlink" title="控制执行顺序"></a>控制执行顺序</h2><p>在Ansible中的每一个Play是会按照Play的顺序依次执行。在每个Play中如果定义了角色，那么会优先运行角色，之后再运行任务。在最后执行被激活的handles处理程序。</p><p>在某些情况下，可能需要在执行角色任务之前执行一些任务，你可以为Play配置<code>pre_tasks</code>部分，这样就可以在运行角色之前执行一部分任务。如果配置在<code>pre_tasks</code>中的任务出发了handles处理程序。那么也会在角色或其他普通任务之前执行处理程序。</p><p>当然也可以使用为Play配置<code>post_tasks</code>部分，来让任务在普通任务之后和激活的处理程序之后再运行。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Play</span> <span class="string">to</span> <span class="string">illustrate</span> <span class="string">order</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">example.com</span></span><br><span class="line">  <span class="attr">pre_tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">&quot;I am pre task&quot;</span></span><br><span class="line">      <span class="attr">notify:</span> <span class="string">my</span> <span class="string">handler</span></span><br><span class="line">  <span class="attr">roles:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">role1</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">&quot;I am nomal task&quot;</span></span><br><span class="line">      <span class="attr">notify:</span> <span class="string">my</span> <span class="string">handler</span></span><br><span class="line">  <span class="attr">post_tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">&quot;I am posted handler&quot;</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>上面的例子中，每个任务部分都会执行debug任务来通知my handler处理程序。my handler任务执行了三次：</p><ul><li>第一次在执行了所有的pre_tasks任务后执行处理程序</li><li>第二次在执行角色结束后的普通tasks任务后执行</li><li>第三次是在执行完post_tasks任务后执行处理程序</li></ul><p>除了将角色包含在Play中的roles部分外，也可以将角色添加到普通的tasks中。使用<code>include_role</code>模块可以动态包含角色，使用<code>import_role</code>模块可以静态导入角色。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Execute</span> <span class="string">a</span> <span class="string">role</span> <span class="string">as</span> <span class="string">a</span> <span class="string">task</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">localhost</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">a</span> <span class="string">simple</span> <span class="string">task</span></span><br><span class="line">      <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">&quot;Im first task&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;A task to include role here&quot;</span></span><br><span class="line">      <span class="attr">include_role:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">linux-system-roles.network</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><h2 id="RHEL-系统角色"><a href="#RHEL-系统角色" class="headerlink" title="RHEL 系统角色"></a>RHEL 系统角色</h2><p>RHEL红帽系统中，从Linux 7.4开始，系统内随附了多个Ansible角色。它们位于<code>rhel-system-roles</code>软件包内。RHEL8中，需要启动AppStream仓库来安装此软件包。</p><table><thead><tr><th align="left">角色名</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">rhel-system-roles.kdump</td><td align="left">配置kdump崩溃恢复服务</td></tr><tr><td align="left">rhel-system-roles.network</td><td align="left">配置网络</td></tr><tr><td align="left">rhel-system-roles.postfix</td><td align="left">配置postfix服务为每个主机配置邮件传输代理</td></tr><tr><td align="left">rhel-system-roles.selinux</td><td align="left">配置和管理SELinux自定义，包括模式、文件、端口上下文、布尔值设置和SELinux用户</td></tr><tr><td align="left">rhel-system-roles.timesync</td><td align="left">使用网络时间协议配置时间同步</td></tr></tbody></table><h3 id="访问RHEL系统角色文档"><a href="#访问RHEL系统角色文档" class="headerlink" title="访问RHEL系统角色文档"></a>访问RHEL系统角色文档</h3><p>安装后，这些RHEL系统角色文档存放在<code>/usr/share/doc/rhel-system-roles</code>中，其中还包含了如何去使用以及使用的例子。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">├── kdump</span><br><span class="line">│   ├── COPYING</span><br><span class="line">│   ├── README.html</span><br><span class="line">│   └── README.md</span><br><span class="line">├── network</span><br><span class="line">│   ├── example-bond-with-vlan-playbook.yml</span><br><span class="line">│   ├── example-bridge-with-vlan-playbook.yml</span><br><span class="line">│   ├── example-down-profile-playbook.yml</span><br><span class="line">│   ├── example-eth-simple-auto-playbook.yml</span><br><span class="line">│   ├── example-eth-with-vlan-playbook.yml</span><br><span class="line">│   ├── example-infiniband-playbook.yml</span><br><span class="line">│   ├── example-inventory</span><br><span class="line">│   ├── example-macvlan-playbook.yml</span><br><span class="line">│   ├── example-remove-profile-playbook.yml</span><br><span class="line">│   ├── LICENSE</span><br><span class="line">│   ├── README.html</span><br><span class="line">│   └── README.md</span><br><span class="line">├── postfix</span><br><span class="line">│   ├── COPYING</span><br><span class="line">│   ├── README.html</span><br><span class="line">│   └── README.md</span><br><span class="line">├── selinux</span><br><span class="line">│   ├── COPYING</span><br><span class="line">│   ├── example-selinux-playbook.yml</span><br><span class="line">│   ├── README.html</span><br><span class="line">│   └── README.md</span><br><span class="line">└── timesync</span><br><span class="line">    ├── COPYING</span><br><span class="line">    ├── example-timesync-playbook.yml</span><br><span class="line">    ├── example-timesync-pool-playbook.yml</span><br><span class="line">    ├── README.html</span><br><span class="line">    └── README.md</span><br></pre></td></tr></table></figure><h3 id="时间同步角色例子"><a href="#时间同步角色例子" class="headerlink" title="时间同步角色例子"></a>时间同步角色例子</h3><p>如果为受控主机配置NTP时间同步服务，那么可以使用<code>rhel-system-roles.timesync</code>角色自动化配置。</p><p>通过<code>/usr/share/doc/rhel-system-roles/timesync/README.md</code>查看示例和需要用到的变量。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Config</span> <span class="string">NTP</span> <span class="string">sync</span> <span class="string">service</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">vars:</span></span><br><span class="line">     <span class="attr">timesync_ntp_servers:</span></span><br><span class="line">       <span class="bullet">-</span> <span class="attr">hostname:</span> <span class="number">0.</span><span class="string">rhel.pool.ntp.org</span></span><br><span class="line">         <span class="attr">iburst:</span> <span class="literal">yes</span></span><br><span class="line">       <span class="bullet">-</span> <span class="attr">hostname:</span> <span class="number">1.</span><span class="string">rhel.pool.ntp.org</span></span><br><span class="line">         <span class="attr">iburst:</span> <span class="literal">yes</span></span><br><span class="line">     <span class="attr">timezone:</span> <span class="string">Asia/Shanghai</span></span><br><span class="line">  <span class="attr">roles:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">rhel-system-roles.timesync</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Set</span> <span class="string">TimeZone</span></span><br><span class="line">      <span class="attr">timezone:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; timezone &#125;&#125;</span>&quot;</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>也可以把在Play中定义的变量放到变量文件中。将变量文件可以放到<code>group_vars</code>或<code>host_vars</code>子目录中。</p><h3 id="配置SELinux角色"><a href="#配置SELinux角色" class="headerlink" title="配置SELinux角色"></a>配置SELinux角色</h3><p>使用<code>linux-system-roles.selinux</code>角色控制SELinux行为。t</p><p>通过<code>/usr/share/doc/rhel-system-roles/selinux/README.md</code>查看示例和需要用到的变量。</p><h4 id="设置SELinux运行模式"><a href="#设置SELinux运行模式" class="headerlink" title="设置SELinux运行模式"></a>设置SELinux运行模式</h4><p>变量 <code>selinux_state: enforcing</code>。可以设置为enforing、permissive、disabled。如果不设置则不更改。</p><h4 id="设置SELinux布尔值"><a href="#设置SELinux布尔值" class="headerlink" title="设置SELinux布尔值"></a>设置SELinux布尔值</h4><p>例如将httpd_enable_homedirs布尔值永久设置为no</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">selinux_booleans:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&#x27;http_enable_homedirs&#x27;</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">&#x27;on&#x27;</span></span><br><span class="line">    <span class="attr">persistent:</span> <span class="string">&#x27;yes&#x27;</span></span><br></pre></td></tr></table></figure><h4 id="设置SELinux-fcontext上下文"><a href="#设置SELinux-fcontext上下文" class="headerlink" title="设置SELinux fcontext上下文"></a>设置SELinux fcontext上下文</h4><p>下面的例子完成了对<code>/srv/www</code>目录下的所有文件的默认SELinux类型设置为<code>httpd_sys_content_t</code>。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">selinux_fcontexts:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">target:</span> <span class="string">&#x27;/srv/www(/.*)?&#x27;</span></span><br><span class="line">    <span class="attr">setype:</span> <span class="string">&#x27;httpd_sys_content_t&#x27;</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><p>使用<code>selinux_restore_dirs</code>变量指定要对其运行<code>restorecon</code>目录的列表。</p><h4 id="设置SELinux端口"><a href="#设置SELinux端口" class="headerlink" title="设置SELinux端口"></a>设置SELinux端口</h4><p>使用<code>selinux_ports</code>变量可以对端口进行管理。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">selinux_ports:</span> </span><br><span class="line">  <span class="bullet">-</span> <span class="attr">ports:</span> <span class="string">&#x27;82&#x27;</span></span><br><span class="line">    <span class="attr">setype:</span> <span class="string">&#x27;http_port_t&#x27;</span></span><br><span class="line">    <span class="attr">proto:</span> <span class="string">&#x27;tcp&#x27;</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">&#x27;present&#x27;</span></span><br></pre></td></tr></table></figure><h2 id="创建角色框架"><a href="#创建角色框架" class="headerlink" title="创建角色框架"></a>创建角色框架</h2><p>创建角色不需要额外的开发工具，角色是文件目录结构和文件组成的。可以使用创建目录和编辑文件命令配合完成创建一个角色框架。为了节省时间，可以使用<code>ansible-galaxy init</code>来创建角色框架。</p><p><code>ansible-galaxy init my_role</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">$ <span class="built_in">ls</span> my_role/</span><br><span class="line">defaults  files  handlers  meta  README.md  tasks  templates  tests  vars</span><br></pre></td></tr></table></figure><h3 id="默认变量的覆盖"><a href="#默认变量的覆盖" class="headerlink" title="默认变量的覆盖"></a>默认变量的覆盖</h3><p>在以下情况中，角色中defaults目录中定义的默认变量会被覆盖：</p><ul><li>在清单文件中定义，作为主机变量或组变量</li><li>在playbook项目的group_vars或hosts_vars目录下的YAML文件中定义</li><li>作为变量嵌套Play的vars关键字中定义</li><li>在Play的定义roles角色时的所定义的变量</li></ul><h2 id="安装V2ray-core服务角色示例"><a href="#安装V2ray-core服务角色示例" class="headerlink" title="安装V2ray-core服务角色示例"></a>安装V2ray-core服务角色示例</h2><p>功能如下：</p><ul><li>自动安装最新版本</li><li>按照受控节点平台自动选择platform平台</li><li>可以选择从Github/Jsdelivr/用户自定义V2ray-core地址下载</li><li>可以控制卸载</li></ul><p>Tasks角色任务:</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="comment"># tasks file for v2ray</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Prepare</span> <span class="string">to</span> <span class="string">Install</span> <span class="string">V2ray-core</span></span><br><span class="line">  <span class="attr">block:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">V2ray</span> <span class="string">download</span> <span class="string">path</span> <span class="string">is</span> <span class="string">exist</span></span><br><span class="line">      <span class="attr">file:</span></span><br><span class="line">        <span class="attr">path:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">directory</span></span><br><span class="line">        <span class="attr">mode:</span> <span class="number">0755</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">set_fact:</span></span><br><span class="line">        <span class="attr">install_error:</span> <span class="literal">false</span></span><br><span class="line">    </span><br><span class="line">  <span class="attr">when:</span> <span class="string">v2ray_present</span> </span><br><span class="line">  </span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Get</span> <span class="string">the</span> <span class="string">latest</span> <span class="string">V2ray</span> <span class="string">version</span> <span class="string">and</span> <span class="string">servers</span> <span class="string">info</span></span><br><span class="line">  <span class="attr">block:</span></span><br><span class="line">   </span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Get</span> <span class="string">Server</span> <span class="string">machine</span> <span class="string">platform</span></span><br><span class="line">      <span class="attr">shell:</span> <span class="string">|</span></span><br><span class="line"><span class="string">        case &quot;$&#123;1:-&quot;&#123;&#123; ansible_facts.machine &#125;&#125;&quot;&#125;&quot; in</span></span><br><span class="line"><span class="string">            i686|i386)</span></span><br><span class="line"><span class="string">                echo &#x27;32&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            x86_64|amd64)</span></span><br><span class="line"><span class="string">                echo &#x27;64&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *armv7*|armv6l)</span></span><br><span class="line"><span class="string">                echo &#x27;arm&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *armv8*|aarch64)</span></span><br><span class="line"><span class="string">                echo &#x27;arm64&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *mips64le*)</span></span><br><span class="line"><span class="string">                echo &#x27;mips64le&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *mips64*)</span></span><br><span class="line"><span class="string">                echo &#x27;mips64&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *mipsle*)</span></span><br><span class="line"><span class="string">                echo &#x27;mipsle&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *mips*)</span></span><br><span class="line"><span class="string">                echo &#x27;mips&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *s390x*)</span></span><br><span class="line"><span class="string">                echo &#x27;s390x&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            ppc64le)</span></span><br><span class="line"><span class="string">                echo &#x27;ppc64le&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            ppc64)</span></span><br><span class="line"><span class="string">                echo &#x27;ppc64&#x27;</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">            *)</span></span><br><span class="line"><span class="string">                return 1</span></span><br><span class="line"><span class="string">            ;;</span></span><br><span class="line"><span class="string">        esac</span></span><br><span class="line"><span class="string"></span>      <span class="attr">register:</span> <span class="string">return_machine</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Get</span> <span class="string">the</span> <span class="string">latest</span> <span class="string">V2ray</span> <span class="string">version</span> <span class="string">and</span> <span class="string">servers</span> <span class="string">info</span></span><br><span class="line">      <span class="attr">shell:</span> <span class="string">&gt;</span></span><br><span class="line"><span class="string">        curl -H &quot;Accept: application/json&quot; -H &quot;User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20180101 Firefox/74.0&quot; -s &quot;https://api.github.com/repos/v2ray/v2ray-core/releases/latest&quot; --connect-timeout 10| grep &#x27;tag_name&#x27; | cut -d\&quot; -f4 </span></span><br><span class="line"><span class="string"></span>      <span class="attr">register:</span> <span class="string">return_version</span></span><br><span class="line">      <span class="attr">args:</span></span><br><span class="line">        <span class="attr">warn:</span> <span class="literal">false</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">set_fact:</span></span><br><span class="line">        <span class="attr">latest_v2ray:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; return_version.stdout_lines[0] &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">machine:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; return_machine.stdout &#125;&#125;</span>&quot;</span></span><br><span class="line">  <span class="attr">rescue:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;ERROR: Get the latest V2ray version and servers info. Please check your Network Connection and V2ray-core version&quot;</span></span><br><span class="line">      <span class="attr">set_fact:</span></span><br><span class="line">        <span class="attr">install_error:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">when:</span> <span class="string">v2ray_present</span> <span class="string">and</span> <span class="string">not</span> <span class="string">install_error</span></span><br><span class="line">        </span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Download</span> <span class="string">V2ray-core</span></span><br><span class="line">  <span class="attr">block:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;Download V2ray-core<span class="template-variable">&#123;&#123; latest_v2ray &#125;&#125;</span> from jsdelivr&quot;</span></span><br><span class="line">      <span class="attr">get_url:</span></span><br><span class="line">        <span class="attr">url:</span> <span class="string">&quot;https://cdn.jsdelivr.net/gh/v2ray/dist/v2ray-linux-<span class="template-variable">&#123;&#123; machine &#125;&#125;</span>.zip&quot;</span></span><br><span class="line">        <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>&quot;</span></span><br><span class="line">      <span class="attr">when:</span> <span class="string">v2ray_download_from</span> <span class="string">==</span> <span class="string">&quot;jsdelivr&quot;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;Download V2ray-core<span class="template-variable">&#123;&#123; latest_v2ray &#125;&#125;</span> from Github&quot;</span></span><br><span class="line">      <span class="attr">get_url:</span></span><br><span class="line">        <span class="attr">url:</span> <span class="string">&quot;https://github.com/v2ray/v2ray-core/releases/download/<span class="template-variable">&#123;&#123; latest_v2ray &#125;&#125;</span>/v2ray-linux-<span class="template-variable">&#123;&#123; machine &#125;&#125;</span>.zip&quot;</span></span><br><span class="line">        <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>&quot;</span></span><br><span class="line">      <span class="attr">when:</span> <span class="string">v2ray_download_from</span> <span class="string">==</span> <span class="string">&quot;Github&quot;</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;Download V2ray-core<span class="template-variable">&#123;&#123; latest_v2ray &#125;&#125;</span> from <span class="template-variable">&#123;&#123; v2ray_download_from &#125;&#125;</span>&quot;</span></span><br><span class="line">      <span class="attr">get_url:</span></span><br><span class="line">        <span class="attr">url:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_from &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>&quot;</span></span><br><span class="line">      <span class="attr">when:</span> <span class="string">|</span></span><br><span class="line"><span class="string">        v2ray_download_from != &quot;jsdelivr&quot;</span></span><br><span class="line"><span class="string">        and</span></span><br><span class="line"><span class="string">        v2ray_download_from != &quot;Github&quot;</span></span><br><span class="line"><span class="string"></span>  <span class="attr">rescue:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;ERROR: Download V2ray-core. Please check your Network Connection and V2ray-core version&quot;</span></span><br><span class="line">      <span class="attr">set_fact:</span></span><br><span class="line">        <span class="attr">install_error:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">when:</span> <span class="string">v2ray_present</span> <span class="string">and</span> <span class="string">not</span> <span class="string">install_error</span></span><br><span class="line">  </span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Unarchive</span> <span class="string">V2ray-core</span></span><br><span class="line">  <span class="attr">block:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Create</span> <span class="string">unarchive</span> <span class="string">V2ray-core</span> <span class="string">directory</span></span><br><span class="line">      <span class="attr">file:</span></span><br><span class="line">        <span class="attr">path:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>/v2ray-linux-<span class="template-variable">&#123;&#123; machine &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">directory</span></span><br><span class="line">        <span class="attr">mode:</span> <span class="number">0755</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Unarchive</span> <span class="string">V2ray-core</span></span><br><span class="line">      <span class="attr">unarchive:</span></span><br><span class="line">        <span class="attr">src:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>/v2ray-linux-<span class="template-variable">&#123;&#123; machine &#125;&#125;</span>.zip&quot;</span></span><br><span class="line">        <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>/v2ray-linux-<span class="template-variable">&#123;&#123; machine &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">remote_src:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">rescue:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;ERROR: Unarchive V2ray-core. Please check your platform&quot;</span></span><br><span class="line">      <span class="attr">set_fact:</span></span><br><span class="line">        <span class="attr">install_error:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">when:</span> <span class="string">v2ray_present</span> <span class="string">and</span> <span class="string">not</span> <span class="string">install_error</span></span><br><span class="line">  </span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">V2ray-core</span> <span class="string">and</span> <span class="string">Start</span> <span class="string">V2ray-core</span></span><br><span class="line">  <span class="attr">block:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Create</span> <span class="string">V2ray</span> <span class="string">install</span> <span class="string">directory</span></span><br><span class="line">        <span class="attr">file:</span></span><br><span class="line">          <span class="attr">path:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item &#125;&#125;</span>&quot;</span></span><br><span class="line">          <span class="attr">state:</span> <span class="string">directory</span></span><br><span class="line">          <span class="attr">mode:</span> <span class="number">0755</span></span><br><span class="line">        <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_installed_dir &#125;&#125;</span>&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Copy</span> <span class="string">binary</span> <span class="string">file</span> <span class="string">into</span> <span class="string">directory</span></span><br><span class="line">        <span class="attr">copy:</span></span><br><span class="line">          <span class="attr">src:</span>  <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>/v2ray-linux-<span class="template-variable">&#123;&#123; machine &#125;&#125;</span>/<span class="template-variable">&#123;&#123; item.src &#125;&#125;</span>&quot;</span></span><br><span class="line">          <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item.dest &#125;&#125;</span>&quot;</span></span><br><span class="line">          <span class="attr">remote_src:</span> <span class="literal">true</span></span><br><span class="line">          <span class="attr">mode:</span> <span class="number">0755</span></span><br><span class="line">        <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_binary &#125;&#125;</span>&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Copy</span> <span class="string">V2ray</span> <span class="string">config</span> <span class="string">and</span> <span class="string">Start</span> <span class="string">V2ray-core</span></span><br><span class="line">        <span class="attr">copy:</span></span><br><span class="line">          <span class="attr">src:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_config &#125;&#125;</span>&quot;</span></span><br><span class="line">          <span class="attr">dest:</span> <span class="string">/etc/v2ray/config.json</span></span><br><span class="line">          <span class="attr">mode:</span> <span class="number">0755</span></span><br><span class="line">        <span class="attr">notify:</span> <span class="string">Start</span> <span class="string">V2ray</span> <span class="string">Service</span></span><br><span class="line">  <span class="attr">rescue:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&quot;ERROR: Install V2ray-core. Please check your permissions&quot;</span></span><br><span class="line">      <span class="attr">set_fact:</span></span><br><span class="line">        <span class="attr">install_error:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">when:</span> <span class="string">v2ray_present</span> <span class="string">and</span> <span class="string">not</span> <span class="string">install_error</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Remove</span> <span class="string">v2ray-core</span> </span><br><span class="line">  <span class="attr">block:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Stop</span> <span class="string">V2ray-core</span> <span class="string">service</span></span><br><span class="line">      <span class="attr">systemd:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">v2ray.service</span></span><br><span class="line">        <span class="attr">daemon_reload:</span> <span class="literal">true</span></span><br><span class="line">        <span class="attr">enabled:</span> <span class="literal">false</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">stopped</span></span><br><span class="line">      <span class="attr">ignore_errors:</span> <span class="literal">true</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Remove</span> <span class="string">V2ray-core</span> <span class="string">service</span></span><br><span class="line">      <span class="attr">file:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">/etc/systemd/system/v2ray.service</span></span><br><span class="line">            <span class="attr">state:</span> <span class="string">absent</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Remove</span> <span class="string">v2ray-core</span> <span class="string">file</span></span><br><span class="line">      <span class="attr">file:</span></span><br><span class="line">          <span class="attr">path:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item &#125;&#125;</span>&quot;</span></span><br><span class="line">          <span class="attr">state:</span> <span class="string">absent</span></span><br><span class="line">      <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_installed_dir &#125;&#125;</span>&quot;</span></span><br><span class="line">    </span><br><span class="line">  <span class="attr">when:</span> <span class="string">not</span> <span class="string">v2ray_present</span> <span class="string">or</span> <span class="string">install_error</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Check</span> <span class="string">remove</span> <span class="string">result</span></span><br><span class="line">  <span class="attr">debug:</span></span><br><span class="line">    <span class="attr">msg:</span> <span class="string">Removed</span> <span class="string">v2ray-core</span></span><br><span class="line">  <span class="attr">when:</span> <span class="string">not</span> <span class="string">v2ray_present</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Check</span> <span class="string">install</span> <span class="string">result</span></span><br><span class="line">  <span class="attr">debug:</span></span><br><span class="line">    <span class="attr">msg:</span> <span class="string">Install</span> <span class="string">V2ray-core</span> <span class="string">Failure</span></span><br><span class="line">  <span class="attr">failed_when:</span> <span class="literal">yes</span></span><br><span class="line">  <span class="attr">when:</span> <span class="string">v2ray_present</span> <span class="string">and</span> <span class="string">install_error</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Check</span> <span class="string">install</span> <span class="string">result</span></span><br><span class="line">  <span class="attr">debug:</span></span><br><span class="line">    <span class="attr">msg:</span> <span class="string">Install</span> <span class="string">V2ray-core</span> <span class="string">Successful</span></span><br><span class="line">  <span class="attr">when:</span> <span class="string">v2ray_present</span> <span class="string">and</span> <span class="string">not</span> <span class="string">install_error</span></span><br></pre></td></tr></table></figure><p>Default变量:</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># You can download the latest V2ray-core from Github/jsdelivr/(https://yourself)</span></span><br><span class="line"><span class="attr">v2ray_download_from:</span> <span class="string">&quot;Github&quot;</span></span><br><span class="line"><span class="attr">v2ray_download_path:</span> <span class="string">&quot;/tmp/v2ray&quot;</span></span><br><span class="line"><span class="attr">v2ray_config:</span> <span class="string">&quot;files/v2ray.conf&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># user_control_boolean</span></span><br><span class="line"><span class="attr">v2ray_present:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Ansible Role Control vars (Don&#x27;t change it!!!)</span></span><br><span class="line"><span class="attr">v2ray_installed_dir:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">/etc/v2ray</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">/var/log/v2ray</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">/usr/bin/v2ray</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; v2ray_download_path &#125;&#125;</span>&quot;</span></span><br><span class="line"><span class="attr">v2ray_binary:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">geoip.dat</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/usr/bin/v2ray</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">geosite.dat</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/usr/bin/v2ray</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">v2ctl</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/usr/bin/v2ray</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">v2ray</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/usr/bin/v2ray</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">systemd/v2ray.service</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/etc/systemd/system</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ansible角色&quot;&gt;&lt;a href=&quot;#Ansible角色&quot; class=&quot;headerlink&quot; title=&quot;Ansible角色&quot;&gt;&lt;/a&gt;Ansible角色&lt;/h1&gt;&lt;p&gt;使用Ansible角色可以有更多的机会去重用以前便携的Playbook中的代码。可以</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 调整连接数</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_forks.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_forks.html</id>
    <published>2020-06-16T12:28:36.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible调整连接数量和同时运行的任务数量"><a href="#Ansible调整连接数量和同时运行的任务数量" class="headerlink" title="Ansible调整连接数量和同时运行的任务数量"></a>Ansible调整连接数量和同时运行的任务数量</h1><h2 id="调整连接数forks"><a href="#调整连接数forks" class="headerlink" title="调整连接数forks"></a>调整连接数forks</h2><p>Ansible在处理Playbook时会按照顺序运行每一个play。确定受管主机列表后，Ansible将按照顺序在受管主机上运行任务。通常只有会在全部受管主机完成当前任务后才会继续往下执行其他任务。</p><p>Ansible可以同时连接到play中的所有主机以执行每项任务，这种方式适用于小规模的主机列表。如果对着数百台受控主机同时进行操作的话，控制节点会面临着巨大的性能压力。</p><p>所以，为了避免这种情况发生导致控制节点压力过大或出现异常，Ansible在执行任务时默认最大连接数为5。这个默认值是由Ansible配置文件中的forks参数控制。如果你的控制节点性能强劲，你可以在配置文件中手动配置该参数调整为更大的数值，这样在执行任务时可以同时连接到更多的受控节点，进而加快任务的执行速度。</p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[defaults]</span></span><br><span class="line"><span class="attr">inventory</span>=inventory</span><br><span class="line"><span class="attr">remote_user</span>=devops</span><br><span class="line"><span class="attr">forks</span>=<span class="number">5</span></span><br></pre></td></tr></table></figure><p>当然<strong>ansible</strong>和<strong>ansible-playbook</strong>命令都提供了<code>-f</code>或<code>--forks</code>选项来覆盖ansible在配置文件中读取到的forks值。</p><h2 id="分批次完成任务"><a href="#分批次完成任务" class="headerlink" title="分批次完成任务"></a>分批次完成任务</h2><p>通常情况下Ansible会在执行下一个任务前，要求全部的受控主机都完成当前的任务。但是要求全部的主机同时完成某一个任务可能会带来麻烦，特别是在处理Web负载均衡的机器时，如果任务要求集群内的全部主机同时重启Web服务，那么业务就会中断。所以在playbook中使用<code>serial</code>关键字可以解决这个问题，它能够控制play批量的完成任务，而不是让全部主机同时都完成一个任务。</p><p>下面的例子是使用<code>serial</code>关键字来控制一批只能2台受控主机完成这个Play，假设我们一共有6台机器，那么剩下的四台机器分别要等前面的两台受控主机执行完成全部的Play后才会完成到它们执行Play，6台节点两两一组，分批次执行任务。这样不会导致我们的业务因为重启全部的机器而终止。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Update</span> <span class="string">web</span> <span class="string">server</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">webservers</span></span><br><span class="line">  <span class="attr">serial:</span> <span class="number">2</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Latest</span> <span class="string">version</span> <span class="string">of</span> <span class="string">apache</span> <span class="string">installed</span></span><br><span class="line">      <span class="attr">yum:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">latest</span></span><br><span class="line">      <span class="attr">notify:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">Restart</span> <span class="string">apache</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">handlers:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Restart</span> <span class="string">apache</span></span><br><span class="line">      <span class="attr">service:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">        <span class="attr">enabled:</span> <span class="literal">yes</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">restarted</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>serial关键字也可以设置为百分比。此百分比应用于该play中主机的总数，已确定每次批量执行play的主机个数。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ansible调整连接数量和同时运行的任务数量&quot;&gt;&lt;a href=&quot;#Ansible调整连接数量和同时运行的任务数量&quot; class=&quot;headerlink&quot; title=&quot;Ansible调整连接数量和同时运行的任务数量&quot;&gt;&lt;/a&gt;Ansible调整连接数量和同时运</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Splunk数据搜索和报表</title>
    <link href="https://blog.yeefire.com/2020_06/splunk.html"/>
    <id>https://blog.yeefire.com/2020_06/splunk.html</id>
    <published>2020-06-10T00:25:48.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Splunk-数据搜索和报表"><a href="#Splunk-数据搜索和报表" class="headerlink" title="Splunk 数据搜索和报表"></a>Splunk 数据搜索和报表</h1><h2 id="Splunk-是？"><a href="#Splunk-是？" class="headerlink" title="Splunk 是？"></a>Splunk 是？</h2><p>Splunk是机器数据分析平台，他可以收集并处理所有有机器产生的日志数据，在Splunk中可以做到”any data from any source”。我们作为管理员可以使用Splunk生成这些数据的报表、仪表盘等，赋予这冰冷枯燥日志数据的新生。</p><p>搜索是Splunk核心功能之一，基本上近乎所有的功能都是由搜索展开的。充分挖掘这些数据并从中获得有价值的信息，这让我想起在泥沙中<strong>淘金</strong>的感觉。从基本的报表和仪表，再到数据模型和功能完备的Splunk应用程序，这些都是由Splunk搜索在后台提供着支撑。</p><blockquote><p>Splunk使用自己的搜索语言(SPL)。SPL有很多搜索指令，其中大部分包含有多种函数，参数和字句。</p></blockquote><span id="more"></span><h2 id="搜索"><a href="#搜索" class="headerlink" title="搜索"></a>搜索</h2><p>Splunk的搜索以基本搜索开头，之后是一系列的搜索指令，命令之间由管道符号(|)分割。Splunk搜索时经常会使用管道符不断精炼数据结果。</p><p>当然Splunk也可以直接搜索你想要的元素，比如一个agent、IP、error。但是只有在数据量很少的情况下才可以这么用，否则在海量(GB)级别的文本数据中搜索一个单词或者一个IP地址还不如淘到金子的可能性大。因此使用SPL和多种Splunk命令来提炼搜索。搜索的越精细，搜索的执行时间就越少，也能尽快的找到这些所需要的数据。</p><blockquote><p>尽可能的在第一个管道符之前尽可能多的过滤内容，这会节省CPU和磁盘I/O。并且在编写完查询指令后可以先将搜索时间番位设置较短的区间，如果查找的结果是需要的数据再扩大搜索范围。</p></blockquote><h2 id="常用搜索指令"><a href="#常用搜索指令" class="headerlink" title="常用搜索指令"></a>常用搜索指令</h2><table><thead><tr><th align="left">命令</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">chart/<br>timechart</td><td align="left">将结果以表格的形式输出。或者借助Splunk图表按时间顺序展示输出结果</td></tr><tr><td align="left">dedup</td><td align="left">根据指定的字段删除重复的结果</td></tr><tr><td align="left">eval</td><td align="left">评估新的或现有的字段和值。eval可以实用化许多不同的函数</td></tr><tr><td align="left">fields</td><td align="left">指定在搜索结果中保留或移除字段</td></tr><tr><td align="left">head</td><td align="left">该命令保留前X（指定值）行的结果</td></tr><tr><td align="left">lookup</td><td align="left">从外部源或列表查找字段，返回附加的字段值</td></tr><tr><td align="left">rare</td><td align="left">从字段中找到最少值</td></tr><tr><td align="left">rename</td><td align="left">重新命名字段</td></tr><tr><td align="left">replace</td><td align="left">该命令允许随后对结果进行搜索和过滤</td></tr><tr><td align="left">sort</td><td align="left">该命令按升降序对结果进行排序</td></tr><tr><td align="left">stats</td><td align="left">对结果执行统计运算。stats命令可以使用许多不同的函数</td></tr><tr><td align="left">table</td><td align="left">该命令把结果以列表的格式输出</td></tr><tr><td align="left">tail</td><td align="left">保留最后X（指定）行的结果</td></tr><tr><td align="left">top</td><td align="left">从字段中找到最常见的值</td></tr><tr><td align="left">transaction</td><td align="left">该命令根据共同的事务标识符将多个时间合并为单一事件</td></tr></tbody></table><h2 id="高级时间配置"><a href="#高级时间配置" class="headerlink" title="高级时间配置"></a>高级时间配置</h2><p>在搜索框的右面可以选择限定时间范围，当你所要查找的时间比较复杂的时候，可以尝试使用高级选项来选取时间范围。</p><p><img src="https://cdn.yeefire.com/hexo/img/%E9%AB%98%E7%BA%A7%E6%97%B6%E9%97%B4%E9%85%8D%E7%BD%AE-2020-06-10.png" alt="高级时间配置-2020-06-10"></p><p>时间修饰符可以接受多种时间单位：秒(s)，分钟(m)，小时(h)，天(d)，星期(w)，月(mon)，季度(q)，年(y)等。</p><p>比如要搜索在一天前的半夜整点到距离当前时间30分钟前出现过的全部事件可以这样表示：最早=-1d@d/最晚=-30m</p><p><img src="https://cdn.yeefire.com/hexo/img/%E6%97%B6%E9%97%B4%E4%BF%AE%E9%A5%B0%E7%AC%A6-2020-06-10.png" alt="时间修饰符-2020-06-10"></p><blockquote><p>(@)是向下取整标志符。</p></blockquote><h2 id="布尔运算符"><a href="#布尔运算符" class="headerlink" title="布尔运算符"></a>布尔运算符</h2><p>Splunk中可以使用三种类型的布尔运算符：AND、OR、NOT。Splunk只会识别这三个大写的运算符，所以要大写！默认情况下AND运算符是隐含的，可以不写。比如 <code>ssh AND failure</code>等同于<code>ssh failure</code>。</p><h2 id="搜索字段"><a href="#搜索字段" class="headerlink" title="搜索字段"></a>搜索字段</h2><p>Splunk中的字段可以被认为是有着一个或多个值的关键词。这些字段都可以被Splunk搜索。进入到Splunk的每一个数据源都会至少包含源、主机、索引、源类型这四个字段，一些数据源会有数百个附加的字段。如果原始日志数据包含有键值对或以JSON或XML结构化格式呈现的数据，Splunk会自动提取字段并使其可供搜索。</p><p>搜索特定的字段值也很简单，在当你Splunk自动识别或手表标记好的字段后，直接输入字段名与布尔运算符就可以进行搜索。如<code>sourcetype=&quot;access_combined&quot; status!=200</code>，就可以搜索含有来源类型为access_combined，并且status字段值不等于200的事件。</p><h2 id="报表"><a href="#报表" class="headerlink" title="报表"></a>报表</h2><p>在搜索结束后可以保存搜索供以后继续使用或者用于仪表盘。保存的搜索被称之为报表。</p><p><img src="https://cdn.yeefire.com/hexo/img/%E5%B0%86%E6%90%9C%E7%B4%A2%E7%BB%93%E6%9E%9C%E5%AD%98%E5%82%A8%E4%B8%BA%E6%8A%A5%E8%A1%A8-2020-06-10.png" alt="将搜索结果存储为报表-2020-06-10"></p><h2 id="让搜索的结果更具有可读性"><a href="#让搜索的结果更具有可读性" class="headerlink" title="让搜索的结果更具有可读性"></a>让搜索的结果更具有可读性</h2><p>有了上面的基础，就可以来为这些数据填些花样玩法。</p><h3 id="table命令生成数据列表"><a href="#table命令生成数据列表" class="headerlink" title="table命令生成数据列表"></a>table命令生成数据列表</h3><p>在Splunk首页选择“搜索和报表”应用程序。时间选择器选择“过去24小时”。之后搜索<code>index=main sourcetypee=access</code>，之后会返回原始数据搜索事件。</p><p>此时我们在刚才的搜索指令使用管道符相连<code>table</code>命令：<code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; | table _time,referer_domain,method,uri_path,JSESSIONID,useragent</code>。</p><p>这样的列表会只显示你关注的字段，而不现实原始事件，将数据以数据列表形式呈现。</p><p><img src="https://cdn.yeefire.com/hexo/img/table%E5%91%BD%E4%BB%A41-2020-06-10.png" alt="table命令1-2020-06-10"></p><p>点击右上角的另存为——&gt;报表，就可以将将搜索存储为报表，方便下次的时候使用。</p><table><thead><tr><th align="left">搜索分段</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">index=”main”</td><td align="left">Splunk中所有的数据都会保存在一个或多个索引中。尽管没有强制要求，不过再好在搜索时指定索引，这样能更快并且更精确的得到搜索结果</td></tr><tr><td align="left">sourcetype=”access_combined”</td><td align="left">只搜索与access_combined数据源类型</td></tr><tr><td align="left">|table _time,referer_domain,method,uri_path,JSESSIONID,useragent</td><td align="left">使用table命令时，将上一步的搜索结果放到管道左面。并告知Splunk以列表格式返回数据。Splunk会在搜索结果中只显示table命令中规定的字段</td></tr></tbody></table><blockquote><p>table命令对大范围数据搜索有很高的性能需求，尽可能的要将table用在搜索末尾，当其他的Splunk命令处理完毕后，再执行table命令。</p></blockquote><h4 id="下载报表"><a href="#下载报表" class="headerlink" title="下载报表"></a>下载报表</h4><p>我们已经把数据呈现为可读的格式，因此可以下载这些数据并存储为CSV文件格式方便我们统计数据。在搜索栏右侧下方有一个导出按钮，这里可以选择其他格式：JSON、XML、CSV。</p><h4 id="将每个字段制表"><a href="#将每个字段制表" class="headerlink" title="将每个字段制表"></a>将每个字段制表</h4><p>如果需要将所有字段都列成表格，没必要指定所有字段名。可以使用通配符(*)。</p><p><code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; | table *</code></p><p>但是！假设全部的字段有很多，然而你还不想要全部字段，只需要大部分的字段，那么你可以在使用table命令之前使用fields命令先移除你不需要的字段再使用通配符(*)。</p><p><code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; |fields - sourcetype,index,_row,date* linecount| table *</code></p><p><img src="https://cdn.yeefire.com/hexo/img/fields%E8%BF%87%E6%BB%A4%E5%89%8D-2020-06-10.png" alt="fields过滤前-2020-06-10"></p><p><img src="https://cdn.yeefire.com/hexo/img/fields%E8%BF%87%E6%BB%A4%E5%90%8E-2020-06-10.png" alt="fields过滤后-2020-06-10"></p><blockquote><p>在fields命令后加上一个减号(-)，Splunk会将后面的字段移除。</p></blockquote><h4 id="找出最常访问的网页"><a href="#找出最常访问的网页" class="headerlink" title="找出最常访问的网页"></a>找出最常访问的网页</h4><p>在获得了Web服务器日志后，你就能看得到你的客户喜欢哪些网站，如果可以找到最常访问的网页，那么可以在这些页面上继续开发新功能！哪些访问次数较少的可以将他们移除掉或者重新设计一下！</p><p><code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; | stats count by uri_path | sort - count</code></p><table><thead><tr><th align="left">搜索分段</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">stats count by uri_path</td><td align="left">使用stats命令，将上一步的搜索结果放在管道左侧，并告知Splunk计算每个uri_path字段值的数量。</td></tr><tr><td align="left">sort - count</td><td align="left">将上一步stats命令生成的count字段作为输入，并告知Splunk将统计结果进行降序(-)，最常访问的网站就会显示在结果的顶端</td></tr></tbody></table><p><strong>搜索访问量排名前10的网页</strong></p><p>可以使用top代替stats命令。默认情况下top会显示排名前10的网页</p><p><code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; | top uri_path</code></p><p>如果你需要查看更多的排行，用limit可以满足你！</p><p><code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; | top limit=20 uri_path</code></p><h4 id="找出最常使用的Web浏览器"><a href="#找出最常使用的Web浏览器" class="headerlink" title="找出最常使用的Web浏览器"></a>找出最常使用的Web浏览器</h4><p>Web日志中也包含了useragent相关信息，其中包括浏览器信息和操作系统信息。</p><p><code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; | eval browser=useragent | replace *Firefox* with Firefox,*Chrome* with Chrome,*MSIE* with IE,*Safari* with Safari,*Opera* with Opera in browser | top useother=t browser</code></p><table><thead><tr><th align="left">搜索分段</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">eval browser=useragent</td><td align="left">使用eval命令，创建一个新的字段browser并将useragent字段中的内通存放到browser字段中</td></tr><tr><td align="left">replace <code>*Firefox* with Firefox,*Chrome* with Chrome,*MSIE* with IE,*Safari* with Safari,*Opera* with Opera in browser</code></td><td align="left">使用replace命令，利用通配符(*)将browser中匹配到的内容使用with参数后面的文本替换。如果包含空格的值要加上引号，否则会导致语法识别错误</td></tr><tr><td align="left">top limit=5 userother=t browser</td><td align="left">top命令告知Splunk找到排名前5的浏览器，并将limit所限制导致溢出的值都归到OTHER下</td></tr></tbody></table><p><img src="https://cdn.yeefire.com/hexo/img/%E6%B5%8F%E8%A7%88%E5%99%A8%E4%BF%A1%E6%81%AF%E7%BB%9F%E8%AE%A1-2020-06-10.png" alt="浏览器信息统计-2020-06-10"></p><p>同理也可以统计出用户所使用的操作系统。</p><p><code>index=&quot;main&quot; sourcetype=&quot;access_combined&quot; | eval os=useragent | replace *Windows* with Windows系统 ,*Mac* with Mac系统,*Linux* with Linux系统 in os | top limit=10 useother=t os</code></p><p><img src="https://cdn.yeefire.com/hexo/img/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E4%BF%A1%E6%81%AF%E7%BB%9F%E8%AE%A1-2020-06-10.png" alt="操作系统信息统计-2020-06-10"></p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Splunk-数据搜索和报表&quot;&gt;&lt;a href=&quot;#Splunk-数据搜索和报表&quot; class=&quot;headerlink&quot; title=&quot;Splunk 数据搜索和报表&quot;&gt;&lt;/a&gt;Splunk 数据搜索和报表&lt;/h1&gt;&lt;h2 id=&quot;Splunk-是？&quot;&gt;&lt;a href=&quot;#Splunk-是？&quot; class=&quot;headerlink&quot; title=&quot;Splunk 是？&quot;&gt;&lt;/a&gt;Splunk 是？&lt;/h2&gt;&lt;p&gt;Splunk是机器数据分析平台，他可以收集并处理所有有机器产生的日志数据，在Splunk中可以做到”any data from any source”。我们作为管理员可以使用Splunk生成这些数据的报表、仪表盘等，赋予这冰冷枯燥日志数据的新生。&lt;/p&gt;
&lt;p&gt;搜索是Splunk核心功能之一，基本上近乎所有的功能都是由搜索展开的。充分挖掘这些数据并从中获得有价值的信息，这让我想起在泥沙中&lt;strong&gt;淘金&lt;/strong&gt;的感觉。从基本的报表和仪表，再到数据模型和功能完备的Splunk应用程序，这些都是由Splunk搜索在后台提供着支撑。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Splunk使用自己的搜索语言(SPL)。SPL有很多搜索指令，其中大部分包含有多种函数，参数和字句。&lt;/p&gt;
&lt;/blockquote&gt;</summary>
    
    
    
    
    <category term="Splunk" scheme="https://blog.yeefire.com/tags/Splunk/"/>
    
    <category term="日志" scheme="https://blog.yeefire.com/tags/%E6%97%A5%E5%BF%97/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 常用模块</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_mod.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_mod.html</id>
    <published>2020-06-09T15:37:35.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible模块的使用"><a href="#Ansible模块的使用" class="headerlink" title="Ansible模块的使用"></a>Ansible模块的使用</h1><h2 id="文件模块"><a href="#文件模块" class="headerlink" title="文件模块"></a>文件模块</h2><p>Files文件模块库包含的模块可以对Linux文件进行管理，如创建、删除、编辑和修改文件的权限与属性等。</p><table><thead><tr><th align="left">模块</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">blockinfile</td><td align="left">插入、更新或删除由可定义标记线包围的多行文本块</td></tr><tr><td align="left">lineinfile</td><td align="left">确保特定行位于某个文件中，或使用反向引用正则表达式来替换现有行。此模块可以在想要更改某一个行的文本时使用</td></tr><tr><td align="left">copy</td><td align="left">将文件从本地或远程计算机复制到目标主机的某个位置。类似于file模块，copy模块还可以设置文件属性，包括SELinux上下文</td></tr><tr><td align="left">fetch</td><td align="left">该模块和copy类似，但以相反的方式工作。fetch用来从目标主机获取文件到本机控制节点上</td></tr><tr><td align="left">file</td><td align="left">设置权限、所有权、SELinux上下文以及常规文件、符号链接、硬连接、目录时间戳等。此模块还可以创建或删除常规文件、符号链接、硬连接和目录。其他过个与文件相关的模块支持与file模块相同的属性设置选项，包括copy模块</td></tr><tr><td align="left">stat</td><td align="left">检索文件的状态信息，与Linux stat命令相似</td></tr><tr><td align="left">synchronize</td><td align="left">对rsync命令的打包</td></tr></tbody></table><h2 id="文件模块使用示例"><a href="#文件模块使用示例" class="headerlink" title="文件模块使用示例"></a>文件模块使用示例</h2><h3 id="确保目标主机上存在文件"><a href="#确保目标主机上存在文件" class="headerlink" title="确保目标主机上存在文件"></a>确保目标主机上存在文件</h3><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Touch</span> <span class="string">a</span> <span class="string">file</span> <span class="string">and</span> <span class="string">set</span> <span class="string">permissions</span></span><br><span class="line">  <span class="attr">file:</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/home/student/touch.me</span></span><br><span class="line">    <span class="attr">owner:</span> <span class="string">student</span></span><br><span class="line">    <span class="attr">group:</span> <span class="string">root</span></span><br><span class="line">    <span class="attr">mode:</span> <span class="number">0000</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">touch</span></span><br></pre></td></tr></table></figure><p>如果目标主机已存在该文件，则会进行touch操作。上面的task除了确保文件存在以外，还会保证文件的权限为设定值。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">  File: touch.me</span><br><span class="line">  Size: 14        Blocks: 8          IO Block: 4096   regular file</span><br><span class="line">Device: 801h/2049dInode: 163550      Links: 1</span><br><span class="line">Access: (0000/----------)  Uid: ( 1000/ student)   Gid: (    0/    root)</span><br><span class="line">Context: unconfined_u:object_r:user_home_t:s0</span><br><span class="line">Access: 2020-06-02 17:11:40.642364330 -0400</span><br><span class="line">Modify: 2020-06-02 17:11:40.642364330 -0400</span><br><span class="line">Change: 2020-06-02 17:11:40.644530998 -0400</span><br><span class="line"> Birth: -</span><br><span class="line">------------------------------</span><br><span class="line">  File: touch.me</span><br><span class="line">  Size: 14        Blocks: 8          IO Block: 4096   regular file</span><br><span class="line">Device: 801h/2049dInode: 163550      Links: 1</span><br><span class="line">Access: (0000/----------)  Uid: ( 1000/ student)   Gid: (    0/    root)</span><br><span class="line">Context: unconfined_u:object_r:user_home_t:s0</span><br><span class="line">Access: 2020-06-02 17:18:59.746867300 -0400</span><br><span class="line">Modify: 2020-06-02 17:18:59.746867300 -0400</span><br><span class="line">Change: 2020-06-02 17:18:59.746867300 -0400</span><br><span class="line"> Birth: -</span><br></pre></td></tr></table></figure><h3 id="修改文件属性"><a href="#修改文件属性" class="headerlink" title="修改文件属性"></a>修改文件属性</h3><p>使用file模块，确保新的或现有文件具有正确的文件属性和SELinux类型。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">SELinux</span> <span class="string">type</span> <span class="string">is</span> <span class="string">set</span> <span class="string">to</span> <span class="string">samba_share_t</span></span><br><span class="line">  <span class="attr">file:</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/home/student/touch.me</span></span><br><span class="line">    <span class="attr">setype:</span> <span class="string">samba_share_t</span></span><br></pre></td></tr></table></figure><p>修改前touch.me文件的setype属性是<code>user_home_t</code>，使用file模块处理后setype属性已经改变为<code>samba_share_t</code>。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">$ ls -lZ</span><br><span class="line">----------. 1 student root unconfined_u:object_r:user_home_t:s0 14 Jun  2 17:18 touch.me</span><br><span class="line">$ ls -lZ</span><br><span class="line">----------. 1 student root unconfined_u:object_r:samba_share_t:s0 14 Jun  2 17:18 touch.me</span><br></pre></td></tr></table></figure><h3 id="永久更改SELinux文件上下文属性"><a href="#永久更改SELinux文件上下文属性" class="headerlink" title="永久更改SELinux文件上下文属性"></a>永久更改SELinux文件上下文属性</h3><p>设置上下文属性时，file模块的行为和chcon类似。通过运行restorecon可能会意外的撤销使用该模块对文件上下文所做的更改。当使用file设置上下文后，可以使用System模块集合中的sefcontext来更新SELinux策略，如<code>semanage fcontext</code>。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">SELinux</span> <span class="string">type</span> <span class="string">is</span> <span class="string">persistently</span> <span class="string">set</span> <span class="string">to</span> <span class="string">samba_share_t</span></span><br><span class="line">  <span class="attr">sefcontext:</span></span><br><span class="line">    <span class="attr">target:</span> <span class="string">/home/student/touch.me</span></span><br><span class="line">    <span class="attr">setype:</span> <span class="string">samba_share_t</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><p>可以看得到在SELinux上下文策略中目标的默认上下文已经更改为<code>samba_share_t</code>。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># semanage fcontext -l | grep touch.me</span></span><br><span class="line">/home/student/touch.me                             all files          system_u:object_r:samba_share_t:s0 </span><br></pre></td></tr></table></figure><blockquote><p>注意：sefcontext模块只更新SELinux策略中目标的默认上下文，并不更改当前现有文件的上下文。</p></blockquote><h3 id="在目标主机上复制和编辑文件"><a href="#在目标主机上复制和编辑文件" class="headerlink" title="在目标主机上复制和编辑文件"></a>在目标主机上复制和编辑文件</h3><p>使用copy模块时，模块假定设置了<code>force: yes</code>。这会强制copy模块覆盖远程文件（如果存在并且包含于与当前要发送的文件内容不同）。如果手动设置<code>force: no</code>，则它仅会在目标主机不存在要复制的这个文件时才会进行复制。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Copy</span> <span class="string">a</span> <span class="string">file</span> <span class="string">to</span> <span class="string">managed</span> <span class="string">hosts</span></span><br><span class="line">  <span class="attr">copy:</span></span><br><span class="line">    <span class="attr">src:</span> <span class="string">file</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/home/student/touch.me</span></span><br><span class="line">    <span class="attr">force:</span> <span class="literal">yes</span></span><br></pre></td></tr></table></figure><p>如果要从目标主机上拉取文件到本机，则使用fetch模块。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Retrieve</span> <span class="string">SSH</span> <span class="string">key</span> <span class="string">from</span> <span class="string">reference</span> <span class="string">host</span></span><br><span class="line">  <span class="attr">fetch:</span></span><br><span class="line">    <span class="attr">src:</span> <span class="string">&quot;/home/<span class="template-variable">&#123;&#123; user &#125;&#125;</span>/.ssh/id_rsa.pub&quot;</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">&quot;files/keys/<span class="template-variable">&#123;&#123; user &#125;&#125;</span>.pub&quot;</span></span><br></pre></td></tr></table></figure><p>要确保现有文件中存在某行文本，可以使用lineinfile模块。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Add</span> <span class="string">a</span> <span class="string">line</span> <span class="string">of</span> <span class="string">text</span> <span class="string">to</span> <span class="string">file</span></span><br><span class="line">  <span class="attr">lineinfile:</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/home/student/touch.me</span></span><br><span class="line">    <span class="attr">line:</span> <span class="string">&quot;Can you touch me?&quot;</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><p>如果要将文本块插入到文档中，应使用blockinfile模块。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Add</span> <span class="string">additional</span> <span class="string">lines</span> <span class="string">to</span> <span class="string">a</span> <span class="string">file</span></span><br><span class="line">  <span class="attr">blockinfile:</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/home/student/touch.me</span></span><br><span class="line">    <span class="attr">block:</span> <span class="string">|</span></span><br><span class="line"><span class="string">        This is the block of first line.</span></span><br><span class="line"><span class="string">        And</span></span><br><span class="line"><span class="string">        This is the block of third line.</span></span><br><span class="line"><span class="string"></span>    <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><blockquote><p>使用blockinfile模块时，注释块标记插入到块的开头和结尾，用来让Ansible识别和保持幂等性。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="comment"># BEGIN ANSIBLE MANAGED BLOCK</span></span><br><span class="line"><span class="string">This</span> <span class="string">is</span> <span class="string">the</span> <span class="string">first</span> <span class="string">line.</span></span><br><span class="line"><span class="comment"># END ANSIBLE MANAGED BLOCK</span></span><br></pre></td></tr></table></figure></blockquote><h3 id="在目标主机上删除文件"><a href="#在目标主机上删除文件" class="headerlink" title="在目标主机上删除文件"></a>在目标主机上删除文件</h3><p>在大多数情况下，如果控制目标主机文件的删除使用file模块的<code>state: absent</code>参数来控制。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Removed</span> <span class="string">file</span> <span class="string">in</span> <span class="string">the</span> <span class="string">server</span></span><br><span class="line">  <span class="attr">file:</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/home/student/touch.me</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">absent</span></span><br></pre></td></tr></table></figure><h3 id="检索文件的详细信息"><a href="#检索文件的详细信息" class="headerlink" title="检索文件的详细信息"></a>检索文件的详细信息</h3><p>使用stat模块可以查看文件的详细信息，并返回文件的事实。你可以利用这些Facts对文件进行检索和校验。stat模块类似于Linux系统中的<code>stat</code>命令。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Check</span> <span class="string">all</span> <span class="string">stat</span> <span class="string">of</span> <span class="string">/etc/passwd</span></span><br><span class="line">  <span class="attr">stat:</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">/etc/passwd</span></span><br><span class="line">  <span class="attr">register:</span> <span class="string">results</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">    <span class="attr">vars:</span> <span class="string">results</span></span><br></pre></td></tr></table></figure><h3 id="同步控制节点和受控节点之间的文件"><a href="#同步控制节点和受控节点之间的文件" class="headerlink" title="同步控制节点和受控节点之间的文件"></a>同步控制节点和受控节点之间的文件</h3><p>使用synchronize模块来操作同步主机间的文件。synchronize对rsync工具进行打包，它简化了playbook中常见文件管理任务。使用该模块要求双方主机安装rsync工具。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">synchronize</span> <span class="string">local</span> <span class="string">file</span> <span class="string">to</span> <span class="string">server</span> <span class="string">file</span></span><br><span class="line">  <span class="attr">synchronize:</span></span><br><span class="line">    <span class="attr">src:</span> <span class="string">/etc</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/home/student/</span></span><br></pre></td></tr></table></figure><h2 id="使用Jinja2模版部署自定义文件"><a href="#使用Jinja2模版部署自定义文件" class="headerlink" title="使用Jinja2模版部署自定义文件"></a>使用Jinja2模版部署自定义文件</h2><p>可以利用Jinja2模版语法通过和变量与事实相配合，对固定地方的值进行覆盖和编辑。来实现定制化修改配置文件。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">使用`&#123;% EXPR %&#125;`用于表达式或逻辑（循环、判断）</span><br><span class="line">使用`&#123;&#123; EXPR &#125;&#125;`用于输出最终表达式或变量的结果</span><br><span class="line">使用`&#123;# COMMENT #&#125;`注释，注释的内容不会出现在最终的结果里</span><br></pre></td></tr></table></figure><h3 id="构建Jinja2模版"><a href="#构建Jinja2模版" class="headerlink" title="构建Jinja2模版"></a>构建Jinja2模版</h3><p>Jinja2模版由多个元素组成：数据、变量和表达式。在呈现Jinja2模版时，这些变量和表达式被替换为对应的值。模版中使用的变量可以在playbook的vars部分中指定。可以将目标主机的事实作为模版中使用的变量。</p><blockquote><p>可以使用<code>ansible all -m setup</code>来查看目标主机中全部的Fact事实。模版文件没有固定的文件拓展名，只要是文本文件即可，但是为了方便记忆理解，通常使用<code>.j2</code>来代表文本文件是Jinja2的模版文件。</p></blockquote><h3 id="部署Jinja2模板"><a href="#部署Jinja2模板" class="headerlink" title="部署Jinja2模板"></a>部署Jinja2模板</h3><p>我们刚刚创建好了Jinja2模版，现在要利用这些模版。我们需要使用<code>template</code>模块。src参数指的是模版文件在控制节点中的路径，dest的值是在目标主机的指定目录生成文件。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">tasks:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">template</span> <span class="string">render</span></span><br><span class="line">    <span class="attr">template:</span></span><br><span class="line">      <span class="attr">src:</span> <span class="string">motd.j2</span></span><br><span class="line">      <span class="attr">dest:</span> <span class="string">/etc/motd</span></span><br><span class="line">      <span class="attr">backup:</span> <span class="literal">true</span></span><br></pre></td></tr></table></figure><p>template和file模块一样支持对文件权限进行设置。</p><h3 id="标示配置文件由Ansible管理"><a href="#标示配置文件由Ansible管理" class="headerlink" title="标示配置文件由Ansible管理"></a>标示配置文件由Ansible管理</h3><p>我们使用模版生成文件后，为了避免管理员用户手动的修改这些配置文件，我们最好在模版的开头写上声明。虽然template不会自动地帮我们完成，但是我们可以在模版文件的开头手动引入设定好的提醒文本，使用Jinja2语法将变量的内容填写到配置文件中。</p><p>可以使用<code>ansible_managed</code> 指令中默认设置的 <code>Ansible managed</code>字符串来执行此操作。这不是一个正常的变量，但是可以在模版中用作一个变量。<code>ansible_managed</code>指令在<code>ansible.cfg</code>文件中的设置：</p><p><code>ansible_managed = Ansible managed: modified on %Y-%m-%d %H:%M:%S</code></p><p>要将在<code>ansible.cfg</code>文件中配置的<code>ansible_managed</code>字符串包含在Jinja2模版内，使用下面的引用变量语法即可。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;&#123; ansible_managed &#125;&#125;</span><br></pre></td></tr></table></figure><p>通过模版生成的配置文件开头存在了<code>Ansible managed: modified on 2020-06-10 15:55:29</code>。这样就能对修改此文件的人有一个提示的作用。</p><h3 id="控制结构"><a href="#控制结构" class="headerlink" title="控制结构"></a>控制结构</h3><p>可以在Jinja2模版中使用控制结构，以减少重复的输入。为Play中每个主机能够动态的生成条目，或者有条件的将文本插入到文件中。</p><h4 id="循环"><a href="#循环" class="headerlink" title="循环"></a>循环</h4><p>Jinja2使用<code>for</code>语句来提供循环功能。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;% for user in users %&#125;</span><br><span class="line">    &#123;&#123; user &#125;&#125;</span><br><span class="line">&#123;% endfor %&#125;</span><br></pre></td></tr></table></figure><p>下面的示例模版使用for逐一遍历users变量中的所有值，将myuser替换为各个值，但值为root时除外。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;# for statement #&#125;</span><br><span class="line">&#123;% for myuser in users if not myuser == &quot;root&quot; %&#125;</span><br><span class="line">User number is &#123;&#123; loop.index &#125;&#125; - &#123;&#123; myuser &#125;&#125;</span><br><span class="line">&#123;% endfor %&#125;</span><br></pre></td></tr></table></figure><p>loop.index变量是循环到当前处的索引号。他在循环第一次执行时的值为1，每一次迭代递增1。</p><p>下面的例子是生成hosts文件。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;% for host in groups[&#x27;all&#x27;] %&#125;</span><br><span class="line">&#123;&#123; hostvars[host][&#x27;ansible_facts&#x27;][&#x27;default_ipv4&#x27;][&#x27;address&#x27;] &#125;&#125; &#123;&#123; hostvars[host][&#x27;ansible_facts&#x27;][&#x27;fqdn&#x27;] &#125;&#125; &#123;&#123; hostvars[host][&#x27;ansible_facts&#x27;][&#x27;hostname&#x27;] &#125;&#125;</span><br><span class="line">&#123;% endfor %&#125;</span><br></pre></td></tr></table></figure><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">generate</span> <span class="string">hosts</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">generate</span> <span class="string">template</span></span><br><span class="line">      <span class="attr">template:</span></span><br><span class="line">        <span class="attr">src:</span> <span class="string">hosts.j2</span></span><br><span class="line">        <span class="attr">dest:</span> <span class="string">/home/student/hosts</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><h4 id="条件语句"><a href="#条件语句" class="headerlink" title="条件语句"></a>条件语句</h4><p>Jinja2使用if语句来提供条件控制。如果满足某些条件，则会按照语句块内的规则继续生成。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;% if finished %&#125;</span><br><span class="line">&#123;&#123; result &#125;&#125;</span><br><span class="line">&#123;% endif %&#125;</span><br></pre></td></tr></table></figure><blockquote><p>Jinja2仅能用于模版，不能用于Playbook。条件语句和循环语句可以相互嵌套。</p></blockquote><h3 id="变量过滤器"><a href="#变量过滤器" class="headerlink" title="变量过滤器"></a>变量过滤器</h3><p>可以使用Jinja2提供的过滤器改变原有变量输出的格式，例如将字符串转换为JSON或YAML。</p><p>如果要转换为json格式时，使用to_json过滤器进行输出。</p><p>如果要转换为yaml格式时，使用to_yaml过滤器进行输出。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;&#123; output | to_json &#125;&#125;</span><br><span class="line">&#123;&#123; output | to_yaml &#125;&#125;</span><br></pre></td></tr></table></figure><p>如果要使结构更适于人类阅读，可以使用下面的过滤器来输出人类可读格式。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">&#123;&#123; output | to_nice_json &#125;&#125;</span><br><span class="line">&#123;&#123; output | to_nice_yaml &#125;&#125;</span><br></pre></td></tr></table></figure><h3 id="变量测试"><a href="#变量测试" class="headerlink" title="变量测试"></a>变量测试</h3><p>在Ansible Playbook中与when子句一同使用的表达式是Jinja2表达式。用于测试返回值的内置Ansible测试failed、changed、succeeded、skipped四种。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">tasks:</span></span><br><span class="line">  <span class="string">.......</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">      <span class="attr">msg:</span> <span class="string">&quot;The task was aborted&quot;</span></span><br><span class="line">    <span class="attr">when:</span> <span class="string">returnvalue</span> <span class="string">is</span> <span class="string">faild</span></span><br></pre></td></tr></table></figure><h2 id="软件包管理"><a href="#软件包管理" class="headerlink" title="软件包管理"></a>软件包管理</h2><p>使用dnf的Ansible模块可以在受控主机上控制dnf软件包管理器。dnf是RHEL8使用的默认包管理器用于替代yum。不过也可以使用yum模块来对RHEL8进行操作。</p><p>下面示例中使用task任务来代替原有的dnf包管理器指令：</p><p><code>dnf install httpd -y</code></p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">the</span> <span class="string">httpd</span> <span class="string">packages</span></span><br><span class="line">  <span class="attr">dnf:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><p>state关键字有如下参数：</p><ul><li>present 如果软件包不存在，则安装软件包</li><li>absent 如果已安装，则删除软件包</li><li>latest 如果软件包不是最新版本，则会对软件包进行更新。要是没有安装则会安装最新版本的软件包</li></ul><p>name关键字有以下使用方式：</p><ul><li>直接填写某一个或以列表的形式填写<strong>多个软件包名称</strong></li><li>使用<code>&#39;*&#39;</code>配合latest可以进行更新系统全部软件包</li><li>若要管理模块或组需要使用<code>@</code>符号</li></ul><p>安装<code>Development Tools</code>软件组的示例：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">the</span> <span class="string">Development</span> <span class="string">Tools</span> <span class="string">group</span></span><br><span class="line">  <span class="attr">dnf:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">‘@Development</span> <span class="string">Tools’</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><p>安装<code>postgresql</code>数据库模块：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">the</span> <span class="string">postgresql</span> <span class="string">module</span></span><br><span class="line">  <span class="attr">dnf:</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">&#x27;@postgresql:9.6/client&#x27;</span></span><br><span class="line">      <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><p>如果包管理器不是yum或者dnf。可以使用<code>package</code>模块替代<code>yum/dnf</code>模块。<code>package</code>模块可以自动检测并使用受控主机的包管理器去安装配置的软件包。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">httpd</span></span><br><span class="line">  <span class="attr">package:</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">      <span class="attr">state:</span> <span class="string">present</span></span><br></pre></td></tr></table></figure><h3 id="收集已安装的软件包信息"><a href="#收集已安装的软件包信息" class="headerlink" title="收集已安装的软件包信息"></a>收集已安装的软件包信息</h3><p>使用<code>package_facts</code>模块就能获取到受控主机中已经安装的软件包。它会将获取到的全部软件包信息存入<code>ansible_facts.packages</code>变量中。</p><p>使用<code>package_facts</code>模块并进行输出的示例：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Output</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">prod</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Check</span> <span class="string">packages</span></span><br><span class="line">      <span class="attr">package_facts:</span></span><br><span class="line">        <span class="attr">manager:</span> <span class="string">auto</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">var:</span> <span class="string">ansible_facts.packages.httpd</span></span><br></pre></td></tr></table></figure><p><code>package_facts</code>模块有两个选项：</p><ul><li>manager  选择软件包管理器。默认auto自动识别</li><li>strategy  策略</li></ul><p>返回prod主机组中已安装的httpd软件包信息。</p><figure class="highlight json"><table><tr><td class="code"><pre><span class="line">ok<span class="punctuation">:</span> <span class="punctuation">[</span>serverc<span class="punctuation">]</span> =&gt; <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;ansible_facts.packages.httpd&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;arch&quot;</span><span class="punctuation">:</span> <span class="string">&quot;x86_64&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;epoch&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">null</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;httpd&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;release&quot;</span><span class="punctuation">:</span> <span class="string">&quot;10.module+el8+2764+7127e69e&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;source&quot;</span><span class="punctuation">:</span> <span class="string">&quot;rpm&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.4.37&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line">ok<span class="punctuation">:</span> <span class="punctuation">[</span>serverd<span class="punctuation">]</span> =&gt; <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;ansible_facts.packages.httpd&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">        <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;arch&quot;</span><span class="punctuation">:</span> <span class="string">&quot;x86_64&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;epoch&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">null</span></span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;httpd&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;release&quot;</span><span class="punctuation">:</span> <span class="string">&quot;10.module+el8+2764+7127e69e&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;source&quot;</span><span class="punctuation">:</span> <span class="string">&quot;rpm&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.4.37&quot;</span></span><br><span class="line">        <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="配置yum仓库"><a href="#配置yum仓库" class="headerlink" title="配置yum仓库"></a>配置yum仓库</h3><h4 id="添加yum仓库"><a href="#添加yum仓库" class="headerlink" title="添加yum仓库"></a>添加yum仓库</h4><p>使用<code>yum_repository</code>模块来控制第三方yum仓库。在添加仓库时即可配置GPG密钥。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Create</span> <span class="string">yum</span> <span class="string">repo</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">prod</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Create</span> <span class="string">yum</span> <span class="string">repo</span></span><br><span class="line">      <span class="attr">yum_repository:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">rpmforge</span></span><br><span class="line">        <span class="attr">description:</span> <span class="string">RPMforge</span> <span class="string">YUM</span> <span class="string">repo</span></span><br><span class="line">        <span class="attr">file:</span> <span class="string">test</span></span><br><span class="line">        <span class="attr">gpgkey:</span> <span class="string">http://materials.example.com/yum/repository/RPM-GPG-KEY-example</span></span><br><span class="line">        <span class="attr">baseurl:</span> <span class="string">http://materials.example.com/yum/repository/</span></span><br><span class="line">        <span class="attr">enabled:</span> <span class="literal">yes</span></span><br><span class="line">        <span class="attr">present:</span> <span class="literal">yes</span></span><br><span class="line">        <span class="attr">gpgcheck:</span> <span class="literal">yes</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>可以直接使用gpgkey选项而不需要使用其他模块进行配置。</p><h2 id="用户管理和身份认证"><a href="#用户管理和身份认证" class="headerlink" title="用户管理和身份认证"></a>用户管理和身份认证</h2><p>如何管理用户和用户组，以及配置ssh-key。</p><h3 id="用户模块"><a href="#用户模块" class="headerlink" title="用户模块"></a>用户模块</h3><p>使用<code>user</code>模块可以管理主机上的用户以及它们的许多参数。也可以删除用户、设置主目录、设置UID、关联的用户组等很多参数。</p><p>如果需要创建可以登录的计算机用户，需要使用password参数和<code>password_hash(&#39;sha512&#39;)</code>搭配生成Hash后的密码才可以登陆系统。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Add</span> <span class="string">user</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">dev</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">User</span> <span class="string">modul</span></span><br><span class="line">      <span class="attr">user:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">natsumi</span></span><br><span class="line">        <span class="attr">shell:</span> <span class="string">/bin/bash</span></span><br><span class="line">        <span class="attr">groups:</span> <span class="string">wheel</span></span><br><span class="line">        <span class="attr">append:</span> <span class="literal">yes</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line">        <span class="attr">password:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; pwd | password_hash(&#x27;sha512&#x27;) &#125;&#125;</span>&quot;</span></span><br><span class="line">  <span class="attr">vars:</span></span><br><span class="line">    <span class="attr">pwd:</span> <span class="string">test123</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="组模块"><a href="#组模块" class="headerlink" title="组模块"></a>组模块</h3><p><code>group</code>模块可以管理受控主机中的用户组。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Add</span> <span class="string">group</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">dev</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">change</span> <span class="string">group</span></span><br><span class="line">      <span class="attr">group:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">devuser</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">present</span>               </span><br></pre></td></tr></table></figure><p><code>group</code>模块参数: gid,local,name,state,system（如果设置为yes，则表示创建的组是系统组）</p><h2 id="系统调度"><a href="#系统调度" class="headerlink" title="系统调度"></a>系统调度</h2><h3 id="at一次性任务"><a href="#at一次性任务" class="headerlink" title="at一次性任务"></a>at一次性任务</h3><p>使用<code>at</code>模块来创建一个一次性任务。可以安排任务在未来的某一个时间点执行一次。</p><p><code>at</code>模块参数: </p><table><thead><tr><th align="left">参数</th><th align="left">选项</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">command</td><td align="left">-</td><td align="left">计划要运行的命令</td></tr><tr><td align="left">count</td><td align="left">-</td><td align="left">单位数字。必须和units一同使用</td></tr><tr><td align="left">script_file</td><td align="left">-</td><td align="left">计划要执行的现有脚本文件</td></tr><tr><td align="left">state</td><td align="left">absent/present</td><td align="left">添加或删除命令或脚本的状态</td></tr><tr><td align="left">unique</td><td align="left">yes/no</td><td align="left">如果任务已在运行，则不会再次执行</td></tr><tr><td align="left">units</td><td align="left">minutes/hours/days/weeks</td><td align="left">时间单位</td></tr></tbody></table><p><code>at</code>模块使用示例:</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Using</span> <span class="string">at</span> <span class="string">make</span> <span class="string">task</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">dev</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">create</span> <span class="string">task</span></span><br><span class="line">      <span class="attr">at:</span></span><br><span class="line">        <span class="attr">command:</span> <span class="string">&quot;echo &#x27;rick&#x27; &gt; lala.txt&quot;</span></span><br><span class="line">        <span class="attr">count:</span> <span class="number">1</span></span><br><span class="line">        <span class="attr">units:</span> <span class="string">minutes</span></span><br><span class="line">        <span class="attr">unique:</span> <span class="literal">yes</span></span><br></pre></td></tr></table></figure><p>目前使用<code>at</code>模块总会在文件名末尾拼接上<code>marcinDELIMITERxxxx</code>字符串，经过Google发现这一串文本是用来在at pool中用来标示任务的。可是在这里为什么将他们输出了出来目前还不得而知。</p><h3 id="cron计划任务"><a href="#cron计划任务" class="headerlink" title="cron计划任务"></a>cron计划任务</h3><p>要完成重复性的任务，也可以使用<code>cron</code>模块来创建计划任务。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">a</span> <span class="string">job</span> <span class="string">that</span> <span class="string">runs</span> <span class="string">at</span> <span class="number">2</span> <span class="string">and</span> <span class="number">5</span> <span class="string">exists.</span> <span class="string">Creates</span> <span class="string">an</span> <span class="string">entry</span> <span class="string">like</span> <span class="string">&quot;0 5,2 * * ls -alh &gt; /dev/null&quot;</span></span><br><span class="line">  <span class="attr">cron:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">&quot;check dirs&quot;</span></span><br><span class="line">    <span class="attr">minute:</span> <span class="string">&quot;0&quot;</span></span><br><span class="line">    <span class="attr">hour:</span> <span class="string">&quot;5,2&quot;</span></span><br><span class="line">    <span class="attr">job:</span> <span class="string">&quot;ls -alh &gt; /dev/null&quot;</span></span><br></pre></td></tr></table></figure><p>想要在特殊时间点，比如系统重启后运行一个任务，可以使用<code>special_time</code>参数来配置cron计划任务。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Ensure</span> <span class="string">a</span> <span class="string">job</span> <span class="string">that</span> <span class="string">runs</span> <span class="string">at</span> <span class="string">system</span> <span class="string">reboot.</span> <span class="string">Creates</span> <span class="string">an</span> <span class="string">entry</span> <span class="string">like</span> <span class="string">&quot;@reboot ls -alh &gt; /dev/null&quot;</span></span><br><span class="line">  <span class="attr">cron:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">&quot;check dirs&quot;</span></span><br><span class="line">    <span class="attr">special_time:</span> <span class="string">reboot</span></span><br><span class="line">    <span class="attr">job:</span> <span class="string">&quot;ls -alh &gt; /dev/null&quot;</span></span><br></pre></td></tr></table></figure><h3 id="reboot模块"><a href="#reboot模块" class="headerlink" title="reboot模块"></a>reboot模块</h3><p>使用reboot模块重新启动比直接用shell模块发起关机更安全，使用shell模块关闭受控主机后，它会等待再次开机恢复运行，才会继续向下执行其他任务和Play。</p><p>对受控主机重启后并持续等待180s。如果受控主机恢复运行则继续执行接下来的任务。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Reboot</span> <span class="string">a</span> <span class="string">slow</span> <span class="string">machine</span> <span class="string">that</span> <span class="string">might</span> <span class="string">have</span> <span class="string">lots</span> <span class="string">of</span> <span class="string">updates</span> <span class="string">to</span> <span class="string">apply</span></span><br><span class="line">  <span class="attr">reboot:</span></span><br><span class="line">    <span class="attr">reboot_timeout:</span> <span class="number">180</span></span><br></pre></td></tr></table></figure><p>如果超出运行时间，则执行出错。接下来的task和play都不会继续执行。</p><p><code>fatal: [servera]: FAILED! =&gt; &#123;&quot;changed&quot;: false, &quot;elapsed&quot;: 19, &quot;msg&quot;: &quot;Timed out waiting for last boot time check (timeout=18)&quot;, &quot;rebooted&quot;: true&#125; </code></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Ansible模块的使用&quot;&gt;&lt;a href=&quot;#Ansible模块的使用&quot; class=&quot;headerlink&quot; title=&quot;Ansible模块的使用&quot;&gt;&lt;/a&gt;Ansible模块的使用&lt;/h1&gt;&lt;h2 id=&quot;文件模块&quot;&gt;&lt;a href=&quot;#文件模块&quot; cla</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 变量和事实</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_vars.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_vars.html</id>
    <published>2020-06-09T02:40:24.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="变量和事实"><a href="#变量和事实" class="headerlink" title="变量和事实"></a>变量和事实</h1><p>如何定义变量、在Playbook中使用使用变量、加密敏感变量、Fact事实、魔法变量。</p><span id="more"></span><h2 id="变量的定义"><a href="#变量的定义" class="headerlink" title="变量的定义"></a>变量的定义</h2><p>变量可以在很多地方定义，他们的作用域也是不同的。</p><p>1、playbook中定义：vars<br>2、playbook中使用变量文件<br>3、在当前目录的host_vars/group_vars目录下定义变量文件（针对灵活、大型的playbook适用）<br>4、运行playbook时，在命令行中使用-e选项来使用变量，这种方式的优先级最高，会覆盖以上所有相同名字的变量属性。</p><h2 id="变量的使用"><a href="#变量的使用" class="headerlink" title="变量的使用"></a>变量的使用</h2><p>在playbook中，使用<code>&quot;&#123;&#123; var_name &#125;&#125;&quot;</code>来引用变量。</p><h2 id="register寄存器"><a href="#register寄存器" class="headerlink" title="register寄存器"></a>register寄存器</h2><p>使用寄存器可以将上一次的执行结果存储到新的变量中，用于下一次使用。</p><h2 id="使用vault加密变量"><a href="#使用vault加密变量" class="headerlink" title="使用vault加密变量"></a>使用vault加密变量</h2><p>当有一些敏感变量，比如密码等信息你应该是不想使用明文存储到变量文件。</p><p><code>ansible-vault [create|decrypt|edit|encrypt|encrypt_string|rekey|view] [options] [vaultfile.yml]</code></p><p>使用ansible-vault可以对变量文件进行加密，在执行playbook的时候通过输入密码或者使用密钥文件来对加密好的变量进行解密。</p><h3 id="如何运行引用了加密变量的playbook"><a href="#如何运行引用了加密变量的playbook" class="headerlink" title="如何运行引用了加密变量的playbook"></a>如何运行引用了加密变量的playbook</h3><p><code>ansible-playbook --ask-vault-pass/--valut-password-file=vault-pass playbook.yml</code></p><h2 id="使用Fact事实"><a href="#使用Fact事实" class="headerlink" title="使用Fact事实"></a>使用Fact事实</h2><p>Fact事实是在我们运行ansible-playbook时自动收集对应主机的基本信息的变量。</p><h3 id="常用的fact事实"><a href="#常用的fact事实" class="headerlink" title="常用的fact事实"></a>常用的fact事实</h3><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">ansible_facts.hostname</span><br><span class="line">ansible_facts.fqdn</span><br><span class="line">ansible_facts.default_ipv4.address</span><br><span class="line">ansible_facts.interfaces</span><br></pre></td></tr></table></figure><h3 id="禁用收集Fact事实"><a href="#禁用收集Fact事实" class="headerlink" title="禁用收集Fact事实"></a>禁用收集Fact事实</h3><p>在Play中添加<code>gather_facts:no</code></p><h3 id="收集目标主机中自定义的Fact"><a href="#收集目标主机中自定义的Fact" class="headerlink" title="收集目标主机中自定义的Fact"></a>收集目标主机中自定义的Fact</h3><p>在目标主机的<code>/etc/ansible/facts.d/</code>目录下创建xxxxx.fact文件，在文件中使用json格式自定义目标主机的Fact。</p><h2 id="使用魔法变量"><a href="#使用魔法变量" class="headerlink" title="使用魔法变量"></a>使用魔法变量</h2><p>一些变量并非事实或通过setup模块配置，但也能由Ansible自动设置。这些魔法变量也可以用于获取与特定受管主机相关的信息。</p><h3 id="groups"><a href="#groups" class="headerlink" title="groups"></a>groups</h3><p>列出清单中的所有组和主机。</p><h3 id="group-names"><a href="#group-names" class="headerlink" title="group_names"></a>group_names</h3><p>列出当前受控主机所属的所有组。</p><h3 id="inventory-hostname"><a href="#inventory-hostname" class="headerlink" title="inventory_hostname"></a>inventory_hostname</h3><p>包含清单中配置的当前受管主机的主机名称。</p><h3 id="hostvars"><a href="#hostvars" class="headerlink" title="hostvars"></a>hostvars</h3><p>引用其他主机的变量，前提是要引用的主机已经执行过获取Fact操作。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">$ ansible all -m debug -a <span class="string">&#x27;var=inventory_hostname&#x27;</span></span><br><span class="line"></span><br><span class="line">servera.lab.example.com | SUCCESS =&gt; &#123;</span><br><span class="line">    <span class="string">&quot;inventory_hostname&quot;</span>: <span class="string">&quot;servera.lab.example.com&quot;</span></span><br><span class="line">&#125;</span><br><span class="line">serverb.lab.example.com | SUCCESS =&gt; &#123;</span><br><span class="line">    <span class="string">&quot;inventory_hostname&quot;</span>: <span class="string">&quot;serverb.lab.example.com&quot;</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;变量和事实&quot;&gt;&lt;a href=&quot;#变量和事实&quot; class=&quot;headerlink&quot; title=&quot;变量和事实&quot;&gt;&lt;/a&gt;变量和事实&lt;/h1&gt;&lt;p&gt;如何定义变量、在Playbook中使用使用变量、加密敏感变量、Fact事实、魔法变量。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 任务控制</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_control.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_control.html</id>
    <published>2020-06-07T17:03:56.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible的循环控制及条件任务"><a href="#Ansible的循环控制及条件任务" class="headerlink" title="Ansible的循环控制及条件任务"></a>Ansible的循环控制及条件任务</h1><p>Ansible Playbook的循环控制、条件控制、处理程序以及错误处理机制。</p><span id="more"></span><h2 id="loop循环控制"><a href="#loop循环控制" class="headerlink" title="loop循环控制"></a>loop循环控制</h2><p>Ansible支持使用loop关键字来执行循环任务。</p><h3 id="简单迭代任务循环"><a href="#简单迭代任务循环" class="headerlink" title="简单迭代任务循环"></a>简单迭代任务循环</h3><p>将loop关键字添加到任务中，并用列表表示要迭代的项目的值。并使用item临时变量来保存每次循环迭代过程中使用的值。</p><p>如下是一个启动两个服务的例子，在没有了解循环控制时应这样编写playbook，分别写两个独立的任务来执行：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Postfix</span> <span class="string">is</span> <span class="string">running</span></span><br><span class="line">  <span class="attr">service:</span> </span><br><span class="line">    <span class="attr">name:</span> <span class="string">postfix</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">httpd</span> <span class="string">is</span> <span class="string">running</span></span><br><span class="line">  <span class="attr">service:</span> </span><br><span class="line">    <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">started</span></span><br></pre></td></tr></table></figure><p>使用loop循环控制，则可以简写如下：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name :</span> <span class="string">Start</span> <span class="string">Postfix</span> <span class="string">and</span> <span class="string">httpd</span> <span class="string">services</span></span><br><span class="line">  <span class="attr">service:</span> </span><br><span class="line">    <span class="attr">name:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item &#125;&#125;</span>&quot;</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line">  <span class="attr">loop:</span> </span><br><span class="line">    <span class="bullet">-</span> <span class="string">postfix</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">httpd</span></span><br></pre></td></tr></table></figure><p>也可以把loop所使用的列表存到play的变量中，他们三个执行的效果是相同的：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">vars:</span></span><br><span class="line">    <span class="attr">start_services:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">postfix</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">httpd</span></span><br><span class="line"><span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name :</span> <span class="string">Start</span> <span class="string">Postfix</span> <span class="string">and</span> <span class="string">httpd</span> <span class="string">services</span></span><br><span class="line">    <span class="attr">service:</span> </span><br><span class="line">        <span class="attr">name:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line">    <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; start_services &#125;&#125;</span>&quot;</span></span><br><span class="line">        </span><br></pre></td></tr></table></figure><h3 id="循环散列或字典列表"><a href="#循环散列或字典列表" class="headerlink" title="循环散列或字典列表"></a>循环散列或字典列表</h3><p>loop也可以循环散列或者是字典，下面示例中每个字典或散列有两个键，分别是name和groups。当前循环中的每个键的值可以分别通过item.name和item.group来检索。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">User</span> <span class="string">exist</span> <span class="string">and</span> <span class="string">are</span> <span class="string">in</span> <span class="string">the</span> <span class="string">corrent</span> <span class="string">Groups</span></span><br><span class="line">  <span class="attr">user:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item.name &#125;&#125;</span>&quot;</span></span><br><span class="line">    <span class="attr">group:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item.group &#125;&#125;</span>&quot;</span></span><br><span class="line">  <span class="attr">loop:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">user1</span></span><br><span class="line">      <span class="attr">group:</span> <span class="string">wheel</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">user2</span></span><br><span class="line">      <span class="attr">group:</span> <span class="string">root</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="早期的循环语法"><a href="#早期的循环语法" class="headerlink" title="早期的循环语法"></a>早期的循环语法</h3><p>在Ansible 2.5之前，大多数的playbook使用不同的循环愈发。提供了多个循环关键字，都以前缀<code>with_</code>开头，后跟Ansible查找插件的名称连用。这种循环语法在目前依旧很常见，但在未来某个时刻将会被弃用。</p><table><thead><tr><th align="left">循环关键字</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">with_items</td><td align="left">和loop类似，但当为with_items提供了列表的列表，他们会被扁平化处理为单级列表。item作为循环变量保存每次迭代过程中的值</td></tr><tr><td align="left">with_file</td><td align="left">此关键字需要控制节点文件名列表。循环变量item保存每次迭代过程中保存文件列表中相应文件的内容</td></tr><tr><td align="left">wirh_sequence</td><td align="left">此关键字不需要列表，而是需要参数生成数字序列列表。循环变量item在每次迭代过程中保存生成的序列中的一个生成项的值</td></tr></tbody></table><h3 id="将Register变量与Loop一起使用"><a href="#将Register变量与Loop一起使用" class="headerlink" title="将Register变量与Loop一起使用"></a>将Register变量与Loop一起使用</h3><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Loop</span> <span class="string">Register</span> <span class="string">Test</span></span><br><span class="line">  <span class="attr">gather_facts:</span> <span class="literal">no</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">localhost</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Loop</span> <span class="string">Echo</span> <span class="string">Task</span></span><br><span class="line">      <span class="attr">shell:</span> <span class="string">&quot;echo This is my item: <span class="template-variable">&#123;&#123; item &#125;&#125;</span>&quot;</span></span><br><span class="line">      <span class="attr">loop:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">one</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">two</span></span><br><span class="line">      <span class="attr">register:</span> <span class="string">echo_results</span></span><br><span class="line">    </span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Show</span> <span class="string">echo_results</span> <span class="string">variable</span></span><br><span class="line">      <span class="attr">debug:</span></span><br><span class="line">        <span class="attr">var:</span> <span class="string">echo_results</span></span><br></pre></td></tr></table></figure><h2 id="条件任务语句"><a href="#条件任务语句" class="headerlink" title="条件任务语句"></a>条件任务语句</h2><p>使用条件语句<code>when</code>可以控制该任务是否执行，根据条件配置满足一定情况下执行任务。比如在执行任务前首先要判断一下磁盘剩余空间、内存大小是否满足需求。如果不满足则直接跳过该任务。</p><p>变量也可以作为when条件语句的判断条件，如下：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Test</span> <span class="string">Boolean</span> <span class="string">Task</span> <span class="string">Demo</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">vars:</span></span><br><span class="line">    <span class="attr">run_task:</span> <span class="literal">true</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">the</span> <span class="string">web</span> <span class="string">services</span></span><br><span class="line">      <span class="attr">yum:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line">      <span class="attr">when:</span> <span class="string">run_task</span></span><br><span class="line"></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>在当变量<code>run_task</code>为真的时候，则执行<code>Install the web services</code>的任务，否则跳过该任务。</p><p>下面是常用的判断条件列表。</p><table><thead><tr><th align="left">判断条件</th><th align="left">示例</th></tr></thead><tbody><tr><td align="left">等于（字符串）</td><td align="left">ansible_machine == “x86_64”</td></tr><tr><td align="left">等于（数字）</td><td align="left">max_memory == 512</td></tr><tr><td align="left">常见判断</td><td align="left">&lt;=、&lt;、&gt;、&gt;=、!=</td></tr><tr><td align="left">变量存在</td><td align="left">max_memory is defined</td></tr><tr><td align="left">变量不存在</td><td align="left">max_memory is not defined</td></tr><tr><td align="left">第一个变量在第二个变量的列表里</td><td align="left">var1 in var_all</td></tr></tbody></table><h3 id="多个条件组合"><a href="#多个条件组合" class="headerlink" title="多个条件组合"></a>多个条件组合</h3><p>在使用<code>when</code>条件语句时，如果要判断组合条件，可以使用<code>and</code>、<code>or</code>关键字来进行组合，并与括号分组条件。</p><p><code>when: ansible_facts.distribution == &quot;RedHat&quot; or ansible_facts.distribution == &quot;Debian&quot;</code></p><p>如果多个条件之间是and关系，也可以使用列表的形式来表示：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">when:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">ansible_facts.distribution</span> <span class="string">==</span> <span class="string">&quot;RedHat&quot;</span></span><br><span class="line">  <span class="bullet">-</span> <span class="string">ansible_facts.distribution</span> <span class="string">==</span> <span class="string">&quot;CentOS&quot;</span></span><br></pre></td></tr></table></figure><p>使用括号能编写更复杂的条件：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">when:</span> <span class="string">&gt;</span></span><br><span class="line"><span class="string">  (ansible_facts.distribution == &quot;RedHat&quot; and ansible_facts.distribution_major_version == &quot;7&quot;)</span></span><br><span class="line"><span class="string">  or</span></span><br><span class="line"><span class="string">  (ansible_facts.distribution == &quot;Fedora&quot; and ansible_facts.distribution_major_version == &quot;28&quot;)</span></span><br></pre></td></tr></table></figure><h3 id="loop循环和条件判断组合使用"><a href="#loop循环和条件判断组合使用" class="headerlink" title="loop循环和条件判断组合使用"></a>loop循环和条件判断组合使用</h3><p>例子中yum模块将要安装mariadb-server软件包，但是要求根目录满足剩余空间300MB以上才会安装，所以可以遍历目标主机上所有挂在的磁盘然后找到根目录再判断剩余空间，如果满足则安装，不满足则跳过该任务。</p><blockquote><p>当对某个任务结合使用when和loop时，将对每一项都使用when语句进行判断。</p></blockquote><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">tasks:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Make</span> <span class="string">Sure</span> <span class="string">root</span> <span class="string">have</span> <span class="string">enough</span> <span class="string">space</span> <span class="string">to</span> <span class="string">install</span> <span class="string">mariadb</span></span><br><span class="line">    <span class="attr">yum:</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">mariadb-server</span></span><br><span class="line">      <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line">    <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; ansible_facts.mounts &#125;&#125;</span>&quot;</span></span><br><span class="line">    <span class="attr">when:</span> <span class="string">item.mount</span> <span class="string">==</span> <span class="string">&quot;/&quot;</span> <span class="string">and</span> <span class="string">item.size_available</span> <span class="string">&gt;</span> <span class="number">300000000</span></span><br></pre></td></tr></table></figure><h2 id="处理程序"><a href="#处理程序" class="headerlink" title="处理程序"></a>处理程序</h2><p>有时候我们需要更改完配置文件后重启服务，但只想对文件有更改的情况下才重启服务。得益于Ansible的模块设计的幂等性，我们可以通过判断是否进行了更改而选择执行任务。这种方式叫处理程序。</p><p>处理程序可看作非活动任务，只有在使用notify语句激活后才会被触发，只有配置文件更新了并激活了该处理任务时，在到处理程序定义的位置时才会执行该任务。</p><blockquote><p>处理任务只有在被激活的情况下才会执行，要注意的是处理程序不会按照你的激活顺序执行，而是按照激活程序的编写顺序以此判断是否被激活和执行。</p></blockquote><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">internet</span> <span class="string">services</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">become:</span> <span class="literal">yes</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Add</span> <span class="string">Web</span> <span class="string">content</span></span><br><span class="line">      <span class="attr">get_url:</span></span><br><span class="line">        <span class="attr">url:</span> <span class="string">http://materials.example.com/labs/playbook-review/index.php</span></span><br><span class="line">        <span class="attr">dest:</span> <span class="string">/var/www/html/index.php</span></span><br><span class="line">        <span class="attr">mode:</span> <span class="number">0644</span></span><br><span class="line">      <span class="attr">notify:</span> <span class="string">restart</span> <span class="string">apache</span></span><br><span class="line">  <span class="attr">handlers:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">restart</span> <span class="string">apache</span></span><br><span class="line">      <span class="attr">systemd:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">restarted</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>在第一次添加新页面后，激活<code>restart apache</code>处理程序，当开始执行handlers处理程序时，发现<code>restart apache</code>处理程序被激活，则执行该任务。</p><p>如果第二次执行该playbook你会发现处理程序并没有执行，因为任务<code>Add Web content</code>返回的状态是OK，由于没有进行任何更改所以不会执行重启httpd服务的操作。</p><h2 id="如何处理任务失败"><a href="#如何处理任务失败" class="headerlink" title="如何处理任务失败"></a>如何处理任务失败</h2><p>Ansible在执行任务的过程中，有任何一个任务执行失败，则不论接下来是否还有任务都不会执行。</p><p>但是如果你有特定的要求，即便是某一个任务执行失败，也继续往下执行其他任务的话，你需要在对应的任务上添加<code>ignore_errors</code>关键字。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Latest</span> <span class="string">version</span> <span class="string">of</span> <span class="string">notapkg</span> <span class="string">is</span> <span class="string">installed</span></span><br><span class="line">  <span class="attr">yum:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">notapkg</span></span><br><span class="line">    <span class="attr">state:</span> <span class="string">latest</span></span><br><span class="line">  <span class="attr">ignore_errors:</span> <span class="literal">yes</span></span><br></pre></td></tr></table></figure><h3 id="任务失败后强制执行处理程序"><a href="#任务失败后强制执行处理程序" class="headerlink" title="任务失败后强制执行处理程序"></a>任务失败后强制执行处理程序</h3><p>哪怕是Play在执行任务的过程中失败了，也会强制执行已经被激活的处理程序。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">internet</span> <span class="string">services</span></span><br><span class="line">  <span class="attr">force_handlers:</span> <span class="literal">yes</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">become:</span> <span class="literal">yes</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Latest</span> <span class="string">version</span> <span class="string">of</span> <span class="string">notapkg</span> <span class="string">is</span> <span class="string">installed</span></span><br><span class="line">      <span class="attr">yum:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">latest</span></span><br><span class="line">      <span class="attr">notify:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">restart</span> <span class="string">apache</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Always</span> <span class="string">is</span> <span class="literal">False</span></span><br><span class="line">      <span class="attr">command:</span> <span class="string">/bin/false</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">handlers:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">restart</span> <span class="string">apache</span></span><br><span class="line">      <span class="attr">systemd:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">restarted</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><h3 id="指定任务失败的条件"><a href="#指定任务失败的条件" class="headerlink" title="指定任务失败的条件"></a>指定任务失败的条件</h3><p>使用<code>failed_when</code>关键字可以指定任务已失败的条件，条件语句和when的条件语句相同。</p><p>下面的例子是当有任何一个磁盘挂载点剩余的空间小于300MB则将任务结果返回为失败，即便是已经成功安装。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">tasks:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Make</span> <span class="string">Sure</span> <span class="string">root</span> <span class="string">have</span> <span class="string">enough</span> <span class="string">space</span> <span class="string">to</span> <span class="string">install</span> <span class="string">mariadb</span></span><br><span class="line">    <span class="attr">yum:</span></span><br><span class="line">      <span class="attr">name:</span> <span class="string">mariadb-server</span></span><br><span class="line">      <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line">    <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; ansible_facts.mounts &#125;&#125;</span>&quot;</span></span><br><span class="line">    <span class="attr">failed_when:</span> <span class="string">item.size_available</span> <span class="string">&lt;</span> <span class="number">300000000</span></span><br></pre></td></tr></table></figure><p>如果<code>failed_when</code>关键字为<code>true</code>那么不管最后的执行结果如何，都会返回任务处理结果为失败。</p><h3 id="指定是否报告任务的Changed结果"><a href="#指定是否报告任务的Changed结果" class="headerlink" title="指定是否报告任务的Changed结果"></a>指定是否报告任务的Changed结果</h3><p>当任务对托管主机进行了更改后，如果有处理任务，则会激活处理任务。但在有些特殊模块如command模块，有时并不能按照预期来返回ok结果，所以只能返回Changed作为任务执行结果，这将会激活处理任务。</p><p>使用<code>changed_when</code>关键字可以控制何时返回Changed执行结果。他和<code>failed_when</code>关键字一样，和<code>when</code>的条件语句相同。你可以对某一变量是否在另一个变量中出现过进行判断。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="attr">tasks:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">shell:</span></span><br><span class="line">      <span class="attr">cmd:</span> <span class="string">/usr/local/bin/upgrade-database</span></span><br><span class="line">    <span class="attr">register:</span> <span class="string">command_result</span></span><br><span class="line">    <span class="attr">changed_when:</span> <span class="string">&quot;&#x27;Success&#x27; in command_result.stdout&quot;</span></span><br><span class="line"><span class="attr">handelers:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">restart</span> <span class="string">database</span></span><br><span class="line">    <span class="attr">service:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">mariadb</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">restarted</span></span><br></pre></td></tr></table></figure><h3 id="Ansible-块和错误自动处理"><a href="#Ansible-块和错误自动处理" class="headerlink" title="Ansible 块和错误自动处理"></a>Ansible 块和错误自动处理</h3><p>在Playbook中，块用来对任务进行逻辑分组，可用于控制任务的执行方式，例如任务块可以和<code>when</code>关键字连用，可以将某一条件用于多个任务。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">internet</span> <span class="string">services</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">become:</span> <span class="literal">yes</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Installed</span> <span class="string">Service</span></span><br><span class="line">      <span class="attr">block:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Latest</span> <span class="string">version</span> <span class="string">of</span> <span class="string">notapkg</span> <span class="string">is</span> <span class="string">installed</span></span><br><span class="line">          <span class="attr">yum:</span></span><br><span class="line">            <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">            <span class="attr">state:</span> <span class="string">latest</span></span><br><span class="line"></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Always</span> <span class="string">is</span> <span class="literal">True</span></span><br><span class="line">          <span class="attr">command:</span> <span class="string">/bin/true</span></span><br><span class="line">          <span class="attr">changed_when:</span> <span class="literal">false</span></span><br><span class="line">      <span class="attr">when:</span> <span class="string">ansible_facts.distribution</span> <span class="string">==</span> <span class="string">&quot;RedHat&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Always</span> <span class="string">is</span> <span class="literal">True</span></span><br><span class="line">      <span class="attr">command:</span> <span class="string">/bin/true</span></span><br><span class="line">      <span class="attr">changed_when:</span> <span class="literal">false</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>通过块，也可以与rescue和always语句连用来处理错误。如果块中包裹的任务有任何一个执行失败，则执行其rescue块中的任务来进行恢复。在block子句中的任务以及rescue运行结束后，最后运行always语句中包含的任务。</p><ul><li>block：定义要运行的主要任务</li><li>rescue：定义在block块中有任务执行失败后要运行的任务</li><li>always：始终都要执行的任务，不论block和rescue子句中定义的任务执行成功还是失败都会运行always中定义的任务。</li></ul><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Test</span> <span class="string">Block</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">all</span></span><br><span class="line">  <span class="attr">become:</span> <span class="literal">yes</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Installed</span> <span class="string">Service</span></span><br><span class="line">      <span class="attr">block:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Latest</span> <span class="string">version</span> <span class="string">of</span> <span class="string">notapkg</span> <span class="string">is</span> <span class="string">installed</span></span><br><span class="line">          <span class="attr">yum:</span></span><br><span class="line">            <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">            <span class="attr">state:</span> <span class="string">latest</span></span><br><span class="line"></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Always</span> <span class="string">is</span> <span class="literal">True</span></span><br><span class="line">          <span class="attr">command:</span> <span class="string">/bin/true</span></span><br><span class="line">          <span class="attr">changed_when:</span> <span class="literal">false</span></span><br><span class="line">      <span class="attr">when:</span> <span class="string">ansible_facts.distribution</span> <span class="string">==</span> <span class="string">&quot;RedHat&quot;</span></span><br><span class="line">      <span class="attr">rescue:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">rescue</span> <span class="string">block</span> <span class="string">tasks</span></span><br><span class="line">          <span class="attr">debug:</span></span><br><span class="line">            <span class="attr">msg:</span> <span class="string">&quot;rescued block tasks&quot;</span></span><br><span class="line">      <span class="attr">always:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Always</span> <span class="string">has</span> <span class="string">been</span> <span class="string">exec</span></span><br><span class="line">          <span class="attr">debug:</span></span><br><span class="line">            <span class="attr">msg:</span> <span class="string">&quot;Always has been exec&quot;</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><h2 id="任务控制总结"><a href="#任务控制总结" class="headerlink" title="任务控制总结"></a>任务控制总结</h2><hr><p>vars变量</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; web_service &#125;&#125;</span>&quot;</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; fw_service &#125;&#125;</span>&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">packages:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; web_package &#125;&#125;</span>&quot;</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; ssl_package &#125;&#125;</span>&quot;</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; fw_package &#125;&#125;</span>&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">ssl_cert_dir:</span> <span class="string">/etc/httpd/conf.d/ssl</span></span><br><span class="line"></span><br><span class="line"><span class="attr">web_config_files:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">server.key</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; ssl_cert_dir &#125;&#125;</span>&quot;</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">server.crt</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; ssl_cert_dir &#125;&#125;</span>&quot;</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">ssl.conf</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/etc/httpd/conf.d</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">src:</span> <span class="string">index.html</span></span><br><span class="line">    <span class="attr">dest:</span> <span class="string">/var/www/html</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p>PlayBook</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Playbook</span> <span class="string">Control</span> <span class="string">Lab</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">webservers</span></span><br><span class="line">  <span class="attr">vars_files:</span> <span class="string">vars.yml</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="comment">#Fail Fast Message</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">check</span> <span class="string">ram</span> <span class="string">size</span></span><br><span class="line">      <span class="attr">fail:</span></span><br><span class="line">        <span class="attr">msg:</span> <span class="string">&quot;Cant install under free ram 256M&quot;</span></span><br><span class="line">      <span class="attr">when:</span> <span class="string">ansible_facts.memtotal_mb</span> <span class="string">&lt;</span>  <span class="string">min_ram_mb</span> <span class="string">and</span> <span class="string">ansible_facts.distribution</span> <span class="type">!=</span> <span class="string">&quot;RedHat&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#Install all Packages</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Installed</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; packages &#125;&#125;</span>&quot;</span> <span class="string">Packages</span></span><br><span class="line">      <span class="attr">yum:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; packages &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#Enable and start services</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">and</span> <span class="string">start</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; services &#125;&#125;</span>&quot;</span> <span class="string">services</span></span><br><span class="line">      <span class="attr">service:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line">        <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; services &#125;&#125;</span>&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">#Block of config tasks</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Config</span> <span class="string">Document</span> <span class="string">Tasks</span></span><br><span class="line">      <span class="attr">block:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">existed</span> <span class="string">ssl_cret_dir</span></span><br><span class="line">          <span class="attr">file:</span></span><br><span class="line">            <span class="attr">path:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; ssl_cert_dir &#125;&#125;</span>&quot;</span></span><br><span class="line">            <span class="attr">state:</span> <span class="string">directory</span></span><br><span class="line"></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Config</span> <span class="string">File</span> <span class="string">existed</span></span><br><span class="line">          <span class="attr">copy:</span></span><br><span class="line">            <span class="attr">src:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item.src &#125;&#125;</span>&quot;</span></span><br><span class="line">            <span class="attr">dest:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item.dest &#125;&#125;</span>&quot;</span></span><br><span class="line">          <span class="attr">loop:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; web_config_files &#125;&#125;</span>&quot;</span></span><br><span class="line">          <span class="attr">notify:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">restart</span> <span class="string">web</span> <span class="string">service</span></span><br><span class="line">      <span class="attr">rescue:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">debug:</span></span><br><span class="line">            <span class="attr">msg:</span> <span class="string">&gt;</span></span><br><span class="line"><span class="string">              One or more of the configuration changes faild, but the web service is still active.</span></span><br><span class="line"><span class="string"></span>    <span class="comment">#Configure the firewall</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Configed</span> <span class="string">Firewalld</span> <span class="string">Allowed</span></span><br><span class="line">      <span class="attr">firewalld:</span></span><br><span class="line">        <span class="attr">service:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; item &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">enabled</span></span><br><span class="line">        <span class="attr">permanent:</span> <span class="literal">true</span></span><br><span class="line">        <span class="attr">immediate:</span> <span class="literal">true</span></span><br><span class="line">      <span class="attr">loop:</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">http</span></span><br><span class="line">        <span class="bullet">-</span> <span class="string">https</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">#Add handlers</span></span><br><span class="line">  <span class="attr">handlers:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">restart</span> <span class="string">web</span> <span class="string">service</span></span><br><span class="line">      <span class="attr">service:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">&quot;<span class="template-variable">&#123;&#123; web_service &#125;&#125;</span>&quot;</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">restarted</span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Ansible的循环控制及条件任务&quot;&gt;&lt;a href=&quot;#Ansible的循环控制及条件任务&quot; class=&quot;headerlink&quot; title=&quot;Ansible的循环控制及条件任务&quot;&gt;&lt;/a&gt;Ansible的循环控制及条件任务&lt;/h1&gt;&lt;p&gt;Ansible Playbook的循环控制、条件控制、处理程序以及错误处理机制。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible Playbook</title>
    <link href="https://blog.yeefire.com/2020_06/ansible_playbook.html"/>
    <id>https://blog.yeefire.com/2020_06/ansible_playbook.html</id>
    <published>2020-06-07T17:02:36.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible-PlayBook"><a href="#Ansible-PlayBook" class="headerlink" title="Ansible PlayBook"></a>Ansible PlayBook</h1><p>如何使用Ansible Playbook来执行复杂任务。其中包括要如何检查Playbook的语法。</p><span id="more"></span><h2 id="PlayBook和临时命令"><a href="#PlayBook和临时命令" class="headerlink" title="PlayBook和临时命令"></a>PlayBook和临时命令</h2><p>临时命令可以作为一次性命令临时的在目标主机上执行一项简单的任务。但是要发挥ansible全部实力的话就要用playbook来完成对选定主机的一个或一组指定的有序任务。playbook是一个文本文件，是以YAML格式编写的文本文件，拓展名通常使用yml保存。</p><blockquote><p>如果当vim识别到该文本文件是yaml格式的话，自动将tab键的制表符改为2个空格，以便格式正确。<br>修改<code>$HOME/.vimrc文件</code>，在其中添加规则：<code>autocmd FileType yaml setlocal ai ts=2 sw=2 et</code></p></blockquote><h2 id="Playbook格式"><a href="#Playbook格式" class="headerlink" title="Playbook格式"></a>Playbook格式</h2><p>使用<code>---</code>三个破折号作为playbook的开头，<code>...</code>三个英文句号作为playbook结尾（结尾非必须）。</p><p>在这两个标记之间，会以一个play列表的形式来定义playbook。YAML列表中的项目以一个破折号加空格开头。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="string">apple</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">orange</span></span><br><span class="line"><span class="bullet">-</span> <span class="string">grape</span></span><br></pre></td></tr></table></figure><p>play本身是一个简直对集合。确保同一个play中的键应当具有相同的缩进量。下面的例子显示了具有三个键的YAML代码片段，其中前两个键具有简单的值。第三个将含有三个项目的列表作为值。</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">example</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">webservers</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">first</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">second</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">third</span></span><br></pre></td></tr></table></figure><p>上面实例play有三个键name、hosts、tasks，他们有着相同的缩紧。第一行的name前面加了一个破折号和一个空格，表示他是第一个键，下面的两个键hosts与tasks和name这个键是同级的。</p><p>name通常作为一个play的开头，用来描述这个play是干嘛的，可以省略但是不推荐这么做。</p><p>hosts指定了要在哪些主机目标上运行这个playbook，前面了解过为如何为主机分组，所以此处可以填写在inventory中编排好的主机或组。</p><blockquote><p>hosts: 可以使用通配符(*)、&amp;与符号、!非符号进行匹配。也可以使用逗号来分割使用的不同的主机或组。⚠️注意：如果要使用这种模式来匹配主机，为了不与shell字符冲突，应使用<code>&#39;&#39;</code>一对单引号来包裹你的匹配模式。</p></blockquote><p>tasks是该play要运行的任务列表。下面的例子中所表达的是:在一个叫example的Play中执行两个简单的任务task1和task2的PlayBook写法：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">example</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">webservers</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">task1</span></span><br><span class="line">      <span class="attr">service:</span></span><br><span class="line">          <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">          <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">task2</span></span><br><span class="line">      <span class="attr">user:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">testuser</span></span><br><span class="line">        <span class="attr">uid:</span> <span class="number">2000</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">present</span></span><br><span class="line"><span class="string">...</span></span><br></pre></td></tr></table></figure><p>一个更长点的例子：</p><figure class="highlight yaml"><table><tr><td class="code"><pre><span class="line"><span class="meta">---</span></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">internet</span> <span class="string">services</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">serverb.lab.example.com</span></span><br><span class="line">  <span class="attr">become:</span> <span class="literal">yes</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">internet</span> <span class="string">services</span></span><br><span class="line">      <span class="attr">yum:</span></span><br><span class="line">        <span class="attr">name:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">firewalld</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">httpd</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">mariadb-server</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">php</span></span><br><span class="line">          <span class="bullet">-</span> <span class="string">php-mysqlnd</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">latest</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">Firewalld</span> <span class="string">service</span></span><br><span class="line">      <span class="attr">systemd:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">firewalld</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line">        <span class="attr">enabled:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Allow</span> <span class="number">80</span> <span class="string">tcp</span> <span class="string">port</span> <span class="string">in</span> <span class="string">firewalld</span></span><br><span class="line">      <span class="attr">firewalld:</span></span><br><span class="line">        <span class="attr">service:</span> <span class="string">http</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">enabled</span></span><br><span class="line">        <span class="attr">permanent:</span> <span class="literal">yes</span></span><br><span class="line">        <span class="attr">immediate:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">httpd</span> <span class="string">services</span></span><br><span class="line">      <span class="attr">systemd:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">httpd</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line">        <span class="attr">enabled:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Enable</span> <span class="string">mariadb</span> <span class="string">services</span></span><br><span class="line">      <span class="attr">systemd:</span></span><br><span class="line">        <span class="attr">name:</span> <span class="string">mariadb</span></span><br><span class="line">        <span class="attr">state:</span> <span class="string">started</span></span><br><span class="line">        <span class="attr">enabled:</span> <span class="literal">yes</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Add</span> <span class="string">Web</span> <span class="string">content</span></span><br><span class="line">      <span class="attr">get_url:</span></span><br><span class="line">        <span class="attr">url:</span> <span class="string">http://materials.example.com/labs/playbook-review/index.php</span></span><br><span class="line">        <span class="attr">dest:</span> <span class="string">/var/www/html/index.php</span></span><br><span class="line">        <span class="attr">mode:</span> <span class="number">0644</span></span><br><span class="line">        </span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Check</span> <span class="string">services</span> <span class="string">working</span> <span class="string">well</span></span><br><span class="line">  <span class="attr">become:</span> <span class="literal">false</span></span><br><span class="line">  <span class="attr">hosts:</span> <span class="string">localhost</span></span><br><span class="line">  <span class="attr">tasks:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">check</span> <span class="string">services</span> <span class="string">correct</span></span><br><span class="line">      <span class="attr">uri:</span></span><br><span class="line">        <span class="attr">url:</span> <span class="string">http://serverb.lab.example.com</span></span><br><span class="line">        <span class="attr">status_code:</span> <span class="number">200</span></span><br><span class="line"><span class="string">...</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="执行playbook"><a href="#执行playbook" class="headerlink" title="执行playbook"></a>执行playbook</h2><p>ansible-playbook playbook.yml</p><h3 id="检查编写的playbook中的语法错误"><a href="#检查编写的playbook中的语法错误" class="headerlink" title="检查编写的playbook中的语法错误"></a>检查编写的playbook中的语法错误</h3><p>ansible-playbook –syntax-check playbook.yml</p><blockquote><p>使用自动检查有时并不能精确的定位到问题位置所在，但是几乎都在问题的附近，也能提供一些指导。</p></blockquote><h3 id="以检查模式运行playbook"><a href="#以检查模式运行playbook" class="headerlink" title="以检查模式运行playbook"></a>以检查模式运行playbook</h3><p>ansible-playbook -C playbook.yml</p><p>使用检查模式运行playbook并不会对目标主机进行任何更改。可以用来在真正运行前进行一次测试。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Ansible-PlayBook&quot;&gt;&lt;a href=&quot;#Ansible-PlayBook&quot; class=&quot;headerlink&quot; title=&quot;Ansible PlayBook&quot;&gt;&lt;/a&gt;Ansible PlayBook&lt;/h1&gt;&lt;p&gt;如何使用Ansible Playbook来执行复杂任务。其中包括要如何检查Playbook的语法。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>Ansible 基础概念</title>
    <link href="https://blog.yeefire.com/2020_05/ansible_basic.html"/>
    <id>https://blog.yeefire.com/2020_05/ansible_basic.html</id>
    <published>2020-05-31T12:09:36.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Ansible-基础概念"><a href="#Ansible-基础概念" class="headerlink" title="Ansible 基础概念"></a>Ansible 基础概念</h1><p>Ansible的基本环境、受控主机清单、Ansible的配置文件。</p><span id="more"></span><h2 id="查看Ansible环境信息"><a href="#查看Ansible环境信息" class="headerlink" title="查看Ansible环境信息"></a>查看Ansible环境信息</h2><p><code>absible --version</code></p><p>查看ansible控制端的环境信息，其中包括默认模块和自定义模块的文件目录以及ansible和python的版本。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">[student@workstation ~]$ ansible --version</span><br><span class="line">ansible 2.8.0</span><br><span class="line">  config file = /etc/ansible/ansible.cfg</span><br><span class="line">  configured module search path = [<span class="string">&#x27;/home/student/.ansible/plugins/modules&#x27;</span>, <span class="string">&#x27;/usr/share/ansible/plugins/modules&#x27;</span>]</span><br><span class="line">  ansible python module location = /usr/lib/python3.6/site-packages/ansible</span><br><span class="line">  executable location = /usr/bin/ansible</span><br><span class="line">  python version = 3.6.8 (default, Apr  3 2019, 17:26:03) [GCC 8.2.1 20180905 (Red Hat 8.2.1-3)]</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="构建ansible清单"><a href="#构建ansible清单" class="headerlink" title="构建ansible清单"></a>构建ansible清单</h2><p>如果要用Ansible管理其他主机，需要将受控主机添加到清单中。</p><p><code>sudo vim /etc/ansible/hosts</code></p><h3 id="使用静态清单配置"><a href="#使用静态清单配置" class="headerlink" title="使用静态清单配置"></a>使用静态清单配置</h3><p>静态清单可以使用多种文件格式，包括INI和YAML。以下使用INI样式格式做例子。</p><h4 id="在INI文件开头直接添加主机IP-域名"><a href="#在INI文件开头直接添加主机IP-域名" class="headerlink" title="在INI文件开头直接添加主机IP/域名"></a>在INI文件开头直接添加主机IP/域名</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">servera.yeefire.com</span><br><span class="line">serverb.yeefire.com</span><br><span class="line">192.168.1.211</span><br><span class="line">192.168.1.232</span><br></pre></td></tr></table></figure><h4 id="将主机进行分组"><a href="#将主机进行分组" class="headerlink" title="将主机进行分组"></a>将主机进行分组</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[china-server]</span><br><span class="line">blog.yeefire.com</span><br><span class="line">server2.yeefire.com</span><br><span class="line"></span><br><span class="line">[us-server]</span><br><span class="line">us1.yeefire.com</span><br><span class="line">us2.yeefire.com</span><br></pre></td></tr></table></figure><h4 id="分组嵌套"><a href="#分组嵌套" class="headerlink" title="分组嵌套"></a>分组嵌套</h4><p>分组嵌套需要在组名处使用<code>:children</code>后缀。分组嵌套可以写在分组之前，他们之间没有绝对顺序。也可以编写与分组嵌套相同的组名，在使用这个名字的时候会将分组嵌套中所有的主机和该名字所对应的组名的主机包括在内。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[china-server]</span><br><span class="line">blog.yeefire.com</span><br><span class="line">server2.yeefire.com</span><br><span class="line"></span><br><span class="line">[us-server]</span><br><span class="line">us1.yeefire.com</span><br><span class="line">us2.yeefire.com</span><br><span class="line"></span><br><span class="line">[webservers:children]</span><br><span class="line">china-server</span><br><span class="line">us-server</span><br><span class="line"></span><br><span class="line">[webservers]</span><br><span class="line">test.app.yeefire.com</span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="简化主机配置"><a href="#简化主机配置" class="headerlink" title="简化主机配置"></a>简化主机配置</h4><p>如果要配置范围主机，一个个添加会很麻烦，通常他们都会有固定的格式。<br>使用<code>[START:END]</code>就可以范围。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">[us-server]</span><br><span class="line">us[001:009].yeefire.com</span><br><span class="line"></span><br><span class="line">[test]</span><br><span class="line">test[a:d].yeefire.com</span><br><span class="line"></span><br></pre></td></tr></table></figure><blockquote><p>localhost是一种特殊的存在，ansible知道他是本机，如果对localhost操作，ansible不使用ssh进行连接，这样可能导致执行结果和其他主机不一致。解决方案也很简单就是将localhost添加到inventory</p></blockquote><h2 id="ansible模块"><a href="#ansible模块" class="headerlink" title="ansible模块"></a>ansible模块</h2><p>模块是ansible的核心功能，近乎一些的操作都和模块相关。</p><p>使用<code>ansible-doc可以阅读模块帮助手册</code>。</p><h3 id="常用模块列表"><a href="#常用模块列表" class="headerlink" title="常用模块列表"></a>常用模块列表</h3><table><thead><tr><th>模块类别</th><th align="left">模块</th><th align="left">描述</th></tr></thead><tbody><tr><td>文件模块</td><td align="left">copy</td><td align="left">将本地文件复制到受管主机</td></tr><tr><td>-</td><td align="left">file</td><td align="left">设置文件的权限和其他属性</td></tr><tr><td>-</td><td align="left">lineinfile</td><td align="left">确保特定行是否在文件中</td></tr><tr><td>-</td><td align="left">synchronize</td><td align="left">使用rsync同步内容</td></tr><tr><td>软件包模块</td><td align="left">package</td><td align="left">自动检测操作系统的软件包管理器管理软件包</td></tr><tr><td>-</td><td align="left">yum</td><td align="left">yum管理软件包</td></tr><tr><td>-</td><td align="left">apt</td><td align="left">apt管理软件包</td></tr><tr><td>-</td><td align="left">dnf</td><td align="left">dnf管理软件包</td></tr><tr><td>-</td><td align="left">pip</td><td align="left">从PyPI管理Python软件包</td></tr><tr><td>系统模块</td><td align="left">firewalld</td><td align="left">使用firewalld管理任意端口和服务</td></tr><tr><td>-</td><td align="left">reboot</td><td align="left">重新启动计算机</td></tr><tr><td>-</td><td align="left">service</td><td align="left">管理服务</td></tr><tr><td>-</td><td align="left">user</td><td align="left">添加、删除、管理用户账户</td></tr><tr><td>NetTools模块</td><td align="left">get_url</td><td align="left">通过HTTP、HTTPS、FTP下载文件</td></tr><tr><td>-</td><td align="left">nmcli</td><td align="left">管理网络</td></tr><tr><td>-</td><td align="left">uri</td><td align="left">与Web服务交互</td></tr></tbody></table><h3 id="ansible-m-setup"><a href="#ansible-m-setup" class="headerlink" title="ansible -m setup"></a>ansible -m setup</h3><p>setup 模块用来收集主机详尽信息。</p><p><code>ansible -m setup localhost</code></p><p>在本地运行ansible的setup模块，收集本地的详尽信息。</p><h2 id="ansible配置文件"><a href="#ansible配置文件" class="headerlink" title="ansible配置文件"></a>ansible配置文件</h2><p>有四种方式来让ansible读取配置文件，优先级依次由高到低：</p><h3 id="使用环境变量"><a href="#使用环境变量" class="headerlink" title="使用环境变量"></a>使用环境变量</h3><p>使用ANSIBLE_CONFIG环境变量，使用环境变量的优先级是最高的，也就是说如果Ansible运行时发现该变量存在，那么会直接使用它而不会理会其他三个位置的配置文件。</p><h3 id="使用-ansible-cfg"><a href="#使用-ansible-cfg" class="headerlink" title="使用./ansible.cfg"></a>使用./ansible.cfg</h3><p>如果在当前执行ansible的目录下存在ansible.cfg配置文件，那么在当没有配置环境变量时，就会使用此配置文件。（可以配置目录结构来方便管理不同的群组）</p><h3 id="使用～-ansible-cfg"><a href="#使用～-ansible-cfg" class="headerlink" title="使用～/.ansible.cfg"></a>使用～/.ansible.cfg</h3><p>使用当前用户Home目录下的ansible.cfg隐藏文件，在当前两个都没有配置的情况下，如果在用户家目录下存在配置文件则会使用此处的配置文件运行ansible。</p><h3 id="使用-etc-ansible-ansible-cfg"><a href="#使用-etc-ansible-ansible-cfg" class="headerlink" title="使用/etc/ansible/ansible.cfg"></a>使用/etc/ansible/ansible.cfg</h3><p>使用<code>/etc/ansible/ansible.cfg</code>全局配置文件是优先级最低的选择，在上面三个地点都没有找到ansible配置文件时则会使用此处的配置文件。如果这个文件也不存在的话……那就完全按照ansible的默认来操作了。</p><h3 id="配置文件参数"><a href="#配置文件参数" class="headerlink" title="配置文件参数"></a>配置文件参数</h3><h4 id="inventory主机清单"><a href="#inventory主机清单" class="headerlink" title="inventory主机清单"></a>inventory主机清单</h4><p>在配置文件中配置好了主机清单后，在运行临时命令或者Playbook时就可以不用手动指定主机清单。</p><p>参数值这里inventory可以是文件，也可以是文件夹。当参数是文件夹时，会使用文件夹下全部的inventory主机清单。</p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="section">[defaults]</span></span><br><span class="line"><span class="attr">inventory</span> = inventory</span><br></pre></td></tr></table></figure>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Ansible-基础概念&quot;&gt;&lt;a href=&quot;#Ansible-基础概念&quot; class=&quot;headerlink&quot; title=&quot;Ansible 基础概念&quot;&gt;&lt;/a&gt;Ansible 基础概念&lt;/h1&gt;&lt;p&gt;Ansible的基本环境、受控主机清单、Ansible的配置文件。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
    <category term="Ansible" scheme="https://blog.yeefire.com/tags/Ansible/"/>
    
  </entry>
  
  <entry>
    <title>42Team-Flask框架-HTTP协议快速了解</title>
    <link href="https://blog.yeefire.com/2020_04/42team_Flask_1_1.html"/>
    <id>https://blog.yeefire.com/2020_04/42team_Flask_1_1.html</id>
    <published>2020-04-26T09:30:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <script id="hbeData" type="hbeData" data-hmacdigest="ac07ef50323184dfe2bc5ecea24c82840467324fac349d3c81efe2242073a3a2">5a907c078efdcc0b5c9e1d9c887e463e035b139523997a7b7ff96104204a4a4ddf859d815e200aa5f8da5775ec00228b7cb29fc72e78d76c5ea2a6c6641ee5815d65ecadda31054b768a3392380f256be9d3c1941818e8255c9a51db7012a325f88eefcc5715a7a45d000306c836904d44a5d098ddec513b5f34a5f02204022acd40319e146b893cc1c41d08152bbaa2cb3dd42fa68d4768bceaea7a697fc5a2856b0e61f84c6198ed2ede16c40cfa94009935fe713884964095b24380739066de67543b00f0e757e407b119cc7a0b9e7e93639f32949ec0d69930ac1bad07c5e366561fa67546fe800b1d28d87fdedfe951224642c6163dd7d9cacf5923e1b478b339254d2ff9eefdd7fb4a3489e194621c89477f2e9b82c5dc3774ce7b3f8f5b727d100689f5630b1e14a81ac41d6ca6ec3957894c7acb69cbbe524d20b1a0823af0c1f3d7aa055231f72e4cbfa4c47e08efd13cd357672d1b806cb865a965bdef0954c8b44fe1b4f59fc503b24662831fe8c178126711a0ec4e7a56c60727cb4f6542b96f168baef8524b7feff483aab1dab67d5dfd99300415780ff942d2faf034f2443754c50b425768fdb939e9bf10ba7c19949c9893987dc64345129a01b0f328618db5fedbbc0bcdbd7fae16c3ced6905c0c358ef2a0eb26508a0f68871ae63c75f4c262e59bfe672dfccd3e37b938e50885ec60b5efaaa583b4ca4d013f6bb623c5b36237552c2247e9751d4a7f5bcff98a33e606bc3fa8f5602dcacea7ff562f5fc1f28bc6e15e6c8ae394a400a9099540c4308cd54eff07e9d46379c1588bba7450638e80dc4c3b0295c60769ed25974c281110ea25bd0c11d282cdf8760e67a352df210139f0f69658f16ffad1c69665d9ce29dcab564b4b57589daa4266d04b177f4229225b5d6efff53e38ce5b77dedfc888b7071997dbd1f40acef952395480c1c9af0af6143ee631d424be6fde88eb6a0c26f9520c09e402b9c8a8237b88d59a224673e9a654d4426be4eb4c06f41b891928889560d3d591ea712db6c3ecffea893a1e7c7d4aed34d3bce33c19db652c98d820831df9bc3674dab5fe444eb163c32d1c2253f6ad5c37f08fc964bfe904bc61c87b45e2f8d6b81bc8f8399d7291acb9f3e9466c36f85b8bef533700f78c4a9b41aa6adb874a875eb431429565c8b9e7b8012b26b513c131ac339b676f3c2c6861a9b570c07bdc9025ffc2815c12ffb2ac3084a3345888b706c14e293eaae71d21acc755c77a171e29a71f6d17c51e73ade2477a7c8ae11e156633c24666deb713bbe9425ea571df5b03190db8277c1ceacd4f6a59d95b41f6d3da7f7b202c3f6b62655392168e9c30113b2a6f802a01c6c266ad763a0f017e12ca187f43c78c5d0a224e482600759101d50be15813dbb722eff5a752b55920fa18a3c77824c52a413686bbe4a702d85495bc943e6165e0ec829f32453d94dafc77ea7209f468d57908d4b0921bebb5a3e63c95557792eb3b2df241800786db67dfd65c1a153b751e46e1b291bc4d47a0c13e43a96b63ae00ceaf40dd2fdfad0b254b02254ffc3d00a0e48917987553be80f0e7c8115032486a1c02a59f9c6623b6b2f795752562d28fdac241042ed63145e9a4f148df392927d399aee47a1621b95e66560e269c2fbab279d192ab97638712780b34e7cfe54787eaa81d0d5a431116d55d008d858e6245a0144d4c09e7c2f70f05bc291423d628a75ce0210862433e76d1479e2ef8944fe9a04188e45bc70a1869cef7ec9f879f2f7d9d65ee09e857308475f868bb7ef66b71c259097b905c2abaade1b047dc74274b725e11f0795e62aaad8a6a8da18facb51c2ae8c59c766679bc619a4e17e442f083666a551ed315ba3869b9720e00fdb8e5ddd7010ea4efb61f50b6e1651db1e63920df0b14c5924b27d9e4ac67bdd4916b9bc6f87056ebc0c7c32e1b9614135ad8325cd56165d3ab8ab5986d19e5c9162cccbf429989b6f999c4e90bbb9427d8f87dbdc0938d51311e2e07c397472ce0771d99ebec1984aca6cf71e39a9ac91f8abeec6ac24901bfb47c91d10b1575ba06f7f57918dac3384aab14adb2415ff077751cab9e04fce313a6d7f5fa6c545bcb9ac46964f1c69d4125038136821d3e1c260b40013ca588e15cb83858d51951b45094b14437245ec73c5c68782fecccf563f4b6f4bd4d0f49d9cc0169b317bdde900338c3318ac5c94691a289f2308e10fe26a8f62b752f843b14d4961efc9f461ed5f68919dd496aeae9437c905518804d70294b6e7f9c3a24ae8f8e9d8fc561bd114925828c56cbd24bbd3c3f05f75c707e522ee437b33abb9af9b87e950fe027b16392cb021b3bf1b4136a0183f144e5861c9ff9dbac3cdb22e984b89ec4c763aeb04af83e749b79e605ac8952b23942769fbbfa9a070ae03c29db9e2599ff5ae85bf883343fa28f608b25f22140653ca3beedfda0a2366eda63690e1ec355be645c1fa0809491357d11179145a98d8294a203c78e98a88949bc1f287fa411d4ca84a7a70677bc663cf9286db9b393bbfcff69e200bd3531df969313684edbbadffeacbd1e6290f5288063362b868af042bffbde89225c0ca6072e7429d84d067d36b8c06d1195f1eca53337097aa8b423c68119318b96932227340c40e7227bec46cba1bb2ca342efe5e1ff4207ff94c424cbf9a8f64a13b3863fd2be7531b251d9bd7b1099e5921d281dbb3aa35eedfeeab4cc8802f187f6cf3528a922aeff85a5e6d1674fa51d5b52ee7c21465e6edeff6b94ceab636bb4ad66e1195a771d38aa768c6a27c7171dd807d1414c24e20849bb44b21a8864bd9cbd1ea3f7a95fdfd241c2e61666d2ad8d05a1591aff1c1125519c508d42c3ad41c83de88d272cca36810e616ec7b647de3296581cbb92b043ce0a7a226af9bf93e68ed2af1b912d347165ff1bcfcb96f7d0daa784d1a6193a52d3d5fbec1105d89cea79107b41352df0b9c00c8f4542dc4a8f2fb5fb78c224b84aa816ac693f8a67ec59aeb8a6b8e54d9e48ae262c616098a54e0e4f8e2426a794ddf73b551f75b318513c51457b8470831385fe6e2b8774c10fe6177095155ad16e4331b7d81d4cb72fefeafa0af16fc26ef7ab707f85aa3055641fee0eea4bc9bfb83d4d3fe84087b295ad1dae71d5c2feb372b5a2f663aeeb34f14845e4c7cc51553d02d6bda6b260c35d32a2ab9a3ce5eab1a15be7f1a4232b4318b527253bf99d8e2a585fbb7ae1931a68552c9192354d8fe7cf1752f9cc645f410ae30e90e6ebac7c486dd5d360c83ab6bdd08ed8ffbc94bce353ba1460b5c7e9c072a4b705e0e0a707f33432470ff83268d3f455f0b88c4760f538ed99078703cbdc59da33aa9a0bee0c8b8b3753a6eb387726d9bf4d0be44b83b7eb758090ed1bc6d06fd64ae35ce63e93f89e4b63fb015b0dd9db8cdd4e97e8f823d8e5f344e7f34fe0a8753cb2b8588b93f2d369dc9903a725421ca450322fe8d27e11d7472512f636d38b40b0f03baebb70e3913191259ab49e4ab47f6e73a228fe456a401ae8a4790ffbf99a1d1717bd8b0bac43cece1a75e1091c40fb58c3fa989e4755b73fa0ef834347799e534e884d6fa7ae0873792ad8e8de315f06d3441c3e95a57b865b97c1c65208672da534a90f43cb31933ed7647009c56291bd4e25f3ee6e84b48f31b4317d1b3eba482bfa1cf0dadbf4d9ec6dfa74a235d098708f309d74132b13027bd268ba5ba4541df2c160a046c41a1e0fee4043655e2c9cd0de8483500f4861d7740d78fbb3be192ef9cee07a236e29ce4dca5ccaafa45dbf1edd07d1d8188bb77969861277f9dc6f2b6c0a81360ccbbedd732b391740d7c66d07a437877e0b6a15b5545e5d0db305cbd7bc28bef617e0c25d3be89e3f027a4ebb5776c58c823ef4de5cd50c395737027157791ae2d95e36bc3e6c9052c2245fa3813d288d9d37c92c197d5611d931c5c99315c261e911500952cd8f579011f0b15a38ff06a2d664b63069dad60b48dfe03b245f6abf916c2a4a4e08d3062ca06014a19e10e7d814b795e0d5d8f4f185dd508d8537d50ad4579eca80c08b73f4394cdc341e55fdf8c6f51f885c38b1d80a49dc3e9f29f567cbd96c74c5a6048d3c363fbe37449ece7dc67c1fbd960bc5adcbd83f92b0c164a98fca8736fb27dceaeba0787f4df07223cffc3a3e08f20e54523c0487ddd8c51482ece57bca090ce054da1baa4cbbc8bacd4ccf5b59375ea2c0499d3cacf43515ea976738ea77835fccb57386af07f9efd35436b5967625afa9451fc5e0622cdec6562729e0082068a83a5f5411afe351d66ac7bb47e413aea30abae13e314375d6303b3c6e3d9ce0c71e81ad58e597674935d4ce08250a062a6fa0c8813523aa016fd2a38226e88613dc2d75f77adebc0d2f22bc7de9d9a43bda8f05aa2b684c54b3bf5be23b8d3b73a07f1854283ba07200bc68ed5f6b700c6bade50d11b1b566a971fcb630156791a7362d480787ea3975a49e462179879aed45fed4a3587913c10dc65aa804b3db5a7a9247a2f2f3a05e7c1ac1750553e9ed5357bc2944e13850d5865162b992e15339a73487e18ef3dab10056a66249ee7cfd8f8967a633c5627ec4840172bd62d379006a2a40c8500d4b4e0331c45e5c79c6b4e8c17fda0ebdcd0a81c1183eb4d571124d32f24b7271e89414f8e20675743d89be32f11bb444476e97374961b0838e2fc26c4b8679b036c6babd341b142290709bbd3ec79450a3645df4e4cbfe6f751729eba2553aa50a5cd138f790c740e9048e16996f7d8e8e99f7a5c9d90c50df3650033d226a5618ffea8b87997f4f7bd2c8275976a740fa65b7ad54ea714a321e0e2d7493e1375c69788f6c63885edf063c822bf7920b404065e535b3c56be845d9e24a080fd0d04fb6263bc9cb3d1a3233e9d81cd3fa7d77603b34f1b39e47ecc4b5366a084a1ec93ddaa96fd70ad7921ce5222a6495b483d33d9811a314ee440e7d62cc1a8d49200de5abf40d0e63a3908ca707358c7ec78418d66ee98f3c233762b9461b0f9536add665df706df92d2da1a51ae3de8d7172ba6c102d43d6c11db6067d23e635406c99a6da1d25e4ed5496c1f238931ec870020191005203cd12ff3e2a0f1025e7f5439a3e502006ce3fe563e59e2e71c707acf8ce45ad36257ad03703a18201e05766b29173c23b879b112e9c378488f0a9e788fec339ede41fb9427267f94f72a345017ff919bf38b3ab5efa0d9100e2083676021bc1faf93058e0d71db7dd79e81d824898f43fb3ea1aee149c34be794c4faf67e335af40c43f45fa82b2d50c9949e0f4f0f3c0264e670bd9d77cd0b50825f1decbb15b7c4a5f5240fd9d66255f73f38abe84c62c5bc02db6b1c7dade08fe770b873efdd3fa18dff1d1946bdbe2afefb1b2ea428e0c8d9b9c567f2469e06fd41bba9a7431c0bc47aad58fb2b6f130d03ab25462111a293b50783160686fad412692ffc53926ef1e3684a66f60e84154bb2aedcde4316e1c3df88dc3d2782e131bb0a21414776f9d9ff5cffae329f208a5e61744775f387edc07e358795d3bbc5519451ec4b890f8553eea593b83fbd08265c300347079d9bd85fd8ee6619f9291cd0d9dfd82fa42dffb0d677109ee3737798ea620c1e751d4fc1312d05a1de075e17dcfd4cdd6e74d48d827ea610dcaa6ae98df775e732021fafa7e6974d03f8ce76e1efe9fc88c8e566b811c9836ff74c59cdcb0ef3e927ce8f5a23c14840fe82d4b9db2a703c65acdb26b22ef9684ca55aee35a5170559a06d59b88d7cf4a0b3a48146b24d53a63a3d94bb10a213d28b019d5a17e8e99d0b76c2578e918abc3dd2562f82585d9c3bc2e2c049b962d18d9a56af6a6a3c7de59beddbc14669e63ae50565246b8deebd97b12d4a284828883886f6ad3d4f605c42c88230a9c42df18c89349d1044670e3c325883ad4da687d59224857ac4ec7b7434e96b07e95da445c6b2f88c5078fb9560fef589f85189452724dc258cd2060cd0c88e8989bf32a4d530ef6db0ace3e77d3d49f796200859be17480f11b2312c7620cd073d8d756e0285480b98430c32eadd89d8a0e213dff5da97b3471d6fb0c867a184d5e629e14acce449e14aeddb60099ed1d09deab4d42ea012624de68b610d43fea0d600174b74062141d6e18f2a09934c7da9d69dd6f2112999f77c72538402da1619e42f4176f1381cf87818dcd3150117b699abeb4ef370e033598d9f571ef1094fdacbe9e8a80c956ba2e2f958f8fee43fe6849e675ff580362a5bb8d95ca149dc52be4fb77238086064c92903ec936da2290bf1e1330270f008a33f5e64e43b46a89ae3abac87bae73070751066ef11c6c9d04439534d2fdb7d25b165252440b88d5765486f172e3310d8bb580f1a1d7074320518050e90f4c55ff9667d7b65acfe9946827e8584b3de4f17938d58ed252b8db601bd7e9423c386a9c5fb7ac037e83532f23dd2d6a754144579e9c1c6f36f05555e11a9d2756d43cade9f379091672cfeb6a4203f5be8bc29fb94ec58d34d1cdb3582e4a91ef2d2dbaab4d688d9210ae43a6c8bfabcb6db1198b25e86c6710ce51fcf787d3476689b531b1262a71fc1fc182678ac6d0993cc082c9d9336cc0bd9940075d5a2f3f5ced562aef2562e3c4243ab74b6c08dbcfc1ae42ab1906e1d52b56b9ddaa59af5d34b9a3a5e8f48a05f75a2cb324b0c954d1fd0d51931a662b467415c2efb41bc30ab2773d8e231ea3a7dcc22d2a2bec07f8f2eb246d3015c73677d4951f75c0667cb09f93424d406344f0b116e4ecc575844130b8beebfcfdf7e3f798605dc4e997c15b27c918c6dd45ca7d1cfd4dd390ee5d3e23faba16f340b3371fb57ff665793a3549564bca955744e4e6cfda54c0ad431692433c693b621c0b51e823b8bf59ff5c4b481af1bbd90ad14ba258607a7ce938543599c0dc0a372a52b5944030c85762b284797b03abfb6d4b75d212046f96d67d3dc27da72bfbc71f20b1822630672836e045a9b5268d05f04bdde8910e4eebf2188a35c88553d2ea3f7cff25a5b65edcb39b0c56654fe45ccb899124f2681848f9292eb13bb3e5a47eb8c2af7a6e2acb99ffb4cad8668a181e75c4cf397472c4bf1eb55b9c0536b373e7da386c7fe0da740a10b799d140300a108cbde533c56241e70db90197462724168304302a7cea19da25e19b5a12ae36c7786e8a8bab0e7fb53308f409ba819e568b23e6ea2b7073b697902bee210276cfed305a791ffc444a9fa5733fbd728a22748aa340150bcb26d324f3e998ab381422d88673aacbd07b7baa4674f5271ff9d6055b64c54872d0ad0cee6df347ada31c605659aac974c5a188fd83a49bae6e24bc362a5ec39e4b4631e50fe7e216fa8253865bad3653be3cc76a3ad5ac95976cff2bb18b04d0683277ddf7fa3a4f9c8b9f5078428b7c25668e0fefa178f21fb8d2483da03adb3c20e69263421b2f1706dcec7f42a9f1f1acf85706b84d58d9b0bb3bb10b7d468342414d06283dde34d6e094edf2ee1fb7bd1a112b49056e502b3e94bd98a54b5dbe7499c90f659adf63338d9384fc7d2292465c95c3028e9260819c7428c3bd4bd4bf982b1a52c2d30a9c3cae6e5b699d1edf101c62e1aeda324fb0b323af312457c98c4e01b7237e6093e8a9efe4caa32f4d9469de00f566fdd4ff62d02a1b21c2b43dba00f7b2cc8d07824d55b8689af1e9d9d14540fa667ef12a837920185c3e3e7171547febf535472b9a08496bece20be3f3d3919b462c9c2a4f8ff0faf3b763c003f38d218ce8888628379c46e9b41e549fede6c40ed0a1805a971d3db138afdd2df82f2c55087bed3820c8f28cfcc1087c57bcd08bf1fff2dc3bfa5258c513b91318b236fa898efcff280ff0a7abe5d6bfd816828a7921a59b19b457bdc9fe5215d633cb36014ee5acf0e6012bc0356f2517632dfb84cb5b37bb2e388311812325f6dad33ddc578c1635c2af3f7008e37f7c6a3048ba4ea25ba0acabf7205b15eda22871c40d9f9cea6568841ddb2f197c385e0bd54bf873d5578b11d9f9e94fc5890e039d0c347f3f98f59bf66eab9491c194b186dde4f4efbb26c7da58c722c210035924042cd82a0c4d252b0fa896bcffa9ce36de49c3c7072ae86c3ebc92a353ba0b86e3d5e520244bd9d35886af5e5eff5a5a3496c098f3e04e957ca8e05c2c34f1edb2bbaf400a557fa134f6d157cafae294ffcd7d17fab3897b29a826d52934e69dcc35cc9fbd4d62ac0bacdda82424a94405b333a9b9fbd0cd1304cacc0410cb59a1defe7536903a00d46f37688838a9c40c8e6d0732fb75e29d5fc5b0ef4b9e659283919bdd4df4aac3ee6e6f948bb2ec0d8b1b24d4efc0891f3a7c2bcad9feb59af50f6b9143e3102fe3d75bfaec9c216f7cd6fd27711a90e98c6cfbf2b9878ad6f1ae0be254a7937164b3897ad02e3e6d31319c608cc3d9839c1b0ca9a22e34fe695c5b3b2e6d61f17f6082b539a432e8b2b35c9ee5eb6192040692ec5306ca5705ab036e592df2a91ffa8381b69fbe43f3098f6f6b9bda57b5b788f03c8173a1f986794da72568bd9dd008b046bdd739da7f0c070f5f0ba23db7f8b03b92d22dc02ddb599e1ddaa0e1f108d912b1bb13640093187f793a167d970640eb98fda9b12829d0a42db7575f176460a7c300c88297298164929551422658108b26246992cfee4ae64a11e310d7b7526f18fe8cc28343bf720ede609931eec6e1cb11f754784e90e47579b577bd12b38098582ddfb7a80ef3f505dad15036614935c6e7a787777f0da6dae1b64dd6cae6b39ca45ffbc2a80c49865e4efd9aeea6e1e7f930a1ce921ee1d865f1fe1b575d09ee6ea4c10d9d5fc26eb3fa6f92699103be9357986347a6ba9d222d2714d2e0dc54b6c8acf5c4746157fd86925ce64232ec21d7806984505141c7fd97a06bc2e1e293d2540beb029d1eadbcdb94999ae53c4412992cb52cc8e0e72954e8c91ff354c06ca5487ae767bfc6041b9bf39c6cfd2458812a91830fa8e7d37a2c59a28801a2431711c3d727b2edb51f30fd4dd77972dfda3fa82be8b77463f0b912517cf057c5bec2c942453eb0a6fb19a0fff30598d6e3f5569846e77576170b285332abbde937091d01cb</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-default">      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-default">42Team内部文章访问需要密码，请输入密码。</span>      </label>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">内部文章，需要密码访问。</summary>
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>42Team-Flask框架-路由和视图</title>
    <link href="https://blog.yeefire.com/2020_04/42team_Flask_1_2.html"/>
    <id>https://blog.yeefire.com/2020_04/42team_Flask_1_2.html</id>
    <published>2020-04-26T09:30:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <script id="hbeData" type="hbeData" data-hmacdigest="91e177de6731fe796edf9562f7e70a7641960f9e9bfa9e008637a440c7a486ff">5a907c078efdcc0b5c9e1d9c887e463e035b139523997a7b7ff96104204a4a4d7c464ea29e389248488945182bad5fe12ba9592756dbe1e537f757363c232771303600b79e2eed72ee87fb2f42041dac11868adf27d9c9d9f5e03839fbd18af64de9e3ab14786c2ca3a84f5cd32c8393bc327ead7378755e6a001e5b85beeb98bab60f301572bed1ec9b1a42395d50bcd06146e4c3b8e9aa96f520a16aabe29947346c73ba55e21f23c118bcbd09bed1f7a16bff82da2794d2c05a7117844115c9fdbe1bbabd43f82974e23fe990d5722fdca7f6d90a17f485628aa7dc8569e3ce662d8b498692d50a147619403335d9a95827b110e0eb2cde86df6508c5be728ed06ccf546b960c3257e09248d9c87981601f5c39d3905b6bdf771600cb06c552f0422b7c9cd537c29071b421a35533b98d430a99a23a7127bbcf37d471de8efc28c8a2b52037248a3af8c6cb34cb8e7639f392ef296aad0663f8475497efbd6124fade7eb2dcc8a084791155a3fd3985920e1d7fb63d1e8299cddc10893d170a6c8b3aaddc900220976c9d31ccea14b094f5af773688e099af1cf75cad523c4b1df29c841103c82f26649918a703d15adf1866ab990e4d809fd9f7a977ce50f71f3ce52e9dd4e20fbb9231096f1f383aebc54cfd81c402de906bb3d2e9c2410b47b601619e5075a4b487b08cd7ac9bfb2ca082dcca51e5ad74898de03f7de005ed51e5d9feb7fe882f0e896b6e262ddb2e7d6d39903d198bb1fff3e2b087313c25d79046c4933bb8cc0d0e9e0393a0870ce3c496c7a3c9fa2312bfb8c3b03a623b4423d0f0837143f0808129074832c52b9172efcc6458d118ef2bbb7c8693744df15c736785331383406d07ce6e86ae721586cebcdbcabd7e593c44f1779f31335cdf7c57702a099e19eae909af4a9b19068f5155fd7bde4418096044600f2c4be59619eb30b94720a0274b787ffb7a77e574500aebe6346fe025dc8e66f4846d446aaeeb5f516a04aca700e29a2701f7b4bfc21c00216ba43aef8a73b8018c09e246c12ccb405cd62ba217ce2ed259ff10bb6b51008aba1d8cdfdab2b2b63d0578e72e4300a24659d2bb9e3125d5a5fb624e7e9e11c181d516734c7ccc8a16bf1d6f35b073059dbcaec1d7238ff3a55f8ee483dddc5d6715997ce7b3d12fe7fd5450a548edd73948e11b905ca8f5cea5b1a26a900bbb855c7906fbc3d6a90f9146afda0afc3e17d6bfa9f4e2b8f1d8ec3b78268bc15f4fe2b469a57969cb2ac8fe6aceb233a3f1141f2bcd6f4f9d55e38a48d654b78ccbfdaf1aa66335799faf892022e2e5a6fc42db84ec9a0131da09521447c2605ba80c3477b4a51b48191dfcf73043680080b32a1fa0940ddc83e6fa103512682dec02de02c47cf484c8600392ea1f8a1bb76861f03fad3833b81f3830f7958f268431c380c96f6d478139a325d9a4fecc98091d1330c0ae4f1ccdf980af406fc01b8b6286269376d2a4b9032dcbf348e6014f01251f3d0b58672653c27e0722ef7b35ad29638ba7bd09e317dea27ce95b51e7cd3bb789da64ef89762d0badcc22a5ede3c04f53465f9829b5b02727a97b5dfcb41e94766c9efb01e0a50eeab41b56d6f5b3b435c006239cfd4ce9021e08f713bc9dc2e2c6d1c8510272c72e2d9e8222c632c77c7520f399ac6799da16149e925da0b365778b5e9f1dea31070615ae5977c9d62f90aaa0f3e8c66a399728b69a85e1ff60a23c94fa6613492affdfc665955526ef965165a77c396b59f28fb43d2913eae090d563baf69ac2eae0fadb6bc8d058369b81a33df962c9eea89f99feebb4d3611582ef1584163676f91c0b1d1e7e2ccf6a7d02428cbed57ed73695a38819dbbe1b55a30ac9712456a68aaa2826c3b4a0dd547f7237352847bad204bb6f06a0d996fc09c853b366a0f72914583020215e7d33ba6130f5a69ae33b0ef2ab035b6e801ff6354dc8b3fca57360e3d84e271a9773bb7b17a6477f262ac756bbd9e4642407ed2d79f86ef7f437b1e461bdc29e63c3e02be321a99ede33616ed826be62b0392aa8056ea2c7a74c9eaf76998827c098e541e81ce35d8af49f3208636d631c008019a9ca795f6ec3a3be1fc34ccbfa5a54015af676e0992ef04d814c3db866b50bb6ba1844f103dd6748e336478e14dd3b374ce93d70d45aa017acb07775d309b6a561a7c78490320aae4634b222f8506c040460f970595766b981703732a1c6d1a4c4fd96ae39921391cc48b77ac0394970ac314c0e062430a4fa10bd07f41b1316ee0e9e9b73f6b3e9b3b54e9eb4487a03fbc31271d83eaf06f18af786932d215f31d6a33485f76a89ba0e1c1c26266e43454a7847a8a90d4a9c79527738201842a453d0ca28c2d5f6b203c8287fafa72c84e8180f566fbaad8b195450c1576bf0b476b4c48e9ea818f05f687e86403d0abd8651641184f966e03ccfaffb1b59ec3bdcd156fd2cc0920b6a9dd94971ed002c16a5c52b278bb6e2665aa798c9370a74467ec0aa18afcf34c139f1fa553ea91d57772d92926eb5336fd1b1bc2cca3282d94c3fce56743d661b7132accf623514ff630d026399298b9cb8a80b49ab78ab9853a804d63a5b6ff12a1e06361ca32a1a98d2cacd3705390c74c3791c5715142a5bcf61213b108eeb9b8d8a3c46e0515734b31709ed2472e98b7c219bc7cf36bfa4f17e71e7322b1781c269bd5b4602225e4954a36046e25d8697cd166a21a7653dc6bdd64eb6ae3af8a45f6531501aa2943a9e8789ea466afa2cc92404b906d10e0ccdf0b7bbc8759c771c2594be662e9bb74f8bd0da07ebb2afcab782712096480cdd0aef52061da602c6897f4aa6f425e538814e221af9f7321cb785618ea972dd61bc1300639a2952673fad883de390cf2886fc05152a4b11d93381d6f9a13a7b0ac75ca1681f5ae267947d3f9ae159a4a3c4d7868682780eca2e35c4cbf4ad6950325ef9bdd27add630b58539a3bb4afd56cb2021c58a1c710e037dd70b1ab73e75df0f764094f48235682aaf89d9263b27f35b312d48a1e4bce8998c0235d555dd6fdba0a4c8ef8b8e5e9e1df527cf141db202b81da9aee37272236c2ba44ff059e5c87480aec519861c28ab5bf15a13cd07d6fa2c8aa08a0b00138924d8020db0a3f0bbd1a180ee540d6dff25624c8c2deeea4be512db4f52b36da014ee994c765e3298fd46a9c6e0cb2e8447c992cbc7af5def1d310640e8332d59b970605c50cc5ae1f5f0c8f456b98b050c77158a7b316946fc759636e5aad6dde4a458d61ce664b172a04afad1db5ecdf7b5c4de804103f8e38368ff0c60b8757da4fe84b211d6118a576a3d04a206d216e715b311ffabd6dec28ec28eb9cce7fb77947d769b7d617963e0fcbf878f9d6a27004b1392a8033ebc46d59d8a6dd93ee0595ea1b9cc6072f17b7fa68d2a18c27601f9c27e3e80264bf06c730b30387a37ece64ded381e25a3d837d22bb3c12aded21fe14725f6cf7e5166593d965a925fb2bc0a1e59533c7c29e1cfa434d5b6b5c0fc74b3dfffa7114a259afcd214fd51e465ab49c92e6f738083bbb8b4eba88d55607624fdf10845680e177cb5b8a45f36677f0caf7ce7ef0643e95e78394488c06d16708709fd2d20a8b3e22aaaabfe8ee28cb9492097dceb52603e5f288608ae15b89edfbebcf88a3069d7f44324100f837a9984ab6a9537c86ed4e6738ef8bda98716b8a582ae9c5a10d08669b688cc4239c20ad12ef4b2d4021b2290fd3640e00032b896b56921470218dca4d3fccaf2fdf5417b839795ad65878f12a93bc23c2bbe55168b40b85fed2c914fb600373e74912d4797035249c8717804dcc963d99a9f4b9383ec7ce5f84a014827ad0e18819e340b004cbf6ec3d2f670af8862ca96570ecf015eb0f11300f1e9fc9a2881a882e03757e501e817f59af61757fe7396196dedc4929b758150b12fe2e18982df3c62a5ae7ff797f04891b06657016520e8253a6968aaedcc6f237cb167751a0424b1d3caba18e452312f4b14b6a357f589568ac1ee76303d2890acf1ae67b38281d80ac06042782b781f7da09f5b3a50fa1363fb1627780b8daf9accdc703d0ac2111cf0c2fb9e223ddcc1ca1d21d8129212d7d18c9eeece784a9e7b916d25c34125413d7462b30dd9f577d220b90506d1e1d6121f0a8d0dfb443f4bdf6fabfbe0ce0cfdf072178397415be0e0521c8fc1aaf716b426a052f30400e443b93d386145df2f561cd9d9578f995d9c9d28b295476d6364529e8491567f7eb7d582e8856affc32aee6fb055918114f6b3bcb69cc10d2d070cb706e7a12d2bb48dd4b1dd8771f01f20ce3d75a90421b9ebb46de543f008d70ee8ba139fa5a1fe6de156216995beec73af47aba9580578009cda4206accf0c777c74f4b4b4528e8bbbe0e5dbf0fd8bef05c3c3e16ad0f1b1936b3f055518fc9d8b48ecd1b6ee1425ce23b7239480f5d685c50eb6d46078457fe340dac9900531cf627561bfb56006e2bc7c208da35f933e233ff8d2a91009f88c3f18e2b707c401c9e3e07d81f0dd415daf611e576597071b924a3c1b7863597e039ecec3b468939dfe36baded47c02c2de1b880cd3598c02b1353f9e437bf3e9c6f9645b551b4caba9ae9d124eaf98210a5755f0648037ad61d2a55da7c94de4d801502e8d36da57751f4ed4665f53fd93b6935706c2f0cd48872fb537e6b9804c2bd056a137b931370d688974808a2b41db92ed664924863cd924eb4860f8355023de50093176bc163375480b6656f0dfe29b65d17286d7149a366f870cb77490db2b5bf1b8a86c13e56416abe73332b6d8739a32912221d3be3ef55aeff0a0ed8529de3196658eee5d2a2abedfc2020dcca906d2fef385eea22e13846c6177fdda734e2102ebfc809f1b1ac6a4fee01196c5c8ba4e7346e1763b24e256a284fba77affda289a5ff6bf5dd5e9832d1f5951410c5c68c9a9568034771b674c8f10b04583df526aed76f126511f300a481f65177458bb7bcd144d20c0fe590b95d4560be24840c6dce0910ee673f81b7da0f832523da7e8f1905bdacf87c0a1347c757866f215e1d59756a91af215083dd3c4adaff505c538c2918152b65faaf3be856ff4cdeba6e83736c45fa8b05c67aff5f79992c82ffa9b0bfe28ec2d1e409422af9e1a00b652c0d6cc74510fceb11d583f2bec09ba964fabeaeec9235512460ec74233f556b6bac45aa29795d30aa17ee613c586c33f79098f03da6b5f8b7bcfa9fccebe7c85a0aa53beebd90c024914cadd9ec8b814a1da4c4e2d54a01d28ce778333aa61d34d00b0bbc94021115ea8887e89c542e9142a42f59f83246b82ae5c2307987e032a093ae2910a01a485b44126c670c2e8dd99c07830f38b59be998e8d42c9f351717a7f1b8e3aaf33d2df110238151e5806a36516c26de59d61a983692474ce283cb23c6638365132f27ac27924a6d5d1b783a59c156aefc84ef732f49cc8e470856f3205303998fd6d535702b75e35f886e857cff007af5e2db22ee474f778bc39f21870c13349f504ce2e659804638dfe05d1b625604489379c00f828a699254d1931d1b31f5eeee3df8dd8a7d2a5c208b29b3bdcdfc54b73cf3d884b34dd91a7ed91896a02142715b096b008f0d40cc6d9fac64c8cb381f880a851184b4bdd4c4ce25ae3c1e5a5be2d55c008d8165d06a37a122c713b3c9d5d4e4493829f9099789b7224170840572a24fe49ea8b2ee32c8eba181cdbb529b8269b0b66b71ae16e15773e04577f805c0f97eb556e0b4d375815e10a16be78e4bd8b0a86e08f2aae4caa484e6bd33c0098e8e78c8aa754cceb1fd6603daf3989ee03f2b8173b0eac3153e3487c91c9f8f8edc2f8de4033f0410f17f6cac67d3e6477e69c921ce4591cff5e076a9985575ba5f1028da5afff20e16d9ec443f9da8a0320a698a6ee3a21b55461dd3aa54a28411a411490594e7db8e2b4b61ec4c0ab1e48ae42b9bc0d6648fcc07f58c59f3b9d2c097b9521a4bf3587e7fbe1aa3f5a68ba42320bb862e02bd08033c8c201c70b719c07f94877dbc390fc28226045513e71a9059d98a09062ef8c9f358abd74e0a60a9bdbda1002f6d29fc1ad4e21bd6951edf51833b9070244164d8e1920ab572a1accc55ead02eff8bc6c7cd08941337ee0f7ba956f0ecadb6f3f972aefc64b2a90f17ed4a110ab1dadc87a272c79b7cd2f4c63c1823cdef6cb3a7ded329001f6778268faa14f073d075b579063a259d55676e5557e12a09f978d9d8cadb059a844b7f8390cd38bbde89798bb18b1bace2a3f8e35cccd328e3d278f62ff11166b8258273f30dd1ac82712c460531c5f605072ee3ca0920d2b8cdc27aaf8a727220b5f5c04e8067da9c34691a5a4da7808e08e3b3b564d2a74f0e7b180ee6b0d8051b9584432318fc45eb325cfec606d2f5ad7d90ef5d46fa920d2bface0ebf368586f98c60b12dd50eef41a8dc3284f41ea290852ce84c29c6c02644289b9aff0c2fb2eb7f93051fa343259017319bb238cb9448fd9946ef63ea7dd2bf03d3474ae49a3dce225cd6de71f49d366130182dc55b54c220ae58764fe1c4ee0c8d622a0785f154083e28f1a52b804845a84f49a09568349b17967916a8e410a295dda366c264a760a79935a08314a955372abd18a48a5a5895e1546696ece5001581c890a8bcd53f91a26b3f02629e10b4f5d82ff5629e178f01e4c4e0504bbd9ae711e885938886c5657c57c90be5edde5fa30cba3917ccf8657c92cc91872e856344e2fbb50c14ca565fec4e2c4f1eb8f87afb8e8f8d98bbdc822d217fdf1006778c54ddbe834867ccf96b4549a07286c73b0d56a0d332effb1a47b306ee8f3fa483120f233bfb84b88ca248977d87d619ae0227129666daf20287fcd7e80c0ea857992fff83fa39b784a3526ea34107cdbf02dbc6d394e519e5b8ea33de9af6c48fac3608188a2bdd18fc71963ca19e0f0d32aa7b2dd1ce5c6a1d7faaccb53f032bb9e2521862a02fdb219bd3f5373fa6b1785cdf16085abe74e60fd4aafbe1747380766cc4474235e0c49fb2c4820a13b9bfb024cf937a87ba41f11f90e91746c4fea78c3dc31fff50356035bd8ece80a5f100313447b491328b8af2dfddcc26a83f6edf</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-default">      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-default">42Team内部文章访问需要密码，请输入密码。</span>      </label>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">内部文章，需要密码访问。</summary>
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>42Team-Flask框架-请求与响应</title>
    <link href="https://blog.yeefire.com/2020_04/42team_Flask_2_1.html"/>
    <id>https://blog.yeefire.com/2020_04/42team_Flask_2_1.html</id>
    <published>2020-04-26T09:30:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <script id="hbeData" type="hbeData" data-hmacdigest="d582b1f3093da56867736ca7bb69e28ba231094573f399403def51b0900c2c60">5a907c078efdcc0b5c9e1d9c887e463e035b139523997a7b7ff96104204a4a4dc0be9c4e8e8fba1835c8030cfda1476a61c65859a5b77d7d98381fa637082d7d82757e2874af99e233f80402f926c05ba5c86014f3624b53160d00cf1886319ebd3704f9346bbe06a5805df92e39e2f208d9405efcdace9eeabefd9f37853ca22d86c5f745ac563d1718f422b501fba15a0e6fea36f1c7ab02f982c624dce483ab09b978c2a909e7e9731b14c258e9b251219aa76858f111262913630d22330d3ddc2c0de63adb4b1b439aca42a8ab6351884c776974627b9ccf4c1f7093c74af5af1f8f8c595ac0e16e0eb598501b8b7fecea427ab8d6866de73702eb0f962015f91b32ad1f5ec5f98df625fb846e670c803b1336b3bc51b5a2200be885db37a01d803465a4d8ede5c01f38a6aa826b67abc6a16f7743bae55a44950d549c925edcdf489677a46f49d1e8fbd50311a54e8aadb876e7a2c51377195b669a44ae9ddcb61e381e43bda699647996caccf56b479f8a1bd829d1fe0dfc1d23390c69fea8baa3d08b4872372730ec6bc675938af111e0aa57b5913aa27231e0cad4bc6dba169453387b996c283690c6cf192e42c3a17bbc9fa74bc9f607f14b9d5fb2f1102dac081cda7b476e7bd6bdd43f4fbb5e0c2ec92de5b29a85b137ac74f9f06135f7e714f5a06be96abd25e95f53f77c80d2b0be3803f7f84256a2f5e93e8bf89a0252617aa3ae230c485baef4c2aa00c01ef38d6e052e5ab2460d57d7626ed02f3c7d02fa346530c27aeb2971113d9eb935ac64caae5b28fa49edb90961c1c6bb659c28ef3dd13618f72c7e607cffc5fb49c70dcaae84a1c0655f562a345eb697c1bc722596d1e3f9bae36cf8e311cdc851de6c996e6e5e9fca45af90283d2aae14d45b53c15030f445cdf2dda67cf77e4fe092329843ce13e106963da35ddd8f8712802dd7da19792c0c2f4a0a55fdaaeb426ed73546aa4d09949a0c7352993000a36802ef0be3f12352af0529c246dd2ecd0da84557bcff5a0a33039bd3af789312dbd673bc2376d4f1b85d50f5d793c0f00b53607c0ca40f309c9b45cc5f5624df68eea577d7199e510e23420c956094c82007a6162376801ab966f20561dc83a1def11b48a165ce8076db41bbcd9bdf3dfd27f0072788ee4a871811b0404e5c2023801f0165a515da7ae84010d88133f62060ab699f04b9265c6fd55c63dcc09a821a8aeb514b72894e7132077d952e55ae2e06295883eefb3fff9cf8f4a778099dfa041bbd4339ce7c2f0990ac152116f0a7f4296d3458f916ff78ee3ea7a0f96af684568f2ada91fefcd8cdb2d44ce6bb98dc5508e3e7c9e56d47bd1a2ea0ce147c38d7cdb712411b3a37b7b259c528e9a313778757685ced05572b34289244cfd931f5b46dabe723688a8858262710d40cd41284e707a5f1ed0e352febc5111e84fc8d2a222675b8a55630eba007c836b5446488669929860022c17cb10996811e1cbcf49fcbf002e5137cd04575f4da304e13c9dfd7ca9beeaf6377bc5bcbfe3531c3afbd943427efb59e35f2ead1988a2215cb27be4e20c30cc33f83b8566ef70fb7215bfeb1738b56485e36ef7e223548d9c7186bc6b080d5ed3a9a6999b794ca62a4c18bb14a70e4f7cc47a4716c09b141b160954c94bbab7db8e295f1fc76f3451c6c18f621799e1cbcb926ed989762b786a7e640a21f4ba2a58415a216477e3f8db09ee0f865e4e15e859e3044fb7de7a510286817a0258f4b0376855f090004b7c80d5fde9d58a26c53ea4ac292aa13c0bd14f10a1456670e793a255c3dc67329483b4f63add478ff45e7cf6d864a51520667ebc2b477bce099efffdbb3f862e19aaf2ef62787de3c7b06030a2dd655866663e9f1be29a5a8b1da6f47e7b9f398cb5d254898f2aa375e28082d307e0af556fc974b483a789a0875f7b4558c33fe012a82458a130b8a5ec61a994144109325b3132a9f91d17c431741bcce64c007298f1c8d8927fe8358fed838146abfd4f061e9862ac9fc2456160ca4680f9b7d536d00b1257f3d1cd7780ee3f5c5722f6540151217fbe34ce03df7549fcf28a660b657bd8c0fd15f5401b4b0a9230b3c9ef8c58bde550c981a12eec5040f261fcfb1a8cc35d98955274acc2cacfa810314dc34cbb931dba4a01432c77ce8f2ed6b09a81f53c46b035a145260fd260288f2d44c3bd62cf43c85a86d33fbc5e6d353cfa9bcdaf0e44dfefcc097724e42de72d37bd6c47b8f3edf74d910b45f5e08012252cbb65ec4e642afd4302e6abe7aac82edba08a819cb38e0b6bb5607cded4bba2e841e2c5977459966ac981f608ad3c4ba0444ea59eb5109a743b75339aaad7e5f836c0a18f83b3b072f301a9344d429c1b2efe589bb63533c1023fbc88991d663b30b9b032b31fd53c8e409462c9573cc4c01bd06087b632211605733a0ef476c44cae34a83213311bcdd4b8fb7c5b8c764f5cafa970a0474759990f045f92910d0586243d4ead1913a2c42a92ded4b69009ec058f54b4780d391f513f6de7bac620015d65e51f800ed0be50ea2bcf0b8e690ae70b6ab735795d4286eec8fd78f834abe31bd2d4e40a3f8df1abd3124172b1e5c4d0ec4759741689dfd4aebdab5c338cd75a29557af53956f966181b092cf2bda5c4e45f44087b25224ed7aab37a531d4374ba8b7efd6e11b7e29e1860cabbb730a0bd091dc4bfe60736c02d593ef6628b48bfcdf52f356a488476813e09ff8ae8d9ced6746fa8b680343f82f68bcb0d7c2c7aa9674b0309852153a99a381c995cd68edd860367f3c9d7199ce4e5120a818b476b579ef1e1bb274e56b07821e211e5d6bb4b5c6b8bf17b1342eeba50dbbc0db50358098220ab816508c2f7052052e8dd1e63fe3ef513ec85323ca3b808b51b07d9e48a069e62633a9813b29cb2d925e1dac23bbed24eb81412cf5d58f744f6b00f4add32ea66be46421fc46c58ffe5230c08469af7f67c4942cc9d104b47e3a17c42f1a4e27fbe7cb7d31b1e3cb059a5dc2c309012c6f288a881eb6b2db32fd7e705980701c51862d43278c439dbc20ddc975ad52ed0b3b9cebf5de9afcbbab42669d8b04fdab5e33481ac128ff9c832843899935c9cc95cfa19d32c4b78180dbc5f0777b4a731caabb094ec2ca022cb0ebba25da1987fed9ceab9959b96f4ddce679c3433ddce96cd0ef6a00ba475d21183d22534bae444fbc6633844c3aff01f2b14f3fe48c9f02855a6c4c2e435e27af67c9054610bfd3e659987a0fb1ac43c0fac5f0c181e2c0a91fd1c547020f25b4a24c420db711d69961ff4e5814267cd2b1103dbe5f32d07cfce2ebe08c2799b05486c5d700601dfc6daed8771adb3612db0f5afa850d5c08fa19cff9ac5566469a53b8c0c45d96819dc74ff4623c10dbfdbca4324a21c0b09dca2dc34bae0101bb9e6a5969b9409b87229830a8e601d2e8519c7a57fa7005c9a4cc9eb2a625b7a88bb55815c0d1d5c33ebb83e2440f4dde5f133b08bfde1d13e60e1be22a4cdd3921fd4ce6dfb9dfda528a9dce6f51f81f59b09035dfb036cfa1386ee358dcc79b6470d36bb5c4acaafc57ef22d134e3be8a61835ebb997609bfdc510a9b30de0fea957909e16aa3732f1162190a27c6d1d32c75eb178fb8128ff6d3097550d1c1e83c19e9f3421d40f419ef9e4340b7408be3838a00acb8ab375f1ba9eb730c91c6fa9415801ffba510a48bd1df89b950e2c547ded2049c32864d36d96a7fde98d92d2c97f7b2d6dfcbd1d0d44bb6a86981085a23b572a7670ef0fc409a08941ffc1235fcc0df0f8864b4ce3cbe1cb99ccac91cd50ffe3cf16e88318200980e83e2a4ed3c170310b801b052fab625421c5d42d7f7be2beb649b5bf2fa1942b99e834f286638ce944afc9a5df9802eb84584a02470aa384092b2fdf75ae87a0f53a9d15a7413cf18dd3e22cd584fed852a9bfeaf551096db3ccc39381a33bb23626435e32edbdcc4dbd2e59ae8c46ec42aeb9eb11e77280f8643e0fbf06d4e1a435cee8a09cd13e3047e3cbd843af3568c54d6fc049d066083d8d999766012537f39c23551ab96533cf4cd65d42760f46330ed66051b56067d3db38796c354bded5c5c4dbadab683e9ea470aea82fb19360fa70205fced2247dc3f5adab9bdf9f02bd0f8a4312a2d299202902aad8c0662a20afb456338a3eb9fa526fb7c79c826f52780fd950b971c18efa143242cc714402acaca7858bd852930ba57bc4619268fbad8b24b86055b2e19d33abe6399fbbf683be907ed724aeb64034fc13afc829f2d5dae732face44936d51e59c0c351da0764ea314435a77a1a3652e040b5b6672a1d4b0ece9b16f75e17dbc8cc2cf77a5a2290a03902914136de07b069c6bb7c20a27ea5e5b154dc3c094b4697991aa29c96be973e9252f9e8e39519cff8626190e4a3ea19141b222ed9205d8f9c2085a51e8702e1352c8ab8e3e8e458136a5511a006df32b076550b58664be10c5a345a608d9cdbae4b226ab667ec994c4ed65b1abffd56323935fa8e58b334450cd707d35aa126cdfcd2008bc8f889ce59c5b410953c01b7b99f78628ea1ce7f8d60a093625877bb61281a98792ffa82d48a28d43e50c0f5c0a01f35929f2adf3244bedd7666af8d6fcfa947e518c0751867be60430917f1654f773903916332584e1c1e285c8a1fdb73a5466fdfa570dec9e39f3d3051e7a40141712e6eb910f581209345c17adb94a2a757add5e727fe2f9c9eba645ac7374cea469db31ce48afe8d1326c7dc3f321a3c641771b8fe2a0abca568295a666de2e08025e8c2b541696f2f99e268e987a833e8412f46a3356fffedffd8dcfa8027a78af9a2bd4cfc53cf530c14c50d38ce3d388fc094dcd06866e199a0bc0cf96697b9476d3102778a2a0a5d798fab27d86f2bfb07629596df48cbb907f2c313c413d68f39ec117ef97a003837b798d07e08102917641888b6f0af3194f2d65caf6ce1a9fbe6effeeb7769d3a62f771cdd217ccd656b8a5293ea921ba2c5140c0dbbce89c10f68008651cb43856b65c98b7678aab09acee848e2c742b86045fd3f13968242ec89fb4ac668955018d1f8f9c6c844b8d904f62e19a611f6fbcdb36fef49c87ca898e81f2cc52af9ef2c8d353470bfd0be1c60be3ba3f9734f8acfe7e551f1609eae5ab99e970dd2dd8f4fb47b656ee6327ef2bceb4484d4a7bf2a748391aaf9a8c3b789d38fbda711b65edf0ebec267a72bd1ee9af219fec18e6c1449e72dc9f2dfde9f5df80599a4530e4690c509668a078ecca8b953c58ce2bb3c8de00ea8327e9a1fd10882a052e8bebb43b60e5c2753f5f71fb81cfd2c5575a1f702502cc457747e0d41e2c1c7f6f8097dff75b3a2429c8401eec923a2d19824daa6ad807fc5f6e226fa1b7010a05310b9fa80cb81939a2fdcab016f3a272d91378bd715b74218306e7a818a3c61c24006a144dd227ebc201d36a71fdcc203a8d1edef44f827a72f6428cecc67977c69461d62fcb6e11c4212d56bade36d841de6df8974800cc27c2b7b13151e8635c065706a559a8bfc67dd5b5004479f28d9e685e5be46bc7610d4c1b6be5a92a04aba1b7c9623b667b177254bad5fe9011a728c067bedebbec1e2b3b8b807fe8e6d6921311867ac866f6c859f527b292a5e329a8e2d838de1121683b8578abe65723b3d533d06ae9b362011486cc708bda2b697e2549cd71826ab536935a067cf01a2471a6d1a70e165c196301a89620906fe67ea76eca26333054ea3b4f27fca33a8071e25b606ecb1a72b7682b0125094346925366afb8fba260ab26470182bb66094afca89b73dfe8fcadf31e2a1d3b9ea995b84305f7720570ffcf6f5f32e2a4d9f1e9f5958c6c00611395d5c15911ac6425618437b1ddbda2abe62821f256a93d6551d555c0e520ad8cd38a6a5831c3a238dfa3acd65aad4a6c120c0edad81da03bfa7c5b96583e3e5c44772e81442b8e8987293d4ba1628e20cd0b452be51f735215386dcfdd02969193519272cea7e2fd7b75a4131d9be487061e50cfe21839f869ccf4be69bae69a5db2618d90032b824b889a3b361f62e56ece49b719e80136d9057526360918cd3a260aadb6452ca1851e3e3aacc03046e69e8902244b5e87eb3481fa291e16a51c2b299039a0bd0b6c603505d9b3d50604446253b6acbf9f7d05fededa3b825bb0b822e49fbd8e0f9e1a316d917dce33553913dcdd24db696ccbfe5d0b83fb51806cfeb17c80c7c62b61453b1a772c536c7221f3b402d1df3e2d3d40b065be4e4366943e084e7a2d80e1ae44497ee89dd85d131250b17d1b37b52e5c055cdc3b3b568d31486dc76db89becb886651f6f3ab09a7bbdbf3794b06bd6c3f5077a5bbcba75a9189ccf545c37567cfad6cf947eaa4fd9d6afd994043455fb366f3844ea3ce9ede483714e86a1cdc434f4cd5a758187987f3f59311a779ecca64cedbbdf8d34c2c3debed1967018263eaeb061d3e5bdc091cb7fdd03505f3fb338e49bce98f31714632823c9f2417f06e93f533095d5b0b2d91e58072cf2eff350eb23a2c6ffd0c6df2eb28933bae1ccb59f2bcadd183f7674e0dc37533359f06e222f9d487ae2548ea35d4bad59883e0c528ff8df0ea1fa868464387e67dc582b6ed392e209ff200bd432c2a88074aef4121563876d86c0c7aaf97c9ff54cf6d4ea6acebef1b7555b606a2b36961ace4f8a65cc6d01f29932887e82154c0ac226dd4fb963fb8d40e0011c171d71ba3131e19e43b709f869ee2c10dd7d60da0ae0d41bed5dd88403ca9f1a9b5bb0c5663d912eb3b80b97328f58289e975ac6a535620b2966cb203033afa43ae0977e068ee0e9f0db771f64eec192bd245941d46f5a1f5209231c1ce502ce8cc0062606a674fb4dc44bd7233e166b689f2ab79af67996a9cb4131b5672fa5a52955dbfaad433678ab9ddbadc0a7aff83075869b865dd54e6ee1b768e6d7d2949dba8921525b74ea3254997cfe14a6eaf0462e50fb48c79183ba14421443695e9ec466f021d7ce84bfe025679263b8dded8a45bd9745a0e5af544728a4e527c817e8ecbfa48a4d2ae581758fb07e28c0028b088362f81101a47c7266a0669733ce7aa598ff126ff07d7100595c811e198c777885cf74454935c334a18881ff30e8fbb664bd5a1a38124e3985776ac4f10ac34b9002ea287d7c8d3e528427f6ce8c932519fff67ca3e5272f8d47c23378a466380f7a80ba512e564235bf8ef2f4c5009a9d0054257ccae401c9962099dcf87c034a16c5782fb6d73e4202256ddea61b2744a8ab4a2a15a19a39a58c65afd578bbb6e175726aed2d3de0efd3a3685c2ec7201a80c47f114bc180f2bd752f06b18581ce56747c65016ca247556618c174e2032b62db1881d188e3a00587e6f408414e3d1975751ea52d8538571b149af16fed591f2b33fb3ee4e6eeb65c45e9823d53d1fe153ba10be60023fabcd8959bb79128c0b344cfbb93b30d294ca6757f2d3e1ebe9d52e21ced4c530c358802e87c475abdc22dfb1ec09a0b66e75ec8cb09693d036f4aa85e09332f18fd7d7081f033b92c42853fb78ce3ee15b65638e154dbf3bd2a768d7c3b0d3fd93c370d886aecb29af45bdd7d32af90aac1628de37fcbdd591cd76e5760543978f1a652cafbbff38e0b755c96410d56e85a7bc021ce14cad9decfb6e5395e889696d2a16c2bc074cf574da90115e7754ccc08ae128dddbf8270986e1e4c07a62b48d92f2af8fbbfbb3ad4a9bf64e6d204450fc780226221be7ae47ab0a4a47db2caf0f2f22456cf781eba15808c90d0c440c75c8721c2731b82fcfa102e6c75b3f2a05429a27609a8cbdee49e3e84d703f9672e37a4b7397a10653b452ba524677ca2e1cfd734e299c9ad55ce5739fe6e20fa3eb5e125eb0f9b3f4e8a3262d0e8db03cacd1727c7e86909767862d3fe1684558548b3aa9fe14bf44ea3399cfa44f2f5778af433dda17f585bce4abeac269605834881769c580cf7e6dd080156cd9d45bbf7388e7a58ed9721a73e2c93750a4052ae4a0a00f7ef7d2db2d52f47af6d1458b5e37f02ec7c0d46df3dc20a3653215bb02a5cda0c7a4c0e45ccde4f715c67aa291f3fbce6b016f3aa46ff2392be989a279627f8d4fea99f7137bf9c166077334aa15c55364a10eb1b20a4817da3d8ab598a896dcd93ae5fe43bce7d504086b12ca981e8cf16e2c5d706f74bf39fee9620382fd818176ce3720832465a24a902151f85a510f35edfabd3165e494ace9621e6e90dc268d4a1e83d8894604b25ac04b4a256d9b29bfcc3e6123828d80287024f94420a2f429b9776d3a4542e337239653bdf4bf0593cf0cca6310cb4985d445abdd2619af23f692b5c710d9e6ca29e22ff848e732b10c5183b0f41d8422249cab6dd1935f38a3cf83d824a01ef8eea7cc515e624d8dfbd8b7d27d461355d282d644debedf5b645b6c065f33525ded1b681ffcd6b38d7636c8ef14fc870878462f095618c495e2a24891636467c43e08d6180b5ba35b7b6ef0a4179f93e0b9436379c1b065139ca72d1fafa2cd7dbde826a75772f03881ab12650f3f0dbc80c40f910d120f458fbf46929a841a10742d5d0f1ef2b2cdf660483dbef6bce100ae36b2ba6f9fbb50008ac0a1d6f5a28726052d0627faee077ea620fcb106fd43af38748e1c2d0303223f44740528224949f2934aa2e06b102fc6877c5e0ccb2244d35e9325a8f04ece537f0f655fba0d6be6c917b122a35e26a16655f98cfd6931bd439cefe1ee66700998e99e55a14cdb51946d5e840f5a8cd9f922a75d0e7c6e4b8b5be79770ccc124a3241d8546b754683b8c069b222068edf9b042ba765a5b25caac048765ea0ba025a67e2ea0238d10280c54fd001a2dd8b7036adf842b24bb311cce77bbe6a2710a2720397eab2f5886e38d63f4934326330f4f3b24dd798f7fa3588869beb5b2a9ecc749761d407858269ab14d11c69f27fcf213f3c20715b833449774f0f2ec2800711ce3e9eb41fd401819c2f1d1296e974a2bd3af6bea96bb9eeca1d62820039e88680f7eef75e90c05da453d66400ea1f959b059fa39b20b4889b28735d2cde54299ddebdaf9ab21f341d3cbed10a247455686d9f954ec8164694ca9fb3cce658e5913e58a733dcb31feacd912918a4ee8dabcdba6dc5f6622752c28aaca9fd70eb29a9439ad005c1f3935eb3194cb2fb868fe534a5f0a45e3725685d787d556ae262bb04a4ff7a9cf0c7a5ec69b85ef1ec224f3e7b30aaffdf2893750c3442052000b46a3f021503b1ec6ac389089bce8c9272e722b91fcea980bc68bf23d1929109aea13e1a64873279a607e711683a8197f8adb6ac326abc3c260010e9016a2afe040a6fe60a76e7fab6b9813923fffff5009a9979cd10c5d8e5a16754931560af1c9b26733167d7cecf4b8edc4b2ac858c72e58b63bd2880784d15635e9ac6030f17e86f23881b646707be7651ce1e46f77a0c99c28ae6e41a7dfc334cc33169238bbc1bd3bd2f0c896ffa68d5aa61c9178b037e66819307b387d29735cec94ed20fe4a3dcd179c079ed3445bb640459be8bde3a296cbe94f501b5d695e0896a9c80a8b8ae6908b3054f3c6afd2624998798e540aacf40660eb5bc9e1643495557c60e690535b9fc800b3b2179dadad4cab5876de6e774fb8fd37501131b23cd9e390654416bf8fed4b8b7820e7821486d15f4f936135e6a0d961f6ddebc012adc45a0afc43f0fa913c96bd527549a0eb5b37fb759fec668d453c4666e603cafb8b9e4d7632319ca5438b6b5715a4e9bde5357140798162acb1e683a62701f33afc5f0c33b5f699c0e5888909261bb2ca77362f03faab90972c4f70a11fd9d0f42cf0e52d5889b50500ec612731e8b858e57e1537158c5fc4e90f3e43cd51f9de049234e69601fd57b43fb87abd7564a60cb30022aff5634a94557500336a396dfcc55f3cdf3af3d88c3fc8528d80cee8d2add53256f44501967b5a632770ea29ede7f3d6e9137e63f3453f4a62165f9807c0ff745d86b6f0c0756afa879503c90d3bb03d89c56d9172feffd169920493dd924cdb5b3c4b43999d85920d3702f02c6df9ea8cd92d361ab66eeba965620aa4bce67b270c82df58a2088e80550b20c0a7b310919c626a948b5199a6c3f860a44cef07e5e51f2bf34248d3e2b9d51ab0afbd66415ac93b07c55b006d1b03406781faeffd61e79da25249dc961dd72efccb511a70b519e5176234bd5a345ae43d53ac59b2f5fe6a8e0888c276773a1f4c4b9ca530716593eee868c5c22975bf89dae4dc1c4da1803e4a9477f059cd9f679469ba2e591ea430b1b5cb9e4606cbde318b2e022753cefbab7bdb7dceefbb63d3a4ff46cae4790895f185e91efe054efc3accad212b8c00cfe7de6414f5ccc3da046f794d17711505b20d15e4a61c383059b6de5f8a285e2d6358bfb94fc09be61215c3a67d7f6acbf8d37732698c5d8be97c086cad140af083e0ec994488a56dfbc4c345f732f2190d14ea7e6dee8974aad2fa624c96f1d70d2abf387439e72c343e3ca7129189fff64e80de6b6f6a7320cd74ae769961a090fdfa7158927685ef8c83e316b209c5cd1040c00e1b52fd0c0115801a965eb2e0839745e8ee75572dda3405aa5b30d6de5641a29b719b6cfa6dc2a52cb3fd9789848b8feb94b1cb2f1c12d3525f8a8633241e1cde8546fb47b07f316d821a06e6b91c250086b58389a34eedb12d05b6066af735973f15dd4690b9f5c149d291c09d0e72b857873083bbca80c7c9cfe44ea8fba55ed541dcb0d94d6e6d35e9ad4a453f8d980f28fa939a9c764dc1a9e855a986e33ce1b6266263f7b0d3fcb33f602a3b3a8f401f2ccc262539076e3d8b6031ad87f7eb0fb8b04a9faba6760b61deb39da89d971f8f6d4aae06529893412a7e34ca6b2572a61205f8fd7d16714c629a209eeabf69897f0e3dd6254f5686331d127e067796f1342d0ca9d0802ed1f77cc4990e7672050f84417cd3e6fcb442e0297dcb8a564e003b05d6479f4fbc7203bafaa655e0673026201aee063d88c2999ccc57273a77d11923627f459745d171382c1a7bfff87857bd68a8076e5cf989ebb5b17687d65f0f9af560b0c3cb6652acd25bff700db901bd740b6d70bc75cf5b4fff6a7332c866df106a86090cd4ab70cc8c6109d5c649e4adb23071270b374d4e8bae8eb9073134c5cb97136e7b34d76bcf2ff580b5c8a61b538145d417d34559918bc6c4e4d1ca97af9174924e0c56c29026dc89f08ac90ab8b36f896910b033e2aa76847b589706471e469c16f7b9ca157d74eed67ae648279763863c05d840144fcb4d9323d2e27208079161d1638a5dab44a4ad592a8419da61d300144f3f4a2ab8ac80c31c3d94dd75ca776c1f111709ae2ea077852122abb73c99151b4744365ca8a8423e8a50338d8f6ba6a5c8b8646591d0c74046426c12662eaf32fc6001c77b357c820f95c7bbbc3a5fdaa4ee30c6250ff4d9981632733fdb1e3267de19e583601b2c81e87fa4faaa60f5631d6ec727bd30633c710e2def8f3556809909b10fe298f9c0570629c8b66cb21173e68ddf27b31ca0126f6d567afcd39623380d6af9d41fd2bf8bf198a35248628bfdbc157ef45f99531a89e3f6bed9b21ad1f7c2ae4f05cf3f641c56811b1c1abd917408ef894b0aa3868a3e450de760d4233077f27c281ba4500e1cfabcff9ccf1147e57f7ce7a4e71f1a947ff8b55f1e4288b5f31fd9c455f637aaa1b790e0cecf6105f2671c71f2d93317cca857691b1173823ef77292f04f3a8aa9768cb9edbf7594ac48b18c2f9249357ed49a526e85ce25af9c3df50fc7a56c0ed4eaef0001849503301fcf9c013416146f200f089176135ecb4760b93cc88bbc041af058d8c387843dc0a034ceffdf263475dc3b6e4a9f13a0f776a4433f3edcb5f5c092e55b241965e8c2163b9afbc780ed56b986a99da02563c3846393d7c1d53bc86006ab268197c109532fe5e5d1756ad961c9503070f6bfed0a52f39884688fd0622a693e20f7e78eb76fc50cfcdf873c5ad12a7f2ae422cae1ef54d2b18f69edd426d4c737ea78fb4405a369b7268d268e7ab4f2adc93eb47cf0a9d36cfe4e545e64d246219773523cda9999ce140bee02dad90dab0b98f808d5cb6540eaf75f0933be3ded229d7818af29d98240b860564fa1d671628f539fb2a63879011a3f0f7375b9774cf5550487d3e8fd915ca88cf5b40e20584922f3cde60120fd2b8c61e7034b90a98b1b269a2f14dbcb60778000bc890d51e7f09a054430525af03af102e02eff8dbb6e291bc54bef36056bb09803de20a67131e99a2c2f4b1204af45255b1976795388dfae7d632ad8dc55f1620e558fd9c15654fd5476698fa7cc34c0fb6da93754c2dfac2dc2315f07f471d9567c1a96691d34f4011f57b7451dbfaf50cde050cab9f6e91bc977df784923776426fb6c9dde82c40fe635f20564f8d540b9492179866c9aa309d6b466cc40daf993376c9e9f17e12e927b221791861ab6385fb4549ef4550e4b85ae87ec8012222c3fc9ce69c556115d349a21cec4ffb6337bf611b94ab206b7f618ed2e6a9b984d8860bcc84358b7d9c0f24264e01eb9746082b3faf0463ea1e1d42aac0b5a78354f5d993efb0987b495ea1a962da1aee58ea5ce0ff337e7514287fc424d71d0a11ea179af49e0c421a1b1eb7711d99a3fe797a08b212c8db7736775a10e889834fbcfba4a5ad00532c087898266a2a84544ff4492533770f5cacac755cfe451b3a8c81cd858b23d62c345959a42871cfba41656bab550911b8ed2b38669c74eae9dff299d95b72209dee3967a415cb1f418e690d232ae398ba8fc8140cf390d0837389cc5a5dacdbfbdf39c80f67937de7d0b52467cbc6743278bdcbc9853fab834e348c5f6ebe5a09e2171ce0b6f782eeb6fb9063918040ae549db129a652dd57c092031f948e1a49352867daf59632ac5764ebf9893b3cb61bdd203f21efc8a872b5479bbf34e976bc96fcc902a4eb71ace4cf7c1950da460df9b0b6eae055723465531b79d0ebd462c0bff07803c37dd418750113d462d5abecef2793d5c12bd0a50adad0d40d98c50d8d14dea15511a0bc8ad7e3650b025b07255c24572df517aa49ecdf94803924d03cf3bb758440bb43a7ff5d92797d375ad9c9c67cd7f05274e9fefce3471eba37f1a17461081aa8f32559aee4c537b68e2473b223c4c9956a06a2fd667b139ad785ef5698962f70016e9369221aec5f6f7d8ad5d3060d0326f32e39d3f7fff8085d0359230bbd7d461cb1f8dcb89036ad9195e5f757d99839354faa6a9d40b1fb67476e07d40f5fdb1a0055a668456ec095acc5459cc7983a0d1cf70e2bc7389b19c49d59712313f8794e886c0b59284918b0437318ea626e25fee4f66ec01e8fda2ed3cede547f22aecf70401e420fe577c17acbf3f6f86ea228140ca053b13a10368b5b9aa223275301d495f71938ebf4fe5c7e0221f588922c8ad88c2d67d23653650ce57ea6aa5a89b07312a5a69e92b8505d0bc486b2d2a354926269b2644fdc160cbcdfd06a365b1de8f2416cf3bd437855431c76b8f6dfd0f1ac0e1af9d1cd968e90f344d96720ca72075642ff12f133cf2402b96f1ca70fa1220aef3e3dff12b2e9a3c361facb76fb3444fcd16e75b17fb1b0921f35c953561f040c289b77cb3432f65989473b116db910accba505a3ca59df1ac436aa871e95ceccb5fdb3592f637534b846923bd98c14ff9ba7f7eb85f0e4dd4d62fa7eff05b56f3806a6f5c763ea4d774407a5f0af80c68e6af06970047e134f7a94cee074774fd2ed6b88a09064b6a950ec58ff7a098389d255499fc57769cb7c9248fa0405bf1c03a3a0222193463c837b1f9a90b02006db1ed3a4d3a6a6e976b248e954e37302c6ad95935fa730310f9e91c8bf8fa45e1340780b0aa320fb05c34141559d4ffb0627033412a0aa06a2e66a44d9d4988732d9d431d6bf1bf746d09f392e76329cf99320f95da7963776b20ec1778f8869fc7bc5be2518be26f977a6d9db1490b00423e501d62f878b61d02683935c60e1984fd05b2057b5a12c985cb71777e2dbe39dc43748323ce6599c0bc4fddbf3b3b4c99ea5cd55cf7e15c8ff4ccd008ca669b32435d3c19f40d5808b50dfc0f5d53e4f90c3927c488929ec588dab6d4904662af4feb8b047c487f5c78e7010d032f0915dee314e290654a18562d1b18330a6484fd60fa0cd47750a85fba92ce248adf86914f3d7e24a14b34dddbeefa88ad5f23c318546dc286d04d2af84801e8007b564a19f7fa63b0bdcf7b5b2bde5ef5a723327d585126f1d9d8d07be1a5044e8e2b15c152d05f94e5f1f1400ece2d43667393f5a9326c958721957f83c01dcee2c28bda5089994f2c6f425b1c1f81949896809200da6be1b303f55aa47634d813bee6691db88ec0ff5d3ecabc132219b3efb056d848e7e5c0e73d9f0eb21d7daf15411791ece97eb8fd9294399ff31d6a17ddd12270840a3e092cb8fbbf97a3d017b5f1f259185496d04ce013affc1520ba895b906336a8819fbbb2690003856608ef5e845c495ec6ba4a021500d7c374eb9a44de50d5286e70b8a2e38e064b4c093e48e7849c279586edb09554c5bae0f65995addaa5be8e50b63fca51731c63dbe77499fef38897d18c71c67470f9b0286a7890da634c47760bac52d614b2adea626a82f95ac847f01fcd070ec24052c4cbd5f56639eebab45f3a7eee4fff4826b9912c800a10b0b34ebff5e114cb7673c2ae9aeb7188c7b14fd95e19f2321992d6ad0d19626c5fda5fd2f2fded8e734fe7128289fdf3417f244a81fa1229f5fff3a29c10c3a4831eaf24fe41ae78d02938d2a2efe667c87e61a2612d54c83ade478d1e712b8aefc79304c6473a41cbd024215f9ccfa2fde290dd90a4e56ba4521a8711daeb67481494d84d5ebb0c136a6d58a9da5a255fd6549724ab19ec33b1d2c18f3a63c630be60428ca159f9277d2aba06545f175251479be9f66d64314f841fefb95efc1d6a6aeb2374119205183a192b17de195b650b6e849d29013a0f3337e3feb277224d21bc06c8f0ae1e79060b6d6966fb9f449e0095a172d62abc1c34ab4119190468e14320569937688c7780aed885d5564fd30c6f0ad56cb5b01bd9da4b8938edaedc5797ccce07ff206b69ccab34b2612f70cd47d19c8fe46c3ab9621cb622e9547fc86542668f39e424e5c6064e93f4e56e81dc13f78e042d894e8ace35a12d731d99594395684f1db84b06534254871695ff7e4e2005c53205b5297711dc2c6af2f0d311c7750cb479148878cd21853bf26fd082707b29d1e967b2a07e6df0879e75f32c501ae7b3d49621af4f9c6d655adbaaf5d21da34b236c75bdee6b599dc6f5050d84ed995d485f8bb8a28028828e40f46afc3812b4b9b276578228d46e2fb9e8b531a457b08992614e8b508f87bf1a44a78496c840ca8ab666f7198a70cd69bb863033e6833e1fe1be913446c89fb2122d51b4abb0a1e2014fd309e7c226748178d9d04f76683be6037df09323e98073f96ed59b933bec163142a2457d5a2d32b739f36e89a43bd4519616a6b52848d8ad08f3e11816e60aa2690e92faba8f0f07dd547c4a6b7a17034ba79e27e7728c4d3934e1edb7a241284fce3cfdc37d1df2b40a8f47afb26b58a6f478712b3ab7a1ab3101f7067831dc34379490c05712f454b8341dce7c19ddd98d78ccb62990d7c12945d001135df94e0d22dd5deda88e77ff386e49a536354ef702de876c79ee8877ca659df56d2efe8836485cfd69688b5b72dde2bb032da8063f6515e57d0e320d98f517dd3d09d4212e930c8a49e1ffba43d575c6806bdafb01888a941a4f07b5baa82eee13c5be6c27be02db308559bb8fef2c2eeceefe2e3dbfb7cce34335558d4df16f3bb626dbf9ad84d4407dd05aa985717404527dd861cf47f60eb388cd2d540df0fa82426ba95f38f2478d2d202ba9555b72333e3dc584d9051493ccadf57398edf81b2f626f54d9e389e9f23784429c55f396fbdb429b8aa6bfce26a1f59e94dc896f7abdf528be97b1b103e47d33f2e54be2a922efc9020b3e693c8387522c102b5508a1ca9885f6a96c52da0bba286dd808a17b21a8ceaed81a670d63981ead1b2c1d467b5bdc20c010bd41379529d6d11518aea07c1c920481d7cf5b83209b7c67859513a74f8c04726ba46f6418cb6adfa5a597a94dee5eb6206e148cc65b9a81f072ec992f2b3574678cd2eda8032dc4a5fb9082c0c3126acaba736483ef51b5938804b579034b193afee10288e06b81f90fc7fb2c575fa0673bbdd9a69a862d7841411afc28662f1956afcedefcbbe50f741a3a26a4100a5517c2dbe78948e117de6c8a2212e8f2fe4f03f2e6dbd291fcb234d96fbc5467db8a05af5870804147d78c30cc2f86f3209318f64766abf41d113485373e404b2ac8b4ba5493bec438f7c703f8d403162e4a47d215f90c7fde83eecac61700a37944080d67f80ad7439051d889ae8ad0d95de6704aada4c7c60d77fddb9c6b0beed7338e0a0b3df3c9a3bdd0cf23731aac5b937b86bc4874868322918b676406d6cfe85b02145bd4c08f0121c69230e2f44167fc48c0af98b91e8a4e1435429f215e9762ce54c8039220de556d70f7e30b4eae46d6ca95ad0a548d3a47edb392bc7bcaf9b3bfe925f6699adb3ada82193bea5a6802f11210c5569a6ddd4265cf437bcef097a367c879aa0bf957edd651eef1ee5bd798b2eb028607ced1f9ff7450c0934712a4691f94d5b04f55e096766567d401029cda45cc9d0291a84d4d3246bd4ade906743c3f10eba3a8eefe3c892438aa2b6260cb87b0bab3922a2cace08bc17e40351169ef89992cf6e7c80303115cc07fc2062ca040298c74249f17788a515a42aed771b017e0047fda98ef65bc26f79996be42711c91c52f8fe2ab30784f2953458350eae70fef1f1fa80283d14f62faff898d5bb4ae12a8515e7d2c21a05392081f9398c3ce475412b599fc6494afa0b7f8fb002fe47902864cf96e12045236e7479646c7689ff35184ec80a20902a030087d5719b09483b3855780edcc53058aa70e3746992f25b4b8f0f3d45cff92a00f635a036292c04b7fc3cd4ec873e409589895fd425b5c984a4fdd1cec827996e568d9a323919185fe1d9952a0598300d573d2e52ce07953576c7c556767edf8aa5778c8640cd6758bc5fe1afd2b04a5468aa5e242f46422216d3f3bf1dc4ae0724f139a8aff1f8ecdf92360535479204e01b33d061ad4677f8f3dfcc569fa486429afcc870c495c8cbfaab0755f9dc5d63ea28c1a50d110e58aa6cf7109485dcc0a40e4bbb43144e17328348594c78cee20762a862e83032add8a8d6c336b2a56910edea8c4ac7581cef8cea059b199bae01ea30161bc154eb4d080063626041a1a731e2a2d64d80955fc7a47ce65968aad8e31886c661aee87362954f2dafc77c61b9a1ddce50b2f8298e4db8abe7a0dd9fb8ff9b65515bb35dd0acba439e042606e1adbc48d04183f71e5328ae019aa877f3cbccf63d4f20210a7dbc1b67ac5e57e46ad14c68adb19125e0e2330c83305c4d1af465fbf4de20b98ee5f035005ee6abd8e72754c0a2d3b420f166248accc5c79f987f3e6140ca7e822c41cbc231754b16abd9c7bbcce4be38b3f8dccde05ae55410568ec2f834161b236522b262ba330d2827b53a254c57f7551e8aee154a9085fcb7bf1d9aee14aa4fdb61592c838a5ca43219b664162dcbe91f11ae2325c32ecf67e454faf13824d72d13e225a1d1a256cb622d9d71d4b063a5a994f16849749e2aac629ea0010f764edd7cc96adbd2f98ec92e70d9cdd544af9c1bab13ee74aefbda281e4021c069874c11bfa3aba8ba907094bea15db3fc824b8d906d4c10a6cdad346525cbce65201387d08edd533fc5fee906dcc5b5525b9faecbc04fd6389038172e2a4e6eeb2361cf93fcd7ce75f84f0926b34a786ae4dc158ae14474db653a099f896c5ddadcd8b5847baaf7373ff5afa19cb15dd0c773d9489bc0a840d9fbbdb7dc7764293224c2017fada7f16db30838ccc007df2431675f56adff7e321157d3ec4c5b31ddbb5743ec75fe719967c55adc079dca736a8c998d8e99aff37d2ed7c9e305b3968fd77e872406906a906ed849672a28b4312c947409f19d81176d96a7cf0dc5814857607603e1311751863b3e0109fcec70265405911cda27567e68e36c35fc787d78ce5ad3d2ac8c03b2dec4e05bf6469a43c6976a3e5a46f935fa5699620d190da999a5a4c0430d2802370027922259d691d64c5bbd3498b9f902a49925894da9887561f0222307964c8b0480f8ffdff0387cef0397283d1149b26d61b11a9c0adbfae86cfe1557f06f38d43d227530fee26d523c1a8724987ec33a80ef0963182412177d1156aab49d31db63dba90004e7b0aad5c8eb5547c3d8f7c676daf24e22921ab8a0fae5e0eca63fef70618d7e043e2d81a8622acd806bb43c293c1cae1a0246d82d33093d802914f2d0709cce9aa01d7ef94be455d5da88778757f33649436daf64a51d01f2ef837e4c75b5d9bc1d5ba3541ef9b639064c23f9a27ab05b8e6cf6588bd3c4205f420efca66a2960f47515ff49ebf8eea25d95ee24ca010f8ec2a97caac673692ede2c9f1f6dee40b851d68373ee36bf8b8a7d0efaeb3718f9267017fd70907673430ccee6b9ffbce005e6ffcff95fb8a9834a98b0bfd40336952409fc59bdbb8427e4776b0d8638ef696adf0162ef9bfd887c499330bf2bb06ca409289bfea72e15af288172295e172da39169aeedb27684b27367bfe4b49ce32fc434bfbe517b78ce1ee1ead1e4f96f503d5b6e769351a14f42521afb758f12c010fcb33f8187f08b0d9daaba5daa2390251de309e7ee7b4fe5b794ddeda455d0e3f91b794aee7a19e412988ae88ae70ea2f07c4e5a8dfbab7708429d98e2cdf60ed8622277b7a26754e22833dc094b2084a6bacc4f63afed76d175d55eaed1731cc49d8d13645ebfe7242b5ae4c6255c3c0bbeb8a98e0d032b13dbb9f113456e141403e11f1605acab1e8fad4b1adcbd83175aaed7d45c2daa0462cd75232796023fde8e70b4a5f6f7849476aac17c25d6cfa7a37b54af2f3eb1ed7e24633811bdd45c89363dd0569c9a51d7dbda6213af7892c229bb03c90941dc1a13dbb9fa488d1bd0f14a88e73690d30a84e939d64ab7a6fe29adf12e6bf9d555c48e75721e14f5c1d2f7054d7b006e35b89238b6d772e838786373d43df78004625034cd140ef1efd5be13bc0152e51e3117a74c2159fa0542618099a1e6919ba41814745eb5e0bf98c3c7cfe434c9ccbdd5399312ddb47189c97ad0187c3e963d8a206ea2ac7244edc5c87e66c6edde950fde9fb4cb54fd6c9394ecdcedbf5056f0a3ca6963e21d2a521c1792675cb2348953952919fe8123236199f8b819ee9011f37b7e2b9234b4694b1c5b5d2144760c306861b499827431cfe98e041cc1a81c5a61477a4bbff605d7c77ccc730ddf94bd66ff784f64c7775af493ae990f39cb6b4e68f7052628abf30d34902976819ce0eb1c932fd4d8e917e5a26b853d3d6f3f7f02daa5f20fac82e2f41347215cb73a9a7fdb9ad35b0265e7bbb2bd62d8feebc00fdd9705158c6a241e8668610fb0e767fe432f77a90076a62111c14905a4447b88b33b8253360c70846c5df2e20dc9cbd04a0d773aa32b460ea3b603c90eaae8ee5dfa91b62b763940d32769d3512824113fbe66d57307419156e869b11cbd721c8fcf3049e29e16ac9c4ea474afd9c673674ad70423956f2512fa79351dff725da440ddfd4f8453d64b4403c8b2f444650f209e4ae964485edd96be92fbd63f4ce693a9656c63ae80765964cbbb84d45b80efc63720d2ca9681a18697e55886937472c82dc5cb2fd5b1b8016aac103703db020df0b4fee0c421171b690ffbdfeaac2b7f2e5ccec63eca6750f10b7a1e043fdff8244a49cbeb69005e55bdf396c0b5dec5b3383f992ac80cf45816e5ac024d64b86399b705b2cc83547407d78c930f842a6b880e69c6c636d7a780e6144d5339842d4198b8b60624f8abbb73a60947171f768ad57f4cb334fceaa449bf69083613ecc744bb6e95dd9b01a7ba5c3f9a3016350512d9390aaf537e626ef6957dc83d220c83f82552b43181f172ce68e5976b0bc7be9e12cce6e997c986457848bd2d1898180f9f999ccd7ffe8adcbe54aba9f996cf0ee28050cba56fc8f8e34686b14e604d6c32e84fd17f08f4f9451e279113c208e420ceffc0d96acefed5cab9d9bff6586ebda01a025daca173c95bc97dfd8ae7146f272186eef95002a5d40711d4cc8e400d177cf3280c6fa8a8fffdd2a5a3ba9a7f6f89aac9a8c70f8151b894683f713b07d58e1c3f1e9fbe746de2d97e9d0be7b8970d4a87a8005ff37ac56d5182dc5348d67a11115868b41f0556ce71146c368c130130bd952ba3da71165e337753d15496d1d2fdb12cc92ad4777dd8dc8bdcb6c61be630777d2f1b14442819a2f284050465cc678d25e8eb34f038a2584cc554b19ebf52c43ff4943227ac3054745c29d93d3f444ec004d15e7a762a87e08e27efe8f1e6b276b0cd2a2e78c15aba6cdf472a9a7e2603453395ac8ff6e19d4c52bc714a055ea36e4b20334c68502efe8d3334ea272879959d84592167b60462195dffed89638c839dd4f54002393daf02ce7b8bc01ad68975e7f4b3d2f61a9445d944035315b5095ba10d7fc9587bc41a24f01107b9971371d7c774d393d41838bf6ec17a5e842578193d2b849277c8da8e3d0341f2e971d5746a260e8aa7c703a4827039c55ed76719fb891026aec1729592199456f5ec72a0c9b3d936f989f3ab5a08b1cb3c8c6a2eed20bf47928616f83b9e10b5820dd1b9d290d9aafc00d997fead152a1634925831c9fb0c633f3c4a14c056f9e38e06cd91e0a1bf7fd5398e7d1b21f819a1d4e723d000d07c78d923ef9e0b1adfad9536d14eba81159cff3157244ad8d0ada1524d2da83593009bf21ebfea40c18463da5cfe5ac5901a1a0a60f91518c4bc7c1b05e5536f9c253e3f92fe3cc85a1f8affcbfc4a10bff9cb90a12</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-default">      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-default">42Team内部文章访问需要密码，请输入密码。</span>      </label>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">内部文章，需要密码访问。</summary>
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>42Team-Flask框架</title>
    <link href="https://blog.yeefire.com/2020_04/42team_Flask.html"/>
    <id>https://blog.yeefire.com/2020_04/42team_Flask.html</id>
    <published>2020-04-17T04:30:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="42Team-Flask框架"><a href="#42Team-Flask框架" class="headerlink" title="42Team Flask框架"></a>42Team Flask框架</h1><h2 id="前排提示"><a href="#前排提示" class="headerlink" title="前排提示"></a>前排提示</h2><p>《42Team-Flask框架》系列教程仅限大连东软信息学院网络中心所属的42Team社团内部使用，该系列文档属于内部资料，仅用于所有42Team社团成员学习使用。</p><p>最近一次的更新日期：2020年4月24日</p><p><a href="#2020%E5%B9%B44%E6%9C%8824%E6%97%A5">本次更新内容</a>：请求与响应</p><span id="more"></span><h2 id="目录"><a href="#目录" class="headerlink" title="目录"></a>目录</h2><h3 id="介绍和安装"><a href="#介绍和安装" class="headerlink" title="介绍和安装"></a>介绍和安装</h3><ul><li><a href="./42team_Flask_0_1.html">Flask介绍</a></li><li><a href="./42team_Flask_0_2.html">使用Pycharm来构建一个全新的Flask项目</a></li></ul><h3 id="基础部分"><a href="#基础部分" class="headerlink" title="基础部分"></a>基础部分</h3><h4 id="第一节课内容"><a href="#第一节课内容" class="headerlink" title="第一节课内容"></a>第一节课内容</h4><ul><li><a href="./42team_Flask_1_1.html">HTTP协议快速了解</a></li><li><a href="./42team_Flask_1_2.html">路由和视图</a></li></ul><h4 id="第二节课内容"><a href="#第二节课内容" class="headerlink" title="第二节课内容"></a>第二节课内容</h4><ul><li><a href="./42team_Flask_2_1.html">请求和响应</a></li></ul><h2 id="更新日志"><a href="#更新日志" class="headerlink" title="更新日志"></a>更新日志</h2><h3 id="2020年4月24日"><a href="#2020年4月24日" class="headerlink" title="2020年4月24日"></a>2020年4月24日</h3><ul><li>路由和视图（完）</li></ul><h3 id="2020年4月20日"><a href="#2020年4月20日" class="headerlink" title="2020年4月20日"></a>2020年4月20日</h3><ul><li>HTTP协议快速了解（完）</li></ul><h3 id="2020年4月17日"><a href="#2020年4月17日" class="headerlink" title="2020年4月17日"></a>2020年4月17日</h3><ul><li>初始化文稿，新建README.md页面</li><li>Flask介绍（完）</li><li>使用Pycharm来构建一个全新的Flask项目</li></ul>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;42Team-Flask框架&quot;&gt;&lt;a href=&quot;#42Team-Flask框架&quot; class=&quot;headerlink&quot; title=&quot;42Team Flask框架&quot;&gt;&lt;/a&gt;42Team Flask框架&lt;/h1&gt;&lt;h2 id=&quot;前排提示&quot;&gt;&lt;a href=&quot;#前排提示&quot; class=&quot;headerlink&quot; title=&quot;前排提示&quot;&gt;&lt;/a&gt;前排提示&lt;/h2&gt;&lt;p&gt;《42Team-Flask框架》系列教程仅限大连东软信息学院网络中心所属的42Team社团内部使用，该系列文档属于内部资料，仅用于所有42Team社团成员学习使用。&lt;/p&gt;
&lt;p&gt;最近一次的更新日期：2020年4月24日&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;#2020%E5%B9%B44%E6%9C%8824%E6%97%A5&quot;&gt;本次更新内容&lt;/a&gt;：请求与响应&lt;/p&gt;</summary>
    
    
    
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
  </entry>
  
  <entry>
    <title>42Team-Flask框架-Flask介绍</title>
    <link href="https://blog.yeefire.com/2020_04/42team_Flask_0_1.html"/>
    <id>https://blog.yeefire.com/2020_04/42team_Flask_0_1.html</id>
    <published>2020-04-17T04:30:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <script id="hbeData" type="hbeData" data-hmacdigest="db89cd99eb828c1006e3526277aeef66cad6ef97a09e5314be62894acb18e144">5a907c078efdcc0b5c9e1d9c887e463e035b139523997a7b7ff96104204a4a4d46c86f3d6af135157dcf7705f7d630d8db299db9fc0597cb0ddcfb9a60eec3ad9e48d5e93d08f66702e2b0e0a65d1fd6423b9ad2e1e9ec49bdd4a699c7de14d630ce9f14486de0c9e89f2af287cffff10de8e51d67bf4e95633d19723e3eebb0ca7ee8663af6adf4fbcbe8b5a42c763d750ad72be3cef37127d21e2310821e04331f9979bf8875d798c73179b8f05c3d9d6a09ba15efd0660f97cc29c9c6f55a4979c8c134708dc4bf153b4b6c842c32696652ebb089ca7689ef7d8ab32e34ed6c29420d4bbdfaef496f0d167ff5abefcbbf1036d3cce9cecde8bf3e81d01b0efa723564a57b3639b20d5b259bd5c0bb198902aa75600f96cdb15482565f9e355d702ef1eecaa1b7c0d5f5e61c8aa9711a8bc9d28ab217c1bbb2d431331827a4314ef3191ac460cb05991f04da8be2faeb590dcccb118292c855b00574b36aa0dfd4124e180c9aca9d59e97d308fa2b6de7bf7e3d4c6d911c1a2defcf4bdff96fb9f7fc1dde2571883a295151509a59a7b1c6a3198602b5a46f40b326c3a2ffc2b630ac4ca3193e0442a80e3b30c9b06a65cc7d18cf1feb1f2eef0bb13eac3ba9b1f0cfeacc05002ae8691cabd05d33c9ef1ca9903bc4bee0603b90ffbdd620f8799cd964fec93535b769196fe0c86ff4eeaa068bff38bc1846c2c6f924997d4e7b7b232c7fafefc2dee5d13187a52ae249593603f963293ccb1663dca3149650ade26fa899e1d28b22b4be4e17f7a3c9643f59f4c773b6bfd154e4ed44e13dd731c24858b1e3fe67fb44a483d3a76a5e86b59f2834b0eb67d1d17cd099262729601ea66102e1cf34f52504a776fef13baf21aac7bcb6279f258f485e6f41989761d25b637c146a480ed29e6587d39dec1206830814f02cad2f8e8bc2d37c05cbc9e725fea3e7f8d396d293befbb0dae1cf7c65bd0a054ba46d60dd27f421662154f7e5ad0f4ee0eadb5483c569d1cd504336429a84fa4a0f0236f9c570771aeacadb266940c58b3b86cd1091ee295048fd65a1bca3252ae88ea76021066447b71259f58a9e2e3a3d2cc42c4d51d334c0a40a54743fa92acaa35c547b34cd8e163a0c84951958c448e245e17162fa3caacf7201172f7d5d544ca2f1bfaf6fcce4cfa8675f6b3d74b2933f12474959dafe820bf7a20f58f9097ce9bfbe34c102a8e9df968f060d02f4de098c74657134ff5f9507d86f675124c7cfad01dac8c6df0585d99204972e88306cfcbc25904acedaa9292e8db60da5cd78828d5962d853eababb1bb36f295b8a08f7c1d6a84a7a5acf74fde2274e171bb0fd30ba9028fb8b3122761162221f49c98b5ddf76c7d19c247c83a95818e5ee3614982d18c5e96ac38b298444a007302c158ed5cbc23e8846ad2f1531a7136c8b24c54720319f1028e369cd17a595853cba0fd04a54eff528550df81dbf9131b0b3076f8adf522a00959536769294f8c9545b076a6065a7c88cedd3d965ff21259ca3784da135d3e5868e8b0d42faaf23bddc9f2299d67f84b348715624a72a1e39af3a258a541f56ff833a6735987e18da05f191d9d383909e26f2f91a3d219ba42c7cd4b2ce8a041d9af949b5763f00fb1031d54cb90a9f4a7257089d34f1beefc2eba7707fd7f53b73d4f8f4195f7cc79691ad4353e73b9fb7998bcf4a2e14e5a80b0fb7060f4e945a2fe8a78dc71f69c633521dae06961fcd34fb58621e8a98f90bdf008729a5da9b763646fa75c2d2ce50c7998e15298471812755a60b77466ef46467b1815c0d7ae97e6f3693d2da6ee5585b6f6c9653fad631f5d05b401a7dd7cda5638ed0fca79bfc5f154ecc9ddc4c9b97cd44ba43676af4615c9087d260fce101bb35d0fa0fd43a1a10fa61580970f35ee5b4a0356b3e74e4c7f37543340c367d5f4d1467089c30c8185bff40760437bdb6b7fc58c00e9802ec0ec7a053bfe65cbc8fc05f5d8e7a8977307fc808081ef1ee2b971b1571e011f7a0f12dbd194b8dd99bf0feac635c6ebf5eeb2f34dc26e056e57de6c9d4b0c02642cf62d3a0856849b554dd6a7e0575beafa765725b71ff6acc50e177f028a9901750ae05af97e48d00e5a263e971969e44fe5e7655e860689c30cbc1933c45c7ca89de2c587768ca65966dcf57594c61a82c92b0c17757a613f4569d5d61e0db93af0f1a37d8903f0d350d05df4ca084c37e2c3f44f53ff20dfb1a332f9a1561f827a3fc3db2a092dd682541c0c3d122a69d9018d8719096b064377cdac925ee31fb4e00c86f60468da09954cc7067fc75b0aaeeca183b776b5dc7cca963501e90c15c5c9920b2056c0650a090d1e770ba246c09fc561596de9ae479bd0db83f8f2c96f40bb353c52f083b23d7642365881290dbc2340279b5d9a1f7be1a5e7645a382abbb7d45ebcf69c1e828f3d2086c5736167956f05e26d8a26f83b6d9f83b05110417ff2e01e48c495a1e585b5d5f7b552ec385cec5620a262590588d4b24380ff27d219c61c7a94f74f28bf387b662db4579008eea67fcb115c105451c0ac5353a138f099e3b2158839fd2f69215e44336faf585bcf08b8166fbdb67505b1e84f0defc61c361bd6b0dc9e92bdc292609b76a7bde9fbfc3a8fbad29a5c3dc9b9aecd64ea987ff2ae09e4e2763290fda932af6c782d2ac59a1a4f8029037b2794a1bb9cbf3a62f0ca1d91c62d12ed032d1e11f1ab8637ba92ddaf74764c937e39f0e8fdbd159a4bf395160f95b8263da2afb66b1bb93585f5345d00223caac4b3c7a7c5dcda9f943ff2c3684dc03ba1224ebd9e7797bad86dcdccde6b46c228b2330ee0c5c44643e4297d41d209df606008b726a1b11d6f46a01fb8079983c8b5b6b1e3a126908580b022dad07b2deed3915d4a462d351da30552227085835b87c1a90df05f6bb828119497b098c7d8d248555e1de46533f812ba18086279efc7305801274cd4e331d480efc7ca7fe7454d27870e3f131810be97409236ad4f0f35d3dd639690f5276a5fd9cb187d4d2e4e14b6d9b80092a97e91b808f55878590f1c7c68da9040f961fd1b330c75be001548a67a42904907c8e413aeea3e777088e5b8fa28ddf22ca67d82792ad09c7aa8e648f2ef838656831c3ac7bedaa2c51579ff03c46876dc78453c246f6058d71827932c83b5535283c7ff2ca438f0c80c70e027d09f17e3434546820a70a01f5ba4cff2de16f06b72c3ef8728597b5ffc31eec96bf31489e5329083c82931dcff11e58acd69c9c5d1b3aa25e3d959268c1e475d55c0bcf7010853041b823fbf2e060c6b173566418ee935aed7dd49ba20fa931b790d2acf126c7b7296f6d6f966bdd9a0251a2fb6df1e9f64e7266dc357be9125b8ece6e1a1f614cc96816e160ab46777a3a6aead1a318a81e27ec210f8d6f4667966c8a62617ea9d2fb622c0de58bc0e08323da49eefe46fe3ddabcfa01d1ba750df17e3e83290cee82d6554ab8522882fb8fdaa458e77342e3112b173d2c9793fa619d58350a8395e5d444ae69cb8ff69c94e37f9bec91cbb0234c3a25c1cfa2a00a56a5bc4b20e79e2a4dd1608b1a927df516e60ba8594f063543c9e4da764cb3bdda700b5334fb9beb5a3c2d9b0b05da05ea14d1727ae9d30c6c11d6ad5d83a70499f39702761e52429b5ed743a2b7a4afb8fba4695c4bbf98301a531e140cc435f75f269e1096e3aa6cb42ed5d791c2bb8a6460019f93c84adef87a02e9d9455058fb558a3511ecee9990c84f8a40264498d50c10d65ac1c19f7350b8ccae70a34a4ff048afa79a3c54bede86ab36a05bd623523e892f9517255bb541e382261f913759252b5ab267f45728e4c3474bdc4103caf7ae824f7b638d011eadb83e52b9ed44245900e6f34e3bc5d1ad0aa8f2c8fde70322ba5dc61d9b36c45e19bdfbce81fd83c08464e74019a7cdddde6604ae20082e3436c19c41dff9a3ddc4975d021e125891b8656050566fed9659aa8b90105b7b70b4f9e6d6071046a94800d4f6ab280928945fbad8a18b41182f4e6bc099f0c271b10d42b4c12eea370299e6c2a44cd037019f1b7d5770d3372107945573ba65ee6a7c612c8f865cbe9e55491577cf1602169d7751b542ab33bd1bc91dbbf60a66ccee6be81f355552265ffaa7eb517fa7a0574a0f68ec383243497967bd7da0f466d4211a20378904b5a03e2c75d2139fea1750da44718b084a62adec830157f01c7c522c26ed7e5a64ce244b15b1362065f2c54b7434851318b501cc9f68e0ff56a083415667e45653aee24f498150986d4d2f11cd3e6871eef77d88662560ce4d103e20642a671ca6fa22236676479c7a01657d227952d6668f005a8c917d1716c6e0b312711e741362a7fb561716c8bebc95778609ab24adf553fe215cdfbb44ea0e7b18685c9e118ff0d8d96f671e6e510fbbcbfc1dfa13711adf4dd12e8e34ab831840b245e4029afeb5a46321bc0323f4ea2a83eb23cf9d9bcb31b8b5811dcd3d5f227a5c0f029f8ece20b628e97cb837257cb7d0ceecf2cf33cebe7428a69d2514ef21a2e03f9c06f7318261e5aa2c191d2ba9151beb564f78ae38fd3a911081e0323c4d098d69aa812e5ce54f3ae38620de4f2bb2b4d474fab61551d71f4db8dcf3350059b9dca2ab88cd767fe3f0a3397efd0235545029ee995206d9b785ec7e1ee7b56a6662d943097cd4c25a0d70c28dd52fd001c90dd9ea5bc92ecea298f3bd673acb02db9ce0b33cde0ed7c385cffefb95222b3a41bad4884d886e9dedbbb17f1f2921062eca882560aea12bed8ab2f314f28e1111529bf6a7be08092b003ce91e3e656bdcc5ab6d4a60f7390707966ed8eed0fd5de25294cfc05238b59575940fd9b7dbb836450be784802d60ef886f413b3af08202fac10e731278688b39c5b4ab00c7a4ae112f33823036be6f1b7b4aad772ba125682392c929a96994ef34358e362e52c9c68b60d132e5201730d9ce27a4f7a81f415d3dfccbad245392126c2d25f5621252251988ffd92b3340445e354c931184e8c74f32b5c970d60b40f4c7757dade16b8113a9ad9ebcd4bc2dd1940f031da31021b954ea0071d9e42fd6e2a4176230117fa4a3e7b4d44607777ad2a2dc333587bd804a974aa0480b46687ef36b377fcd268ffcce2358d23c21ace1d37</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-default">      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-default">42Team内部文章访问需要密码，请输入密码。</span>      </label>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">内部文章，需要密码访问。</summary>
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>42Team-Flask框架-使用Pycharm来构建一个全新的Flask项目</title>
    <link href="https://blog.yeefire.com/2020_04/42team_Flask_0_2.html"/>
    <id>https://blog.yeefire.com/2020_04/42team_Flask_0_2.html</id>
    <published>2020-04-17T04:30:00.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<div class="hbe hbe-container" id="hexo-blog-encrypt" data-wpm="Oh, this is an invalid password. Check and try again, please." data-whm="OOPS, these decrypted content may changed, but you can still have a look.">  <script id="hbeData" type="hbeData" data-hmacdigest="f0d14fc57ace14ec722a82ce6862b5105ec8b82aad11c253a30f9e926a412304">5a907c078efdcc0b5c9e1d9c887e463e035b139523997a7b7ff96104204a4a4d4a016413c1da100833949e90e139d78ac602f21879b702647d18f2ae29468c16685e2cfde61ea86c3a919f4c646ce133737c38bae124e15343a59c77f428042c09d618957691cbad867161e11a5d2e3269b12e4476ae85edf31d74ea8229b7291265f831f83c8ae8a071955cb8d86baa0e25641d4757420295d751961726ef3efa47b26925d3e83e51a606dc2df782372210db72ca4794705c209f7151039dff5c1d5d1bc1dfdf8ba5f890d34ca9f8fe90c3d11eed696351ecbab33d2df6c5a9ce2bc29e8a37a01b9751d08f3c75c1e17d5e0af9a37f9e61975f92f3f9fa16edeb0b40e8fc4a80d6d6884639a68c5508b248c0b8c7a132d85eef7162df0561c7baa95728160cef0dfcadf66bbdbeb7d950a6b416932e33fd4ad25bf7459391ef8c4f097a42c3e18456d8445b01873f775840bba2b97432c0353e88427b1697cdeaf24e63cf3d5b5e038b10e0d48fc3bb92e9984b305683471be01a06ad7684d999f72badd31e397da050fe6dfb37e0573c527fff57a4e96be411a0885da03199b028e4938d977afe0e95561ec73aa8557a580efac1f80d3c06cb6b29ac192f01bbb332ca8ed56ec1f32cc900b6dcca5a0f6d2ac570735fbd824cc988884d3742dc6e49c0ee6fbd7cffeec0dddbcbf6a6667ab51ccf067cc3935791fc260d48d9541f94f034582a2d84a457ec2c4cba0cc6199281599c9ea14d43b4915601272e395dc41a9d3366c99e4e618338658200585d357c9d7f30b5f943110c67aab3e85659c634bdee39d0a66c7f1fbafaf726b02e609bc1dfda7e8752a70c9f8d32e1b94c8f5164dfd4474ae981a24fbfde2140e49d09113fccde9cb2c2150cd6f13d882b20a49200ca12f4faf45e5bff868d375deaae61ab8734f3116e9cb3cc6967ef6b521ee35b3d325bb837e6e0e3de7428b7da813617e685e3216adf0cf5a9db089e4f609f0c77d91e85e5d804f9e790bda6533c4aae447aa1b7a6c6b230cf3c2fc9a29d2b2d23bc37f14bc8c1af494ac0ecd21befe4ce22adbf5656ba53642470b84c8d181fc68455236c7258561496b8caefd9d62e5872e458884b4f18ccd43134800afa15c42936fc33b5e367e14f5793d11bfa1fbbb75325c3350f946756f872754c2b42b581f3ae6a63a8104c56d354e347f3be0eca2c18ed6bdff2e2159ee2100bfc1c422067a6bf8a6f87e868c377fba8ed398bbc2cb08656ec1049d5594f95a89df309d3b767ba8d99f11bb96c7d129ac0005b0ca5fb47e46613a86e9e9da76b2d5fa1d0fe5f52cebd5a8e7b18369109e6a6ed0969f867523ebf77d8bdb1e4e024a2958b133615d21386be7be0ceb9b5eb0a5ac20f948b8bcbbc0371f953ad92f153420715c40d1e664c072109e93325291dca7f5257abde6113b1d2a0496ce8ee35d8a6ffcf6abed581b364bf6de2fc5935eb20adf5766c0602a338b424b6dd7f9da9b1cdc1ef77c57ced898a0581c11973a2785e2b6523de31a22a3bb7ac998b552a95898624db129eddb2108971b7bdc5b4ea6fee4aac9a8ebae44323ec21da079d4694f82db35bc0f25fc8775e4ae14ce2c470aad76d62b01563cbadf3ca8e117e6babc4180f82c71442aeecb2211f453bdbbeae5fe8e01c25e72904a307abdd332f7fb9c9db9071181af963360dbf7a6aa745ab413ff860a440dacc6f6a0303631950a25b3af880338aaf945c12ed2ba6ff6132a59e1f2cb653615ed52ee564b18c7ad3da095786e421229b5f3d6c58b34a339593af76196e7732f61787bd1e098511dc0522e66474ec97f07696d2b3abe6db26dac4d5896173330df4a50d62e3ff9f315e006b88a04d8c784802bb0ecc2a0b659f9a88eff33eaf1c65d10def69d06d116f6d43853c25fbbe819f02b302d0283144016e45bbceb05525598dafa8c7c0aae5982591212e5828518be9a833dedda0201fb41bc1fb471f22d4042677b30c7f6fe0d618c9237966b51b6c07f4a08d75aba1119ea50654be8e80982b4266ed9fbfd9ddb2c6f2631926b88858f52f7b47c745d1bb907584b38ece23011660007a0ac64decb465428ae92a27425a7e3ec405adc27b7d69fe80f258fd50751b5a00632933feb7b48c7e37dc963e9900fc616215c9a0faa474c2d2172a5a8f8778793865d12788ec52a95b57cbc464cbd03e6461e9dae6c59a57542f3d21de4923f1685040649ca62c8dabef599ce08360b4202485b4be7f08b0f2d8037f0e78a0bafd7809c557824c9bddea0b57e311b6936828fd9210acbe313aa115281c3df5021c1f948e52230072b7afb82bc9942c2fdfe0596ff80c1c1cadb080ea8c71365740a7ce0e8432422ce75922c2eb132baf7df8e0aaad374839458b58ca4a968ee0a8216a92ffac96cba6a6be9cba9c8cd194c263b80b475b8ae015ebd2f0b8c802f7c42b168fd9f5050a85cf5136ae2a9bfd1432a35faddfc563a6d4b86ff480117eef0e5e838982defd552291cc9e482505dfc4988f987541bec08bcd9a785c10c72bd66383cbb639299d168e7209ed899bd71b93d4cc243d135b5d35ceb08a1bd62c30c21eda152f34b524fa48f8d0040c4b41cefe651e6c58a22bec3511c81c29604c83b43df58543b159492db5b4fedf03db4c3a480e9ce0e44b9be7664c594411e14b12bd4e3af97e937b306244707dcd38185ed9dbe4dcdfd89d8b42f5cd027e0401cf6b1a5296f87c601e8cc7dc8472f465a5e8eac3c0decafef7b7d3d126c3250feb9f65c54ef8a8f30d76b1cf6907e06bd08afbdb11674a8d96fa3ae2efd6e8f0a94393fe429508e251d2d625f4baac98ca1144ddddd021b891fbf5652179a33d01a9bfb4a0bad5d46853ce42ed612b4800d1697007873745eae78587af0cff730881ab20fadf6f849b951bb4d497e1f593873e5b312e9edb0799a24e6e1329888115b743e30c7759d3301c3e3d7de97227d1d3f58e9f310fbea92037dc5ceb4ce2f085d816b04fbb858d5e486dec9ffa994de27608fc1e40674c4a023e87ff47116ccfaef9a4d7e363cb8658908ee060ab07143738837089f40f752e37294586302db5741c805b928046889cf3bf50678d0b4cb6f8577a33e662396c9efcef9a9124fca5a3e10273437dc98a3b63773442f1eab6938ee505cca14c53fb6fb5ee1626e6608fa713aa7ff9d2af67b5701223dfa662df33819443b4db8e4376cb1e3ba11bc3f5d872a92d55cde99aa50e090c92e09edcd95ae11cc5c2c96eb743d37a34ae1727d4a7cca245398faf29723425caf4200d689687bc3a4c87a34c021ca85cf344ffcc6d52199cc037eed5d796360c0618ec7a215fa10af18fe75e90141385298beb7aa4037cf2789aeaca8b0eaa2203b3e4d18dd6d30f0d068ed22ba816b1272a35fcaa55486ae76856ac65d94dabef2cd107d481dcbf750b2e5e810e3eb8d66d2e49e267c92d24940de82bc38b7451d316dc312f00d03f54b3aa6483cb7e2d48805a61bec7097fb2ec7d76451c1c883dbd74516ac090dd3edb62261c8c3d6105d03e8cb2d010c6c1c4ecc42c432dede94109ef3b2dbd25af6bd4621fb6e71fcd39c28b35827977f843fa0164ce21846ab4ab208e16208db6bcadb546b5fbd2231381fe48152e297687c5ffc1ac69589760ae852ae72407c32cd36de7860522eaaf6b0938ada64543fc0a793101d94446af811db280f93072ca5aa7d05825e64c3632e1797dd6a1d3954f695c68ee3e15b4d24d9a24b09fcbee59018d8199d28718614219c3edae4a10353504dbae9dbde4bdc2c3114b8ee98ffbe6e169cf650c61146f1dc347e7b6f752090f7439d843f2ed09668174bb8bfb84c5c3e0e888a12c340fe4357f6e6d0d5d582766ab932a7ee9daa1d6ff7ad503ee44e04e5068ff23567bcad4f5d3668754463d146877e71275f6bd7d838faf4fdf6f60c6ba4cbe4a36847162da76cdd235dfb215b5232bba7110bbd64b8fe939eb21c7685f94b6a651aea2b0ec9b9d3c8ce6afa7fa4133e92b19f03ea97b095754a092ace1478ec9ef4c85d3d61d333a9d133508d28dbda504d68d88222d00e70da84f5e9d60ace9b2e8d553ca5cc7067cbbb8bcafc48deadc72633bde097ca04770e8f8e9965ac80c99809fd03ebc1d6ad0b81242d578812c876f42d55c433f2b049d31bb049c2c68d2445d9c313214ec0672f91df18fdcd4e414aa82db1bf58509d5a4db207a1a92b0f4559a6cc4b741a267b93da5ac9ff1e312f71dd9182e7e05489331981e3bc15c7226107c0cec0efddbd26898c869c97aae27df755489eddadc4c5d091cbdaaab36ce7e62a78bcec9fc780d5b412e74c294fe8e0eaa53a192817547f21a26134a2bf2f01c1a6fe726701b83f461e5bd8835115571f4c5c749a929c598ba3a5b70f6e087b8e9d6fbc1b953e96cc1f5ee6df06853a6d3867baaf18c37a21061f976bc597487a916d2133b8819a14675bd784eb49f4c8556db6ec571a9391b371d2e911dfca0b26d3d22edfb3799dc78e8a06ec3c7a69dfe0ca044401e47ec7a32b343bb1a6000971e7ddab11829828494482935a5134f5f402488a3c83a116256bc1b865a7aa8ac65a2bac3f00108380443d39563034d50e20c700d86c97669b76919a64366d5e87f02e9d0558785859428080cb4d6a938ec2944a1ce46cc208763697bfa3c0ff6cef748655bc4fb2002e6c8a497b3fed1ad545de070b1531c7ea3acd58b43d22f5b18db1440415170ca6617027c613b5e6020c672d5479ed7cd859bc2f557b231ad439dec72e69b3e888b4b1bbed070bccf43aa41bb6be6c8904ddc3a3b6c5ef4826457503fd00c00796926e5054f188e074e25c538f8a12691e74d8e4c1765baecbe5de617f537f710f6280e8ed74b838a7eb362b4f09ddc99fc29d4479ea6ccdc3a3881b6551b869217d3af8d2c916dfdc00f92242950f847ac3f9adc047ccd340dfca69ab7c331eb9d17b586b4eafc822ef2dfdce525a877cfbea041a45244abe87eed25f0f17de50eb91a95c88127785b0fa528b2cf1c21b48b9464e98b36ab43feffbc7d3b8c1f181a38ffe9ab103cb0b740e52f861148bda2082a5de0766a8803949511c175d92b6b98e971fc1913ffe80de031f6a02397c0de7ad049c5e368b49a2b5db08cc0440925921e7eb18ac26d4877bc63e3923c900a9335fe49441af819767b345be297c290973ce881c746e46e45121d3c2970eaf74fa9dfd473f02197dd3ebd54b5f0d142679157da58ad9cb1ef9d01b6548334d10bd721833a77a0764b55037edf1ac995cab15ecb912e26e90feebf28354e2b088fb4b2c98d5dcbbbe8e262e3ce3bbe2c442876ee5c27be76dd788bc3c41155813ea0c5cf95a6034c0339126967895e848b648051e13077f42eaf3d45fb8a0eabd0a3e87d596af583981a200a1e0490e29d484fa84db5e38a390362ed3da93d2a6f6584c17a6c43d82b50f1745fccc75bf46870f61f84c99a6fa3163a0e2dc3588450239c286d03b819252c24964d7667482e3a2900d44ffb3714f7e1881dbdfaf5250f921830b97ba12e2ac75fe18bc994ee918d393d49529c1847620e72bfd3e685cd79303e072a622eb7da0477b3683d7d43a5b8ab2f1c86443fcdd40daf3e2a661efbd6a1e3da1f39a99036478e262287ff83893ee767b0e821dd63ce0b40d80336e45014996b95263e6d3a27ff5e473c90f555216a2893c7083ae0d3bc8783f469c5d085a0e2d050af2c5b4698bc44018016f2667a618a961136e2b25aff4f0f9a88fa1a8642678911d3cb0a943d24947f2a18326e8ff78ebe2f637b2782f9c8646adb214db24a7a25a50c87330fbb95ce4662cbf0b97286955215476e2c878b276bddb6a548975680405ac54efbd78857fc01e4e35166dc030a6ce7f3b6701f0438d8f0f8e7e1da1235350d9085e0fd8aaaa447d4b529c28b580d0d4e852429a922fc98ab5fd73347df4b9833c255fe8c883cb8bdc67b048f738aaf91b86ff48de65373e415bc79660acc2383a8ae249a137635b1981c5fea0019ca9c4bba1cbbe57cda0e2744c04257a4537a02f14ec4a318055c69eb</script>  <div class="hbe hbe-content">    <div class="hbe hbe-input hbe-input-default">      <input class="hbe hbe-input-field hbe-input-field-default" type="password" id="hbePass">      <label class="hbe hbe-input-label hbe-input-label-default" for="hbePass">        <span class="hbe hbe-input-label-content hbe-input-label-content-default">42Team内部文章访问需要密码，请输入密码。</span>      </label>    </div>  </div></div><script data-pjax src="/lib/hbe.js"></script><link href="/css/hbe.style.css" rel="stylesheet" type="text/css">]]></content>
    
    
    <summary type="html">内部文章，需要密码访问。</summary>
    
    
    
    
    <category term="hide" scheme="https://blog.yeefire.com/tags/hide/"/>
    
  </entry>
  
  <entry>
    <title>How to install RHEL8(Centos) on Dell R710/R610 server</title>
    <link href="https://blog.yeefire.com/2020_03/install_centos8_R710.html"/>
    <id>https://blog.yeefire.com/2020_03/install_centos8_R710.html</id>
    <published>2020-03-21T10:03:12.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="How-to-install-RHEL8-Centos-on-Dell-R710-R610-server"><a href="#How-to-install-RHEL8-Centos-on-Dell-R710-R610-server" class="headerlink" title="How to install RHEL8(Centos) on Dell R710/R610 server"></a>How to install RHEL8(Centos) on Dell R710/R610 server</h1><p>When I install RHEL8.x I cound’t discover my RAID Controller’s devices on Install Storage set-up optional.When I try to google find the resolutions I know a large number of storage controller device’s drivers has been removed from RHEL8,which means the Dell R710/R610 installed H700 RAID controller card won’t be supported RHEL 8.X natively.</p><p>Nevertheless you can still install RHEL8 on these machines with use of driver update disk(DUD).</p><h2 id="Setup-DUD"><a href="#Setup-DUD" class="headerlink" title="Setup DUD"></a>Setup DUD</h2><p>Using this link below ,you are specifically looking for the <code>megaraid_sas</code> drivers.</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">dmesg | grep raid</span><br><span class="line">[    3.702959] megaraid_sas: loading out-of-tree module taints kernel.</span><br><span class="line">[    3.703082] megaraid_sas: module verification failed: signature and/or required key missing - tainting kernel</span><br><span class="line">[    3.705684] megaraid_sas 0000:03:00.0: FW now <span class="keyword">in</span> Ready state</span><br><span class="line">[    3.705687] megaraid_sas 0000:03:00.0: 63 bit DMA mask and 32 bit consistent mask</span><br><span class="line">[    3.705915] megaraid_sas 0000:03:00.0: firmware supports msix        : (0)</span><br><span class="line">[    3.705918] megaraid_sas 0000:03:00.0: current msix/online cpus      : (1/16)</span><br><span class="line">[    3.705919] megaraid_sas 0000:03:00.0: RDPQ mode     : (disabled)</span><br><span class="line">[    3.750024] megaraid_sas 0000:03:00.0: controller <span class="built_in">type</span>       : MR(512MB)</span><br><span class="line">[    3.750027] megaraid_sas 0000:03:00.0: Online Controller Reset(OCR)  : Enabled</span><br><span class="line">[    3.750029] megaraid_sas 0000:03:00.0: Secure JBOD support   : No</span><br><span class="line">[    3.750030] megaraid_sas 0000:03:00.0: NVMe passthru support : No</span><br><span class="line">[    3.750032] megaraid_sas 0000:03:00.0: FW provided TM TaskAbort/Reset <span class="built_in">timeout</span>        : 0 secs/0 secs</span><br><span class="line">[    3.750036] megaraid_sas 0000:03:00.0: megasas_init_mfi: fw_support_ieee=67108864</span><br><span class="line">[    3.750069] megaraid_sas 0000:03:00.0: INIT adapter <span class="keyword">done</span></span><br><span class="line">[    3.750071] megaraid_sas 0000:03:00.0: Jbod map is not supported megasas_setup_jbod_map 5389</span><br><span class="line">[    3.795034] megaraid_sas 0000:03:00.0: pci <span class="built_in">id</span>                : (0x1000)/(0x0079)/(0x1028)/(0x1f17)</span><br><span class="line">[    3.795039] megaraid_sas 0000:03:00.0: unevenspan support    : no</span><br><span class="line">[    3.795041] megaraid_sas 0000:03:00.0: firmware crash dump   : no</span><br><span class="line">[    3.795042] megaraid_sas 0000:03:00.0: jbod <span class="built_in">sync</span> map         : no</span><br></pre></td></tr></table></figure><p>If you specific DUD drivers that you  need for RHEL8 is below address to download.</p><p><span class="exturl" data-url="aHR0cHM6Ly9lbHJlcG8ub3JnL2xpbnV4L2R1ZC9lbDgveDg2XzY0L2RkLW1lZ2FyYWlkX3Nhcy0wNy43MDcuNTEuMDAtMS5lbDhfMS5lbHJlcG8uaXNv" title="https://elrepo.org/linux/dud/el8/x86_64/dd-megaraid_sas-07.707.51.00-1.el8_1.elrepo.iso">https://elrepo.org/linux/dud/el8/x86_64/dd-megaraid_sas-07.707.51.00-1.el8_1.elrepo.iso<i class="fa fa-external-link"></i></span></p><p>When you downloaded the DUD ISO driver.Using the <code>dd</code> to burn it in another USB or DVD media devices.</p><p><code>dd if=dd-megaraid_sas-07.707.51.00-1.el8_1.elrepo.iso of=/dev/sdc</code></p><h2 id="Installation-System"><a href="#Installation-System" class="headerlink" title="Installation System"></a>Installation System</h2><p>The install process is as follows:</p><ul><li>Download RHEL8.x media file and burn to usb or dev devices media.</li><li>Download DUD drivers in iso format and burn to usb drive.</li><li>Boot with <strong>both</strong> RHEL8 and DUD mounted before booting Install RHEL.</li><li>Installer should detect the DUD iso and install the proper drivers.</li></ul><p>During booting RHEL8 Installer and When you see a countdown on the screen.At this time interrupt the installer with the TAB key and append the following to your boot options last.</p><p><code>inst.dd=/dev/sdb</code></p><p>On my system, the DUD was /dev/sdb and the RHEL8 install media was /dev/sda.</p><p>Soon after you can view the RAID Devices find it out.</p><p>Install it usually.</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;How-to-install-RHEL8-Centos-on-Dell-R710-R610-server&quot;&gt;&lt;a href=&quot;#How-to-install-RHEL8-Centos-on-Dell-R710-R610-server&quot; class=&quot;headerl</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
  </entry>
  
  <entry>
    <title>Centos8安装Docker报错解决方案</title>
    <link href="https://blog.yeefire.com/2020_03/centos8_install_docker.html"/>
    <id>https://blog.yeefire.com/2020_03/centos8_install_docker.html</id>
    <published>2020-03-21T08:57:26.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Centos8安装Docker失败的解决方案"><a href="#Centos8安装Docker失败的解决方案" class="headerlink" title="Centos8安装Docker失败的解决方案"></a>Centos8安装Docker失败的解决方案</h1><p>在Centos8中，默认安装的的容器管理工具是使用了Podman，Podman的设计理念非常好，整合了pod思想，用户可以直接启动容器而不是像Docker那样通过守护进程启动，这样也会提高安全性。但是现在Podman国内使用的人数并不是很多，还会有一些问题出现。所以在Centos8上先将Podman替换为Docker。在Centos8下安装Docker会有container.io的依赖问题，现在来解决一下。</p><p>但是要注意的是，在Centos8中使用Docker启动容器的话，容器内默认的网络是不通的，需要简单的配置。在这一篇文章中<a href="https://blog.yeefire.com/2020_03/centos8_docker_network.html">Centos8安装Docker后容器内无法访问网络</a>提供了解决办法。</p><h2 id="简要概括"><a href="#简要概括" class="headerlink" title="简要概括"></a>简要概括</h2><p>思路是卸载<code>podman</code>，安装<code>docker-ce</code>的repo源，解决依赖，安装完成，启动服务就是这样了。</p><h2 id="卸载podman"><a href="#卸载podman" class="headerlink" title="卸载podman"></a>卸载<code>podman</code></h2><p><code>dnf remove -y podman</code></p><h2 id="安装docker-ce官方源"><a href="#安装docker-ce官方源" class="headerlink" title="安装docker-ce官方源"></a>安装<code>docker-ce</code>官方源</h2><p>首先我们添加<code>docker-ce</code>官方的源，这样才能用到最新版本的Docker。</p><p><code>dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo</code></p><p>之后更新一下列表和依赖</p><p><code>dnf update -y</code></p><p>如果在update过程中提示添加GPG密钥，yes通过即可。稍稍等待一会吧。</p><h2 id="解决依赖问题"><a href="#解决依赖问题" class="headerlink" title="解决依赖问题"></a>解决依赖问题</h2><p>如果安装完官方源后，直接安装<code>docker-ce</code>时<code>containerd.io</code>这个包会出现版本依赖的问题，如下：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">[root@DELL ~]dnf install docker-ce docker-ce-cli</span><br><span class="line">Last metadata expiration check: 0:09:11 ago on Sat 21 Mar 2020 04:17:47 PM CST.</span><br><span class="line">Error: </span><br><span class="line"> Problem: package docker-ce-3:19.03.8-3.el7.x86_64 requires containerd.io &gt;= 1.2.2-3, but none of the providers can be installed</span><br><span class="line">  - cannot install the best candidate <span class="keyword">for</span> the job</span><br><span class="line">  - package containerd.io-1.2.10-3.2.el7.x86_64 is excluded</span><br><span class="line">  - package containerd.io-1.2.13-3.1.el7.x86_64 is excluded</span><br><span class="line">  - package containerd.io-1.2.2-3.3.el7.x86_64 is excluded</span><br><span class="line">  - package containerd.io-1.2.2-3.el7.x86_64 is excluded</span><br><span class="line">  - package containerd.io-1.2.4-3.1.el7.x86_64 is excluded</span><br><span class="line">  - package containerd.io-1.2.5-3.1.el7.x86_64 is excluded</span><br><span class="line">  - package containerd.io-1.2.6-3.3.el7.x86_64 is excluded</span><br><span class="line">(try to add <span class="string">&#x27;--skip-broken&#x27;</span> to skip uninstallable packages or <span class="string">&#x27;--nobest&#x27;</span> to use not only best candidate packages)</span><br></pre></td></tr></table></figure><p>解决方案有两个，要么安装老版本的<code>docker-ce</code>，要么升级<code>container.io</code>。我肯定选择第二个，问题形成的原因也很简单，官方的repo源里面的<code>container.io</code>版本比较老。我们去下载一个符合版本要求的<code>container.io</code>包。</p><p><code>dnf install -y https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm</code></p><p>一条毒奶粉（dnf）命令直接安装目前最新的<code>container.io</code> 包。哦对了，该包来源于Docker官方，下载的是<code>x86_64</code>架构的包。如果你是其他平台，请到<span class="exturl" data-url="aHR0cHM6Ly9kb3dubG9hZC5kb2NrZXIuY29tL2xpbnV4L2NlbnRvcy83Lw==" title="https://download.docker.com/linux/centos/7/">这儿里<i class="fa fa-external-link"></i></span>自己来选吧。</p><h2 id="安装docker-ce"><a href="#安装docker-ce" class="headerlink" title="安装docker-ce"></a>安装docker-ce</h2><p><code>container.io</code>的依赖问题已经解决完了，接下来直接安装就好了！</p><p><code>dnf install -y  docker-ce docker-ce-cli</code></p><h2 id="开启服务"><a href="#开启服务" class="headerlink" title="开启服务"></a>开启服务</h2><p><code>systemctl enable --now docker</code></p><p>成功安装后开启docker守护进程，尝试一下启动一个容器。没有问题的话就是安装成功了。但是要注意的是，如果你发现在容器内部无法访问网络，那么你可以尝试一下用firewalld开启你的IP地址转发功能，具体操作和解决方案在这里<a href="https://blog.yeefire.com/2020_03/centos8_docker_network.html">Centos8安装Docker后容器内无法访问网络</a>。</p><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群<span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h1 id=&quot;Centos8安装Docker失败的解决方案&quot;&gt;&lt;a href=&quot;#Centos8安装Docker失败的解决方案&quot; class=&quot;headerlink&quot; title=&quot;Centos8安装Docker失败的解决方案&quot;&gt;&lt;/a&gt;Centos8安装Docker失败的解决</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="Docker" scheme="https://blog.yeefire.com/tags/Docker/"/>
    
    <category term="Podman" scheme="https://blog.yeefire.com/tags/Podman/"/>
    
  </entry>
  
  <entry>
    <title>Centos8安装Docker后容器内无法访问网络</title>
    <link href="https://blog.yeefire.com/2020_03/centos8_docker_network.html"/>
    <id>https://blog.yeefire.com/2020_03/centos8_docker_network.html</id>
    <published>2020-03-19T04:25:55.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Centos8安装Docker后容器内无法访问网络"><a href="#Centos8安装Docker后容器内无法访问网络" class="headerlink" title="Centos8安装Docker后容器内无法访问网络"></a>Centos8安装Docker后容器内无法访问网络</h1><p>在Centos8中，默认安装的的容器管理工具是使用了Podman，Podman的设计理念非常好，整合了pod思想，用户可以直接启动容器而不是像Docker那样通过守护进程启动，这样也会提高安全性。但是现在Podman国内使用的人数并不是很多，还会有一些问题出现。所以在Centos8上先将Podman替换为Docker。</p><p>在安装好Docker后，结果没有网络，经过排查发现是没有开启ip转发。正常情况下，Docker会自动开启地址转发。但是，不知道为什么Docker在Centos8中没有开启iptables的地址转发，需要我们使用<code>firewalld</code>防火墙管理工具来手动开启IP地址转发功能。</p><span id="more"></span><h2 id="检查iptables"><a href="#检查iptables" class="headerlink" title="检查iptables"></a>检查iptables</h2><p>接下来会清除iptables现有规则，如果你一直使用的是<code>firewalld</code>来管理你的防火墙，就没必要查看现有的iptbales规则了。</p><p><code>iptabels -L</code></p><h2 id="临时关闭firewalld和docker服务"><a href="#临时关闭firewalld和docker服务" class="headerlink" title="临时关闭firewalld和docker服务"></a>临时关闭<code>firewalld</code>和<code>docker</code>服务</h2><p><code>systemctl stop firewalld docker</code> </p><h2 id="清除现有防火墙规则"><a href="#清除现有防火墙规则" class="headerlink" title="清除现有防火墙规则"></a>清除现有防火墙规则</h2><p>由于docker启动容器时会在iptables中添加规则，我们先把原来</p><p><strong><code>iptables -P INPUT ACCEPT</code> 先放行规则，非常重要！</strong></p><p>否则22端口也就是你的SSH服务可能再也连不上了。</p><p><code>iptables -F</code> 清除所有规则</p><h2 id="开启端口转发"><a href="#开启端口转发" class="headerlink" title="开启端口转发"></a>开启端口转发</h2><h3 id="1、开启内核IP地址转发功能"><a href="#1、开启内核IP地址转发功能" class="headerlink" title="1、开启内核IP地址转发功能"></a>1、开启内核IP地址转发功能</h3><p>首先查看内核是否开启IP地址转发功能</p><p><code>cat /proc/sys/net/ipv4/ip_forward</code></p><p>返回为1已开启，返回0则需要手动开一下。</p><p><code>echo &quot;net.ipv4.ip_forward = 1&quot; &gt;&gt; /etc/sysctl.conf</code> 复制到终端上！以root用户身份执行。</p><p><code>sysctl -p</code> 使更改立即生效。</p><h3 id="2、防火墙放行IP地址转发"><a href="#2、防火墙放行IP地址转发" class="headerlink" title="2、防火墙放行IP地址转发"></a>2、防火墙放行IP地址转发</h3><p>现在将firewalld服务启动</p><p><code>systemctl start firewalld</code></p><p>默认情况下<code>firewalld</code>会禁止转发流量，可以执行<code>firewall-cmd --query-masquerade</code>查看状态，应该是no，请执行下面的命令开启转发。</p><p><code>firewall-cmd --add-masquerade --permanent</code> 永久开启IP地址转发</p><p><code>firewall-cmd --reload</code> 重载防火墙规则，使之生效</p><h2 id="启动Docker服务"><a href="#启动Docker服务" class="headerlink" title="启动Docker服务"></a>启动Docker服务</h2><p>现在可以启动docker服务检查容器网络是否正常。</p><p><code>systemctl start docker</code></p><p><code>docker run -it  --rm centos:latest ping baidu.com</code></p><p>额外要注意的一点是，如果你防火墙屏蔽了<code>icmp</code>的<code>echo-request</code>请求，也就是我们说的禁止Ping。那么在容器中Ping别人及其的时候也会被主机防火墙拦截下来，Ping不通的哦。如果Ping不通可以使用<code>curl www.baidu.com</code>看看能不能访问得到百度页面，这样检测。</p><p>如果想了解更多Firewalld的内容请看我的这篇博文：<a href="https://blog.yeefire.com/2020_02/Linux_Firewalld.html">这可能是最全的firewalld防火墙常用指令教程</a></p><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群:<br><span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog(Telegram)<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Centos8安装Docker后容器内无法访问网络&quot;&gt;&lt;a href=&quot;#Centos8安装Docker后容器内无法访问网络&quot; class=&quot;headerlink&quot; title=&quot;Centos8安装Docker后容器内无法访问网络&quot;&gt;&lt;/a&gt;Centos8安装Docker后容器内无法访问网络&lt;/h1&gt;&lt;p&gt;在Centos8中，默认安装的的容器管理工具是使用了Podman，Podman的设计理念非常好，整合了pod思想，用户可以直接启动容器而不是像Docker那样通过守护进程启动，这样也会提高安全性。但是现在Podman国内使用的人数并不是很多，还会有一些问题出现。所以在Centos8上先将Podman替换为Docker。&lt;/p&gt;
&lt;p&gt;在安装好Docker后，结果没有网络，经过排查发现是没有开启ip转发。正常情况下，Docker会自动开启地址转发。但是，不知道为什么Docker在Centos8中没有开启iptables的地址转发，需要我们使用&lt;code&gt;firewalld&lt;/code&gt;防火墙管理工具来手动开启IP地址转发功能。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="Docker" scheme="https://blog.yeefire.com/tags/Docker/"/>
    
    <category term="Podman" scheme="https://blog.yeefire.com/tags/Podman/"/>
    
  </entry>
  
  <entry>
    <title>Docker或Podman容器内无法解析DNS问题多种解决方案</title>
    <link href="https://blog.yeefire.com/2020_03/docker_DNS_resolve.html"/>
    <id>https://blog.yeefire.com/2020_03/docker_DNS_resolve.html</id>
    <published>2020-03-08T08:19:19.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Docker或Podman容器内无法解析DNS问题多种解决方案"><a href="#Docker或Podman容器内无法解析DNS问题多种解决方案" class="headerlink" title="Docker或Podman容器内无法解析DNS问题多种解决方案"></a>Docker或Podman容器内无法解析DNS问题多种解决方案</h1><p>新安装了Centos8使用Podman，但是在容器内怎样都无法解析域名DNS。尝试了网上大多数的解决办法依然无效。在当我一筹莫展之时我想到了奥利给叔告诉过我“遇到什么困难，都不要怕！微笑的面对他”！</p><p>最终还是想到了是不是firewalld没有开启IP地址伪装（IP转发）功能。三下五除二赶紧执行<code>firewall-cmd --query-masquerade</code>。果然没有开启，开启后解决问题，瞬间晴朗。</p><p>下面是我和网络上其他人对于Docker容器内无法解析DNS地址的问题总结。</p><span id="more"></span><h2 id="开机防火墙IP地址伪装（IP地址转发）功能"><a href="#开机防火墙IP地址伪装（IP地址转发）功能" class="headerlink" title="开机防火墙IP地址伪装（IP地址转发）功能"></a>开机防火墙IP地址伪装（IP地址转发）功能</h2><p>如果使用的是Centos(RHEL)，并且没有关闭<code>Firewalld</code>防火墙，你需要留意是否开启了IP转发功能。</p><p><code>sudo firewall-cmd --query-masquerade</code>返回的结果为no，则没有开启。yes则为已经开启了IP地址转发，如果问题没有解决，请继续往下看。</p><p><code>sudo firewall-cmd --add-masquerade --permanent &amp;&amp; sudo firewall-cmd --reload</code>开启IP地址转发并生效。开启后请再次尝试容器内是否可以正常解析域名。</p><p>如果你想了解更多关于<code>firewalld</code>，请看我的另一篇博文<a href="https://blog.yeefire.com/2020_02/Linux_Firewalld.html">这可能是最全的firewalld防火墙常用指令教程</a></p><h2 id="开启内核IP地址转发"><a href="#开启内核IP地址转发" class="headerlink" title="开启内核IP地址转发"></a>开启内核IP地址转发</h2><p><code>cat /proc/sys/net/ipv4/ip_forward</code>查看是否已经开启，0为关闭状态，1为开启状态。如果已经开启请尝试其他解决方案。</p><p>如果返回值为0，则为关闭状态。切换到root用户执行<code>echo &quot;net.ipv4.ip_forward = 1&quot; &gt;&gt; /etc/sysctl.conf</code>，继续执行<code>sysctl -p /etc/sysctl.conf</code>使之永久生效。</p><p>之后需要重新启动网络服务来使IP地址转发功能生效：</p><p>如果你是Centos(RHEL)系，需要重新启动<code>network</code>服务。执行<code>systemctl restart network</code>重启服务后生效。</p><p>如果是Debian/Ubuntu系列的发行版，执行<code>/etc/init.d/procps restart</code>或<code>/etc/init.d/procps.sh restart</code>生效。</p><h2 id="配置一个正确的DNS"><a href="#配置一个正确的DNS" class="headerlink" title="配置一个正确的DNS"></a>配置一个正确的DNS</h2><p>正常情况下，运行的容器会与主机使用相同的<code>resolv.conf</code>文件来进行DNS解析，也就是说如果在本机上可以正常解析域名，那么只要开启了IP地址转发的情况下，容器中也可以正常解析。</p><p>你可以先查看你的<code>resolv.conf</code>文件文件配置的是否正确。</p><p><code>cat /etc/resolv.conf</code></p><p>如果发现DNS服务器地址有误，你可以手动编辑此文件，但是NetworkManager会在下次启动时网卡时对该文件还原为它的配置。所以，我们直接使用<code>NetworkManager</code>来更改我们的DNS比较妥当些。如果你的网络不是由<code>NetworkManager</code>管理。你可以试试看直接修改<code>/etc/resolv.conf</code>文件。</p><p>执行<code>sudo nmcli connection</code>来查看当前所有网络连接。</p><p><code>sudo nmcli connection modify ethernet-eth0(你的网卡连接名) ipv4.dns=114.114.114.114</code></p><p><code>sudo nmcli connection up ethernet-eth0(你的网卡连接名)</code>重启网卡，使手动配置的DNS生效。</p><h2 id="强制Docker使用自定义的DNS地址"><a href="#强制Docker使用自定义的DNS地址" class="headerlink" title="强制Docker使用自定义的DNS地址"></a>强制Docker使用自定义的DNS地址</h2><p><code>vim /etc/docker/daemon.json</code>修改该文件，如果没有该文件的话直接新建即可。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 修改该文件内容为如下全部文本，注意花括号也包括在内。DNS服务器我使用的是114DNS，你也可以进行更换。</span></span><br><span class="line"></span><br><span class="line">&#123;</span><br><span class="line">  <span class="string">&quot;dns&quot;</span>: [<span class="string">&quot;114.114.114.114&quot;</span>]</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>希望这篇文章能解决你的问题！如果还是不行，请在评论区留言，将你的大致情况说说看，我们一起研究研究看。</p><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群:<br><span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog(Telegram)<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p><hr>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Docker或Podman容器内无法解析DNS问题多种解决方案&quot;&gt;&lt;a href=&quot;#Docker或Podman容器内无法解析DNS问题多种解决方案&quot; class=&quot;headerlink&quot; title=&quot;Docker或Podman容器内无法解析DNS问题多种解决方案&quot;&gt;&lt;/a&gt;Docker或Podman容器内无法解析DNS问题多种解决方案&lt;/h1&gt;&lt;p&gt;新安装了Centos8使用Podman，但是在容器内怎样都无法解析域名DNS。尝试了网上大多数的解决办法依然无效。在当我一筹莫展之时我想到了奥利给叔告诉过我“遇到什么困难，都不要怕！微笑的面对他”！&lt;/p&gt;
&lt;p&gt;最终还是想到了是不是firewalld没有开启IP地址伪装（IP转发）功能。三下五除二赶紧执行&lt;code&gt;firewall-cmd --query-masquerade&lt;/code&gt;。果然没有开启，开启后解决问题，瞬间晴朗。&lt;/p&gt;
&lt;p&gt;下面是我和网络上其他人对于Docker容器内无法解析DNS地址的问题总结。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="Docker" scheme="https://blog.yeefire.com/tags/Docker/"/>
    
    <category term="Podman" scheme="https://blog.yeefire.com/tags/Podman/"/>
    
  </entry>
  
  <entry>
    <title>使用NetworkManager来管理树莓派Ubuntu系统网络以及个人的体验优化</title>
    <link href="https://blog.yeefire.com/2020_03/Raspberry_Ubuntu.html"/>
    <id>https://blog.yeefire.com/2020_03/Raspberry_Ubuntu.html</id>
    <published>2020-03-01T10:03:46.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="使用-NetworkManager-来管理树莓派-Ubuntu-系统网络-以及个人的体验优化"><a href="#使用-NetworkManager-来管理树莓派-Ubuntu-系统网络-以及个人的体验优化" class="headerlink" title="使用 NetworkManager 来管理树莓派 Ubuntu 系统网络 以及个人的体验优化"></a>使用 NetworkManager 来管理树莓派 Ubuntu 系统网络 以及个人的体验优化</h1><p>由于Raspbian官方网站上目前只提供arm32的系统。手里的这块树莓派4 4G发挥不出来它的最大性能，想想就难受。看到了有Ubuntu Server for Raspberry 3/4 的64位版本就心血来潮准备刷入。</p><p>烧录好镜像后，插卡！der～开机。使用默认的用户名和密码：<code>ubuntu</code>顺利进入系统。虽然没有显示器，插上网线！原来的时候在路由器里分配好的静态IP由于Mac地址没变，自然还是那个老IP咯。但是发现没有NetworkManager，感觉不太方便啊！虽然原来的Raspbian也没有，当时想想就算了哈！这回装了新系统，干脆弄的舒服点。</p><span id="more"></span><h1 id="安装NetworkManager"><a href="#安装NetworkManager" class="headerlink" title="安装NetworkManager"></a>安装NetworkManager</h1><p><code>sudo apt install network-namager</code> 理论上不一会就安装好了，如果你的网络环境不太好，可以使用国内源来加快下载速度（下面会提到）</p><p>安装好之后需要将默认的网络管理切换到<code>NetworkManager</code>上</p><p>编辑文件 <code>/etc/netplan/50-cloud-init.yaml</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 将默认配置全部注释，填写如下配置：</span></span><br><span class="line"></span><br><span class="line">network:</span><br><span class="line">    version: 2</span><br><span class="line">    renderer: NetworkManager</span><br></pre></td></tr></table></figure><p>启动NetworkManager<code>systemctl enable NetworkManager &amp;&amp; systemctl start NetworkManager </code></p><p>更改重启后生效，但先别急着重启，记得先添加一个默认的网络连接。</p><h2 id="添加默认网络连接"><a href="#添加默认网络连接" class="headerlink" title="添加默认网络连接"></a>添加默认网络连接</h2><p>如果你没有显示器，这一步要跳过的话那么很可能你本次的折腾只旅就到此为止了！如果忽略这一步骤，树莓派下次启动时不会链接到任何的网络，也就是没办法树莓派建立SSH远程连接哦。</p><h3 id="使用nmtui图形化配置第一个网络连接"><a href="#使用nmtui图形化配置第一个网络连接" class="headerlink" title="使用nmtui图形化配置第一个网络连接"></a>使用<code>nmtui</code>图形化配置第一个网络连接</h3><p><code>sudo nmtui</code></p><p><img src="https://cdn.yeefire.com/hexo/img/nmtui-1.png" alt="nmtui-1.png"></p><p>你可以选择<code>Edit a Connection</code>来手动配置网络。</p><p>也可以选择<code>Activate a Connection</code>选择并且连接一个无线网络，请记得勾选上自动连接！</p><p>请确保成功连接并且添加后在重启树莓派。</p><h3 id="或者使用nmcli命令行配置第一个网络连接"><a href="#或者使用nmcli命令行配置第一个网络连接" class="headerlink" title="或者使用nmcli命令行配置第一个网络连接"></a>或者使用<code>nmcli</code>命令行配置第一个网络连接</h3><p>由于我插着网线，我建立一个以太网类型的连接，使用默认的<code>eth0</code>网络接口并且IP全部由路由器DHCP自动分配。</p><p><code>sudo nmcli connection add type ethernet ifname eth0 ipv4.method auto ipv6.method auto autoconnect yes</code></p><p>使用<code>nmcli connection</code>检查一下是否成功添加。</p><p>请确保成功连接并且添加后在重启树莓派。</p><h1 id="个人偏好设置"><a href="#个人偏好设置" class="headerlink" title="个人偏好设置"></a>个人偏好设置</h1><h2 id="更换国内源"><a href="#更换国内源" class="headerlink" title="更换国内源"></a>更换国内源</h2><p>我的网络环境并不太好，使用官方源来更新或者下载包会特别的慢。我是用清华大学开学镜像站来作为我的国内源。</p><p>我使用的系统是<code>Ubuntu 18.04.4 LTS</code>长期支持版。代号为<code>bionic</code>，你如果使用的是更新的版本比如<code>19.10/20.04</code>的话请将下方镜像源里的<code>bionic</code>字样替换为你自己的版本代号。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">cat</span> /etc/lsb-release <span class="comment"># 查看自己的Ubuntu版本</span></span><br><span class="line">DISTRIB_ID=Ubuntu</span><br><span class="line">DISTRIB_RELEASE=18.04</span><br><span class="line">DISTRIB_CODENAME=bionic</span><br><span class="line">DISTRIB_DESCRIPTION=<span class="string">&quot;Ubuntu 18.04.4 LTS&quot;</span></span><br></pre></td></tr></table></figure><p>备份镜像源<code>mv /etc/apt/sources.list /etc/apt/sources.list.bak</code></p><p>编辑文件文件<code>/etc/apt/sources.list</code>，将全部内容清空后复制以下内容到该文件中：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse</span><br><span class="line"><span class="comment"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse</span></span><br><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse</span><br><span class="line"><span class="comment"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse</span></span><br><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse</span><br><span class="line"><span class="comment"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse</span></span><br><span class="line">deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse</span><br><span class="line"><span class="comment"># deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse</span></span><br></pre></td></tr></table></figure><p>我为了加快每次使用apt获取源的速度注释掉了源代码的源，如果你有需要的话请自行开启。</p><p><code>sudo apt update</code>更新并获取源</p><h2 id="配置-Bash-自动补全"><a href="#配置-Bash-自动补全" class="headerlink" title="配置 Bash 自动补全"></a>配置 Bash 自动补全</h2><p>我在安装好系统后发现没有自动补全，忘记命令选项和参数的时候会比较尴尬。</p><p>首先请确认你已经安装了<code>bash-completion</code>这个包，默认情况下是已经安装在你的系统中的。</p><p>但是安装好后双击<code>Tab</code>键还是没有命令补全，需要在<code>/etc/bash.bashrc</code>中<strong>取消注释</strong>掉如下部分代码。重新登录后生效。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># enable bash completion in interactive shells</span></span><br><span class="line"><span class="keyword">if</span> ! <span class="built_in">shopt</span> -oq posix; <span class="keyword">then</span></span><br><span class="line">  <span class="keyword">if</span> [ -f /usr/share/bash-completion/bash_completion ]; <span class="keyword">then</span></span><br><span class="line">    . /usr/share/bash-completion/bash_completion</span><br><span class="line">  <span class="keyword">elif</span> [ -f /etc/bash_completion ]; <span class="keyword">then</span></span><br><span class="line">    . /etc/bash_completion</span><br><span class="line">  <span class="keyword">fi</span></span><br><span class="line"><span class="keyword">fi</span></span><br></pre></td></tr></table></figure><h2 id="安装-firewalld-防火墙"><a href="#安装-firewalld-防火墙" class="headerlink" title="安装 firewalld 防火墙"></a>安装 <code>firewalld</code> 防火墙</h2><p>习惯了RHEL系的系统，使用<code>firewalld</code>也比较顺手，所以就使用它来管理系统防火墙咯。</p><p><code>sudo apt install firewalld</code> </p><p><code>sudo systemctl enable firewalld.service &amp;&amp; sudo systemctl start firewalld.service</code></p><p>不需要进行额外的配置，如果你想了解更多关于<code>firewalld</code>，请看我的另一篇博文<a href="https://blog.yeefire.com/2020_02/Linux_Firewalld.html">这可能是最全的firewalld防火墙常用指令教程</a></p><p>目前就先这个样子，以后如果我自己有新需求的话还会在这里保存或者记录下来过程。感谢大家阅读和支持，希望能帮助到你。</p><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群<span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;使用-NetworkManager-来管理树莓派-Ubuntu-系统网络-以及个人的体验优化&quot;&gt;&lt;a href=&quot;#使用-NetworkManager-来管理树莓派-Ubuntu-系统网络-以及个人的体验优化&quot; class=&quot;headerlink&quot; title=&quot;使用 NetworkManager 来管理树莓派 Ubuntu 系统网络 以及个人的体验优化&quot;&gt;&lt;/a&gt;使用 NetworkManager 来管理树莓派 Ubuntu 系统网络 以及个人的体验优化&lt;/h1&gt;&lt;p&gt;由于Raspbian官方网站上目前只提供arm32的系统。手里的这块树莓派4 4G发挥不出来它的最大性能，想想就难受。看到了有Ubuntu Server for Raspberry 3/4 的64位版本就心血来潮准备刷入。&lt;/p&gt;
&lt;p&gt;烧录好镜像后，插卡！der～开机。使用默认的用户名和密码：&lt;code&gt;ubuntu&lt;/code&gt;顺利进入系统。虽然没有显示器，插上网线！原来的时候在路由器里分配好的静态IP由于Mac地址没变，自然还是那个老IP咯。但是发现没有NetworkManager，感觉不太方便啊！虽然原来的Raspbian也没有，当时想想就算了哈！这回装了新系统，干脆弄的舒服点。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="firewalld" scheme="https://blog.yeefire.com/tags/firewalld/"/>
    
    <category term="Raspberry" scheme="https://blog.yeefire.com/tags/Raspberry/"/>
    
    <category term="树莓派" scheme="https://blog.yeefire.com/tags/%E6%A0%91%E8%8E%93%E6%B4%BE/"/>
    
    <category term="NetworkManager" scheme="https://blog.yeefire.com/tags/NetworkManager/"/>
    
  </entry>
  
  <entry>
    <title>Linux 存储设备的挂载及识别</title>
    <link href="https://blog.yeefire.com/2020_02/Linux_mount.html"/>
    <id>https://blog.yeefire.com/2020_02/Linux_mount.html</id>
    <published>2020-02-21T13:54:51.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="存储设备的挂载及识别"><a href="#存储设备的挂载及识别" class="headerlink" title="存储设备的挂载及识别"></a>存储设备的挂载及识别</h1><!-- TOC --><ul><li><a href="#%E5%AD%98%E5%82%A8%E8%AE%BE%E5%A4%87%E7%9A%84%E6%8C%82%E8%BD%BD%E5%8F%8A%E8%AF%86%E5%88%AB">存储设备的挂载及识别</a><ul><li><a href="#%E5%AD%98%E5%82%A8%E6%8C%82%E8%BD%BD%E7%9A%84%E6%A6%82%E5%BF%B5">存储挂载的概念</a></li><li><a href="#%E6%9F%A5%E6%89%BE%E5%AD%98%E5%82%A8%E8%AE%BE%E5%A4%87">查找存储设备</a></li><li><a href="#%E5%AD%98%E5%82%A8%E7%9A%84%E6%8C%82%E8%BD%BD">存储的挂载</a></li><li><a href="#%E8%A7%A3%E9%99%A4%E6%8C%82%E8%BD%BD">解除挂载</a></li><li><a href="#%E5%AE%9E%E7%8E%B0%E5%AD%98%E5%82%A8%E8%AE%BE%E5%A4%87%E5%BC%80%E6%9C%BA%E8%87%AA%E5%8A%A8%E6%8C%82%E8%BD%BD">实现存储设备开机自动挂载</a></li></ul></li></ul><!-- /TOC --><h2 id="存储挂载的概念"><a href="#存储挂载的概念" class="headerlink" title="存储挂载的概念"></a>存储挂载的概念</h2><p>将驻留在物理磁盘或虚拟镜像上的文件系统添加到现有目录树的过程称为<code>挂载</code>。其中挂载到系统的目录称为<code>挂载点</code>。</p><p>存储设备由一个特殊文件类型表示，称为<code>块设备</code>。块设备存储在<code>/dev</code>目录下。在RHEL系操作系统中，检测到的第一个SCSI、SATA或USB存储设备叫<code>sda</code>,块设备在<code>/dev/sda</code>，第二个是<code>sdb</code>以此类推。该名称代表整个存储设备。若要挂载某一分区，那么在<code>/dev/sda</code>上的第一个分区叫<code>sda1</code>、第二个分区叫<code>sda2</code>以此类推。</p><blockquote><p>虚拟机中的磁盘驱动器是例外情况，通常显示为<code>/dev/vd(x)</code>或<code>/dev/xvd(x)</code></p></blockquote><span id="more"></span><h2 id="查找存储设备"><a href="#查找存储设备" class="headerlink" title="查找存储设备"></a>查找存储设备</h2><p><code>fdisk -l</code>显示磁盘分区信息<br><code>df -h</code>显示已经挂载的文件系统的信息。<br><code>lsblk</code>树状图显示磁盘分区以及挂载信息</p><h2 id="存储的挂载"><a href="#存储的挂载" class="headerlink" title="存储的挂载"></a>存储的挂载</h2><p>常用<code>mount &lt;operation&gt; &lt;mountpoint&gt;</code>命令挂载存储设备，这种手动的挂载都是临时的，重启便失效。</p><p>参数1(operation):指定要挂载的文件系统</p><p>参数2(mountpoint):指定将要挂载的文件系统挂载到本机的目标目录(挂载点)</p><p>从发现存储设备到挂载存储设备的过程例子如下：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">lsblk <span class="comment"># 使用命令`lsblk`发现存储设备以及分区</span></span><br><span class="line">NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT</span><br><span class="line">sda           8:0    0   1.8T  0 disk </span><br><span class="line">├─sda1        8:1    0   200M  0 part </span><br><span class="line">└─sda2        8:2    0   1.8T  0 part /home/pi/disk</span><br><span class="line">sdb           8:16   1    29G  0 disk </span><br><span class="line">└─sdb1        8:17   1    29G  0 part </span><br><span class="line">mmcblk0     179:0    0 119.3G  0 disk </span><br><span class="line">├─mmcblk0p1 179:1    0   256M  0 part /boot</span><br><span class="line">└─mmcblk0p2 179:2    0   119G  0 part /</span><br><span class="line"></span><br><span class="line"><span class="comment"># 找到了想要挂载的磁盘驱动器`sdb`，现在将这个驱动器的第一个分区`sdb1`挂载到本机的`/mnt/mydisk`目录下</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">mkdir</span> /mnt/mydisk </span><br><span class="line"><span class="comment"># 创建目录作为挂载点</span></span><br><span class="line"></span><br><span class="line">mount /dev/sdb1  /mnt/mydisk</span><br><span class="line"><span class="comment"># 将`/dev/sdb1`挂载到`/mnt/mydisk`目录上。</span></span><br></pre></td></tr></table></figure><p><img src="https://cdn.yeefire.com/hexo/img/%E6%8C%82%E8%BD%BD%E8%BF%87%E7%A8%8B.png" alt="挂载过程.png"></p><blockquote><p>如果提示权限不足，请使用root权限操作。</p></blockquote><p>现在已经将<code>/dev/sdb1</code>磁盘分区挂载到了系统的<code>/mnt/mydisk</code>挂载点上。</p><p>检查是否已经成功地挂载，可以使用<code>df -h</code>或<code>lsblk</code>。</p><p><img src="https://cdn.yeefire.com/hexo/img/%E6%A3%80%E6%9F%A5%E6%8C%82%E8%BD%BD.png" alt="检查挂载.png"></p><h2 id="解除挂载"><a href="#解除挂载" class="headerlink" title="解除挂载"></a>解除挂载</h2><p>使用<code>umount &lt;mountpoint&gt;</code>来解除对文件系统的挂载。</p><p>参数1(mountpoint):要解除挂载的挂载点</p><p>比如我们刚刚将<code>/dev/sdb1</code>挂载到了系统的<code>/mnt/mydisk</code>挂载点上，使用<code>umount /mnt/mydisk</code>即可解除挂载。</p><h2 id="实现存储设备开机自动挂载"><a href="#实现存储设备开机自动挂载" class="headerlink" title="实现存储设备开机自动挂载"></a>实现存储设备开机自动挂载</h2><p>使用<code>mount</code>的挂载只是临时的，重启后就失效了，如果需要继续使用存储设备就要重新挂载，相当的麻烦。</p><p>实现开机自动挂载需要修改系统的<code>/etc/fstab</code>配置文件，在这个配置文件中添加一些要挂载存储设备的信息。</p><blockquote><p>对<code>/etc/fstab</code>修改比较危险，如果没有一定把握请不要使用这种方式挂载存储设备，如果配置有误，系统重启后将进入恢复模式无法正常的开机。</p></blockquote><p><code>fstab</code>支持两种配置方式：</p><ul><li>使用UUID配置(推荐。只要不格式化，UUID不会改变)</li><li>使用存储设备的块设备文件<code>/dev/sdb1</code>(如果设备的顺序有变化或者向系统中添加了其他的设备，设备块设备文件路径会有变化导致系统无法正常启动)</li></ul><p>使用<code>lsblk -f</code>列出系统中发现的现有分区以及文件系统的UUID和该分区文件系统的格式等信息。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">lsblk -f</span><br><span class="line">NAME        FSTYPE LABEL   UUID                                 FSAVAIL FSUSE% MOUNTPOINT</span><br><span class="line">sda                                                                            </span><br><span class="line">├─sda1      vfat   EFI     67E3-17ED                                           </span><br><span class="line">└─sda2      exfat  HD      5D31-C4ED                                 1T    44% /home/pi/disk</span><br><span class="line">sdb                                                                            </span><br><span class="line">└─sdb1      vfat   ESD-ISO F0ED-593A                              28.9G     0% /mnt/mydisk</span><br><span class="line">mmcblk0                                                                        </span><br><span class="line">├─mmcblk0p1 vfat   boot    5203-DB74                               199M    21% /boot</span><br><span class="line">└─mmcblk0p2 ext4   rootfs  2ab3f8e1-7dc6-43f5-b0db-dd5759d51d4e   99.8G    11% /</span><br></pre></td></tr></table></figure><p><img src="https://cdn.yeefire.com/hexo/img/lsblk-f.png" alt="lsblk-f.png"></p><p>可以看到<code>/dev/sdb1</code>文件系统的格式为<code>vfat</code>，UUID为<code>F0ED-593A</code>。</p><p>切换到root用户，编辑<code>/etc/fstab</code>文件，并按照<code>fstab</code>文件原有的格式添加到文件末尾行。</p><p><code>UUID=F0ED-593A /mnt/mydisk vfat defaults 0 0</code></p><p><img src="https://cdn.yeefire.com/hexo/img/fstab.png" alt="fstab.png"></p><p>使用<code>mount -a</code>对<code>fstab</code>配置文件中的全部磁盘分区以此进行挂载，如果没有报错，则配置文件编写正确。</p><p>使用<code>df -h</code>检查挂载点是否正确。</p><hr>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;存储设备的挂载及识别&quot;&gt;&lt;a href=&quot;#存储设备的挂载及识别&quot; class=&quot;headerlink&quot; title=&quot;存储设备的挂载及识别&quot;&gt;&lt;/a&gt;存储设备的挂载及识别&lt;/h1&gt;&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AD%98%E5%82%A8%E8%AE%BE%E5%A4%87%E7%9A%84%E6%8C%82%E8%BD%BD%E5%8F%8A%E8%AF%86%E5%88%AB&quot;&gt;存储设备的挂载及识别&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AD%98%E5%82%A8%E6%8C%82%E8%BD%BD%E7%9A%84%E6%A6%82%E5%BF%B5&quot;&gt;存储挂载的概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9F%A5%E6%89%BE%E5%AD%98%E5%82%A8%E8%AE%BE%E5%A4%87&quot;&gt;查找存储设备&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AD%98%E5%82%A8%E7%9A%84%E6%8C%82%E8%BD%BD&quot;&gt;存储的挂载&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%A7%A3%E9%99%A4%E6%8C%82%E8%BD%BD&quot;&gt;解除挂载&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%9E%E7%8E%B0%E5%AD%98%E5%82%A8%E8%AE%BE%E5%A4%87%E5%BC%80%E6%9C%BA%E8%87%AA%E5%8A%A8%E6%8C%82%E8%BD%BD&quot;&gt;实现存储设备开机自动挂载&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;存储挂载的概念&quot;&gt;&lt;a href=&quot;#存储挂载的概念&quot; class=&quot;headerlink&quot; title=&quot;存储挂载的概念&quot;&gt;&lt;/a&gt;存储挂载的概念&lt;/h2&gt;&lt;p&gt;将驻留在物理磁盘或虚拟镜像上的文件系统添加到现有目录树的过程称为&lt;code&gt;挂载&lt;/code&gt;。其中挂载到系统的目录称为&lt;code&gt;挂载点&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;存储设备由一个特殊文件类型表示，称为&lt;code&gt;块设备&lt;/code&gt;。块设备存储在&lt;code&gt;/dev&lt;/code&gt;目录下。在RHEL系操作系统中，检测到的第一个SCSI、SATA或USB存储设备叫&lt;code&gt;sda&lt;/code&gt;,块设备在&lt;code&gt;/dev/sda&lt;/code&gt;，第二个是&lt;code&gt;sdb&lt;/code&gt;以此类推。该名称代表整个存储设备。若要挂载某一分区，那么在&lt;code&gt;/dev/sda&lt;/code&gt;上的第一个分区叫&lt;code&gt;sda1&lt;/code&gt;、第二个分区叫&lt;code&gt;sda2&lt;/code&gt;以此类推。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;虚拟机中的磁盘驱动器是例外情况，通常显示为&lt;code&gt;/dev/vd(x)&lt;/code&gt;或&lt;code&gt;/dev/xvd(x)&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
  </entry>
  
  <entry>
    <title>Firewalld 防火墙常用指令教程-常用规则(禁止Ping | 放行端口)</title>
    <link href="https://blog.yeefire.com/2020_02/Linux_Firewalld.html"/>
    <id>https://blog.yeefire.com/2020_02/Linux_Firewalld.html</id>
    <published>2020-02-21T13:52:27.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Linux的Firewalld防火墙"><a href="#Linux的Firewalld防火墙" class="headerlink" title="Linux的Firewalld防火墙"></a>Linux的Firewalld防火墙</h1><!-- TOC --><ul><li><a href="#linux%E7%9A%84firewalld%E9%98%B2%E7%81%AB%E5%A2%99">Linux的Firewalld防火墙</a></li><li><a href="#1-firewalld%E9%98%B2%E7%81%AB%E5%A2%99%E7%AE%80%E4%BB%8B">1. <code>firewalld</code>防火墙简介</a><ul><li><a href="#11-firewalld%E4%B8%8Eiptables%E7%9A%84%E4%B8%BB%E8%A6%81%E5%8C%BA%E5%88%AB">1.1. <code>firewalld</code>与<code>iptables</code>的主要区别</a></li><li><a href="#12-%E5%AF%B9firewalldzone%E7%BD%91%E7%BB%9C%E5%8C%BA%E7%9A%84%E7%90%86%E8%A7%A3">1.2. 对<code>firewalld</code>Zone网络区的理解</a></li></ul></li><li><a href="#2-%E5%AE%89%E8%A3%85firewalld%E9%98%B2%E7%81%AB%E5%A2%99">2. 安装<code>firewalld</code>防火墙</a><ul><li><a href="#21-%E5%90%AF%E5%8A%A8%E9%98%B2%E7%81%AB%E5%A2%99">2.1. 启动防火墙</a></li><li><a href="#22-%E6%A3%80%E6%9F%A5%E9%98%B2%E7%81%AB%E5%A2%99%E6%98%AF%E5%90%A6%E8%BF%90%E8%A1%8C">2.2. 检查防火墙是否运行</a></li></ul></li><li><a href="#3-%E4%BD%BF%E7%94%A8firewall-cmd%E8%BF%9B%E8%A1%8C%E7%AE%A1%E7%90%86">3. 使用<code>firewall-cmd</code>进行管理</a><ul><li><a href="#31-zone%E7%BD%91%E7%BB%9C%E5%8C%BA%E7%AE%A1%E7%90%86">3.1. Zone网络区管理</a><ul><li><a href="#311-%E6%9F%A5%E7%9C%8B%E6%89%80%E6%9C%89zone%E7%BD%91%E7%BB%9C%E5%8C%BA">3.1.1. 查看所有Zone网络区</a></li><li><a href="#312-%E6%9F%A5%E7%9C%8Bfirewalld%E9%BB%98%E8%AE%A4zone">3.1.2. 查看<code>firewalld</code>默认Zone</a></li><li><a href="#313-%E6%9F%A5%E8%AF%A2%E6%9F%90%E4%B8%AA%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E4%B8%8A%E4%BD%BF%E7%94%A8%E7%9A%84zone">3.1.3. 查询某个网络接口上使用的Zone</a></li><li><a href="#314-%E6%9F%A5%E7%9C%8B%E5%B7%B2%E6%BF%80%E6%B4%BB%E7%9A%84zone%E7%9A%84%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E5%88%97%E8%A1%A8">3.1.4. 查看已激活的Zone的网络接口列表</a></li><li><a href="#315-%E6%9F%A5%E8%AF%A2%E6%9F%90%E4%B8%80%E4%B8%AAzone%E7%9A%84%E8%AF%A6%E7%BB%86%E8%A7%84%E5%88%99%E4%BF%A1%E6%81%AF">3.1.5. 查询某一个Zone的详细规则信息</a></li><li><a href="#316-%E4%BF%AE%E6%94%B9%E5%BD%93%E5%89%8D%E9%BB%98%E8%AE%A4%E7%9A%84zone%E7%BD%91%E7%BB%9C%E5%8C%BA">3.1.6. 修改当前默认的Zone网络区</a></li><li><a href="#317-%E4%BF%AE%E6%94%B9%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E4%B8%8A%E7%9A%84zone%E7%BD%91%E7%BB%9C%E5%8C%BA">3.1.7. 修改网络接口上的Zone网络区</a></li><li><a href="#318-%E5%88%A0%E9%99%A4%E7%BB%91%E5%AE%9A%E5%9C%A8%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E4%B8%8A%E7%9A%84zone%E7%BD%91%E7%BB%9C%E5%8C%BA">3.1.8. 删除绑定在网络接口上的Zone网络区</a></li></ul></li><li><a href="#32-%E9%87%8D%E6%96%B0%E5%8A%A0%E8%BD%BDfirewalld%E9%98%B2%E7%81%AB%E5%A2%99">3.2. 重新加载<code>firewalld</code>防火墙</a><ul><li><a href="#321-%E4%B8%8D%E4%B8%AD%E6%96%AD%E7%94%A8%E6%88%B7%E8%BF%9E%E6%8E%A5">3.2.1. 不中断用户连接</a></li><li><a href="#322-%E5%AE%8C%E5%85%A8%E9%87%8D%E8%BD%BD%E9%98%B2%E7%81%AB%E5%A2%99%E5%B9%B6%E6%96%AD%E5%BC%80%E7%8E%B0%E6%9C%89%E7%9A%84%E7%94%A8%E6%88%B7%E8%BF%9E%E6%8E%A5">3.2.2. 完全重载防火墙，并断开现有的用户连接</a></li></ul></li><li><a href="#33-%E6%89%93%E5%BC%80%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99%E7%AB%AF%E5%8F%A3%E6%94%BE%E8%A1%8C%E7%AB%AF%E5%8F%A3">3.3. 打开/关闭防火墙端口(放行端口)</a><ul><li><a href="#331-%E6%89%93%E5%BC%80%E9%98%B2%E7%81%AB%E5%A2%99%E7%AB%AF%E5%8F%A3%E6%94%BE%E8%A1%8C%E7%AB%AF%E5%8F%A3">3.3.1. 打开防火墙端口(放行端口)</a></li><li><a href="#332-%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99%E7%AB%AF%E5%8F%A3%E5%85%B3%E9%97%AD%E7%AB%AF%E5%8F%A3">3.3.2. 关闭防火墙端口(关闭端口)</a></li></ul></li><li><a href="#34-%E6%94%BE%E8%A1%8C%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99%E6%9F%90%E4%B8%80%E6%9C%8D%E5%8A%A1%E6%94%BE%E8%A1%8C%E6%9C%8D%E5%8A%A1">3.4. 放行/关闭防火墙某一服务(放行服务)</a><ul><li><a href="#341-%E6%9F%A5%E7%9C%8B%E6%89%80%E6%9C%89%E6%94%AF%E6%8C%81%E7%9A%84%E6%9C%8D%E5%8A%A1">3.4.1. 查看所有支持的服务</a></li><li><a href="#342-%E6%9F%A5%E8%AF%A2%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%A3%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF">3.4.2. 查询服务端口详细信息</a></li><li><a href="#343-%E6%94%BE%E8%A1%8C%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%A3">3.4.3. 放行服务端口</a></li><li><a href="#344-%E5%85%B3%E9%97%AD%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%A3">3.4.4. 关闭服务端口</a></li></ul></li><li><a href="#35-%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91">3.5. 端口转发</a><ul><li><a href="#351-%E5%BC%80%E5%90%AFip%E4%BC%AA%E8%A3%85">3.5.1. 开启IP伪装</a></li><li><a href="#352-%E5%BC%80%E5%90%AF%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91">3.5.2. 开启端口转发</a></li><li><a href="#353-%E5%85%B3%E9%97%AD%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91">3.5.3. 关闭端口转发</a></li></ul></li></ul></li><li><a href="#4-%E4%BD%BF%E7%94%A8%E5%AF%8C%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE%E5%A4%8D%E6%9D%82firewalld%E7%AD%96%E7%95%A5">4. 使用富规则配置复杂<code>firewalld</code>策略</a><ul><li><a href="#41-%E5%AF%8C%E8%A7%84%E5%88%99%E7%9A%84%E5%91%BD%E4%BB%A4%E6%A0%BC%E5%BC%8F">4.1. 富规则的命令格式</a></li><li><a href="#42-%E7%90%86%E8%A7%A3%E5%A4%9A%E8%A7%84%E5%88%99%E5%91%BD%E4%BB%A4">4.2. 理解多规则命令</a><ul><li><a href="#421-family">4.2.1. family</a></li><li><a href="#422-source">4.2.2. source</a></li><li><a href="#423-destination">4.2.3. destination</a></li><li><a href="#424-element">4.2.4. element</a><ul><li><a href="#4241-service%E6%9C%8D%E5%8A%A1%E5%90%8D%E7%A7%B0">4.2.4.1. service服务名称</a></li><li><a href="#4242-port%E7%AB%AF%E5%8F%A3">4.2.4.2. port端口</a></li><li><a href="#4243-protocol%E5%8D%8F%E8%AE%AE">4.2.4.3. protocol协议</a></li><li><a href="#4244-icmp-block%E9%98%BB%E6%96%AD">4.2.4.4. icmp-block阻断</a></li><li><a href="#4245-icmp-type%E7%B1%BB%E5%9E%8B">4.2.4.5. icmp-type类型</a></li><li><a href="#4246-masquerade-ip%E5%9C%B0%E5%9D%80%E4%BC%AA%E8%A3%85">4.2.4.6. masquerade IP地址伪装</a></li><li><a href="#4247-forward-port%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91">4.2.4.7 forward-port端口转发</a></li></ul></li><li><a href="#425-log%E6%97%A5%E5%BF%97">4.2.5. log日志</a></li><li><a href="#426-action%E5%8A%A8%E4%BD%9Cacceptrejectdrop">4.2.6. Action动作(accept|reject|drop)</a></li></ul></li><li><a href="#43-%E5%88%A0%E9%99%A4%E5%AF%8C%E8%A7%84%E5%88%99">4.3. 删除富规则</a><ul><li><a href="#431-%E6%9F%A5%E8%AF%A2%E6%89%80%E6%9C%89%E5%AF%8C%E8%A7%84%E5%88%99">4.3.1 查询所有富规则</a></li><li><a href="#432-%E5%88%A0%E9%99%A4%E5%AF%8C%E8%A7%84%E5%88%99">4.3.2 删除富规则</a></li></ul></li><li><a href="#44-%E5%AF%8C%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE%E5%AE%9E%E4%BE%8B">4.4. 富规则配置实例</a><ul><li><a href="#441-%E9%98%BB%E6%AD%A2echo-request%E8%AF%B7%E6%B1%82">4.4.1 阻止<code>echo-request</code>请求</a></li><li><a href="#442-%E6%8B%92%E7%BB%9D%E6%9F%90%E4%B8%80ip%E6%AE%B5%E8%AE%BF%E9%97%AE%E6%9C%AC%E6%9C%BAftp%E6%9C%8D%E5%8A%A1">4.4.2 拒绝某一IP(段)访问本机ftp服务</a></li><li><a href="#443-%E4%BD%BF%E7%94%A8%E5%AF%8C%E8%A7%84%E5%88%99%E8%BF%9B%E8%A1%8C%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91">4.4.3 使用富规则进行端口转发</a></li><li><a href="#444-%E4%B8%A2%E5%BC%83%E6%9D%A5%E8%87%AA%E6%9F%90ip%E5%9F%9F%E7%9A%84%E6%89%80%E6%9C%89%E8%BF%9E%E6%8E%A5">4.4.4 丢弃来自某IP域的所有连接</a></li></ul></li></ul></li></ul><!-- /TOC --><p>使用防火墙可以对外部的数据包进行过滤和阻止，尽可能减少暴露在网络上的危险以保护系统安全。在<code>RHEL7</code>系的Linux系统中，已经将<code>iptables</code>防火墙管理工具使用<code>firewalld</code>代替。这篇文章的所有案例在<code>RHEL8</code>上成功执行，如果遇到了问题请尝试变通或者在底部评论区与我留言。噗！这是我第一次做标题党哈哈哈。</p><p>更新日期：2020年3月4日(富规则配置举例、增加富规则中的<code>icmp-type</code>过滤规则、优化了一些细节错误)。常见用法已经全部写在文章中，之后会不定期更新细节。</p><span id="more"></span><h1 id="1-firewalld防火墙简介"><a href="#1-firewalld防火墙简介" class="headerlink" title="1. firewalld防火墙简介"></a>1. <code>firewalld</code>防火墙简介</h1><p><code>firewalld</code>提供了一个动态管理的防火墙，在对防火墙规则修改时不需要断开连接就可以激活规则，并且支持网络区域<code>zones</code>,用来分配一个网络及相关连接一种程度上的信任。它已经对<code>IPv4</code>和<code>IPv6</code>进行支持。并且可以选择对规则临时或永久修改。</p><p><strong>本文使用的<code>firewalld</code>版本:<code>0.7.0</code></strong></p><h2 id="1-1-firewalld与iptables的主要区别"><a href="#1-1-firewalld与iptables的主要区别" class="headerlink" title="1.1. firewalld与iptables的主要区别"></a>1.1. <code>firewalld</code>与<code>iptables</code>的主要区别</h2><ul><li><p><code>iptables</code>在<code>/etc/sysconfig/iptables-config</code>文件中存储配置。<code>firewalld</code>在<code>/etc/firewalld/</code>下存储XML配置文件。</p></li><li><p>使用<code>iptables</code>时每一个规则的更改意味着要清除所有旧的规则，然后从<code>/etc/sysconfig/iptables-config</code>配置文件中读取所有新的规则并载入。然而使用<code>firewalld</code>可以临时的将新添加的规则载入使用，不会像<code>iptables</code>一样丢失连接。</p></li></ul><p>使用<code>iptables</code>命令行和<code>firewalld</code>工具和内核的<code>NetFilter</code>（内核防火墙框架）的交互示意图如下。</p><p><img src="https://cdn.yeefire.com/hexo/img/iptables%E4%B8%8Efirewalld%E5%8C%BA%E5%88%AB.png" alt="iptables与firewalld区别.png"></p><blockquote><p>可以看出<code>NetFilter</code>才是真正的“防火墙”，它是Linux操作系统核心层内部的一个数据包处理框架，由图可以看出，不论是<code>iptables</code>命令行工具还是<code>firewalld</code>工具，它们都会通过<code>iptables command</code>与<code>NetFilter</code>(内核防火墙框架)放出来的接口实现沟通并使防火墙的规则生效。</p></blockquote><h2 id="1-2-对firewalldZone网络区的理解"><a href="#1-2-对firewalldZone网络区的理解" class="headerlink" title="1.2. 对firewalldZone网络区的理解"></a>1.2. 对<code>firewalld</code>Zone网络区的理解</h2><p>基于对网络中的设备和通信所给予的信任程度不同，<code>firewalld</code>防火墙可以用来将网络分割成不同的区域。</p><p>使用<code>firewall-cmd --get-zones</code>查看默认提供的<code>zone</code>，这些<code>zone</code>提供了一些基本的规则，也可以修改并保存规则。比如在工作单位时我切换到<code>home</code>Zone来屏蔽大多数让我分心的网络连接，然而回家后我需要娱乐娱乐，此时我将Zone改为<code>home</code>或者我信任我家里的网络并且改为了<code>trust</code>Zone，这样又可以悠闲的享受那些娱乐网站咯。</p><table><thead><tr><th align="left">Zone类型</th><th align="left"></th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">block</td><td align="left">封锁</td><td align="left">任何的连接都会被拒绝接收，并返回<code>icmp(6)-host-prohibited</code>拒绝信息</td></tr><tr><td align="left">dmz</td><td align="left">非军事区</td><td align="left">处于此区域的设备可以公开访问，可以有限制的进入内部网络，仅接收经过选择的连接</td></tr><tr><td align="left">drop</td><td align="left">抛弃</td><td align="left">接收到的任何连接都会被悄无声息的抛弃掉，不返回任何相应，仅允许对外发出的连接</td></tr><tr><td align="left">external</td><td align="left">外部</td><td align="left">不信任来自网络的所有连接，仅接收经过选择的连接</td></tr><tr><td align="left">home</td><td align="left">家庭区</td><td align="left">用于家庭网络。信任网络中的大多数连接，仅接收经过选择的连接</td></tr><tr><td align="left">internal</td><td align="left">内部</td><td align="left">与home提供的默认规则相同</td></tr><tr><td align="left">public</td><td align="left">公共</td><td align="left">不能相信网络内的其他计算机不会对您的计算机造成危害，仅接收经过选择的连接</td></tr><tr><td align="left">trust</td><td align="left">信任</td><td align="left">可以接受任何的网络连接</td></tr><tr><td align="left">work</td><td align="left">工作</td><td align="left">与public提供的默认规则相同</td></tr></tbody></table><p>上面的所有Zones每个网络接口可以使用一个Zone作为当前Zone。当接入网络连接后，<code>NetWorkManager</code>将被分配为你设定好的默认Zone网络区，<code>firewalld</code>默认的网络区为<code>public</code>。</p><h1 id="2-安装firewalld防火墙"><a href="#2-安装firewalld防火墙" class="headerlink" title="2. 安装firewalld防火墙"></a>2. 安装<code>firewalld</code>防火墙</h1><p>安装<code>firewalld</code>需要以root用户身份执行下面的命令，并且执行<code>firewalld</code>命令时也要使用root用户身份执行。</p><p><code>dnf install firewalld</code></p><p>如果你安装了系统图形界面，并且也想使用图形化工具来管理<code>firewalld</code>，请执行如下命令。</p><p><code>dnf install firewall-config</code></p><p><strong>但是本文中不会涉及到使用图形化工具配置<code>firewalld</code>防火墙</strong></p><h2 id="2-1-启动防火墙"><a href="#2-1-启动防火墙" class="headerlink" title="2.1. 启动防火墙"></a>2.1. 启动防火墙</h2><p>设置<code>firewalld</code>防火墙为默认防火墙并随着系统启动服务</p><p><code>systemctl enable firewalld</code></p><p>启动防火墙</p><p><code>systemctl start firewalld</code></p><blockquote><p>如果对<code>systemctl</code>命令不了解，可以在浏览<a href="https://blog.yeefire.com/2020/02/21/Linux-%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B%E5%92%8C%E6%8E%A7%E5%88%B6%E6%9C%8D%E5%8A%A1/">守护进程和控制服务</a>相关博文。</p></blockquote><h2 id="2-2-检查防火墙是否运行"><a href="#2-2-检查防火墙是否运行" class="headerlink" title="2.2. 检查防火墙是否运行"></a>2.2. 检查防火墙是否运行</h2><p><code>systemctl status firewalld.service</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl status firewalld.service</span><br><span class="line">● firewalld.service - firewalld - dynamic firewall daemon</span><br><span class="line">   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)</span><br><span class="line">   Active: active (running) since Wed 2020-02-05 08:03:45 CST; 10h ago</span><br><span class="line">     Docs: man:firewalld(1)</span><br><span class="line"> Main PID: 1539 (firewalld)</span><br><span class="line">    Tasks: 2 (<span class="built_in">limit</span>: 49252)</span><br><span class="line">   Memory: 35.7M</span><br><span class="line">   CGroup: /system.slice/firewalld.service</span><br><span class="line">           └─1539 /usr/libexec/platform-python -s /usr/sbin/firewalld --nofork --nopid</span><br><span class="line"></span><br><span class="line">Feb 05 08:03:44 centos8 systemd[1]: Starting firewalld - dynamic firewall daemon...</span><br><span class="line">Feb 05 08:03:45 centos8 systemd[1]: Started firewalld - dynamic firewall daemon.</span><br></pre></td></tr></table></figure><p>使用<code>firewall-cmd --state</code>也可以查看防火墙运行状态</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --state</span><br><span class="line">running <span class="comment"># 运行中</span></span><br></pre></td></tr></table></figure><h1 id="3-使用firewall-cmd进行管理"><a href="#3-使用firewall-cmd进行管理" class="headerlink" title="3. 使用firewall-cmd进行管理"></a>3. 使用<code>firewall-cmd</code>进行管理</h1><h2 id="3-1-Zone网络区管理"><a href="#3-1-Zone网络区管理" class="headerlink" title="3.1. Zone网络区管理"></a>3.1. Zone网络区管理</h2><h3 id="3-1-1-查看所有Zone网络区"><a href="#3-1-1-查看所有Zone网络区" class="headerlink" title="3.1.1. 查看所有Zone网络区"></a>3.1.1. 查看所有Zone网络区</h3><p><code>firewall-cmd --list-all-zones</code></p><p>列出所有Zone的配置规则</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --list-all-zones </span><br><span class="line">block</span><br><span class="line">  target: %%REJECT%%</span><br><span class="line">  icmp-block-inversion: no</span><br><span class="line">  interfaces: </span><br><span class="line">  sources: </span><br><span class="line">...</span><br></pre></td></tr></table></figure><p>还可以精简的只输出Zone的名字</p><p><code>firewall-cmd --get-zones</code></p><h3 id="3-1-2-查看firewalld默认Zone"><a href="#3-1-2-查看firewalld默认Zone" class="headerlink" title="3.1.2. 查看firewalld默认Zone"></a>3.1.2. 查看<code>firewalld</code>默认Zone</h3><p><code>firewall-cmd --get-default-zone</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --get-default-zone </span><br><span class="line">public  <span class="comment"># `firewalld`默认Zone为public</span></span><br></pre></td></tr></table></figure><h3 id="3-1-3-查询某个网络接口上使用的Zone"><a href="#3-1-3-查询某个网络接口上使用的Zone" class="headerlink" title="3.1.3. 查询某个网络接口上使用的Zone"></a>3.1.3. 查询某个网络接口上使用的Zone</h3><p><code>firewall-cmd --get-zone-of-interface=XXXX</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --get-zone-of-interface=ens32  <span class="comment"># 这里查看ens32网络接口当前的Zone</span></span><br><span class="line">public  <span class="comment"># 当前ens32接口上激活的是`public`Zone</span></span><br></pre></td></tr></table></figure><h3 id="3-1-4-查看已激活的Zone的网络接口列表"><a href="#3-1-4-查看已激活的Zone的网络接口列表" class="headerlink" title="3.1.4. 查看已激活的Zone的网络接口列表"></a>3.1.4. 查看已激活的Zone的网络接口列表</h3><p><code>firewall-cmd --get-active-zones</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --get-active-zones       </span><br><span class="line">public  </span><br><span class="line">  interfaces: ens32</span><br><span class="line"></span><br><span class="line"><span class="comment"># 可以看到，当前只有public网络区被激活。并且只有一个网络接口`ens32`使用这个Zone</span></span><br></pre></td></tr></table></figure><h3 id="3-1-5-查询某一个Zone的详细规则信息"><a href="#3-1-5-查询某一个Zone的详细规则信息" class="headerlink" title="3.1.5. 查询某一个Zone的详细规则信息"></a>3.1.5. 查询某一个Zone的详细规则信息</h3><p><code>firewall-cmd --zone=public --list-all</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --zone=public --list-all </span><br><span class="line">public (active)</span><br><span class="line">  target: default</span><br><span class="line">  icmp-block-inversion: no</span><br><span class="line">  interfaces: ens32</span><br><span class="line">  sources: </span><br><span class="line">  services: cockpit dhcpv6-client ssh</span><br><span class="line">  ports: 8096/tcp</span><br><span class="line">  protocols: </span><br><span class="line">  masquerade: no</span><br><span class="line">  forward-ports: </span><br><span class="line">  source-ports: </span><br><span class="line">  icmp-blocks: </span><br><span class="line">  rich rules: </span><br><span class="line"></span><br><span class="line">  <span class="comment"># 可以看到public网络区的规则信息：绑定了`ens32`网络接口，放行了cockpit dhcpv6-client ssh 服务的默认端口规则，还放行了8096的tcp端口。</span></span><br></pre></td></tr></table></figure><h3 id="3-1-6-修改当前默认的Zone网络区"><a href="#3-1-6-修改当前默认的Zone网络区" class="headerlink" title="3.1.6. 修改当前默认的Zone网络区"></a>3.1.6. 修改当前默认的Zone网络区</h3><p>比如设置默认网络区为<code>public</code>，更改会立即生效。此时此刻，所有接口上默认绑定的Zone网络区都会切换到新的这个<code>public</code>Zone网络区上。</p><p><code>firewall-cmd --set-default-zone=public</code></p><h3 id="3-1-7-修改网络接口上的Zone网络区"><a href="#3-1-7-修改网络接口上的Zone网络区" class="headerlink" title="3.1.7. 修改网络接口上的Zone网络区"></a>3.1.7. 修改网络接口上的Zone网络区</h3><p>如果有许多网络接口，要更改当前<code>ens32</code>网络接口绑定的Zone网络区为<code>home</code>，可以执行如下命令。</p><p><code>firewall-cmd --zone=home --change-interface=ens32</code></p><h3 id="3-1-8-删除绑定在网络接口上的Zone网络区"><a href="#3-1-8-删除绑定在网络接口上的Zone网络区" class="headerlink" title="3.1.8. 删除绑定在网络接口上的Zone网络区"></a>3.1.8. 删除绑定在网络接口上的Zone网络区</h3><p>如果你不想让某以网络接口绑定到任何的网络区上，你可以执行如下命令。但是这么做无异于裸奔在网络世界中！</p><p><code>firewall-cmd --remove-interface=ens32</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --remove-interface=ens32 </span><br><span class="line">You<span class="string">&#x27;re performing an operation over default zone (&#x27;</span>public<span class="string">&#x27;) </span></span><br><span class="line"><span class="string">but your connections/interfaces are in zone &#x27;</span>trusted<span class="string">&#x27; (see --get-active-zones)</span></span><br><span class="line"><span class="string">You most likely need to use --zone=trusted option.  # 由于没有加上--zone参数，这里给我们一个提示。</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">success</span></span><br></pre></td></tr></table></figure><blockquote><p>实际上任何一个网络接口都要绑定一个Zone网络区，如果将绑定的网络区删除，在<code>reload</code>firewall规则后会发现刚刚删除Zone的网络接口自动绑定到了<code>trusted</code>的Zone网络区，也就是说不受到防火墙的任何规则限制，比较危险。</p></blockquote><h2 id="3-2-重新加载firewalld防火墙"><a href="#3-2-重新加载firewalld防火墙" class="headerlink" title="3.2. 重新加载firewalld防火墙"></a>3.2. 重新加载<code>firewalld</code>防火墙</h2><h3 id="3-2-1-不中断用户连接"><a href="#3-2-1-不中断用户连接" class="headerlink" title="3.2.1. 不中断用户连接"></a>3.2.1. 不中断用户连接</h3><p>通常在对规则添加<code>--permanent</code>永久生效的选项后，规则不会立即生效，需要重新加载防火墙后配置的永久规则才会生效。在不中断用户现有的连接的情况下，建议使用<code>firewall-cmd --reload</code>来重新加载防火墙。</p><p><code>firewall-cmd --reload</code></p><h3 id="3-2-2-完全重载防火墙，并断开现有的用户连接"><a href="#3-2-2-完全重载防火墙，并断开现有的用户连接" class="headerlink" title="3.2.2. 完全重载防火墙，并断开现有的用户连接"></a>3.2.2. 完全重载防火墙，并断开现有的用户连接</h3><p>通常在<code>firewalld</code>防火墙出现问题时才会使用这种方式重载防火墙，这种方式会断开现有的网络连接，即丢失状态信息！</p><p><code>firewall-cmd --complete-reload</code></p><h2 id="3-3-打开-关闭防火墙端口-放行端口"><a href="#3-3-打开-关闭防火墙端口-放行端口" class="headerlink" title="3.3. 打开/关闭防火墙端口(放行端口)"></a>3.3. 打开/关闭防火墙端口(放行端口)</h2><p>如果本地需要开放一个端口供外部访问，那么你可以将这个端口添加到某一网络区的放行端口规则中。</p><h3 id="3-3-1-打开防火墙端口-放行端口"><a href="#3-3-1-打开防火墙端口-放行端口" class="headerlink" title="3.3.1. 打开防火墙端口(放行端口)"></a>3.3.1. 打开防火墙端口(放行端口)</h3><p><code>firewall-cmd  --add-port=portid[-portid]/protocol [--permanent] [--zone=zone]</code></p><p>参数(portid[-portid]):要开放的端口号，如果是一个范围则使用<code>10000-12000</code>表达一个范围。</p><p>参数(protocol):<span class="exturl" data-url="aHR0cHM6Ly93d3cuY25ibG9ncy5jb20veXN1d2FuZ3FpYW5nL3AvMTE0ODU2NDYuaHRtbA==" title="https://www.cnblogs.com/ysuwangqiang/p/11485646.html">TCP/UDP协议<i class="fa fa-external-link"></i></span></p><p>可选参数(zone):将规则添加到哪个Zone网络区中，如果缺省该参数则添加到默认Zone网络区中。</p><p>可选选项(–permanent):规则永久保存，重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效，但是重新加载防火墙后规则会<strong>失效</strong>。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --add-port=6000-7000/tcp --permanent --zone=public <span class="comment"># 在public网络区下放行6000~7000之间TCP通信协议的网络端口(闭区间)，规则永久保存并且在下一次重新加载防火墙后生效。</span></span><br><span class="line">success</span><br><span class="line"></span><br><span class="line">firewall-cmd --zone=public --list-all <span class="comment"># 检查修改后的public网络区的规则，发现并没有新添加的放行端口规则，说明规则还没有生效，需要重新加在防火墙。</span></span><br><span class="line">public (active)</span><br><span class="line">  target: default</span><br><span class="line">  icmp-block-inversion: no</span><br><span class="line">  interfaces: ens32</span><br><span class="line">  sources: </span><br><span class="line">  services: cockpit dhcpv6-client http https ssh</span><br><span class="line">  ports: 8096/tcp</span><br><span class="line">  protocols: </span><br><span class="line">  masquerade: no</span><br><span class="line">  forward-ports: </span><br><span class="line">  source-ports: </span><br><span class="line">  icmp-blocks: </span><br><span class="line">  rich rules: </span><br><span class="line"></span><br><span class="line"></span><br><span class="line">firewall-cmd --reload <span class="comment"># 重新加载防火墙</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --list-all --zone=public <span class="comment"># 再次检查规则是否生效。发现规则已生效。</span></span><br><span class="line">public</span><br><span class="line">  target: default</span><br><span class="line">  icmp-block-inversion: no</span><br><span class="line">  interfaces: </span><br><span class="line">  sources: </span><br><span class="line">  services: cockpit dhcpv6-client http https ssh</span><br><span class="line">  ports: 8096/tcp 6000-7000/tcp</span><br><span class="line">  protocols: </span><br><span class="line">  masquerade: no</span><br><span class="line">  forward-ports: </span><br><span class="line">  source-ports: </span><br><span class="line">  icmp-blocks: </span><br><span class="line">  rich rules: </span><br></pre></td></tr></table></figure><p>下面在默认的网络区内永久放行单个TCP端口</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --add-port=6000/tcp --permanent <span class="comment"># 这里没有添加`--zone`的选项和参数，会自动添加到默认网络区中。</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --reload 重新加载防火墙，使规则生效。</span><br></pre></td></tr></table></figure><h3 id="3-3-2-关闭防火墙端口-关闭端口"><a href="#3-3-2-关闭防火墙端口-关闭端口" class="headerlink" title="3.3.2. 关闭防火墙端口(关闭端口)"></a>3.3.2. 关闭防火墙端口(关闭端口)</h3><p>刚刚已经将端口放行，并且暴露在外。如果需要这个端口的服务不再使用，出于安全考虑你可以将这个端口从放行规则中删除掉。</p><p><code>firewall-cmd --remove-port=portid[-portid]/protocol [--permanent] [--zone=zone] </code></p><p>参数(–remove-port=portid[-portid]/protocol):你要移除的端口号/端口范围，注意表明是TCP协议还是UDP协议哦。和你添加的时候一样，如果添加时你写的是一个端口范围，那么删除时只能将全部的端口范围删除掉，不能只删除端口范围中一部分端口。</p><p>可选参数(–zone=zone)：关闭指定网络区中的端口，如果缺省该参数，则从默认的网络区中删除端口。</p><p>可选选项(–permanent)：规则永久保存，重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效，但是重新加载防火墙后规则会<strong>失效</strong>。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --remove-port=8080/tcp --permanent <span class="comment">#关闭默认Zone网络区开放的TCP8080端口</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --remove-port=1000-2000/udp --zone=public --permanent  <span class="comment">#永久关闭在public网络区下开放的UDP1000-2000端口。</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="3-4-放行-关闭防火墙某一服务-放行服务"><a href="#3-4-放行-关闭防火墙某一服务-放行服务" class="headerlink" title="3.4. 放行/关闭防火墙某一服务(放行服务)"></a>3.4. 放行/关闭防火墙某一服务(放行服务)</h2><p>firewalld中存储了常见服务的默认端口信息，如果你的服务没有更改过默认的端口号，那么可以直接使用<code>firewald</code>放行服务，它会根据默认规则，自动放行一个或一组此服务需要的端口。只需要管理员来记忆服务名就好咯！</p><h3 id="3-4-1-查看所有支持的服务"><a href="#3-4-1-查看所有支持的服务" class="headerlink" title="3.4.1. 查看所有支持的服务"></a>3.4.1. 查看所有支持的服务</h3><p><code>firewall-cmd --get-services</code></p><p>你能看到所有firewald存储的默认服务端口号，如果此时你需要开启某一服务的端口就不需要记他们默认的端口号了，试试<code>firewall-cmd --add-service=XXXX</code>。</p><h3 id="3-4-2-查询服务端口详细信息"><a href="#3-4-2-查询服务端口详细信息" class="headerlink" title="3.4.2. 查询服务端口详细信息"></a>3.4.2. 查询服务端口详细信息</h3><p>刚才查询到了所有支持的服务，那firewalld给我们提供的默认服务的端口号究竟是啥呢？</p><p><code>firewall-cmd --permanent --service=https --get-port</code></p><p>返回<code>443/tcp</code>。</p><h3 id="3-4-3-放行服务端口"><a href="#3-4-3-放行服务端口" class="headerlink" title="3.4.3. 放行服务端口"></a>3.4.3. 放行服务端口</h3><p><code>firewall-cmd --add-service=service [--permanent] [--zone=zone]  [--timeout=timeval]</code></p><p>参数(–add-service):要放行的服务名，如ssh、http、https。</p><p>可选参数(–zone=zone)：将此规则添加到网络区，如果缺省该参数，添加到默认网络区内。</p><p>可选参数(–timeout=timeval)：临时生效时间，不可与<code>--permanent</code>连用。表达方式可以是<code>--timeout=[100s | 100m | 100h]</code>。(timeval is either a number (of seconds) or number followed by one of characters s(seconds), m(minutes), h(hours))</p><p>可选选项(–permanent)：规则永久保存，重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效，但是重新加载防火墙后规则会<strong>失效</strong>。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --add-service=https --permanent  <span class="comment">#永久放行在默认网络区内的https(443端口)服务</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --add-service=https --<span class="built_in">timeout</span>=1h <span class="comment">#临时放行在默认网络区内的https服务1小时</span></span><br><span class="line"></span><br><span class="line">firewwall-cmd --add-service=https --zone=home --permanent <span class="comment">#永久放行在home网络区中的https服务</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><h3 id="3-4-4-关闭服务端口"><a href="#3-4-4-关闭服务端口" class="headerlink" title="3.4.4. 关闭服务端口"></a>3.4.4. 关闭服务端口</h3><p>如果关闭某一服务所对应的端口，那么将会时该服务无法对外部提供服务，请确定好删除的服务名，以免影响业务的正常服务！</p><p>你可以通过<code>firewall-cmd --list-all</code>查看默认网络区下，当前开放了哪些服务与规则，确保在关闭之前，这些服务和端口是开放的状态。</p><p><code>firewall-cmd --remove-service=https [--permanent] [--zone=zone]</code></p><p>参数与规则与关闭端口类似，在此不再赘述。</p><h2 id="3-5-端口转发"><a href="#3-5-端口转发" class="headerlink" title="3.5. 端口转发"></a>3.5. 端口转发</h2><p>端口转发可以将到达某一端口的数据包转发到本机或其他机器上另一个的一个端口上。使用端口转发功能需要现开启<code>firewalld</code>的IP伪装功能。</p><p>使用<code>firewall-cmd --list-forward-ports</code>可以查询所有端口转发规则。</p><h3 id="3-5-1-开启IP伪装"><a href="#3-5-1-开启IP伪装" class="headerlink" title="3.5.1. 开启IP伪装"></a>3.5.1. 开启IP伪装</h3><p>防火墙可以实现IP伪装，默认为关闭状态。可以使用<code>firewall-cmd --query-masquerade</code>进行查询。</p><p><code>firewall-cmd --query-masquerade</code>查询默认Zone网络区内的ip伪装功能是否开启。</p><p>返回<code>no</code>则为关闭状态。</p><p><code>firewall-cmd --add-masquerade [--permanent] [--zone=zone] [--timeout=timeval]</code></p><p>参数(–add-masquerade):开放IP转发功能。</p><p>可选参数(–zone=zone)：将此规则添加到网络区，如果缺省该参数，添加到默认网络区内。</p><p>可选参数(–timeout=timeval)：临时生效时间，不可与<code>--permanent</code>连用。表达方式可以是<code>--timeout=[100s | 100m | 100h]</code>。</p><p>可选选项(–permanent)：规则永久保存，重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效，但是重新加载防火墙后规则会<strong>失效</strong>。</p><p>如果不需要IP地址伪装，使用下面的命令关闭。</p><p><code>firewall-cmd --remove-masquerade [--permanent] [--zone=zone]</code></p><h3 id="3-5-2-开启端口转发"><a href="#3-5-2-开启端口转发" class="headerlink" title="3.5.2. 开启端口转发"></a>3.5.2. 开启端口转发</h3><p>请确保在开启端口转发前已经开启IP伪装功能。如果需要<code>IPv6</code>的端口转发，请富规则方式配置。</p><p><code>firewall-cmd --add-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]] [--permanent] [--zone=zone] [--timeout=timeval]</code></p><p><strong>参数(–add-forward-port):</strong></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">portid:本机端口号</span><br><span class="line">protocal:UDP/TCP协议，此处只能选择一个。</span><br><span class="line">[portid]:要转发到的端口。如果缺省该参数则默认与设置的本地端口一致。</span><br><span class="line">[address]:要转发到的地址。如果缺省该参数则默认为本机地址。</span><br></pre></td></tr></table></figure><p>可选选项(–permanent)：规则永久保存，重新加载防火墙后生效。如果缺省该参数则修改的规则立即生效，但是重新加载防火墙后规则会<strong>失效</strong>。</p><p>其他参数不再赘述。</p><p>下面是一些使用端口转发的案例：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --add-masquerade <span class="comment"># 开启IP伪装（转发到其他IP上时必须开启，仅转发本地端口则非必须开启）</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">firewall-cmd --add-forward-port=port=8888:proto=udp:toport=53 --permanent <span class="comment">#永久将本机默认网络区下的本地UDP8888端口转发到本地UDP53端口上。</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --add-forward-port=port=7777:proto=tcp:toport=6667:toaddr=192.168.1.160 --zone=public  <span class="comment">#临时在public网络区下将本机7777端口的TCP流量转发到192.168.1.160上的6667端口上，重载防火墙后失效</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --add-forward-port=port=7777:proto=tcp:toport=6667:toaddr=192.168.1.160 --<span class="built_in">timeout</span>=100s <span class="comment">#临时在100秒内将默认网络区下将本机7777端口的TCP流量转发到192.168.1.160上的6667端口上，超时或重载防火墙后失效。</span></span><br></pre></td></tr></table></figure><h3 id="3-5-3-关闭端口转发"><a href="#3-5-3-关闭端口转发" class="headerlink" title="3.5.3. 关闭端口转发"></a>3.5.3. 关闭端口转发</h3><p>使用 <code>firewall-cmd --list-forward-ports </code>查询当前已加载所有的端口转发规则</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --list-forward-ports <span class="comment">#查询当前已加载所有的端口转发规则</span></span><br><span class="line">port=8888:proto=udp:toport=53:toaddr= <span class="comment">#发现有一个转发规则</span></span><br></pre></td></tr></table></figure><p>当不需要这个规则时我们可以删除它。</p><p><code>firewall-cmd --remove-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]] [--permanent] [--zone=zone] [--timeout=timeval]</code></p><p>参数部分不再解释。与添加时的意思相对应。可以先查询规则，确定好你要删除的规则后将规则填写到<code>--remove-forward-port=</code>后即可。</p><blockquote><p>注意：如果你添加端口转发规则时，选择了<code>--permanet</code>永久生效,那么在永久删除时也要添加上<code>--permanet</code>选项。除非是想临时取消此这条规则。</p></blockquote><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --list-forward-ports <span class="comment">#查询当前已加载所有的端口转发规则</span></span><br><span class="line">port=8888:proto=udp:toport=53:toaddr= <span class="comment">#发现有一个转发规则，现在删除此规则。</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --remove-forward-port=port=8888:proto=udp:toport=53:toaddr=  --permanet  <span class="comment"># 在默认的网络区内永久删除这条转发规则。</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --reload <span class="comment">#使修改生效</span></span><br></pre></td></tr></table></figure><h1 id="4-使用富规则配置复杂firewalld策略"><a href="#4-使用富规则配置复杂firewalld策略" class="headerlink" title="4. 使用富规则配置复杂firewalld策略"></a>4. 使用富规则配置复杂<code>firewalld</code>策略</h1><p>通过<code>rich language</code>语法，可以建立复杂防火墙规则。并且还可以永久生效。这种语言使用关键词值，是 <code>iptables</code> 工具的抽象表示。</p><h2 id="4-1-富规则的命令格式"><a href="#4-1-富规则的命令格式" class="headerlink" title="4.1. 富规则的命令格式"></a>4.1. 富规则的命令格式</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --add-rich-rule=<span class="string">&#x27;rule&#x27;</span> [--permanent] [--zone=zone]  [--<span class="built_in">timeout</span>=timeval]</span><br><span class="line"></span><br><span class="line"><span class="comment"># rule规则详细参数</span></span><br><span class="line">rule [family=<span class="string">&quot;&lt;rule family&gt;&quot;</span>]</span><br><span class="line">[ <span class="built_in">source</span> address=<span class="string">&quot;&lt;address&gt;&quot;</span> [invert=<span class="string">&quot;True&quot;</span>] ]</span><br><span class="line">[ destination address=<span class="string">&quot;&lt;address&gt;&quot;</span> [invert=<span class="string">&quot;True&quot;</span>] ]</span><br><span class="line">[ &lt;element&gt; ]</span><br><span class="line">[ <span class="built_in">log</span> [prefix=<span class="string">&quot;&lt;prefix text&gt;&quot;</span>] [level=<span class="string">&quot;&lt;log level&gt;&quot;</span>] [<span class="built_in">limit</span></span><br><span class="line">value=<span class="string">&quot;rate/duration&quot;</span>] ] [ audit ]</span><br><span class="line">[ accept|reject|drop ]</span><br></pre></td></tr></table></figure><p>一条富规则绑定在一个Zone网络区下，一个网络区可以绑定多条富规则。如果几个规则相互影响或者冲突，则匹配第一条规则。</p><h2 id="4-2-理解多规则命令"><a href="#4-2-理解多规则命令" class="headerlink" title="4.2. 理解多规则命令"></a>4.2. 理解多规则命令</h2><h3 id="4-2-1-family"><a href="#4-2-1-family" class="headerlink" title="4.2.1. family"></a>4.2.1. family</h3><p><code>[family=&quot;&lt;rule family&gt;&quot;]</code></p><p><code>family rule</code>可以是IPv4或者IPv6，将对选择的流量进行限制。此处的参数可以省略不填写，但是<code>source</code>或者<code>destination</code>中出现了IP地址，则必须填写并指定<code>rule</code>。省略则同时对IPv6和IPv4进行限制。</p><h3 id="4-2-2-source"><a href="#4-2-2-source" class="headerlink" title="4.2.2. source"></a>4.2.2. source</h3><p><code>[ source [not] address=&quot;&lt;address&gt;&quot; ]</code></p><p>源地址，不支持主机名。源地址可以是一个IPv4地址或IPv6地址或者一个网络地址段。可以使用<code>not</code>写在地址前来<strong>反转</strong>你的地址所表达的限定范围。</p><h3 id="4-2-3-destination"><a href="#4-2-3-destination" class="headerlink" title="4.2.3. destination"></a>4.2.3. destination</h3><p><code>[ destination [not] address=&quot;&lt;address&gt;&quot; ]</code></p><p>限制目标地址，与源地址使用相同的表示方法，同样支持<code>not</code>反转。</p><h3 id="4-2-4-element"><a href="#4-2-4-element" class="headerlink" title="4.2.4. element"></a>4.2.4. element</h3><p><code>element</code>为限定的规则。该项只能为下面的几个要素之一，不能将他们同时进行应用。根据你的需求选取一个要素进行限制。</p><h4 id="4-2-4-1-service服务名称"><a href="#4-2-4-1-service服务名称" class="headerlink" title="4.2.4.1. service服务名称"></a>4.2.4.1. service服务名称</h4><p>此处填写<code>firewalld</code>默认提供的服务名称。获取firewalld默认提供的服务清单可以使用此命令<code>firewall-cmd --get-services</code>，也可以看上面的3.4章节了解firewalld内置服务。</p><p><code>service name=&quot;server&quot;</code></p><h4 id="4-2-4-2-port端口"><a href="#4-2-4-2-port端口" class="headerlink" title="4.2.4.2. port端口"></a>4.2.4.2. port端口</h4><p><code>port port=number_or_range protocol=&quot;tcp | udp&quot;</code></p><p><code>number_or_range</code>端口既可以是一个端口号，也可以是一个端口范围，如<code>6000-7111</code>。<code>protocol</code>协议可以指定为<code>tcp</code>或<code>udp</code>。</p><h4 id="4-2-4-3-protocol协议"><a href="#4-2-4-3-protocol协议" class="headerlink" title="4.2.4.3. protocol协议"></a>4.2.4.3. protocol协议</h4><p><code>protocol value=protocol_name_or_ID</code></p><p><code>protocol_name_or_ID</code>可以是一个协议名，也可以是协议ID，可以在<code>/etc/protocols</code>文件中查看预设支持的协议。</p><h4 id="4-2-4-4-icmp-block阻断"><a href="#4-2-4-4-icmp-block阻断" class="headerlink" title="4.2.4.4. icmp-block阻断"></a>4.2.4.4. icmp-block阻断</h4><p><code>icmp-block name=icmptype_name</code></p><p><code>icmptype_name</code>为特定的icmp类型名，使用<code>icmp-block</code>元素可以禁止一个或多个ICMP类型。所有的ICMP类型可以使用<code>firewall-cmd --get-icmptypes</code>命令来查看。</p><h4 id="4-2-4-5-icmp-type类型"><a href="#4-2-4-5-icmp-type类型" class="headerlink" title="4.2.4.5. icmp-type类型"></a>4.2.4.5. icmp-type类型</h4><p>此处可以为所选的icmp类型指定动作。</p><h4 id="4-2-4-6-masquerade-IP地址伪装"><a href="#4-2-4-6-masquerade-IP地址伪装" class="headerlink" title="4.2.4.6. masquerade IP地址伪装"></a>4.2.4.6. masquerade IP地址伪装</h4><p>规则里的IP伪装。用源地址而不是目的地址来把伪装限制在一个范围内。</p><h4 id="4-2-4-7-forward-port端口转发"><a href="#4-2-4-7-forward-port端口转发" class="headerlink" title="4.2.4.7 forward-port端口转发"></a>4.2.4.7 forward-port端口转发</h4><p><code>forward-port port=number_or_range protocol=protocol to-port=number_or_range to-addr=address</code></p><p><code>number_or_range</code>可以是一个端口号或者端口范围。<code>protocol</code>UDP/TCP协议。<code>address</code>目的IP地址。</p><p>与<code>firewall-cmd --add-forward-port</code>语法相近。如果省略<code>address</code>，则为本地端口转发。</p><h3 id="4-2-5-log日志"><a href="#4-2-5-log日志" class="headerlink" title="4.2.5. log日志"></a>4.2.5. log日志</h3><p><code>log [prefix=prefix text] [level=log level] limit value=rate/duration</code></p><p>记录访问请求。你可以指定日志记录等级，<code>log level</code>记录等级可以是 emerg,alert,crit,error,warning,notice,info 或者 debug 中的一个。</p><p><code>rate/duration</code>,rate为次数，duration是持续时间，单位可以是s,m,h,d。最大限定值是 1/d ，意为每天最多有一条日志进入。</p><h3 id="4-2-6-Action动作-accept-reject-drop"><a href="#4-2-6-Action动作-accept-reject-drop" class="headerlink" title="4.2.6. Action动作(accept|reject|drop)"></a>4.2.6. Action动作(accept|reject|drop)</h3><p>使用<code>accept</code>所有新的连接请求都会被允许。使用<code>reject</code>连接将被拒绝，对方将会收到一个拒绝信息。使用<code>drop</code>所有数据包会被丢弃，并且不会返回任何消息给对方。</p><h2 id="4-3-删除富规则"><a href="#4-3-删除富规则" class="headerlink" title="4.3. 删除富规则"></a>4.3. 删除富规则</h2><p>删除富规则与删除端口转发类似，直接将添加富规则的语言规则填写到<code>--remove-rich-rule</code>选项里。首先应该查询目前所有生效的富规则。</p><h3 id="4-3-1-查询所有富规则"><a href="#4-3-1-查询所有富规则" class="headerlink" title="4.3.1 查询所有富规则"></a>4.3.1 查询所有富规则</h3><p><code>firewall-cmd --list-rich-rules</code></p><p>之后会以一行行的形式返回每一条富规则。</p><h3 id="4-3-2-删除富规则"><a href="#4-3-2-删除富规则" class="headerlink" title="4.3.2 删除富规则"></a>4.3.2 删除富规则</h3><p><code>firewall-cmd --remove-rich-rule=&#39;rule&#39; [--permanent]</code></p><p>将查询到要删除的富规则复制到<code>--remove-rich-rule=</code>参数后面，以防止输入出错。如果想永久删除，那么您需要添加<code>--permanent</code>选项以永久保存。如果你在添加富规则时仅仅是临时生效，那么不应该填写此选项。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">firewall-cmd --list-rich-rules  <span class="comment"># 显示所有生效的富规则</span></span><br><span class="line">rule icmp-type name=<span class="string">&quot;echo-request&quot;</span> drop <span class="comment"># 返回一条富规则</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --remove-rich-rule=<span class="string">&#x27;rule icmp-type name=&quot;echo-request&quot; drop&#x27;</span> --permanent <span class="comment"># 永久删除该条富规则</span></span><br><span class="line">success <span class="comment">#返回结果</span></span><br><span class="line"></span><br><span class="line">firewall-cmd --reload <span class="comment">#重载防火墙规则后生效</span></span><br></pre></td></tr></table></figure><h2 id="4-4-富规则配置实例"><a href="#4-4-富规则配置实例" class="headerlink" title="4.4. 富规则配置实例"></a>4.4. 富规则配置实例</h2><h3 id="4-4-1-阻止echo-request请求"><a href="#4-4-1-阻止echo-request请求" class="headerlink" title="4.4.1 阻止echo-request请求"></a>4.4.1 阻止<code>echo-request</code>请求</h3><p>阻止ICMP协议中的<code>echo-request</code>也就是我们常说的禁止Ping。</p><p><code>firewall-cmd --add-rich-rule=&#39;rule icmp-type name=&quot;echo-request&quot; drop&#39; --permanent</code></p><p>使用Drop动作可以伪装成无法联系到主机的效果。</p><h3 id="4-4-2-拒绝某一IP-段-访问本机ftp服务"><a href="#4-4-2-拒绝某一IP-段-访问本机ftp服务" class="headerlink" title="4.4.2 拒绝某一IP(段)访问本机ftp服务"></a>4.4.2 拒绝某一IP(段)访问本机ftp服务</h3><p><code>firewall-cmd --add-rich-rule=&#39;rule family=&quot;ipv4&quot; source address=&quot;10.0.1.0/24&quot; service name=&quot;ftp&quot; reject&#39; --permanent</code></p><p>永久拒绝IP来自10.0.1.*的客户访问本机FTP服务器。</p><p><code>firewall-cmd --add-rich-rule=&#39;rule family=&quot;ipv6&quot; source address=&quot;2409:8a18:600:b250::239&quot; service name=&quot;ssh&quot; log limit value=&quot;1/m&quot; drop&#39; --permanent</code></p><p>永久拒绝来自2409:8a18:600:b250::239的用户远程登录到本机SSH服务器，并且以每分钟一次的速率进行日志记录。</p><h3 id="4-4-3-使用富规则进行端口转发"><a href="#4-4-3-使用富规则进行端口转发" class="headerlink" title="4.4.3 使用富规则进行端口转发"></a>4.4.3 使用富规则进行端口转发</h3><p>永久对当IP来自为192.168.1.175用户访问本机22端口时，将流量转发至192.168.1.3的22号tcp端口上。注意需要开启IP地址伪装，重载防火墙规则后生效。</p><p><code>firewall-cmd --add-rich-rule=&#39;rule family=&quot;ipv4&quot; source address=&quot;192.168.1.175&quot; forward-port port=&quot;22&quot; protocol=&quot;tcp&quot; to-addr=&quot;192.168.1.3&quot;&#39; --permanent</code></p><p>开启IP地址伪装，否则无法将流量转发到其他IP上。</p><p><code>firewall-cmd --add-masquerade --permanent</code></p><h3 id="4-4-4-丢弃来自某IP域的所有连接"><a href="#4-4-4-丢弃来自某IP域的所有连接" class="headerlink" title="4.4.4 丢弃来自某IP域的所有连接"></a>4.4.4 丢弃来自某IP域的所有连接</h3><p><code>firewall-cmd --add-rich-rule=&#39;rule family=&quot;ipv4&quot; source address=&quot;172.23.0.0/16&quot; drop&#39;</code></p><p>丢弃来自<code>172.23.0.0/16</code>网段下的所有连接。</p><h2 id="基本内容基本已经完成，后续会继续更新细节的地方。不过更新速度可能会慢一些了。如果第一时间想要得到最新更新消息可以加入我的电报群！同时如果您发现了文章中的任何处存在错误，请您务必与我联系，我会及时更改防止继续误导别人，在此表示十分感谢！"><a href="#基本内容基本已经完成，后续会继续更新细节的地方。不过更新速度可能会慢一些了。如果第一时间想要得到最新更新消息可以加入我的电报群！同时如果您发现了文章中的任何处存在错误，请您务必与我联系，我会及时更改防止继续误导别人，在此表示十分感谢！" class="headerlink" title="基本内容基本已经完成，后续会继续更新细节的地方。不过更新速度可能会慢一些了。如果第一时间想要得到最新更新消息可以加入我的电报群！同时如果您发现了文章中的任何处存在错误，请您务必与我联系，我会及时更改防止继续误导别人，在此表示十分感谢！"></a>基本内容基本已经完成，后续会继续更新细节的地方。不过更新速度可能会慢一些了。如果第一时间想要得到最新更新消息可以加入我的电报群！同时如果您发现了文章中的任何处存在错误，请您务必与我联系，我会及时更改防止继续误导别人，在此表示十分感谢！</h2><h2 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h2><p><span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3J1aXNlbmFiYy9hcnRpY2xlL2RldGFpbHMvODc5MjA1Mjg=" title="https://blog.csdn.net/ruisenabc/article/details/87920528">《netfilter 理解》——CSDN<i class="fa fa-external-link"></i></span></p><p><span class="exturl" data-url="aHR0cHM6Ly93d3cuY25ibG9ncy5jb20veXN1d2FuZ3FpYW5nL3AvMTE0ODU2NDYuaHRtbA==" title="https://www.cnblogs.com/ysuwangqiang/p/11485646.html">《TCP和UDP区别》——博客园<i class="fa fa-external-link"></i></span></p><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群:<br><span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog(Telegram)<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p><hr>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Linux的Firewalld防火墙&quot;&gt;&lt;a href=&quot;#Linux的Firewalld防火墙&quot; class=&quot;headerlink&quot; title=&quot;Linux的Firewalld防火墙&quot;&gt;&lt;/a&gt;Linux的Firewalld防火墙&lt;/h1&gt;&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#linux%E7%9A%84firewalld%E9%98%B2%E7%81%AB%E5%A2%99&quot;&gt;Linux的Firewalld防火墙&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#1-firewalld%E9%98%B2%E7%81%AB%E5%A2%99%E7%AE%80%E4%BB%8B&quot;&gt;1. &lt;code&gt;firewalld&lt;/code&gt;防火墙简介&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#11-firewalld%E4%B8%8Eiptables%E7%9A%84%E4%B8%BB%E8%A6%81%E5%8C%BA%E5%88%AB&quot;&gt;1.1. &lt;code&gt;firewalld&lt;/code&gt;与&lt;code&gt;iptables&lt;/code&gt;的主要区别&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#12-%E5%AF%B9firewalldzone%E7%BD%91%E7%BB%9C%E5%8C%BA%E7%9A%84%E7%90%86%E8%A7%A3&quot;&gt;1.2. 对&lt;code&gt;firewalld&lt;/code&gt;Zone网络区的理解&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85firewalld%E9%98%B2%E7%81%AB%E5%A2%99&quot;&gt;2. 安装&lt;code&gt;firewalld&lt;/code&gt;防火墙&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E5%90%AF%E5%8A%A8%E9%98%B2%E7%81%AB%E5%A2%99&quot;&gt;2.1. 启动防火墙&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E6%A3%80%E6%9F%A5%E9%98%B2%E7%81%AB%E5%A2%99%E6%98%AF%E5%90%A6%E8%BF%90%E8%A1%8C&quot;&gt;2.2. 检查防火墙是否运行&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E4%BD%BF%E7%94%A8firewall-cmd%E8%BF%9B%E8%A1%8C%E7%AE%A1%E7%90%86&quot;&gt;3. 使用&lt;code&gt;firewall-cmd&lt;/code&gt;进行管理&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-zone%E7%BD%91%E7%BB%9C%E5%8C%BA%E7%AE%A1%E7%90%86&quot;&gt;3.1. Zone网络区管理&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#311-%E6%9F%A5%E7%9C%8B%E6%89%80%E6%9C%89zone%E7%BD%91%E7%BB%9C%E5%8C%BA&quot;&gt;3.1.1. 查看所有Zone网络区&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#312-%E6%9F%A5%E7%9C%8Bfirewalld%E9%BB%98%E8%AE%A4zone&quot;&gt;3.1.2. 查看&lt;code&gt;firewalld&lt;/code&gt;默认Zone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#313-%E6%9F%A5%E8%AF%A2%E6%9F%90%E4%B8%AA%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E4%B8%8A%E4%BD%BF%E7%94%A8%E7%9A%84zone&quot;&gt;3.1.3. 查询某个网络接口上使用的Zone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#314-%E6%9F%A5%E7%9C%8B%E5%B7%B2%E6%BF%80%E6%B4%BB%E7%9A%84zone%E7%9A%84%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E5%88%97%E8%A1%A8&quot;&gt;3.1.4. 查看已激活的Zone的网络接口列表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#315-%E6%9F%A5%E8%AF%A2%E6%9F%90%E4%B8%80%E4%B8%AAzone%E7%9A%84%E8%AF%A6%E7%BB%86%E8%A7%84%E5%88%99%E4%BF%A1%E6%81%AF&quot;&gt;3.1.5. 查询某一个Zone的详细规则信息&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#316-%E4%BF%AE%E6%94%B9%E5%BD%93%E5%89%8D%E9%BB%98%E8%AE%A4%E7%9A%84zone%E7%BD%91%E7%BB%9C%E5%8C%BA&quot;&gt;3.1.6. 修改当前默认的Zone网络区&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#317-%E4%BF%AE%E6%94%B9%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E4%B8%8A%E7%9A%84zone%E7%BD%91%E7%BB%9C%E5%8C%BA&quot;&gt;3.1.7. 修改网络接口上的Zone网络区&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#318-%E5%88%A0%E9%99%A4%E7%BB%91%E5%AE%9A%E5%9C%A8%E7%BD%91%E7%BB%9C%E6%8E%A5%E5%8F%A3%E4%B8%8A%E7%9A%84zone%E7%BD%91%E7%BB%9C%E5%8C%BA&quot;&gt;3.1.8. 删除绑定在网络接口上的Zone网络区&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E9%87%8D%E6%96%B0%E5%8A%A0%E8%BD%BDfirewalld%E9%98%B2%E7%81%AB%E5%A2%99&quot;&gt;3.2. 重新加载&lt;code&gt;firewalld&lt;/code&gt;防火墙&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#321-%E4%B8%8D%E4%B8%AD%E6%96%AD%E7%94%A8%E6%88%B7%E8%BF%9E%E6%8E%A5&quot;&gt;3.2.1. 不中断用户连接&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#322-%E5%AE%8C%E5%85%A8%E9%87%8D%E8%BD%BD%E9%98%B2%E7%81%AB%E5%A2%99%E5%B9%B6%E6%96%AD%E5%BC%80%E7%8E%B0%E6%9C%89%E7%9A%84%E7%94%A8%E6%88%B7%E8%BF%9E%E6%8E%A5&quot;&gt;3.2.2. 完全重载防火墙，并断开现有的用户连接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E6%89%93%E5%BC%80%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99%E7%AB%AF%E5%8F%A3%E6%94%BE%E8%A1%8C%E7%AB%AF%E5%8F%A3&quot;&gt;3.3. 打开/关闭防火墙端口(放行端口)&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#331-%E6%89%93%E5%BC%80%E9%98%B2%E7%81%AB%E5%A2%99%E7%AB%AF%E5%8F%A3%E6%94%BE%E8%A1%8C%E7%AB%AF%E5%8F%A3&quot;&gt;3.3.1. 打开防火墙端口(放行端口)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#332-%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99%E7%AB%AF%E5%8F%A3%E5%85%B3%E9%97%AD%E7%AB%AF%E5%8F%A3&quot;&gt;3.3.2. 关闭防火墙端口(关闭端口)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-%E6%94%BE%E8%A1%8C%E5%85%B3%E9%97%AD%E9%98%B2%E7%81%AB%E5%A2%99%E6%9F%90%E4%B8%80%E6%9C%8D%E5%8A%A1%E6%94%BE%E8%A1%8C%E6%9C%8D%E5%8A%A1&quot;&gt;3.4. 放行/关闭防火墙某一服务(放行服务)&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#341-%E6%9F%A5%E7%9C%8B%E6%89%80%E6%9C%89%E6%94%AF%E6%8C%81%E7%9A%84%E6%9C%8D%E5%8A%A1&quot;&gt;3.4.1. 查看所有支持的服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#342-%E6%9F%A5%E8%AF%A2%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%A3%E8%AF%A6%E7%BB%86%E4%BF%A1%E6%81%AF&quot;&gt;3.4.2. 查询服务端口详细信息&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#343-%E6%94%BE%E8%A1%8C%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%A3&quot;&gt;3.4.3. 放行服务端口&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#344-%E5%85%B3%E9%97%AD%E6%9C%8D%E5%8A%A1%E7%AB%AF%E5%8F%A3&quot;&gt;3.4.4. 关闭服务端口&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91&quot;&gt;3.5. 端口转发&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#351-%E5%BC%80%E5%90%AFip%E4%BC%AA%E8%A3%85&quot;&gt;3.5.1. 开启IP伪装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#352-%E5%BC%80%E5%90%AF%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91&quot;&gt;3.5.2. 开启端口转发&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#353-%E5%85%B3%E9%97%AD%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91&quot;&gt;3.5.3. 关闭端口转发&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8%E5%AF%8C%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE%E5%A4%8D%E6%9D%82firewalld%E7%AD%96%E7%95%A5&quot;&gt;4. 使用富规则配置复杂&lt;code&gt;firewalld&lt;/code&gt;策略&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E5%AF%8C%E8%A7%84%E5%88%99%E7%9A%84%E5%91%BD%E4%BB%A4%E6%A0%BC%E5%BC%8F&quot;&gt;4.1. 富规则的命令格式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E7%90%86%E8%A7%A3%E5%A4%9A%E8%A7%84%E5%88%99%E5%91%BD%E4%BB%A4&quot;&gt;4.2. 理解多规则命令&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#421-family&quot;&gt;4.2.1. family&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#422-source&quot;&gt;4.2.2. source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#423-destination&quot;&gt;4.2.3. destination&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#424-element&quot;&gt;4.2.4. element&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#4241-service%E6%9C%8D%E5%8A%A1%E5%90%8D%E7%A7%B0&quot;&gt;4.2.4.1. service服务名称&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4242-port%E7%AB%AF%E5%8F%A3&quot;&gt;4.2.4.2. port端口&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4243-protocol%E5%8D%8F%E8%AE%AE&quot;&gt;4.2.4.3. protocol协议&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4244-icmp-block%E9%98%BB%E6%96%AD&quot;&gt;4.2.4.4. icmp-block阻断&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4245-icmp-type%E7%B1%BB%E5%9E%8B&quot;&gt;4.2.4.5. icmp-type类型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4246-masquerade-ip%E5%9C%B0%E5%9D%80%E4%BC%AA%E8%A3%85&quot;&gt;4.2.4.6. masquerade IP地址伪装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4247-forward-port%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91&quot;&gt;4.2.4.7 forward-port端口转发&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#425-log%E6%97%A5%E5%BF%97&quot;&gt;4.2.5. log日志&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#426-action%E5%8A%A8%E4%BD%9Cacceptrejectdrop&quot;&gt;4.2.6. Action动作(accept|reject|drop)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E5%88%A0%E9%99%A4%E5%AF%8C%E8%A7%84%E5%88%99&quot;&gt;4.3. 删除富规则&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#431-%E6%9F%A5%E8%AF%A2%E6%89%80%E6%9C%89%E5%AF%8C%E8%A7%84%E5%88%99&quot;&gt;4.3.1 查询所有富规则&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#432-%E5%88%A0%E9%99%A4%E5%AF%8C%E8%A7%84%E5%88%99&quot;&gt;4.3.2 删除富规则&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E5%AF%8C%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE%E5%AE%9E%E4%BE%8B&quot;&gt;4.4. 富规则配置实例&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#441-%E9%98%BB%E6%AD%A2echo-request%E8%AF%B7%E6%B1%82&quot;&gt;4.4.1 阻止&lt;code&gt;echo-request&lt;/code&gt;请求&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#442-%E6%8B%92%E7%BB%9D%E6%9F%90%E4%B8%80ip%E6%AE%B5%E8%AE%BF%E9%97%AE%E6%9C%AC%E6%9C%BAftp%E6%9C%8D%E5%8A%A1&quot;&gt;4.4.2 拒绝某一IP(段)访问本机ftp服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#443-%E4%BD%BF%E7%94%A8%E5%AF%8C%E8%A7%84%E5%88%99%E8%BF%9B%E8%A1%8C%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91&quot;&gt;4.4.3 使用富规则进行端口转发&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#444-%E4%B8%A2%E5%BC%83%E6%9D%A5%E8%87%AA%E6%9F%90ip%E5%9F%9F%E7%9A%84%E6%89%80%E6%9C%89%E8%BF%9E%E6%8E%A5&quot;&gt;4.4.4 丢弃来自某IP域的所有连接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;p&gt;使用防火墙可以对外部的数据包进行过滤和阻止，尽可能减少暴露在网络上的危险以保护系统安全。在&lt;code&gt;RHEL7&lt;/code&gt;系的Linux系统中，已经将&lt;code&gt;iptables&lt;/code&gt;防火墙管理工具使用&lt;code&gt;firewalld&lt;/code&gt;代替。这篇文章的所有案例在&lt;code&gt;RHEL8&lt;/code&gt;上成功执行，如果遇到了问题请尝试变通或者在底部评论区与我留言。噗！这是我第一次做标题党哈哈哈。&lt;/p&gt;
&lt;p&gt;更新日期：2020年3月4日(富规则配置举例、增加富规则中的&lt;code&gt;icmp-type&lt;/code&gt;过滤规则、优化了一些细节错误)。常见用法已经全部写在文章中，之后会不定期更新细节。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
    <category term="firewalld" scheme="https://blog.yeefire.com/tags/firewalld/"/>
    
  </entry>
  
  <entry>
    <title>Linux 查找系统中的文件</title>
    <link href="https://blog.yeefire.com/2020_02/Linux_find.html"/>
    <id>https://blog.yeefire.com/2020_02/Linux_find.html</id>
    <published>2020-02-21T13:50:17.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="查找系统中的文件"><a href="#查找系统中的文件" class="headerlink" title="查找系统中的文件"></a>查找系统中的文件</h1><p>使用<code>locate</code>和<code>find</code>即可实现在挂载的文件系统中搜索文件。</p><!-- TOC --><ul><li><a href="#%E6%9F%A5%E6%89%BE%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E6%96%87%E4%BB%B6">查找系统中的文件</a><ul><li><a href="#locate%E4%B8%8Efind%E4%BB%8B%E7%BB%8D"><code>locate</code>与<code>find</code>介绍</a><ul><li><a href="#locate%E5%91%BD%E4%BB%A4"><code>locate</code>命令</a></li><li><a href="#find%E5%91%BD%E4%BB%A4"><code>find</code>命令</a></li></ul></li><li><a href="#%E6%A0%B9%E6%8D%AE%E5%90%8D%E7%A7%B0%E6%9F%A5%E6%89%BE%E6%96%87%E4%BB%B6locate">根据名称查找文件<code>locate</code></a><ul><li><a href="#%E5%B8%B8%E7%94%A8%E9%80%89%E9%A1%B9">常用选项</a></li></ul></li><li><a href="#%E4%BD%BF%E7%94%A8find%E6%9F%A5%E6%89%BE%E6%96%87%E4%BB%B6">使用<code>find</code>查找文件</a><ul><li><a href="#%E5%B8%B8%E7%94%A8%E9%80%89%E9%A1%B9-1">常用选项</a><ul><li><a href="#name%E9%80%89%E9%A1%B9"><code>-name</code>选项：</a></li><li><a href="#iname%E9%80%89%E9%A1%B9"><code>-iname</code>选项：</a></li><li><a href="#user%E5%92%8C-group%E9%80%89%E9%A1%B9"><code>-user</code>和<code>-group</code>选项：</a></li></ul></li></ul></li></ul></li></ul><!-- /TOC --><h2 id="locate与find介绍"><a href="#locate与find介绍" class="headerlink" title="locate与find介绍"></a><code>locate</code>与<code>find</code>介绍</h2><h3 id="locate命令"><a href="#locate命令" class="headerlink" title="locate命令"></a><code>locate</code>命令</h3><p><code>locate</code>命令是搜索预先生成的数据库中的文件名或文件路径，这份数据库正常是由<code>cron</code>计划任务每天自动更新，数据库默认位置在：</p><p>Ubuntu <code>/var/cache/locate/locatedb</code></p><p>RHEL<code>/var/lib/mlocate/mlocate.db</code></p><p>如果没有该数据库那么需要手动生成，使用管理员用户执行命令<code>updatedb</code>即可自动生成。</p><span id="more"></span><h3 id="find命令"><a href="#find命令" class="headerlink" title="find命令"></a><code>find</code>命令</h3><p><code>find</code>是爬取整个文件系统来实时的搜索文件系统，所以搜索比较慢。如果是刚刚添加的文件使用<code>find</code>才能搜索到，因为<code>locate</code>需要等待下一次更新数据库后才能搜索的到新添加的文件。</p><h2 id="根据名称查找文件locate"><a href="#根据名称查找文件locate" class="headerlink" title="根据名称查找文件locate"></a>根据名称查找文件<code>locate</code></h2><p><code>locate</code>命令根据<code>locatedb</code>数据库文件进行搜索并返回文件名和路径，通过数据库查询搜索会非常的快，因此只在你眨眼的功夫你想要搜索的文件路径或名称就显示到你的眼前了。</p><blockquote><p>以普通用户身份搜索条目时，调用<code>locate</code>搜索的用户必须对包含所匹配元素的目录树有读取的权限，否则是不会返回结果的。</p></blockquote><p>在该账户有权限读取的目录树中，搜索名称或路径包含<code>passwd</code>的文件。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">locate passwd   <span class="comment"># 搜索passwd</span></span><br><span class="line">/etc/cron.daily/passwd</span><br><span class="line">/etc/pam.d/chpasswd</span><br><span class="line">/etc/pam.d/passwd</span><br><span class="line">/etc/passwd</span><br><span class="line">/etc/passwd-</span><br><span class="line">/etc/security/opasswd</span><br><span class="line">/etc/sudoers.d/010_pi-nopasswd</span><br><span class="line">...</span><br></pre></td></tr></table></figure><p>即使文件名或目录包含匹配到的搜索，<strong>也会返回结果</strong>。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">locate image    <span class="comment"># 搜索image</span></span><br><span class="line">/home/pi/Tools/fuzzDicts/images</span><br><span class="line">/home/pi/Tools/fuzzDicts/images/README.MD</span><br><span class="line">/home/pi/Tools/fuzzDicts/images/api.jpg</span><br><span class="line">/home/pi/Tools/fuzzDicts/images/directory.jpg</span><br><span class="line">/home/pi/Tools/fuzzDicts/images/fileExt.png</span><br><span class="line">/home/pi/Tools/fuzzDicts/images/parameter.jpg</span><br><span class="line">/home/pi/Tools/fuzzDicts/images/password.jpg</span><br><span class="line">/home/pi/Tools/fuzzDicts/images/sql.jpg</span><br></pre></td></tr></table></figure><h3 id="常用选项"><a href="#常用选项" class="headerlink" title="常用选项"></a>常用选项</h3><p><code>-i</code>选项：不区分大小写，对所有大小写字母的组合都会进行匹配。</p><p><code>-l</code>选项：限制<code>locate</code>搜索结果的返回数量，实例如下，限制结果仅返回5个匹配项。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">locate  -l 5 v2ray <span class="comment"># 搜索`v2ray`并限制结果仅返回5个匹配项。</span></span><br><span class="line">/etc/systemd/system/multi-user.target.wants/v2ray.service</span><br><span class="line">/etc/systemd/system/v2ray.service</span><br><span class="line">/etc/v2ray</span><br><span class="line">/etc/v2ray/config.json</span><br><span class="line">/home/pi/disk/v2ray_client.json</span><br></pre></td></tr></table></figure><h2 id="使用find查找文件"><a href="#使用find查找文件" class="headerlink" title="使用find查找文件"></a>使用<code>find</code>查找文件</h2><p><code>find</code>命令在本地文件系统中实时的搜索，查找符合匹配条件的文件。使用<code>find</code>命令要求当前用户对要查看内容的目录有<code>读取</code>和<code>执行</code>的权限。</p><p><code>find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]</code></p><blockquote><p><code>find</code>命令有很多选项，使用这些选项可以对文件进行精确的搜索，比如通过时间戳、文件大小、修改时间等其他文件特性任意组合对文件进行查找和筛选。</p></blockquote><h3 id="常用选项-1"><a href="#常用选项-1" class="headerlink" title="常用选项"></a>常用选项</h3><h4 id="name选项："><a href="#name选项：" class="headerlink" title="-name选项："></a><code>-name</code>选项：</h4><p>后面跟上文件名可以查找匹配所给的文件名的文件，并返回该文件的绝对路径。例如若要在文件系统的<code>/</code>根目录下搜索名为<code>ssh_host_rsa_key</code>的文件：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> find / -name <span class="string">&quot;ssh_host_rsa_key&quot;</span></span><br><span class="line">/etc/ssh/ssh_host_rsa_key</span><br></pre></td></tr></table></figure><p>还可以使用通配符搜索文件。使用通配符搜索时一定要将文件名用引号引起，防止当前使用的终端对通配符进行解析。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> find / -name <span class="string">&quot;*.conf&quot;</span>   </span><br><span class="line">/lib/modprobe.d/systemd.conf</span><br><span class="line">/lib/modprobe.d/aliases.conf</span><br><span class="line">/lib/modprobe.d/fbdev-blacklist.conf</span><br><span class="line">/lib/systemd/system/rc-local.service.d/debian.conf</span><br><span class="line">/lib/systemd/system/systemd-resolved.service.d/resolvconf.conf</span><br><span class="line">/lib/systemd/system/systemd-timesyncd.service.d/disable-with-time-daemon.conf</span><br><span class="line">/lib/systemd/system/user-.slice.d/10-defaults.conf</span><br><span class="line">/lib/systemd/resolv.conf</span><br><span class="line">...</span><br></pre></td></tr></table></figure><h4 id="iname选项："><a href="#iname选项：" class="headerlink" title="-iname选项："></a><code>-iname</code>选项：</h4><p>使用方式和<code>-name</code>选项一致，但使用<code>-iname</code>选项搜索时不区分大小写。并且同样支持通配符搜索文件。</p><h4 id="user和-group选项："><a href="#user和-group选项：" class="headerlink" title="-user和-group选项："></a><code>-user</code>和<code>-group</code>选项：</h4><p>可以通过文件的所有者和所有组来对文件进行搜索，<code>-uid</code>和<code>-gid</code>也是用来限定文件所有权的选项。并且可以与其他选项如<code>-name</code>搭配使用。例如搜索用户为<code>www</code>所属的全部文件：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">find / -user www <span class="comment"># 在根目录下开始搜索文件所有者是`www`的所有文件及目录。</span></span><br><span class="line">/home/wwwroot/mail.yeefire.com</span><br><span class="line">/home/wwwroot/blog.yeefire.com</span><br><span class="line">/home/wwwroot/blog.yeefire.com/log.txt</span><br><span class="line">/home/wwwroot/blog.yeefire.com/var</span><br><span class="line">/home/wwwroot/blog.yeefire.com/var/Upgrade.php</span><br><span class="line">/home/wwwroot/blog.yeefire.com/var/Typecho</span><br><span class="line">...</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> find / -user www -name <span class="string">&quot;*yeefire.com&quot;</span></span><br><span class="line">/home/wwwroot/mail.yeefire.com</span><br><span class="line">/home/wwwroot/blog.yeefire.com</span><br></pre></td></tr></table></figure><hr>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;查找系统中的文件&quot;&gt;&lt;a href=&quot;#查找系统中的文件&quot; class=&quot;headerlink&quot; title=&quot;查找系统中的文件&quot;&gt;&lt;/a&gt;查找系统中的文件&lt;/h1&gt;&lt;p&gt;使用&lt;code&gt;locate&lt;/code&gt;和&lt;code&gt;find&lt;/code&gt;即可实现在挂载的文件系统中搜索文件。&lt;/p&gt;
&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9F%A5%E6%89%BE%E7%B3%BB%E7%BB%9F%E4%B8%AD%E7%9A%84%E6%96%87%E4%BB%B6&quot;&gt;查找系统中的文件&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#locate%E4%B8%8Efind%E4%BB%8B%E7%BB%8D&quot;&gt;&lt;code&gt;locate&lt;/code&gt;与&lt;code&gt;find&lt;/code&gt;介绍&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#locate%E5%91%BD%E4%BB%A4&quot;&gt;&lt;code&gt;locate&lt;/code&gt;命令&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#find%E5%91%BD%E4%BB%A4&quot;&gt;&lt;code&gt;find&lt;/code&gt;命令&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%A0%B9%E6%8D%AE%E5%90%8D%E7%A7%B0%E6%9F%A5%E6%89%BE%E6%96%87%E4%BB%B6locate&quot;&gt;根据名称查找文件&lt;code&gt;locate&lt;/code&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B8%B8%E7%94%A8%E9%80%89%E9%A1%B9&quot;&gt;常用选项&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%BF%E7%94%A8find%E6%9F%A5%E6%89%BE%E6%96%87%E4%BB%B6&quot;&gt;使用&lt;code&gt;find&lt;/code&gt;查找文件&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B8%B8%E7%94%A8%E9%80%89%E9%A1%B9-1&quot;&gt;常用选项&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#name%E9%80%89%E9%A1%B9&quot;&gt;&lt;code&gt;-name&lt;/code&gt;选项：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#iname%E9%80%89%E9%A1%B9&quot;&gt;&lt;code&gt;-iname&lt;/code&gt;选项：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#user%E5%92%8C-group%E9%80%89%E9%A1%B9&quot;&gt;&lt;code&gt;-user&lt;/code&gt;和&lt;code&gt;-group&lt;/code&gt;选项：&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;locate与find介绍&quot;&gt;&lt;a href=&quot;#locate与find介绍&quot; class=&quot;headerlink&quot; title=&quot;locate与find介绍&quot;&gt;&lt;/a&gt;&lt;code&gt;locate&lt;/code&gt;与&lt;code&gt;find&lt;/code&gt;介绍&lt;/h2&gt;&lt;h3 id=&quot;locate命令&quot;&gt;&lt;a href=&quot;#locate命令&quot; class=&quot;headerlink&quot; title=&quot;locate命令&quot;&gt;&lt;/a&gt;&lt;code&gt;locate&lt;/code&gt;命令&lt;/h3&gt;&lt;p&gt;&lt;code&gt;locate&lt;/code&gt;命令是搜索预先生成的数据库中的文件名或文件路径，这份数据库正常是由&lt;code&gt;cron&lt;/code&gt;计划任务每天自动更新，数据库默认位置在：&lt;/p&gt;
&lt;p&gt;Ubuntu &lt;code&gt;/var/cache/locate/locatedb&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;RHEL&lt;code&gt;/var/lib/mlocate/mlocate.db&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果没有该数据库那么需要手动生成，使用管理员用户执行命令&lt;code&gt;updatedb&lt;/code&gt;即可自动生成。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
  </entry>
  
  <entry>
    <title>Linux 守护进程和控制服务</title>
    <link href="https://blog.yeefire.com/2020_02/Linux_systemd.html"/>
    <id>https://blog.yeefire.com/2020_02/Linux_systemd.html</id>
    <published>2020-02-21T13:48:59.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<!-- TOC --><ul><li><a href="#systemd%E7%AE%80%E4%BB%8B"><code>systemd</code>简介</a></li><li><a href="#systemctl%E7%AE%80%E4%BB%8B"><code>systemctl</code>简介</a></li><li><a href="#%E6%9F%A5%E8%AF%A2%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81">查询服务状态</a></li><li><a href="#%E6%8E%A7%E5%88%B6%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1">控制系统服务</a><ul><li><a href="#%E5%81%9C%E6%AD%A2%E6%9C%8D%E5%8A%A1%E5%B9%B6%E6%A3%80%E6%9F%A5%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81">停止服务并检查服务状态</a></li><li><a href="#%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1%E5%B9%B6%E6%A3%80%E6%9F%A5%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81">启动服务并检查服务状态</a></li><li><a href="#%E9%87%8D%E5%90%AF%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%AF%B9%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%81%9C%E6%AD%A2%E5%92%8C%E5%90%AF%E5%8A%A8">重启服务实现对服务的停止和启动</a></li><li><a href="#%E5%8F%91%E5%87%BA%E6%8C%87%E4%BB%A4%E4%BD%BF%E6%9C%8D%E5%8A%A1%E5%9C%A8%E4%B8%8D%E5%81%9C%E6%AD%A2%E6%88%96%E9%87%8D%E5%90%AF%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E9%87%8D%E6%96%B0%E5%8A%A0%E8%BD%BD%E5%85%B6%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">发出指令使服务在不停止或重启的情况下重新加载其配置文件</a></li><li><a href="#%E5%B1%8F%E8%94%BD%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1">屏蔽系统服务</a></li><li><a href="#%E4%BD%BF%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B%E5%9C%A8%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E6%97%B6%E8%87%AA%E5%8A%A8%E5%90%AF%E5%8A%A8%E5%92%8C%E5%81%9C%E6%AD%A2">使守护进程在系统启动时自动启动和停止</a></li></ul></li></ul><!-- /TOC --><h2 id="systemd简介"><a href="#systemd简介" class="headerlink" title="systemd简介"></a><code>systemd</code>简介</h2><p>Linux系统和服务进程由<code>systemd</code>系统和服务管理器进行管理，它提供了一种方式可以在启动时和运行中的系统上激活系统资源、Web守护进程和其他进程。</p><p>一般情况下，守护进程在系统启动时自动开启并持续维护服务运行，直到服务器关机或手动停止。通常来说，守护进程的进程名以<code>d</code>命名结尾。</p><span id="more"></span><h2 id="systemctl简介"><a href="#systemctl简介" class="headerlink" title="systemctl简介"></a><code>systemctl</code>简介</h2><p><code>systemctl</code>命令用于管理各种类型的systemd对象，他们称之为<code>单元</code>。使用<code>systemctl</code>命令可以对单元进行状态的管理，比如运行、停止运行、设置为开机启动等。</p><p>比较重要的一个单元类型是服务单元，服务单元通常的拓展名为<code>.service</code>，代表系统服务。这种单元用于启动经常访问的守护进程，如<code>Nginx</code>Web服务器。还有其他单元类型，如<code>socket</code>套接字单元、<code>path</code>路径单元等。</p><h2 id="查询服务状态"><a href="#查询服务状态" class="headerlink" title="查询服务状态"></a>查询服务状态</h2><p>使用<code>systemctl status name[.type]</code>来查询服务状态。如果未提供单元类型(type)，则默认为<code>service</code>服务单元。(如果该服务单元存在的话~)</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl status sshd.service   <span class="comment">#查看ssh服务器守护进程的状态</span></span><br><span class="line">● sshd.service - OpenSSH server daemon</span><br><span class="line">   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)</span><br><span class="line">   Active: active (running) since Fri 2020-01-31 10:38:57 CST; 3h 15min ago</span><br><span class="line">     Docs: man:sshd(8)</span><br><span class="line">           man:sshd_config(5)</span><br><span class="line"> Main PID: 1572 (sshd)</span><br><span class="line">    Tasks: 1 (<span class="built_in">limit</span>: 49169)</span><br><span class="line">   Memory: 7.7M</span><br><span class="line">   CGroup: /system.slice/sshd.service</span><br><span class="line">           └─1572 /usr/sbin/sshd -D -oCiphers=aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes256-cbc,aes128-gcm@openssh.com,aes128-ctr,aes128-cbc -oMACs=hmac-sh&gt;</span><br><span class="line">Jan 31 11:32:15 centos8 sshd[4221]: Accepted password <span class="keyword">for</span> yourname from 192.168.1.157 port 44876 ssh2</span><br><span class="line">Jan 31 11:32:15 centos8 sshd[4221]: pam_unix(sshd:session): session opened <span class="keyword">for</span> user yourname by (uid=0)</span><br><span class="line">Jan 31 11:32:27 centos8 sshd[4307]: Accepted password <span class="keyword">for</span> yourname from 192.168.1.157 port 44900 ssh2</span><br></pre></td></tr></table></figure><p><img src="https://cdn.yeefire.com/hexo/img/status.png" alt="status.png"></p><p>在上面的状态中找到几个关键词：</p><table><thead><tr><th align="left">关键词</th><th align="left">描述</th></tr></thead><tbody><tr><td align="left">loaded</td><td align="left">单元配置文件已受理</td></tr><tr><td align="left">enabled</td><td align="left">在系统启动时自动运行</td></tr><tr><td align="left">disabled</td><td align="left">在启动运行时<strong>不会</strong>自动启动</td></tr><tr><td align="left">active(running)</td><td align="left">正在通过一个或多个进程持续运行中</td></tr><tr><td align="left">active(exited)</td><td align="left">已经成功完成一次性的任务并结束守护</td></tr><tr><td align="left">active(waiting)</td><td align="left">运行中，但正在等待事件发生…</td></tr><tr><td align="left">inactive</td><td align="left">进程没有运行</td></tr></tbody></table><h2 id="控制系统服务"><a href="#控制系统服务" class="headerlink" title="控制系统服务"></a>控制系统服务</h2><h3 id="停止服务并检查服务状态"><a href="#停止服务并检查服务状态" class="headerlink" title="停止服务并检查服务状态"></a>停止服务并检查服务状态</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl stop sshd.service</span><br><span class="line">systemctl status sshd.service</span><br></pre></td></tr></table></figure><h3 id="启动服务并检查服务状态"><a href="#启动服务并检查服务状态" class="headerlink" title="启动服务并检查服务状态"></a>启动服务并检查服务状态</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl start sshd.service</span><br><span class="line">systemctl status sshd.service</span><br></pre></td></tr></table></figure><h3 id="重启服务实现对服务的停止和启动"><a href="#重启服务实现对服务的停止和启动" class="headerlink" title="重启服务实现对服务的停止和启动"></a>重启服务实现对服务的停止和启动</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl restart sshd.service</span><br><span class="line">systemctl status sshd.service</span><br></pre></td></tr></table></figure><h3 id="发出指令使服务在不停止或重启的情况下重新加载其配置文件"><a href="#发出指令使服务在不停止或重启的情况下重新加载其配置文件" class="headerlink" title="发出指令使服务在不停止或重启的情况下重新加载其配置文件"></a>发出指令使服务在不停止或重启的情况下重新加载其配置文件</h3><p>如果对服务的配置文件进行了修改，不想对服务关闭影响业务的情况下使用<code>reload</code>选项来让服务对配置文件重新读取并加载。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl reload sshd.service</span><br><span class="line">systemctl status sshd.service</span><br></pre></td></tr></table></figure><h3 id="屏蔽系统服务"><a href="#屏蔽系统服务" class="headerlink" title="屏蔽系统服务"></a>屏蔽系统服务</h3><p>有些时候，系统中可能安装了相互冲突的服务，比如防火墙<code>iptables</code>与<code>firewalld</code>。为了防止管理员意外的启动两个服务可以将服务进行屏蔽。屏蔽服务将在配置文件目录中创建软连接，将其服务指向<code>/dev/null</code>设备文件，这样不小心启动了冲突的服务也不会出现有什么<strong>刺激</strong>的事情发生！</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl mask sshd.service <span class="comment"># 屏蔽ssh服务器守护进程</span></span><br><span class="line">Created symlink /etc/systemd/system/sshd.service → /dev/null.</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl start sshd.service <span class="comment"># 屏蔽后尝试启动</span></span><br><span class="line">Failed to start sshd.service: Unit sshd.service is masked. <span class="comment"># 提示服务单元被屏蔽，无法启动。</span></span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl unmask sshd.service <span class="comment"># 解除屏蔽ssh服务器守护进程</span></span><br><span class="line">Removed /etc/systemd/system/sshd.service.</span><br></pre></td></tr></table></figure><h3 id="使守护进程在系统启动时自动启动和停止"><a href="#使守护进程在系统启动时自动启动和停止" class="headerlink" title="使守护进程在系统启动时自动启动和停止"></a>使守护进程在系统启动时自动启动和停止</h3><p>在使用<code>systemctl</code>对一个守护进程启动或停止，不能保证其下一次系统运行时也是启动或停止的状态。当相应的<code>systemd</code>配置目录中创建了软连接时，服务会随着系统启动的时候启动。软连接可以通过<code>systemctl</code>命令创建和删除。</p><p>首先要查看服务状态，如果关键词出现<code>disabled</code>证明这个服务在系统启动时不会随着系统一起启动，否则相反。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl <span class="built_in">enable</span> sshd.service   <span class="comment"># 设置软连接，使得该服务随系统启动时启动。</span></span><br><span class="line">systemctl is-enabled sshd.service   <span class="comment"># 验证状态，返回为`enabled`为开启自动启动，`disabled`为不会开机自动启动。</span></span><br><span class="line">enabled</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">systemctl <span class="built_in">disable</span> sshd.service   <span class="comment"># 删除软连接，使得该服务不会随系统启动时启动。</span></span><br><span class="line">systemctl is-enabled sshd.service   <span class="comment"># 验证状态，返回为`enabled`为开启自动启动，`disabled`为不会开机自动启动。</span></span><br><span class="line">disabled</span><br></pre></td></tr></table></figure><hr>]]></content>
    
    
    <summary type="html">&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#systemd%E7%AE%80%E4%BB%8B&quot;&gt;&lt;code&gt;systemd&lt;/code&gt;简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#systemctl%E7%AE%80%E4%BB%8B&quot;&gt;&lt;code&gt;systemctl&lt;/code&gt;简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9F%A5%E8%AF%A2%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81&quot;&gt;查询服务状态&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8E%A7%E5%88%B6%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1&quot;&gt;控制系统服务&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%81%9C%E6%AD%A2%E6%9C%8D%E5%8A%A1%E5%B9%B6%E6%A3%80%E6%9F%A5%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81&quot;&gt;停止服务并检查服务状态&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1%E5%B9%B6%E6%A3%80%E6%9F%A5%E6%9C%8D%E5%8A%A1%E7%8A%B6%E6%80%81&quot;&gt;启动服务并检查服务状态&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%87%8D%E5%90%AF%E6%9C%8D%E5%8A%A1%E5%AE%9E%E7%8E%B0%E5%AF%B9%E6%9C%8D%E5%8A%A1%E7%9A%84%E5%81%9C%E6%AD%A2%E5%92%8C%E5%90%AF%E5%8A%A8&quot;&gt;重启服务实现对服务的停止和启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%91%E5%87%BA%E6%8C%87%E4%BB%A4%E4%BD%BF%E6%9C%8D%E5%8A%A1%E5%9C%A8%E4%B8%8D%E5%81%9C%E6%AD%A2%E6%88%96%E9%87%8D%E5%90%AF%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%E9%87%8D%E6%96%B0%E5%8A%A0%E8%BD%BD%E5%85%B6%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot;&gt;发出指令使服务在不停止或重启的情况下重新加载其配置文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B1%8F%E8%94%BD%E7%B3%BB%E7%BB%9F%E6%9C%8D%E5%8A%A1&quot;&gt;屏蔽系统服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%BF%E5%AE%88%E6%8A%A4%E8%BF%9B%E7%A8%8B%E5%9C%A8%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E6%97%B6%E8%87%AA%E5%8A%A8%E5%90%AF%E5%8A%A8%E5%92%8C%E5%81%9C%E6%AD%A2&quot;&gt;使守护进程在系统启动时自动启动和停止&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;systemd简介&quot;&gt;&lt;a href=&quot;#systemd简介&quot; class=&quot;headerlink&quot; title=&quot;systemd简介&quot;&gt;&lt;/a&gt;&lt;code&gt;systemd&lt;/code&gt;简介&lt;/h2&gt;&lt;p&gt;Linux系统和服务进程由&lt;code&gt;systemd&lt;/code&gt;系统和服务管理器进行管理，它提供了一种方式可以在启动时和运行中的系统上激活系统资源、Web守护进程和其他进程。&lt;/p&gt;
&lt;p&gt;一般情况下，守护进程在系统启动时自动开启并持续维护服务运行，直到服务器关机或手动停止。通常来说，守护进程的进程名以&lt;code&gt;d&lt;/code&gt;命名结尾。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
  </entry>
  
  <entry>
    <title>Linux SSH远程访问</title>
    <link href="https://blog.yeefire.com/2020_02/Linux_sshd.html"/>
    <id>https://blog.yeefire.com/2020_02/Linux_sshd.html</id>
    <published>2020-02-21T13:46:01.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<!-- TOC --><ul><li><a href="#ssh-%E6%98%AF%E4%BB%80%E4%B9%88"><code>SSH</code> 是什么</a></li><li><a href="#ssh%E7%9A%84%E9%A3%9F%E7%94%A8%E6%96%B9%E6%B3%95"><code>SSH</code>的食用方法</a><ul><li><a href="#%E7%99%BB%E5%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BE%E5%A4%87%E7%B3%BB%E7%BB%9F">登录远程设备系统</a><ul><li><a href="#%E4%BD%BF%E7%94%A8%E8%BF%9C%E7%A8%8B%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E6%9D%A5%E7%99%BB%E5%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BE%E5%A4%87%E7%B3%BB%E7%BB%9F">使用远程系统的用户名来登录远程设备系统</a></li><li><a href="#%E4%BD%BF%E7%94%A8%E5%BD%93%E5%89%8D%E7%94%A8%E6%88%B7%E8%BA%AB%E4%BB%BD%E7%99%BB%E5%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BE%E5%A4%87%E7%9A%84%E7%B3%BB%E7%BB%9F">使用当前用户身份，登录远程设备的系统</a></li></ul></li><li><a href="#%E4%BD%BF%E7%94%A8w%E5%91%BD%E4%BB%A4%E7%9C%8B%E7%9C%8B%E8%B0%81%E7%8E%B0%E5%9C%A8%E7%99%BB%E9%99%86%E4%BA%86%E8%BF%99%E5%8F%B0%E7%B3%BB%E7%BB%9F">使用<code>w</code>命令看看谁现在登陆了这台系统</a></li></ul></li><li><a href="#ssh%E5%85%AC%E9%92%A5"><code>SSH</code>公钥</a></li><li><a href="#%E9%85%8D%E7%BD%AEssh%E5%85%8D%E5%AF%86%E7%99%BB%E5%BD%95"><code>配置SSH免密登录</code></a><ul><li><a href="#ssh-keygen%E7%94%9F%E6%88%90%E5%AF%86%E9%92%A5"><code>ssh-keygen</code>生成密钥</a></li><li><a href="#ssh-copy-id%E5%8F%91%E9%80%81%E5%85%AC%E9%92%A5"><code>ssh-copy-id</code>发送公钥</a></li></ul></li></ul><!-- /TOC --><h2 id="SSH-是什么"><a href="#SSH-是什么" class="headerlink" title="SSH 是什么"></a><code>SSH</code> 是什么</h2><p><code>SSH</code>是<code>OpenSSH Secure Shell</code>通用的简称，<code>OpenSSH Secure Shell(SSH)</code>是用来在远程设备的操作系统上安全运行Shell，只需要提供远程目的设备系统的用户信息并且完成身份认证就可以对登录到该系统执行命令了。</p><span id="more"></span><h2 id="SSH的食用方法"><a href="#SSH的食用方法" class="headerlink" title="SSH的食用方法"></a><code>SSH</code>的食用方法</h2><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]</span><br><span class="line">         [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-J destination] [-L address]</span><br><span class="line">         [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address] [-S ctl_path]</span><br><span class="line">         [-W host:port] [-w local_tun[:remote_tun]] destination [<span class="built_in">command</span>]</span><br></pre></td></tr></table></figure><p>这么看的话选项和参数有点多！不过常用的仅仅几个，下面的例子会介绍<code>SSH</code>的常见使用方法。</p><blockquote><p>默认SSH服务器的远程端口是<strong>22</strong>，也就是说在没有指定<code>[-p port]</code>选项时假定ssh服务端口就是22。如果你出于安全考虑，将<code>OpenSSH</code>服务器上对外暴露的端口修改为其他端口号上，那么在远程访问服务器时使用<code>ssh</code>需要手动指定<code>-p 端口号</code>才能与你的SSH服务器建立连接。</p></blockquote><h3 id="登录远程设备系统"><a href="#登录远程设备系统" class="headerlink" title="登录远程设备系统"></a>登录远程设备系统</h3><h4 id="使用远程系统的用户名来登录远程设备系统"><a href="#使用远程系统的用户名来登录远程设备系统" class="headerlink" title="使用远程系统的用户名来登录远程设备系统"></a>使用远程系统的用户名来登录远程设备系统</h4><p><code>ssh &lt;username&gt;@&lt;remote_address&gt;</code></p><p>参数1(username):指定要登录到远程设备的用户名</p><p>参数2(remote_address):远程设备的IP地址或域名</p><p>例如：</p><p><code>ssh root@yeefire.com</code></p><p>以<code>root</code>用户身份(用户名)来登录<code>yeefire.com</code>域名的IP所指向的远程服务器系统。</p><h4 id="使用当前用户身份，登录远程设备的系统"><a href="#使用当前用户身份，登录远程设备的系统" class="headerlink" title="使用当前用户身份，登录远程设备的系统"></a>使用当前用户身份，登录远程设备的系统</h4><p><code>ssh yeefire.com</code></p><p>使用你执行<code>ssh</code>命令的这个用户身份来登录到<code>yeefire.com</code>上，假定你现在的用户身份名为<code>root</code>那么可以理解为上面的命令被解析为<code>ssh root@yeefire.com</code></p><h3 id="使用w命令看看谁现在登陆了这台系统"><a href="#使用w命令看看谁现在登陆了这台系统" class="headerlink" title="使用w命令看看谁现在登陆了这台系统"></a>使用<code>w</code>命令看看谁现在登陆了这台系统</h3><p><code>w</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">w</span><br><span class="line"></span><br><span class="line"> 14:55:29 up 17:01,  1 user,  load average: 1.39, 1.49, 1.52</span><br><span class="line">USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT</span><br><span class="line">pi       pts/2    192.168.1.194    12:53    0.00s  0.11s  0.01s w</span><br></pre></td></tr></table></figure><p>在上面可以看到，用户名，使用的是什么终端，从些远程位置进行了登录以及登陆时间。</p><h2 id="SSH公钥"><a href="#SSH公钥" class="headerlink" title="SSH公钥"></a><code>SSH</code>公钥</h2><p>为了确保与服务器之间保持安全的网络通信，当从SSH客户端登录远程设备系统时，在该客户端开始登陆前，客户端会向目标索取服务器公钥，如果第一次与服务器链接会让你确认服务器公钥的准确性(防止中间人攻击)，一旦接受了公钥，就会保存在<code>~/.ssh/known_hosts</code>文件中，并且每次与远程设备系统设备链接时会与本机系统第一次保存的公钥进行比对，如果发现不匹配则立即拒绝并断开链接，并假定网络通信已遭劫持或服务器被入侵。</p><blockquote><p>但是，当你给远程的设备重做了系统，由于重新生成了公钥会和你本机系统SSH客户端存储的公钥不一致，所以也会断开连接。如果你确信你当前的网络不存在安全问题，你可以在<code>~/.ssh/known_hosts</code>文件中删除旧的公钥记录，便可以重新与远程服务器进行建立可靠连接并登录。</p></blockquote><h2 id="配置SSH免密登录"><a href="#配置SSH免密登录" class="headerlink" title="配置SSH免密登录"></a><code>配置SSH免密登录</code></h2><p>使用公钥身份验证即可对SSH登录进行身份验证，而不需要输入密码。执行<code>ssh-keygen</code>命令生成密钥，其中生成的私钥保存在<code>~./ssh/id_rsa</code>，公钥保存在<code>~./ssh/id_rsa.pub</code></p><blockquote><p>注意，你的私钥一定要保存好，它现在相当于你的登录密码！如果私钥被盗取，那么其他人可以利用你的私钥毫不客气地远程SSH登录到你的系统并窃取你珍藏许久的小电影。</p></blockquote><p>下面是配置免密SSH登录的顺序和例子：</p><h3 id="ssh-keygen生成密钥"><a href="#ssh-keygen生成密钥" class="headerlink" title="ssh-keygen生成密钥"></a><code>ssh-keygen</code>生成密钥</h3><p>在你的本机系统上执行 <code>ssh-keygen</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">ssh-keygen</span><br><span class="line">Generating public/private rsa key pair.</span><br><span class="line">Enter file <span class="keyword">in</span> <span class="built_in">which</span> to save the key (/home/username/.ssh/id_rsa): <span class="comment"># 回车</span></span><br><span class="line">Enter passphrase (empty <span class="keyword">for</span> no passphrase): <span class="comment"># 回车</span></span><br><span class="line">Enter same passphrase again:  <span class="comment"># 回车</span></span><br><span class="line">Your identification has been saved <span class="keyword">in</span> /home/username/.ssh/id_rsa.</span><br><span class="line">Your public key has been saved <span class="keyword">in</span> /home/username/.ssh/id_rsa.pub.</span><br><span class="line">The key fingerprint is:</span><br><span class="line">SHA256:0kyfGMx571yKfjmtmMwnEYeJp2BYgf5yi0qWXCr18/k username@centos8</span><br><span class="line">The key<span class="string">&#x27;s randomart image is:</span></span><br><span class="line"><span class="string">+---[RSA 3072]----+</span></span><br><span class="line"><span class="string">|     ...         |</span></span><br><span class="line"><span class="string">|    . .o .       |</span></span><br><span class="line"><span class="string">|   . o  *..o     |</span></span><br><span class="line"><span class="string">|    o o+.==o.    |</span></span><br><span class="line"><span class="string">|  . .o..Sooo. .  |</span></span><br><span class="line"><span class="string">| o =. o.. .+ o   |</span></span><br><span class="line"><span class="string">|. * o+ .  ..+o   |</span></span><br><span class="line"><span class="string">| +  .o.. +.o= .  |</span></span><br><span class="line"><span class="string">|  ..  o.E *+.o   |</span></span><br><span class="line"><span class="string">+----[SHA256]-----+</span></span><br></pre></td></tr></table></figure><p>在生成密钥的过程中，会询问你密钥保存位置。也会询问你”二次认证”的密码(不需要再为私钥设置密码，全部回车即可！我们目的就是配置免密登录。如果你此处输入了密码，那么在使用私钥认证的时候仍然需要进行密码认证。但是设置私钥密码的好处是当你私钥被盗后，你有时间在对方破解你的私钥密码时重新生成一对密钥来保护你的系统)。此处全部直接回车即可。</p><h3 id="ssh-copy-id发送公钥"><a href="#ssh-copy-id发送公钥" class="headerlink" title="ssh-copy-id发送公钥"></a><code>ssh-copy-id</code>发送公钥</h3><p>现在已经生成了本机的私钥与公钥，将本机的公钥发送给你的远程设备系统即可实现免密登录。</p><p><code>ssh-copy-id &lt;username&gt;@&lt;remote_address&gt; </code></p><p>参数1(username):指定要登录到远程设备的用户名</p><p>参数2(remote_address):远程设备的IP地址或域名</p><p>之后输入SSH登录密码，便会将公钥发送到远程设备的默认公钥存储位置存储。</p><p>现在，你当你<code>ssh &lt;username&gt;@&lt;remote_address&gt;</code>时，你会发现不需要输入密码即可登录到远程设备的系统上了。</p><hr>]]></content>
    
    
    <summary type="html">&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#ssh-%E6%98%AF%E4%BB%80%E4%B9%88&quot;&gt;&lt;code&gt;SSH&lt;/code&gt; 是什么&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ssh%E7%9A%84%E9%A3%9F%E7%94%A8%E6%96%B9%E6%B3%95&quot;&gt;&lt;code&gt;SSH&lt;/code&gt;的食用方法&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%99%BB%E5%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BE%E5%A4%87%E7%B3%BB%E7%BB%9F&quot;&gt;登录远程设备系统&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%BF%E7%94%A8%E8%BF%9C%E7%A8%8B%E7%B3%BB%E7%BB%9F%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E6%9D%A5%E7%99%BB%E5%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BE%E5%A4%87%E7%B3%BB%E7%BB%9F&quot;&gt;使用远程系统的用户名来登录远程设备系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%BF%E7%94%A8%E5%BD%93%E5%89%8D%E7%94%A8%E6%88%B7%E8%BA%AB%E4%BB%BD%E7%99%BB%E5%BD%95%E8%BF%9C%E7%A8%8B%E8%AE%BE%E5%A4%87%E7%9A%84%E7%B3%BB%E7%BB%9F&quot;&gt;使用当前用户身份，登录远程设备的系统&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%BF%E7%94%A8w%E5%91%BD%E4%BB%A4%E7%9C%8B%E7%9C%8B%E8%B0%81%E7%8E%B0%E5%9C%A8%E7%99%BB%E9%99%86%E4%BA%86%E8%BF%99%E5%8F%B0%E7%B3%BB%E7%BB%9F&quot;&gt;使用&lt;code&gt;w&lt;/code&gt;命令看看谁现在登陆了这台系统&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ssh%E5%85%AC%E9%92%A5&quot;&gt;&lt;code&gt;SSH&lt;/code&gt;公钥&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%85%8D%E7%BD%AEssh%E5%85%8D%E5%AF%86%E7%99%BB%E5%BD%95&quot;&gt;&lt;code&gt;配置SSH免密登录&lt;/code&gt;&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#ssh-keygen%E7%94%9F%E6%88%90%E5%AF%86%E9%92%A5&quot;&gt;&lt;code&gt;ssh-keygen&lt;/code&gt;生成密钥&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ssh-copy-id%E5%8F%91%E9%80%81%E5%85%AC%E9%92%A5&quot;&gt;&lt;code&gt;ssh-copy-id&lt;/code&gt;发送公钥&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;SSH-是什么&quot;&gt;&lt;a href=&quot;#SSH-是什么&quot; class=&quot;headerlink&quot; title=&quot;SSH 是什么&quot;&gt;&lt;/a&gt;&lt;code&gt;SSH&lt;/code&gt; 是什么&lt;/h2&gt;&lt;p&gt;&lt;code&gt;SSH&lt;/code&gt;是&lt;code&gt;OpenSSH Secure Shell&lt;/code&gt;通用的简称，&lt;code&gt;OpenSSH Secure Shell(SSH)&lt;/code&gt;是用来在远程设备的操作系统上安全运行Shell，只需要提供远程目的设备系统的用户信息并且完成身份认证就可以对登录到该系统执行命令了。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
  </entry>
  
  <entry>
    <title>42Team小组_Linux基础培训课件</title>
    <link href="https://blog.yeefire.com/2020_02/42team_Linux.html"/>
    <id>https://blog.yeefire.com/2020_02/42team_Linux.html</id>
    <published>2020-02-21T13:41:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<!-- TOC --><ul><li><a href="#1linux%E6%98%AF%E4%BB%80%E4%B9%88%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F">1、Linux是什么操作系统？</a></li><li><a href="#2linux%E5%92%8C%E5%85%B6%E4%BB%96%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E5%A4%84%E5%92%8C%E4%BC%98%E7%82%B9">2、Linux和其他操作系统的不同之处和优点</a><ul><li><a href="#21linux%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E5%A4%84">2.1Linux的不同之处</a></li><li><a href="#22linux%E7%9B%B8%E6%AF%94windows%E7%9A%84%E4%BC%98%E7%82%B9">2.2Linux相比Windows的优点</a></li></ul></li><li><a href="#3linux%E7%9A%84%E5%AE%89%E8%A3%85%E6%96%B9%E5%BC%8F">3、Linux的安装方式</a><ul><li><a href="#31%E5%9C%A8%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%B8%AD%E5%AE%89%E8%A3%85linux">3.1在虚拟机中安装Linux</a><ul><li><a href="#311%E6%9C%89%E5%93%AA%E4%BA%9B%E5%B8%B8%E8%A7%81%E7%9A%84%E8%99%9A%E6%8B%9F%E6%9C%BA">3.1.1有哪些常见的虚拟机？</a></li><li><a href="#312%E4%B8%8B%E8%BD%BD%E8%99%9A%E6%8B%9F%E6%9C%BA">3.1.2下载虚拟机</a></li><li><a href="#313%E5%AE%89%E8%A3%85%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%B9%B6%E5%BC%80%E5%90%AF%E8%99%9A%E6%8B%9F%E5%8C%96%E6%94%AF%E6%8C%81">3.1.3安装虚拟机并开启虚拟化支持</a></li><li><a href="#%E5%9C%A8%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%B8%AD%E5%AE%89%E8%A3%85linux">在虚拟机中安装Linux</a></li></ul></li><li><a href="#32%E5%9C%A8%E5%AE%9E%E4%BD%93%E6%9C%BA%E5%AE%89%E8%A3%85linux">3.2在实体机安装Linux</a></li></ul></li><li><a href="#4linux%E5%9F%BA%E7%A1%80%E5%91%BD%E4%BB%A4">4、Linux基础命令</a><ul><li><a href="#41-%E7%AC%AC%E4%B8%80%E8%8A%82%E8%AF%BE">4.1 第一节课：</a><ul><li><a href="#411-touch%E5%91%BD%E4%BB%A4">4.1.1 <code>touch</code>命令：</a></li><li><a href="#412-ls-%E5%91%BD%E4%BB%A4">4.1.2 <code>ls</code> 命令：</a></li><li><a href="#413-nano-%E5%91%BD%E4%BB%A4">4.1.3 <code>nano</code> 命令：</a></li><li><a href="#414-cat-%E5%91%BD%E4%BB%A4">4.1.4 <code>cat</code> 命令：</a></li><li><a href="#415-mkdir-%E5%91%BD%E4%BB%A4">4.1.5 <code>mkdir</code> 命令：</a></li><li><a href="#416-cd-%E5%91%BD%E4%BB%A4">4.1.6 <code>cd</code> 命令：</a></li><li><a href="#417-pwd-%E5%91%BD%E4%BB%A4">4.1.7 <code>pwd</code> 命令：</a></li><li><a href="#418-top-%E5%91%BD%E4%BB%A4">4.1.8 <code>top</code> 命令：</a></li></ul></li><li><a href="#42-%E7%AC%AC%E4%BA%8C%E8%8A%82%E8%AF%BE">4.2 第二节课：</a><ul><li><a href="#421-%E5%A1%AB%E5%9D%91-%E7%B3%BB%E7%BB%9F%E6%9D%83%E9%99%90">4.2.1 填坑 <code>系统权限</code>：</a></li><li><a href="#422-%E4%BF%AE%E6%94%B9%E5%AF%86%E7%A0%81">4.2.2 修改密码：</a></li><li><a href="#423-%E4%BC%91%E7%9C%A0%E8%BF%9B%E7%A8%8B">4.2.3 休眠进程：</a></li><li><a href="#424-%E5%8E%8B%E7%BC%A9">4.2.4 压缩：</a></li><li><a href="#425-tar%E6%89%93%E5%8C%85">4.2.5 <code>tar</code>打包：</a></li><li><a href="#426-%E6%9B%B4%E6%94%B9apt%E6%BA%90%E4%B8%BA%E5%9B%BD%E5%86%85%E6%BA%90">4.2.6 更改apt源为国内源：</a></li></ul></li></ul></li></ul><!-- /TOC --><h2 id="1、Linux是什么操作系统？"><a href="#1、Linux是什么操作系统？" class="headerlink" title="1、Linux是什么操作系统？"></a>1、Linux是什么操作系统？</h2><p>Linux操作系统也可以叫做“Linux发行版”。通常来讲，一个Linux发行版包括Linux内核，以及将Linux发行版系统安装到本机的安装程序，还有每个发行版具有特色的专有软件。各个发行版都有其不同的特色，有些发行版对不同电脑硬件结构进行优化和支持，有些发行版对普通用户或开发者使用方式的调整，也有对针对实时应用或嵌入式系统的开发等等。当前，超过三百个发行版被积极的开发，最普遍被使用的发行版有大约十二个。较为知名的有Debian、Ubuntu、Fedora和openSUSE等。</p><span id="more"></span><p><img src="https://cdn.yeefire.com/hexo/img/Linux%E5%8F%91%E8%A1%8C%E7%89%88.jpg" alt="Linux发行版.jpg"></p><h2 id="2、Linux和其他操作系统的不同之处和优点"><a href="#2、Linux和其他操作系统的不同之处和优点" class="headerlink" title="2、Linux和其他操作系统的不同之处和优点"></a>2、Linux和其他操作系统的不同之处和优点</h2><h3 id="2-1Linux的不同之处"><a href="#2-1Linux的不同之处" class="headerlink" title="2.1Linux的不同之处"></a>2.1Linux的不同之处</h3><pre><code>1、Linux 是一个文件系统，万物皆为文件。2、主力在于命令行，而不是图形界面。</code></pre><h3 id="2-2Linux相比Windows的优点"><a href="#2-2Linux相比Windows的优点" class="headerlink" title="2.2Linux相比Windows的优点"></a>2.2Linux相比Windows的优点</h3><pre><code>1、Linux占用资源少，如果不启用图形界面的话占用内存资源极低。2、基本上所有的Linux发行版都是免费的！！！3、安全！权限管理严格，很少被病毒针对。4、内核开源，全世界人民共同努力的结晶。5、命令行高效（习惯了你就不愿意回到Windows了）</code></pre><h2 id="3、Linux的安装方式"><a href="#3、Linux的安装方式" class="headerlink" title="3、Linux的安装方式"></a>3、Linux的安装方式</h2><h3 id="3-1在虚拟机中安装Linux"><a href="#3-1在虚拟机中安装Linux" class="headerlink" title="3.1在虚拟机中安装Linux"></a>3.1在虚拟机中安装Linux</h3><h4 id="3-1-1有哪些常见的虚拟机？"><a href="#3-1-1有哪些常见的虚拟机？" class="headerlink" title="3.1.1有哪些常见的虚拟机？"></a>3.1.1有哪些常见的虚拟机？</h4><pre><code>1、Vmware虚拟机（有能力的话请支持正版，因为是商业软件所以比较稳定）2、VirtualBox虚拟机（开源！但是不太稳定）</code></pre><h4 id="3-1-2下载虚拟机"><a href="#3-1-2下载虚拟机" class="headerlink" title="3.1.2下载虚拟机"></a>3.1.2下载虚拟机</h4><pre><code>Windows系统Vmware虚拟机：[Vmware for Windows](http://172.24.4.199/load/246.html)Macos系统Vmware虚拟机：[Vmware for Mac](http://172.24.4.199/load/166.html)</code></pre><h4 id="3-1-3安装虚拟机并开启虚拟化支持"><a href="#3-1-3安装虚拟机并开启虚拟化支持" class="headerlink" title="3.1.3安装虚拟机并开启虚拟化支持"></a>3.1.3安装虚拟机并开启虚拟化支持</h4><p>1、查看自己的电脑二级虚拟化功能是否已经开启：</p><p>右键左下角开始菜单，找到<code>Windows Powershell</code>,在里面输入<code>systeminfo</code>。</p><p><img src="https://cdn.yeefire.com/hexo/img/powershell_input_systeminfo.png" alt="powershell_input_systeminfo.png"></p><p>查看是否支持虚拟化</p><p><img src="https://cdn.yeefire.com/hexo/img/powershell_show_systeminfo.png" alt="powershell_show_systeminfo.png"></p><p>如果虚拟化这部分的信息都为yes那么为已经开启，否则请百度搜索<code>你的电脑型号+开启虚拟化支持</code>,在Bios设置中将选项开启。</p><h4 id="在虚拟机中安装Linux"><a href="#在虚拟机中安装Linux" class="headerlink" title="在虚拟机中安装Linux"></a>在虚拟机中安装Linux</h4><p><span class="exturl" data-url="aHR0cDovL21pcnJvcnMubmV1c29mdC5lZHUuY24vdWJ1bnR1LXJlbGVhc2VzL2Jpb25pYy91YnVudHUtMTguMDQuMy1kZXNrdG9wLWFtZDY0Lmlzbw==" title="http://mirrors.neusoft.edu.cn/ubuntu-releases/bionic/ubuntu-18.04.3-desktop-amd64.iso">http://mirrors.neusoft.edu.cn/ubuntu-releases/bionic/ubuntu-18.04.3-desktop-amd64.iso<i class="fa fa-external-link"></i></span></p><h3 id="3-2在实体机安装Linux"><a href="#3-2在实体机安装Linux" class="headerlink" title="3.2在实体机安装Linux"></a>3.2在实体机安装Linux</h3><p>暂不考虑，感兴趣的来找我。</p><h2 id="4、Linux基础命令"><a href="#4、Linux基础命令" class="headerlink" title="4、Linux基础命令"></a>4、Linux基础命令</h2><h3 id="4-1-第一节课："><a href="#4-1-第一节课：" class="headerlink" title="4.1 第一节课："></a>4.1 第一节课：</h3><h4 id="4-1-1-touch命令："><a href="#4-1-1-touch命令：" class="headerlink" title="4.1.1 touch命令："></a>4.1.1 <code>touch</code>命令：</h4><p><code>touch</code> 可以创建一个新的空文件，或者更新已有文件的文件时间标签</p><p>1、使用<code>touch</code>创建一个名字为<code>42team.txt</code>空文本文件</p><p><code>touch 42team.txt</code></p><p>2、使用<code>touch</code>创建一个名字为<code>.hidefile</code>空文本文件</p><p><code>touch .hidefile</code></p><h4 id="4-1-2-ls-命令："><a href="#4-1-2-ls-命令：" class="headerlink" title="4.1.2 ls 命令："></a>4.1.2 <code>ls</code> 命令：</h4><p><code>ls</code>可以显示当前文件夹下或指定某一文件夹、文件的文件名称、以及属性等。</p><p>1、直接在终端里输入<code>ls</code></p><p>2、尝试使用 <code>ls --help</code> 来获取<code>ls</code>命令的帮助</p><p>3、<code>ls -a</code> 显示当前文件夹下的所有文件及文件夹，包括隐藏文件(以.开头的文件为隐藏文件)</p><p>4、<code>ls -l</code> 以列表的方式显示当前文件夹下的所有文件及文件夹(这样可以将文件属性显示出来)</p><p>5、<code>ls -al</code> 选项可以组合，这样组合的话会将当前目录下的所有文件，以列表的形式显示出来</p><h4 id="4-1-3-nano-命令："><a href="#4-1-3-nano-命令：" class="headerlink" title="4.1.3 nano 命令："></a>4.1.3 <code>nano</code> 命令：</h4><p><code>nano</code>是一个对Linux新手比较友好的文本编辑器，很好上手使用，但是以后我们会逐渐放弃使用它，转而使用功能更强大的<code>vi/vim</code>文本编辑器。</p><p>1、<code>nano 42team.txt</code> 编辑当前目录下的42team.txt这个文本文件</p><p>在里面输入完内容后，按下<code>Ctrl+x</code>键推出，然后再按下<code>Y</code>键选择保存。</p><p>2、再次使用<code>nano</code>在<code>42team.txt</code>的最后一行添加<code>http://172.24.4.199</code>文本，退出并保存。</p><h4 id="4-1-4-cat-命令："><a href="#4-1-4-cat-命令：" class="headerlink" title="4.1.4 cat 命令："></a>4.1.4 <code>cat</code> 命令：</h4><p><code>cat</code>命令是Linux下的一个文本输出命令，通常是用于观看某个文件的内容。</p><p>1、<code>cat 42team.txt</code> 将42team.txt文件里的内容输出到终端里。</p><p>2、<code>cat -n 42team.txt</code> 将42team.txt文件里的内容输出到终端里，并显示行号。</p><h4 id="4-1-5-mkdir-命令："><a href="#4-1-5-mkdir-命令：" class="headerlink" title="4.1.5 mkdir 命令："></a>4.1.5 <code>mkdir</code> 命令：</h4><p><code>mkdir</code>命令是Linux下创建目录文件夹的命令。</p><p>1、<code>mkdir test</code> 在当前目录下创建一个名为<code>test</code>的目录</p><h4 id="4-1-6-cd-命令："><a href="#4-1-6-cd-命令：" class="headerlink" title="4.1.6 cd 命令："></a>4.1.6 <code>cd</code> 命令：</h4><p><code>cd</code> 命令是英文”Change Directory”的缩写，意思是改变当前所在的文件夹。</p><p>1、<code>cd test</code> 将当前的工作目录，切换到刚刚创建的<code>test</code>目录。</p><h4 id="4-1-7-pwd-命令："><a href="#4-1-7-pwd-命令：" class="headerlink" title="4.1.7 pwd 命令："></a>4.1.7 <code>pwd</code> 命令：</h4><p><code>pwd</code>命令是用来显示当前所在的文件夹的路径。</p><p>1、直接在终端中输入<code>pwd</code>命令，会将所在目录的绝对路径输出出来。</p><h4 id="4-1-8-top-命令："><a href="#4-1-8-top-命令：" class="headerlink" title="4.1.8 top 命令："></a>4.1.8 <code>top</code> 命令：</h4><p><code>top</code>工具用来显示当前系统所占用的硬件资源，按<code>Ctrl+C</code>关闭工具</p><p>1、直接输入<code>top</code>命令。</p><h3 id="4-2-第二节课："><a href="#4-2-第二节课：" class="headerlink" title="4.2 第二节课："></a>4.2 第二节课：</h3><h4 id="4-2-1-填坑-系统权限："><a href="#4-2-1-填坑-系统权限：" class="headerlink" title="4.2.1 填坑 系统权限："></a>4.2.1 填坑 <code>系统权限</code>：</h4><p><img src="https://cdn.yeefire.com/hexo/img/%E6%96%87%E4%BB%B6%E6%9D%83%E9%99%90.png" alt="文件权限.png"></p><p>r 读   4</p><p>w 写   2</p><p>x 执行 1</p><p>1、更改文件权限</p><p><code>chmod u/g/o/a  +/-/=  r/w/x  文件名</code></p><p><code>chmod  664 文件名</code> (644相当于rw- rw- r–)</p><p>2、仅三种权限有意义</p><p>—     表示没有权限</p><p>r-x    表示查看权限</p><p>rwx    表示创建删除权限</p><h4 id="4-2-2-修改密码："><a href="#4-2-2-修改密码：" class="headerlink" title="4.2.2 修改密码："></a>4.2.2 修改密码：</h4><p>1、修改当前登入用户的密码</p><p><code>passwd</code></p><p>2、作为root管理员修改用户的密码</p><p>注意：当你作为系统管理员去修改其他用户的密码时，你不需要输入该用户原有的密码，因为在这台Linux中你是才是老大。</p><p><code>passwd + 用户名</code></p><h4 id="4-2-3-休眠进程："><a href="#4-2-3-休眠进程：" class="headerlink" title="4.2.3 休眠进程："></a>4.2.3 休眠进程：</h4><p>1、在终端里休眠一个进程按下<code>Ctrl+Z</code>便可暂停这个进程，休眠时进程将在后台，但是不会继续运行，直到将其恢复。</p><p>2、显示当前所有系统作业<code>jobs</code></p><p>在<code>jobs</code>中就可以发现有哪些进程被休眠掉了，当然jobs还可以查看其他的进程状态。</p><p>3、恢复进程到前台终端使用<code>fg</code></p><p>注意：仅输入<code>fg</code>会自动恢复最近的一个被休眠的进程，如果你有多个休眠进程，并且想要指定某一个来恢复，你需要先用<code>jobs</code>命令查看作业号，之后使用<code>fg 作业号</code>的形式恢复指定进程到前台。</p><p>4、恢复进程到后台使用<code>bg</code></p><h4 id="4-2-4-压缩："><a href="#4-2-4-压缩：" class="headerlink" title="4.2.4 压缩："></a>4.2.4 压缩：</h4><p>Linux常见的两种压缩方式：bzip2 gzip</p><p>1、<code>bzip2</code>压缩及解压</p><p>压缩：<code>bzip2 文件名</code></p><p>解压：<code>bunzip2 文件名</code></p><p>2、<code>gzip</code>压缩及解压</p><p>压缩：<code>gzip 文件名</code></p><p>解压：<code>gunzip 文件名</code></p><p>3、生成一个10M的文件来测试两个压缩的效率</p><p><code>dd if=/dev/zero of=/home/xxx/test10M bs=1M count=10</code> 在家目录下生成一个文件名为<code>test10M</code>的10M大小的文件</p><p><code>bzip2 -k /home/xxx/test10M</code></p><p><code>gzip -k /home/xxx/test10M</code></p><p>查看两个压缩后的我文件大小。</p><h4 id="4-2-5-tar打包："><a href="#4-2-5-tar打包：" class="headerlink" title="4.2.5 tar打包："></a>4.2.5 <code>tar</code>打包：</h4><p>1、打包</p><p>因为只能压缩文件不能压缩目录，所以要对一个目录进行压缩，必须先对其进行打包之后再压缩。</p><p><code>tar -cvf 打包后生成的文件名 被打包的目录名</code></p><p>2、解包</p><p><code>tar -xvf 要被解包的文件名</code></p><p>3、打包+压缩</p><p><code>tar -jcvf 打包并且压缩生成的文件名.tar.bz2 被打包的目录名</code></p><p><code>tar -gcvf 打包并且压缩生成的文件名.tar.gz 被打包的目录名</code></p><p>4、解包+解压</p><p><code>tar -jxvf 要解压的bzip2文件</code></p><p><code>tar -gxvf 要解压的gzip文件</code></p><p>参数解释：</p><p>c 表示打包</p><p>x 表示解包</p><p>v 表示以详细的信息显示出来</p><p>f 后面紧跟着文件目标</p><p>j 以<code>bzip2</code>格式压缩或解压</p><p>g 以<code>gzip</code>格式压缩或解压</p><p>注意：使用<code>tar</code>打包、解包的话默认源文件会保留。</p><h4 id="4-2-6-更改apt源为国内源："><a href="#4-2-6-更改apt源为国内源：" class="headerlink" title="4.2.6 更改apt源为国内源："></a>4.2.6 更改apt源为国内源：</h4><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">在/etc/apt/sources.list文件前面添加如下条目</span><br><span class="line">#添加阿里源</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse</span><br><span class="line">deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse</span><br><span class="line">deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse</span><br><span class="line"></span><br></pre></td></tr></table></figure><p><code>sudo apt update</code></p>]]></content>
    
    
    <summary type="html">&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1linux%E6%98%AF%E4%BB%80%E4%B9%88%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F&quot;&gt;1、Linux是什么操作系统？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2linux%E5%92%8C%E5%85%B6%E4%BB%96%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E5%A4%84%E5%92%8C%E4%BC%98%E7%82%B9&quot;&gt;2、Linux和其他操作系统的不同之处和优点&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21linux%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E5%A4%84&quot;&gt;2.1Linux的不同之处&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22linux%E7%9B%B8%E6%AF%94windows%E7%9A%84%E4%BC%98%E7%82%B9&quot;&gt;2.2Linux相比Windows的优点&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3linux%E7%9A%84%E5%AE%89%E8%A3%85%E6%96%B9%E5%BC%8F&quot;&gt;3、Linux的安装方式&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31%E5%9C%A8%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%B8%AD%E5%AE%89%E8%A3%85linux&quot;&gt;3.1在虚拟机中安装Linux&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#311%E6%9C%89%E5%93%AA%E4%BA%9B%E5%B8%B8%E8%A7%81%E7%9A%84%E8%99%9A%E6%8B%9F%E6%9C%BA&quot;&gt;3.1.1有哪些常见的虚拟机？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#312%E4%B8%8B%E8%BD%BD%E8%99%9A%E6%8B%9F%E6%9C%BA&quot;&gt;3.1.2下载虚拟机&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#313%E5%AE%89%E8%A3%85%E8%99%9A%E6%8B%9F%E6%9C%BA%E5%B9%B6%E5%BC%80%E5%90%AF%E8%99%9A%E6%8B%9F%E5%8C%96%E6%94%AF%E6%8C%81&quot;&gt;3.1.3安装虚拟机并开启虚拟化支持&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9C%A8%E8%99%9A%E6%8B%9F%E6%9C%BA%E4%B8%AD%E5%AE%89%E8%A3%85linux&quot;&gt;在虚拟机中安装Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32%E5%9C%A8%E5%AE%9E%E4%BD%93%E6%9C%BA%E5%AE%89%E8%A3%85linux&quot;&gt;3.2在实体机安装Linux&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4linux%E5%9F%BA%E7%A1%80%E5%91%BD%E4%BB%A4&quot;&gt;4、Linux基础命令&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E7%AC%AC%E4%B8%80%E8%8A%82%E8%AF%BE&quot;&gt;4.1 第一节课：&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#411-touch%E5%91%BD%E4%BB%A4&quot;&gt;4.1.1 &lt;code&gt;touch&lt;/code&gt;命令：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#412-ls-%E5%91%BD%E4%BB%A4&quot;&gt;4.1.2 &lt;code&gt;ls&lt;/code&gt; 命令：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#413-nano-%E5%91%BD%E4%BB%A4&quot;&gt;4.1.3 &lt;code&gt;nano&lt;/code&gt; 命令：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#414-cat-%E5%91%BD%E4%BB%A4&quot;&gt;4.1.4 &lt;code&gt;cat&lt;/code&gt; 命令：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#415-mkdir-%E5%91%BD%E4%BB%A4&quot;&gt;4.1.5 &lt;code&gt;mkdir&lt;/code&gt; 命令：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#416-cd-%E5%91%BD%E4%BB%A4&quot;&gt;4.1.6 &lt;code&gt;cd&lt;/code&gt; 命令：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#417-pwd-%E5%91%BD%E4%BB%A4&quot;&gt;4.1.7 &lt;code&gt;pwd&lt;/code&gt; 命令：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#418-top-%E5%91%BD%E4%BB%A4&quot;&gt;4.1.8 &lt;code&gt;top&lt;/code&gt; 命令：&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E7%AC%AC%E4%BA%8C%E8%8A%82%E8%AF%BE&quot;&gt;4.2 第二节课：&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#421-%E5%A1%AB%E5%9D%91-%E7%B3%BB%E7%BB%9F%E6%9D%83%E9%99%90&quot;&gt;4.2.1 填坑 &lt;code&gt;系统权限&lt;/code&gt;：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#422-%E4%BF%AE%E6%94%B9%E5%AF%86%E7%A0%81&quot;&gt;4.2.2 修改密码：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#423-%E4%BC%91%E7%9C%A0%E8%BF%9B%E7%A8%8B&quot;&gt;4.2.3 休眠进程：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#424-%E5%8E%8B%E7%BC%A9&quot;&gt;4.2.4 压缩：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#425-tar%E6%89%93%E5%8C%85&quot;&gt;4.2.5 &lt;code&gt;tar&lt;/code&gt;打包：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#426-%E6%9B%B4%E6%94%B9apt%E6%BA%90%E4%B8%BA%E5%9B%BD%E5%86%85%E6%BA%90&quot;&gt;4.2.6 更改apt源为国内源：&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;1、Linux是什么操作系统？&quot;&gt;&lt;a href=&quot;#1、Linux是什么操作系统？&quot; class=&quot;headerlink&quot; title=&quot;1、Linux是什么操作系统？&quot;&gt;&lt;/a&gt;1、Linux是什么操作系统？&lt;/h2&gt;&lt;p&gt;Linux操作系统也可以叫做“Linux发行版”。通常来讲，一个Linux发行版包括Linux内核，以及将Linux发行版系统安装到本机的安装程序，还有每个发行版具有特色的专有软件。各个发行版都有其不同的特色，有些发行版对不同电脑硬件结构进行优化和支持，有些发行版对普通用户或开发者使用方式的调整，也有对针对实时应用或嵌入式系统的开发等等。当前，超过三百个发行版被积极的开发，最普遍被使用的发行版有大约十二个。较为知名的有Debian、Ubuntu、Fedora和openSUSE等。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
  </entry>
  
  <entry>
    <title>如何在AmazeUI中当改变select标签后触发Vue方法的问题</title>
    <link href="https://blog.yeefire.com/2020_02/AmazeUI.html"/>
    <id>https://blog.yeefire.com/2020_02/AmazeUI.html</id>
    <published>2020-02-21T10:23:53.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="如何在AmazeUI中当改变select标签后触发Vue方法的问题。"><a href="#如何在AmazeUI中当改变select标签后触发Vue方法的问题。" class="headerlink" title="如何在AmazeUI中当改变select标签后触发Vue方法的问题。"></a>如何在AmazeUI中当改变select标签后触发Vue方法的问题。</h1><!-- TOC --><ul><li><a href="#%E5%A6%82%E4%BD%95%E5%9C%A8amazeui%E4%B8%AD%E5%BD%93%E6%94%B9%E5%8F%98select%E6%A0%87%E7%AD%BE%E5%90%8E%E8%A7%A6%E5%8F%91vue%E6%96%B9%E6%B3%95%E7%9A%84%E9%97%AE%E9%A2%98">如何在AmazeUI中当改变select标签后触发Vue方法的问题。</a><ul><li><a href="#%E9%A6%96%E5%85%88">首先</a></li><li><a href="#%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0">问题描述</a></li><li><a href="#%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88">解决方案</a><ul><li><a href="#html">HTML</a></li><li><a href="#js">JS</a></li></ul></li><li><a href="#%E7%BB%93%E5%B0%BE">结尾</a></li></ul></li></ul><!-- /TOC --><h2 id="首先"><a href="#首先" class="headerlink" title="首先"></a>首先</h2><p>我是一个有全栈梦的程序猿，但是写前端对我来说实在是有些难受，这个假期在大学社团中我负责一个项目的后端与后台管理界面，不得不要写页面，那么借此机会也来学一下Vue和前端的基础。 </p><span id="more"></span><p><strong>我希望看到这篇博文中的人对本文解决方案的有改进方法的朋友能够在留言区或Telegram中进行沟通，谢谢！</strong> </p><h2 id="问题描述"><a href="#问题描述" class="headerlink" title="问题描述"></a>问题描述</h2><p>在使用AmazeUI这套后台模板时，碰到了我原来没有遇到过的问题。<strong>我想每次在更改<code>select</code>标签中的<code>option</code>选项时都调用Vue对象中的一个方法,将所选<code>option</code>的<code>value</code>值弹出来。</strong>但是使用Vue的<code>@change</code>时没办法监听AmazeUI中select标签的改变。因为我刚刚学习Vue还有很多地方不懂，一开始怀疑自己的语法可能有问题，但是我在一个全新的HTML页面中尝试了我的语法发现并没有遇到问题。于是我开始仔细观察AmazeUI后台模板中的这个select标签，发现它有一个特别的属性:<code>data-am-selected=&quot;&#123;btnSize: &#39;sm&#39;&#125;&quot;</code>后来经过搜索得知这个AmazeUI的一个样式，如果将它删掉那么可以通过Vue监听改变下拉框的事件，但是样式就丢失了，所以经过翻阅博客和自己尝试最终找到了一个在我这里可用的解决方案。</p><h2 id="解决方案"><a href="#解决方案" class="headerlink" title="解决方案"></a>解决方案</h2><p>在尝试解决问题的过程中，我发现原生js的<code>onclick</code>可以监听到AmazeUI中<code>select</code>的更改选项<code>option</code>的事件！<br>那么是否可以通过原生js的<code>onclick</code>触发的事件去调用Vue中的<code>methods</code>的方法呢？ </p><p><strong>于是我在原生JS的onclick中调用了Vue对象list的getAll()方法。问题解决！</strong></p><h3 id="HTML"><a href="#HTML" class="headerlink" title="HTML"></a>HTML</h3><figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">select</span>  <span class="attr">data-am-selected</span>=<span class="string">&quot;&#123;btnSize: &#x27;sm&#x27;&#125;&quot;</span> <span class="attr">onchange</span>=<span class="string">&quot;list.getAll()&quot;</span> <span class="attr">v-model</span>=<span class="string">&quot;choice_option&quot;</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;1&quot;</span>&gt;</span>正常状态<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;0&quot;</span> &gt;</span>待审核状态<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;-1&quot;</span>&gt;</span>未通过审核状态<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">&quot;2&quot;</span> <span class="attr">selected</span>&gt;</span>全部歌曲<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">p</span>&gt;</span>value=&#123;&#123;choice_option&#125;&#125;<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br></pre></td></tr></table></figure><h3 id="JS"><a href="#JS" class="headerlink" title="JS"></a>JS</h3><figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">var</span> list = <span class="keyword">new</span> <span class="title class_">Vue</span>(&#123;</span><br><span class="line">    <span class="attr">el</span>: <span class="string">&#x27;#lists&#x27;</span>,</span><br><span class="line">    <span class="attr">data</span>: &#123;</span><br><span class="line">        <span class="attr">choice_option</span>: <span class="string">&quot;2&quot;</span>,</span><br><span class="line">    &#125;,</span><br><span class="line">    <span class="attr">methods</span>: &#123;</span><br><span class="line">        <span class="attr">getAll</span>:<span class="keyword">function</span> (<span class="params"></span>) &#123;</span><br><span class="line">            <span class="title function_">alert</span>(<span class="string">&quot;触发事件&quot;</span>)</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure><h2 id="结尾"><a href="#结尾" class="headerlink" title="结尾"></a>结尾</h2><p>总的来说就是用原生js去调用Vue中的方法，或许这个问题比较低级，我一度不想写这个博文，因为可能会被喷哈哈。但是《暗时间》中提到过小问题也要写博文，这样能在字里行间在进行一次咀嚼，大脑短期记忆的容量有限但是相对计算机而言存储空间可以无限的。不管怎么样我会选择花些时间去整理这次困扰到我的问题。希望能给遇到同样问题的朋友提供帮助，也希望能收到大家的留言来提供更好的解决方法。谢谢。 </p><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群<span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;如何在AmazeUI中当改变select标签后触发Vue方法的问题。&quot;&gt;&lt;a href=&quot;#如何在AmazeUI中当改变select标签后触发Vue方法的问题。&quot; class=&quot;headerlink&quot; title=&quot;如何在AmazeUI中当改变select标签后触发Vue方法的问题。&quot;&gt;&lt;/a&gt;如何在AmazeUI中当改变select标签后触发Vue方法的问题。&lt;/h1&gt;&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A6%82%E4%BD%95%E5%9C%A8amazeui%E4%B8%AD%E5%BD%93%E6%94%B9%E5%8F%98select%E6%A0%87%E7%AD%BE%E5%90%8E%E8%A7%A6%E5%8F%91vue%E6%96%B9%E6%B3%95%E7%9A%84%E9%97%AE%E9%A2%98&quot;&gt;如何在AmazeUI中当改变select标签后触发Vue方法的问题。&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%A6%96%E5%85%88&quot;&gt;首先&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0&quot;&gt;问题描述&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88&quot;&gt;解决方案&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#html&quot;&gt;HTML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#js&quot;&gt;JS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%BB%93%E5%B0%BE&quot;&gt;结尾&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;首先&quot;&gt;&lt;a href=&quot;#首先&quot; class=&quot;headerlink&quot; title=&quot;首先&quot;&gt;&lt;/a&gt;首先&lt;/h2&gt;&lt;p&gt;我是一个有全栈梦的程序猿，但是写前端对我来说实在是有些难受，这个假期在大学社团中我负责一个项目的后端与后台管理界面，不得不要写页面，那么借此机会也来学一下Vue和前端的基础。 &lt;/p&gt;</summary>
    
    
    
    
    <category term="前端" scheme="https://blog.yeefire.com/tags/%E5%89%8D%E7%AB%AF/"/>
    
    <category term="AmazeUI" scheme="https://blog.yeefire.com/tags/AmazeUI/"/>
    
  </entry>
  
  <entry>
    <title>使用Docker部署安装WordPress博客平台</title>
    <link href="https://blog.yeefire.com/2020_02/Docker_WordPress.html"/>
    <id>https://blog.yeefire.com/2020_02/Docker_WordPress.html</id>
    <published>2020-02-21T07:23:30.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="使用Docker部署安装WordPress博客平台"><a href="#使用Docker部署安装WordPress博客平台" class="headerlink" title="使用Docker部署安装WordPress博客平台"></a>使用Docker部署安装WordPress博客平台</h1><p>使用Docker可以快速的创建一个WordPress容器。在快节奏的生活中，讲究的是效率、便捷、稳定。使用容器可以很方便的对WordPress平台的迁移与管理，接下来我将记录下来我搭建的过程。</p><!-- TOC --><ul><li><a href="#%E4%BD%BF%E7%94%A8docker%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85wordpress%E5%8D%9A%E5%AE%A2%E5%B9%B3%E5%8F%B0">使用Docker部署安装WordPress博客平台</a><ul><li><a href="#%E5%89%8D%E6%8E%92%E6%8F%90%E7%A4%BA">前排提示</a></li><li><a href="#0x01%E5%AE%89%E8%A3%85docker%E5%B7%B2%E7%BB%8F%E5%AE%89%E8%A3%85%E7%9A%84%E8%AF%B7%E7%95%A5%E8%BF%87">0x01安装Docker（已经安装的请略过）</a><ul><li><a href="#%E9%85%8D%E7%BD%AE-docker-ce-apt-%E6%BA%90">配置 Docker-CE APT 源</a></li><li><a href="#%E5%AE%89%E8%A3%85-docker-ce">安装 Docker-CE</a></li></ul></li><li><a href="#0x02%E9%85%8D%E7%BD%AEdocker-repository%E4%BB%93%E5%BA%93%E9%95%9C%E5%83%8F%E5%8A%A0%E9%80%9F%E4%B8%8D%E9%9C%80%E8%A6%81%E4%BB%93%E5%BA%93%E5%8A%A0%E9%80%9F%E8%AF%B7%E7%95%A5%E8%BF%87">0x02配置Docker Repository仓库镜像加速(不需要仓库加速请略过)</a></li><li><a href="#0x03%E6%90%AD%E5%BB%BA-wordpress%E6%AD%A3%E7%89%87%E6%AD%A3%E7%89%87">0x03搭建 WordPress（正片、正片！）</a><ul><li><a href="#%E6%8B%89%E5%8F%96wordpress%E9%95%9C%E5%83%8F">拉取WordPress镜像</a></li><li><a href="#%E6%8B%89%E5%8F%96mariadb-55%E7%89%88%E6%9C%AC%E9%95%9C%E5%83%8F">拉取MariaDB 5.5版本镜像</a></li><li><a href="#%E5%90%AF%E5%8A%A8maria%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%B9%E5%99%A8">启动Maria数据库容器</a></li><li><a href="#%E5%88%9B%E5%BB%BAwordpress%E4%BD%BF%E7%94%A8%E7%9A%84%E6%95%B0%E6%8D%AE%E5%BA%93">创建WordPress使用的数据库</a></li><li><a href="#%E8%BF%90%E8%A1%8Cwordpress%E5%AE%B9%E5%99%A8">运行WordPress容器</a></li></ul></li></ul></li></ul><!-- /TOC --><h2 id="前排提示"><a href="#前排提示" class="headerlink" title="前排提示"></a>前排提示</h2><p>我当前的环境是Debian 10，如果你是其他的Linux发行版，那么请不要完全按照本文进行操作，请变通（比如您是RHEL系，您需要将本文中的apt包管理器换做yum/dnf包管理器进行安装软件包）！如果遇到问题可以在底部留言给我。</p><p><strong>如果您已经安装好Docker，并且不需要配置Docker Repository镜像加速的话，直接看第0x03部分就好了</strong></p><span id="more"></span><h2 id="0x01安装Docker（已经安装的请略过）"><a href="#0x01安装Docker（已经安装的请略过）" class="headerlink" title="0x01安装Docker（已经安装的请略过）"></a>0x01安装Docker（已经安装的请略过）</h2><h3 id="配置-Docker-CE-APT-源"><a href="#配置-Docker-CE-APT-源" class="headerlink" title="配置 Docker-CE APT 源"></a>配置 Docker-CE APT 源</h3><p>由于 apt 源使用 HTTPS 以确保软件下载过程中不被篡改。因此，我们首先需要添加使用 HTTPS 传输的软件包以及 CA 证书。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt-get update</span><br><span class="line"></span><br><span class="line"><span class="built_in">sudo</span> apt-get install \</span><br><span class="line">     apt-transport-https \</span><br><span class="line">     ca-certificates \</span><br><span class="line">     curl \</span><br><span class="line">     gnupg2 \</span><br><span class="line">     lsb-release \</span><br><span class="line">     software-properties-common</span><br></pre></td></tr></table></figure><p>由于国内的网络政策，可能使用Docker官方源下载较慢，建议使用国内镜像源，详见下方注释。</p><p>为了确认所下载软件包的合法性，需要添加软件源的 GPG 密钥。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | <span class="built_in">sudo</span> apt-key add -</span><br><span class="line"></span><br><span class="line"><span class="comment"># 官方源</span></span><br><span class="line"><span class="comment"># curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -</span></span><br></pre></td></tr></table></figure><p>然后我们需要向apt source.list 中添加Docker-CE 软件源：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> add-apt-repository \</span><br><span class="line">   <span class="string">&quot;deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/debian \</span></span><br><span class="line"><span class="string">   <span class="subst">$(lsb_release -cs)</span> \</span></span><br><span class="line"><span class="string">   stable&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 官方源</span></span><br><span class="line"><span class="comment"># sudo add-apt-repository \</span></span><br><span class="line"><span class="comment">#    &quot;deb [arch=amd64] https://download.docker.com/linux/debian \</span></span><br><span class="line"><span class="comment">#    $(lsb_release -cs) \</span></span><br><span class="line"><span class="comment">#    stable&quot;</span></span><br></pre></td></tr></table></figure><h3 id="安装-Docker-CE"><a href="#安装-Docker-CE" class="headerlink" title="安装 Docker-CE"></a>安装 Docker-CE</h3><p>更新 apt 软件包缓存，并安装 <code>docker-ce</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> apt-get update</span><br><span class="line"></span><br><span class="line"><span class="built_in">sudo</span> apt-get install docker-ce</span><br></pre></td></tr></table></figure><h2 id="0x02配置Docker-Repository仓库镜像加速-不需要仓库加速请略过"><a href="#0x02配置Docker-Repository仓库镜像加速-不需要仓库加速请略过" class="headerlink" title="0x02配置Docker Repository仓库镜像加速(不需要仓库加速请略过)"></a>0x02配置Docker Repository仓库镜像加速(不需要仓库加速请略过)</h2><p>以下系统目前是支持的：Ubuntu 16.04+、Debian 8+、CentOS 7</p><p>使用 systemd 的系统，请在 <code>/etc/docker/daemon.json</code> 中写入如下内容（如果文件不存在请新建该文件）</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  <span class="string">&quot;registry-mirrors&quot;</span>: [</span><br><span class="line">    <span class="string">&quot;https://dockerhub.azk8s.cn&quot;</span>,</span><br><span class="line">    <span class="string">&quot;https://hub-mirror.c.163.com&quot;</span></span><br><span class="line">  ]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>编写的daemon.json文件一定要符合JSON规范，否则Docker无法启动</p></blockquote><p>之后重新载入daemon配置文件并重启Docker服务</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl daemon-reload</span><br><span class="line"><span class="built_in">sudo</span> systemctl restart docker</span><br></pre></td></tr></table></figure><p><img src="https://cdn.yeefire.com/hexo/img/Docker_daemon.png" alt="Docker_daemon.png"></p><h2 id="0x03搭建-WordPress（正片、正片！）"><a href="#0x03搭建-WordPress（正片、正片！）" class="headerlink" title="0x03搭建 WordPress（正片、正片！）"></a>0x03搭建 WordPress（正片、正片！）</h2><h3 id="拉取WordPress镜像"><a href="#拉取WordPress镜像" class="headerlink" title="拉取WordPress镜像"></a>拉取WordPress镜像</h3><p><code>docker pull wordpress:latest</code></p><p>latest标签为当前最新的WordPress容器版本</p><h3 id="拉取MariaDB-5-5版本镜像"><a href="#拉取MariaDB-5-5版本镜像" class="headerlink" title="拉取MariaDB 5.5版本镜像"></a>拉取MariaDB 5.5版本镜像</h3><p>MariaDB 5.5之前的版本完全参照Mysql版本，与Mysql语法兼容。</p><p><code>docker pull mariadb:5.5</code></p><h3 id="启动Maria数据库容器"><a href="#启动Maria数据库容器" class="headerlink" title="启动Maria数据库容器"></a>启动Maria数据库容器</h3><p><code>docker run --name=mariadb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=输入数据库root用户的密码 -v /etc/mariadb/data:/var/lib/mysql -d --restart=always mariadb:5.5</code></p><h3 id="创建WordPress使用的数据库"><a href="#创建WordPress使用的数据库" class="headerlink" title="创建WordPress使用的数据库"></a>创建WordPress使用的数据库</h3><p>为了安全考量，我们需要创建一个单独的用户给WordPress使用。加下来我们需要进入到MariaDB容器中，并使用Mysql命令来创建一个数据库，并分配一个用户给这个数据库。</p><p><code>docker exec -it mariadb /bin/bash</code></p><p>进入容器后我们使用刚才在容器上指定的root密码来登录MariaDB</p><p><code>mysql -u root -p 输入数据库root用户的密码</code></p><p>之后会进入到这样的交互界面：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">root@b45ff49a112a:/# mysql -u root -p 输入数据库root用户的密码 (回车)</span><br><span class="line">Welcome to the MariaDB monitor.  Commands end with ; or \g.</span><br><span class="line">Your MariaDB connection id is 8</span><br><span class="line">Server version: 5.5.64-MariaDB-1~trusty mariadb.org binary distribution</span><br><span class="line"></span><br><span class="line">Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.</span><br><span class="line"></span><br><span class="line">Type &#x27;help;&#x27; or &#x27;\h&#x27; for help. Type &#x27;\c&#x27; to clear the current input statement.</span><br><span class="line"></span><br><span class="line">MariaDB [(none)]&gt;</span><br></pre></td></tr></table></figure><ul><li><strong>下面我会将交互模式返回的信息也表现出来用于大家检验命令执行的正确性。</strong></li></ul><p>创建WordPress数据库，数据库名为 <code>wordpress</code></p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">MariaDB [(<span class="keyword">none</span>)]<span class="operator">&gt;</span> <span class="keyword">create</span> database wordpress;</span><br><span class="line">Query OK, <span class="number">1</span> <span class="type">row</span> affected (<span class="number">0.00</span> sec)</span><br></pre></td></tr></table></figure><p>创建WordPress用户，用户名为 <code>wordpress</code>,密码为 <code>password</code></p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">MariaDB [(<span class="keyword">none</span>)]<span class="operator">&gt;</span> <span class="keyword">create</span> <span class="keyword">user</span> <span class="string">&#x27;wordpress&#x27;</span>@<span class="string">&#x27;%&#x27;</span> identified <span class="keyword">by</span> <span class="string">&#x27;password&#x27;</span>;</span><br><span class="line">Query OK, <span class="number">0</span> <span class="keyword">rows</span> affected (<span class="number">0.00</span> sec)</span><br></pre></td></tr></table></figure><ul><li>我这边仅作为示范，将用户与数据库设为的相同名称。</li></ul><p>为<code>wordpress</code>用户添加对数据库<code>wordpress</code>的所有的权限，并设置访问密码为<code>password</code></p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">MariaDB [(<span class="keyword">none</span>)]<span class="operator">&gt;</span> <span class="keyword">grant</span> <span class="keyword">all</span> privileges <span class="keyword">on</span> wordpress.<span class="operator">*</span> <span class="keyword">to</span> <span class="string">&#x27;wordpress&#x27;</span>@<span class="string">&#x27;%&#x27;</span> identified <span class="keyword">by</span> <span class="string">&#x27;password&#x27;</span>;</span><br><span class="line">Query OK, <span class="number">0</span> <span class="keyword">rows</span> affected (<span class="number">0.00</span> sec)</span><br></pre></td></tr></table></figure><p>最后我们刷新数据库用户权限，立即生效</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">MariaDB [(<span class="keyword">none</span>)]<span class="operator">&gt;</span> flush privileges;</span><br><span class="line">Query OK, <span class="number">0</span> <span class="keyword">rows</span> affected (<span class="number">0.01</span> sec)</span><br></pre></td></tr></table></figure><h3 id="运行WordPress容器"><a href="#运行WordPress容器" class="headerlink" title="运行WordPress容器"></a>运行WordPress容器</h3><p>到这里准备工作已经做好了，请记录好刚才为WordPress数据库设置的用户名和密码，稍后将会使用。</p><p><code>-p 80:80</code> 将容器的80端口映射到本机的80端口并开放，使之可以通过<code>http://本机ip</code>访问搭建的WordPress博客平台。</p><p><code>docker run --name=wordpress -p 80:80 -v /home/wordpress:/var/www/html -d --restart=always wordpress:latest</code></p><p>马上就好……现在你可以访问一下你的<code>http://ip</code>或者<code>http://域名</code></p><p>我们到了这最后一步：</p><p><img src="https://cdn.yeefire.com/hexo/img/wordpress_ip.jpg" alt="wordpress_ip.jpg"></p><p>如果你刚才没有按照本教程配置数据库，你这里自己填写就好。如果你是按照本教程搭建到这里，那么在此处请填写你服务器本机的IP地址或域名！（当然数据库主机这里你也可以填写MariaDB容器的IP地址）</p><p>之后数据库名和用户名都为我们刚才设置好的<code>wordpress</code>,密码也填写好。点提交就好咯~</p><p>有机会的话我们弄个SSL证书给它挂上，然后用Nginx反向代理来访问我们的WordPress容器，不一定哪天写一份教程出来。</p><p>参考：</p><p><span class="exturl" data-url="aHR0cHM6Ly9odWIuZG9ja2VyLmNvbS9fL3dvcmRwcmVzcw==" title="https://hub.docker.com/_/wordpress">Docker Hub WordPress<i class="fa fa-external-link"></i></span></p><p><span class="exturl" data-url="aHR0cHM6Ly9kb2NzLmRvY2tlci5jb20v" title="https://docs.docker.com/">Docker Doc<i class="fa fa-external-link"></i></span></p><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群:<br><span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog(Telegram)<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p><hr>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;使用Docker部署安装WordPress博客平台&quot;&gt;&lt;a href=&quot;#使用Docker部署安装WordPress博客平台&quot; class=&quot;headerlink&quot; title=&quot;使用Docker部署安装WordPress博客平台&quot;&gt;&lt;/a&gt;使用Docker部署安装WordPress博客平台&lt;/h1&gt;&lt;p&gt;使用Docker可以快速的创建一个WordPress容器。在快节奏的生活中，讲究的是效率、便捷、稳定。使用容器可以很方便的对WordPress平台的迁移与管理，接下来我将记录下来我搭建的过程。&lt;/p&gt;
&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%BF%E7%94%A8docker%E9%83%A8%E7%BD%B2%E5%AE%89%E8%A3%85wordpress%E5%8D%9A%E5%AE%A2%E5%B9%B3%E5%8F%B0&quot;&gt;使用Docker部署安装WordPress博客平台&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E6%8E%92%E6%8F%90%E7%A4%BA&quot;&gt;前排提示&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#0x01%E5%AE%89%E8%A3%85docker%E5%B7%B2%E7%BB%8F%E5%AE%89%E8%A3%85%E7%9A%84%E8%AF%B7%E7%95%A5%E8%BF%87&quot;&gt;0x01安装Docker（已经安装的请略过）&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%85%8D%E7%BD%AE-docker-ce-apt-%E6%BA%90&quot;&gt;配置 Docker-CE APT 源&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85-docker-ce&quot;&gt;安装 Docker-CE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#0x02%E9%85%8D%E7%BD%AEdocker-repository%E4%BB%93%E5%BA%93%E9%95%9C%E5%83%8F%E5%8A%A0%E9%80%9F%E4%B8%8D%E9%9C%80%E8%A6%81%E4%BB%93%E5%BA%93%E5%8A%A0%E9%80%9F%E8%AF%B7%E7%95%A5%E8%BF%87&quot;&gt;0x02配置Docker Repository仓库镜像加速(不需要仓库加速请略过)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#0x03%E6%90%AD%E5%BB%BA-wordpress%E6%AD%A3%E7%89%87%E6%AD%A3%E7%89%87&quot;&gt;0x03搭建 WordPress（正片、正片！）&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8B%89%E5%8F%96wordpress%E9%95%9C%E5%83%8F&quot;&gt;拉取WordPress镜像&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8B%89%E5%8F%96mariadb-55%E7%89%88%E6%9C%AC%E9%95%9C%E5%83%8F&quot;&gt;拉取MariaDB 5.5版本镜像&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%90%AF%E5%8A%A8maria%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%B9%E5%99%A8&quot;&gt;启动Maria数据库容器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%88%9B%E5%BB%BAwordpress%E4%BD%BF%E7%94%A8%E7%9A%84%E6%95%B0%E6%8D%AE%E5%BA%93&quot;&gt;创建WordPress使用的数据库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%BF%90%E8%A1%8Cwordpress%E5%AE%B9%E5%99%A8&quot;&gt;运行WordPress容器&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;前排提示&quot;&gt;&lt;a href=&quot;#前排提示&quot; class=&quot;headerlink&quot; title=&quot;前排提示&quot;&gt;&lt;/a&gt;前排提示&lt;/h2&gt;&lt;p&gt;我当前的环境是Debian 10，如果你是其他的Linux发行版，那么请不要完全按照本文进行操作，请变通（比如您是RHEL系，您需要将本文中的apt包管理器换做yum/dnf包管理器进行安装软件包）！如果遇到问题可以在底部留言给我。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;如果您已经安装好Docker，并且不需要配置Docker Repository镜像加速的话，直接看第0x03部分就好了&lt;/strong&gt;&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="Docker" scheme="https://blog.yeefire.com/tags/Docker/"/>
    
    <category term="Podman" scheme="https://blog.yeefire.com/tags/Podman/"/>
    
    <category term="Raspberry" scheme="https://blog.yeefire.com/tags/Raspberry/"/>
    
    <category term="树莓派" scheme="https://blog.yeefire.com/tags/%E6%A0%91%E8%8E%93%E6%B4%BE/"/>
    
  </entry>
  
  <entry>
    <title>在Raspberry树莓派中搭建NFS存储服务器</title>
    <link href="https://blog.yeefire.com/2020_02/Raspberry_NFS.html"/>
    <id>https://blog.yeefire.com/2020_02/Raspberry_NFS.html</id>
    <published>2020-02-21T07:22:51.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="在-Raspberry-树莓派-中搭建NFS存储服务器"><a href="#在-Raspberry-树莓派-中搭建NFS存储服务器" class="headerlink" title="在 Raspberry 树莓派 中搭建NFS存储服务器"></a>在 Raspberry 树莓派 中搭建NFS存储服务器</h1><p>好多人买来树莓派不知道怎么折腾，我的朋友送给我一个树莓派4，我就在琢磨怎么利用好它。看到了它的USB3.0突然想到挂载一个移动硬盘然后做云存储吧。树莓派4这次升级了处理器、USB3.0和真千兆网口（emm以前是和USB共用的总线……速度不堪想象）。<br>综上所述，我开始有了在树莓派4上搭建NFS服务器的想法，下面将记录本次搭建的过程和遇到的问题。</p><!-- TOC --><ul><li><a href="#%E5%9C%A8-raspberry-%E6%A0%91%E8%8E%93%E6%B4%BE-%E4%B8%AD%E6%90%AD%E5%BB%BAnfs%E5%AD%98%E5%82%A8%E6%9C%8D%E5%8A%A1%E5%99%A8">在 Raspberry 树莓派 中搭建NFS存储服务器</a><ul><li><a href="#%E5%89%8D%E6%8F%90">前提</a></li><li><a href="#%E5%AE%89%E8%A3%85%E5%BF%85%E5%A4%87%E5%8C%85">安装必备包</a></li><li><a href="#%E5%88%9B%E5%BB%BA%E8%A6%81%E5%85%B1%E4%BA%AB%E7%9A%84%E7%9B%AE%E5%BD%95%E6%96%87%E4%BB%B6%E5%A4%B9">创建要共享的目录文件夹</a></li><li><a href="#%E7%BC%96%E8%BE%91%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">编辑配置文件</a></li><li><a href="#%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1">启动服务</a></li><li><a href="#%E8%AE%BE%E7%BD%AE%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF%E5%8A%A8nfs-server%E6%9C%8D%E5%8A%A1">设置开机自启动nfs-server服务</a></li><li><a href="#%E6%8C%82%E8%BD%BDnfs">挂载NFS</a><ul><li><a href="#%E5%9C%A8-windows-%E4%B8%8A%E6%8C%82%E8%BD%BD-nfs">在 Windows 上挂载 NFS</a></li><li><a href="#%E5%9C%A8-linux-%E4%B8%AD%E6%8C%82%E8%BD%BD-nfs">在 Linux 中挂载 NFS</a></li></ul></li><li><a href="#%E5%A4%A7%E5%8A%9F%E5%91%8A%E6%88%90">大功告成</a></li></ul></li></ul><!-- /TOC --><h2 id="前提"><a href="#前提" class="headerlink" title="前提"></a>前提</h2><p>我使用树莓派官方推荐的系统 Raspbian 操作并搭建成功，如果你安装了Ubuntu for Arm等其它系统，请不要完全按照本文进行操作，请变通或者在底部留言给我。</p><span id="more"></span><h2 id="安装必备包"><a href="#安装必备包" class="headerlink" title="安装必备包"></a>安装必备包</h2><p><code>sudo apt-get install nfs-kernel-server nfs-common portmap</code></p><h2 id="创建要共享的目录文件夹"><a href="#创建要共享的目录文件夹" class="headerlink" title="创建要共享的目录文件夹"></a>创建要共享的目录文件夹</h2><p><code>sudo mkdir /mnt/nfs</code></p><h2 id="编辑配置文件"><a href="#编辑配置文件" class="headerlink" title="编辑配置文件"></a>编辑配置文件</h2><p><code>sudo vi /etc/exports</code><br>PS：如果不习惯<code>vi/vim</code>编辑器的朋友可以使用<code>nano</code>编辑器来替代文中的<code>vi</code>编辑器</p><p>在文件尾加入如下行：</p><p><code>/mnt/nfs *(rw,sync,no_root_squash)</code></p><p>参数说明：</p><p>1、此处的*是代表允许任何主机来挂载和使用你现在搭建的NFS服务，为了安全建议使用将此处的*替换为你固定的IP。</p><p>2、rw：挂载后可对目录进行读写，如果想以只读方式挂载，那么将<code>rw</code>替换为<code>ro</code>。</p><p>3、sync：同时将数据写入到内存与硬盘中，保证不丢失数据。</p><p>4、no_root_squash：当NFS客户端以root管理员访问时，映射为NFS服务器的root管理员</p><p>如果你想了解更多的参数，这里有一篇别人的文章，建议向深入了解的朋友可以看看：<span class="exturl" data-url="aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MjY1MTM3L2FydGljbGUvZGV0YWlscy84MzE0NjQyMQ==" title="https://blog.csdn.net/qq_38265137/article/details/83146421">NFS服务详解<i class="fa fa-external-link"></i></span></p><h2 id="启动服务"><a href="#启动服务" class="headerlink" title="启动服务"></a>启动服务</h2><p><code>sudo systemctl start nfs-server</code></p><h2 id="设置开机自启动nfs-server服务"><a href="#设置开机自启动nfs-server服务" class="headerlink" title="设置开机自启动nfs-server服务"></a>设置开机自启动nfs-server服务</h2><p><code>sudo systemctl enable nfs-server</code></p><h2 id="挂载NFS"><a href="#挂载NFS" class="headerlink" title="挂载NFS"></a>挂载NFS</h2><h3 id="在-Windows-上挂载-NFS"><a href="#在-Windows-上挂载-NFS" class="headerlink" title="在 Windows 上挂载 NFS"></a>在 Windows 上挂载 NFS</h3><p>1、首先开启Windows的NFS客户端服务，按照<span class="exturl" data-url="aHR0cHM6Ly9qaW5neWFuLmJhaWR1LmNvbS9hcnRpY2xlL2FkYzgxNTEzYjc2YjNhZjcyM2JmNzNiMC5odG1s" title="https://jingyan.baidu.com/article/adc81513b76b3af723bf73b0.html">百度的教程即可<i class="fa fa-external-link"></i></span>打开。</p><p>2、在CMD中输入:</p><p><code>mount \\树莓派的IP地址\mnt\nfs z:</code></p><p>PS:上面的<code>z:</code>是将nfs云存储挂载到了Z这个盘符上（不要和现有的盘符冲突就行，比如说你要挂载到C：上肯定就是不行的）。</p><p>如果看到下面的提示，那么就证明挂载成功了。</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">z: is now successfully connected to \\xxx.xxx.xxx.xxx\mnt\nfs</span><br><span class="line"></span><br><span class="line">The command completed successfully.</span><br></pre></td></tr></table></figure><p>之后打开<code>计算机</code>，就能看到你刚才挂载的nfs了。</p><p><strong>如果遇到下面的报错，那就是你在Windows中挂载的有问题。</strong></p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Network Error - 53                                                             </span><br><span class="line"></span><br><span class="line">Type &#x27;NET HELPMSG 53&#x27; for more information. </span><br></pre></td></tr></table></figure><p>一般这种都是在挂载时IP地址没有填写正确，或者挂载的目录不正确，请反复检查来排查错误。</p><h3 id="在-Linux-中挂载-NFS"><a href="#在-Linux-中挂载-NFS" class="headerlink" title="在 Linux 中挂载 NFS"></a>在 Linux 中挂载 NFS</h3><p>1、安装<code>nfs-utils</code>和<code>portma</code>包</p><p><code>sudo apt-get install nfs-common portmap</code></p><p>2、创建一个提供挂载的目录<br><code>sudo mkdir /mnt/mount_nfs</code></p><p>3、挂载</p><p><code>sudo mount -t nfs 192.168.xxx.xxx:/mnt/nfs /mnt/mount_nfs</code></p><p>请将xxx这部分替换为树莓派的IP地址</p><h2 id="大功告成"><a href="#大功告成" class="headerlink" title="大功告成"></a>大功告成</h2><p>文章主要针对在树莓派上搭建NFS服务。当然其他的Linux设备或系统也可以按照这篇文章来操作，基本都能实现。但是不同的操作系统会有区别，希望你能搭建成功！</p><p>欢迎进行留言~</p><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群<span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;在-Raspberry-树莓派-中搭建NFS存储服务器&quot;&gt;&lt;a href=&quot;#在-Raspberry-树莓派-中搭建NFS存储服务器&quot; class=&quot;headerlink&quot; title=&quot;在 Raspberry 树莓派 中搭建NFS存储服务器&quot;&gt;&lt;/a&gt;在 Raspberry 树莓派 中搭建NFS存储服务器&lt;/h1&gt;&lt;p&gt;好多人买来树莓派不知道怎么折腾，我的朋友送给我一个树莓派4，我就在琢磨怎么利用好它。看到了它的USB3.0突然想到挂载一个移动硬盘然后做云存储吧。树莓派4这次升级了处理器、USB3.0和真千兆网口（emm以前是和USB共用的总线……速度不堪想象）。&lt;br&gt;综上所述，我开始有了在树莓派4上搭建NFS服务器的想法，下面将记录本次搭建的过程和遇到的问题。&lt;/p&gt;
&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9C%A8-raspberry-%E6%A0%91%E8%8E%93%E6%B4%BE-%E4%B8%AD%E6%90%AD%E5%BB%BAnfs%E5%AD%98%E5%82%A8%E6%9C%8D%E5%8A%A1%E5%99%A8&quot;&gt;在 Raspberry 树莓派 中搭建NFS存储服务器&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E6%8F%90&quot;&gt;前提&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85%E5%BF%85%E5%A4%87%E5%8C%85&quot;&gt;安装必备包&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%88%9B%E5%BB%BA%E8%A6%81%E5%85%B1%E4%BA%AB%E7%9A%84%E7%9B%AE%E5%BD%95%E6%96%87%E4%BB%B6%E5%A4%B9&quot;&gt;创建要共享的目录文件夹&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%BC%96%E8%BE%91%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot;&gt;编辑配置文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1&quot;&gt;启动服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%AE%BE%E7%BD%AE%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF%E5%8A%A8nfs-server%E6%9C%8D%E5%8A%A1&quot;&gt;设置开机自启动nfs-server服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8C%82%E8%BD%BDnfs&quot;&gt;挂载NFS&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9C%A8-windows-%E4%B8%8A%E6%8C%82%E8%BD%BD-nfs&quot;&gt;在 Windows 上挂载 NFS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9C%A8-linux-%E4%B8%AD%E6%8C%82%E8%BD%BD-nfs&quot;&gt;在 Linux 中挂载 NFS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A4%A7%E5%8A%9F%E5%91%8A%E6%88%90&quot;&gt;大功告成&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;


&lt;h2 id=&quot;前提&quot;&gt;&lt;a href=&quot;#前提&quot; class=&quot;headerlink&quot; title=&quot;前提&quot;&gt;&lt;/a&gt;前提&lt;/h2&gt;&lt;p&gt;我使用树莓派官方推荐的系统 Raspbian 操作并搭建成功，如果你安装了Ubuntu for Arm等其它系统，请不要完全按照本文进行操作，请变通或者在底部留言给我。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
    <category term="Raspberry" scheme="https://blog.yeefire.com/tags/Raspberry/"/>
    
    <category term="树莓派" scheme="https://blog.yeefire.com/tags/%E6%A0%91%E8%8E%93%E6%B4%BE/"/>
    
  </entry>
  
  <entry>
    <title>在 树莓派 Linux 中搭建匿名 danted socks5 代理服务器</title>
    <link href="https://blog.yeefire.com/2020_02/Raspberry_danted.html"/>
    <id>https://blog.yeefire.com/2020_02/Raspberry_danted.html</id>
    <published>2020-02-21T06:15:42.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="在-树莓派-Linux-中搭建匿名-danted-socks5-代理服务器"><a href="#在-树莓派-Linux-中搭建匿名-danted-socks5-代理服务器" class="headerlink" title="在 树莓派 Linux 中搭建匿名 danted socks5 代理服务器"></a>在 树莓派 Linux 中搭建匿名 danted socks5 代理服务器</h1><p>如果你跟我有这样的需求，并且还想继续折腾这块树莓派，你可以我对这次在树莓派4（理论任何树莓派版本都行）上搭建socks5服务器。</p><!-- TOC --><ul><li><a href="#%E5%9C%A8-%E6%A0%91%E8%8E%93%E6%B4%BE-linux-%E4%B8%AD%E6%90%AD%E5%BB%BA%E5%8C%BF%E5%90%8D-danted-socks5-%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8">在 树莓派 Linux 中搭建匿名 danted socks5 代理服务器</a><ul><li><a href="#%E5%89%8D%E6%8F%90">前提</a></li><li><a href="#%E5%AE%89%E8%A3%85%E5%BF%85%E5%A4%87%E5%8C%85">安装必备包</a></li><li><a href="#%E5%A4%87%E4%BB%BDdante-server%E9%BB%98%E8%AE%A4%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">备份dante-server默认的配置文件</a></li><li><a href="#%E7%BC%96%E8%BE%91%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6">编辑配置文件</a></li><li><a href="#%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1">启动服务</a></li><li><a href="#%E8%AE%BE%E7%BD%AE%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF%E6%9C%8D%E5%8A%A1">设置开机自启服务</a></li><li><a href="#%E5%85%B6%E4%BB%96%E9%97%AE%E9%A2%98">其他问题</a></li><li><a href="#%E5%A4%A7%E5%8A%9F%E5%91%8A%E6%88%90">大功告成</a></li></ul></li></ul><!-- /TOC --><h2 id="前提"><a href="#前提" class="headerlink" title="前提"></a>前提</h2><p>我是用的是目前树莓派官网提供的最新 Raspbian Linux 操作系统，如果你安装的是Ubuntu for Arm等其它系统，请不要完全按照本文进行操作，请变通！如果遇到问题可以在底部留言给我。</p><span id="more"></span><h2 id="安装必备包"><a href="#安装必备包" class="headerlink" title="安装必备包"></a>安装必备包</h2><p><code>sudo apt install dante-server</code></p><h2 id="备份dante-server默认的配置文件"><a href="#备份dante-server默认的配置文件" class="headerlink" title="备份dante-server默认的配置文件"></a>备份dante-server默认的配置文件</h2><p><code>sudo cp /etc/danted.conf /etc/danted.conf.bak</code></p><p>备份配置文件，如果改的太乱我们可以很方便的恢复。</p><h2 id="编辑配置文件"><a href="#编辑配置文件" class="headerlink" title="编辑配置文件"></a>编辑配置文件</h2><p><code>sudo vi /etc/danted.conf</code></p><p>PS：如果不习惯<code>vi/vim</code>编辑器的朋友可以使用<code>nano</code>编辑器来替代文中的<code>vi</code>编辑器</p><p>1：首先删除该配置文件中的初始所有文本</p><p>2：将如下内容复制到配置文件中：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">logoutput: /var/log/danted.log</span><br><span class="line">internal: 此处填写你本地的IP或者网卡接口名 port = 1080</span><br><span class="line">external: 此处填写你本地的IP或者网卡接口名</span><br><span class="line">method: username none</span><br><span class="line">user.privileged: proxy</span><br><span class="line">user.notprivileged: nobody</span><br><span class="line">user.libwrap: nobody</span><br><span class="line">client pass &#123;</span><br><span class="line">from: 0.0.0.0/0 to: 0.0.0.0/0</span><br><span class="line">log: connect disconnect</span><br><span class="line">&#125;</span><br><span class="line">pass &#123;</span><br><span class="line">from: 0.0.0.0/0 to: 0.0.0.0/0 port gt 1023</span><br><span class="line">command: bind</span><br><span class="line">log: connect disconnect</span><br><span class="line">&#125;</span><br><span class="line">pass &#123;</span><br><span class="line">from: 0.0.0.0/0 to: 0.0.0.0/0</span><br><span class="line">command: connect udpassociate</span><br><span class="line">log: connect disconnect</span><br><span class="line">&#125;</span><br><span class="line">block &#123;</span><br><span class="line">from: 0.0.0.0/0 to: 0.0.0.0/0</span><br><span class="line">log: connect error</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure><p>3：请注意：上述配置文件中搭建的是匿名服务，如果需要安全认证请翻阅官方文档。</p><h2 id="启动服务"><a href="#启动服务" class="headerlink" title="启动服务"></a>启动服务</h2><p><code>sudo systemctl start danted</code></p><p>如果直接启动成功，并没有报错那么下面的内容你可以不用在意，下面的报错只有树莓派用户才会遇到。</p><p>如果在树莓派上启动<code>danted</code>服务此时会报错，内容如下：</p><figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">Job for danted.service failed because the control process exited with error code.</span><br><span class="line">See &quot;systemctl status danted.service&quot; and &quot;journalctl -xe&quot; for details.</span><br></pre></td></tr></table></figure><p>解决方案：</p><p>编辑danted.service服务</p><p><code>vi /lib/systemd/system/danted.service</code></p><p>PS：如果不习惯<code>vi/vim</code>编辑器的朋友可以使用<code>nano</code>编辑器来替代文中的<code>vi</code>编辑器</p><p><strong>将第19行<code>ReadOnlyDirectories</code>中的<code>\lib64</code>删除掉，如下图。</strong></p><p><img src="https://cdn.yeefire.com/hexo/img/danted.png" alt="danted.png"></p><p><strong>保存后，执行<code>sudo systemctl daemon-reload</code>重新加载所有systemd服务的配置文件</strong></p><p><strong>之后再次启动danted服务<code>sudo systemctl start danted</code></strong></p><p>OK，启动成功。这个问题在树莓派上出现的原因是Raspbian官方系统只有32位（虽然3B以上的板子是支持64位的），所以在使用lib64库的时候会报错，在配置文件中删掉lib64的支持即可。（可能表述不正确）</p><h2 id="设置开机自启服务"><a href="#设置开机自启服务" class="headerlink" title="设置开机自启服务"></a>设置开机自启服务</h2><p><code>sudo systemctl enable danted</code></p><h2 id="其他问题"><a href="#其他问题" class="headerlink" title="其他问题"></a>其他问题</h2><p>可以使用<code>sudo systemctl status danted</code>查看服务状态。</p><p>如果是runing那么一切正常。如果是dead状态，那么问题出在你的配置文件，请重新检查你的ip或者网卡名是否正确。</p><p>修改过配置文件后，记得重启danted服务：<code>sudo systemctl restart danted</code></p><h2 id="大功告成"><a href="#大功告成" class="headerlink" title="大功告成"></a>大功告成</h2><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群<span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;在-树莓派-Linux-中搭建匿名-danted-socks5-代理服务器&quot;&gt;&lt;a href=&quot;#在-树莓派-Linux-中搭建匿名-danted-socks5-代理服务器&quot; class=&quot;headerlink&quot; title=&quot;在 树莓派 Linux 中搭建匿名 danted socks5 代理服务器&quot;&gt;&lt;/a&gt;在 树莓派 Linux 中搭建匿名 danted socks5 代理服务器&lt;/h1&gt;&lt;p&gt;如果你跟我有这样的需求，并且还想继续折腾这块树莓派，你可以我对这次在树莓派4（理论任何树莓派版本都行）上搭建socks5服务器。&lt;/p&gt;
&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9C%A8-%E6%A0%91%E8%8E%93%E6%B4%BE-linux-%E4%B8%AD%E6%90%AD%E5%BB%BA%E5%8C%BF%E5%90%8D-danted-socks5-%E4%BB%A3%E7%90%86%E6%9C%8D%E5%8A%A1%E5%99%A8&quot;&gt;在 树莓派 Linux 中搭建匿名 danted socks5 代理服务器&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E6%8F%90&quot;&gt;前提&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85%E5%BF%85%E5%A4%87%E5%8C%85&quot;&gt;安装必备包&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A4%87%E4%BB%BDdante-server%E9%BB%98%E8%AE%A4%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot;&gt;备份dante-server默认的配置文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%BC%96%E8%BE%91%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot;&gt;编辑配置文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1&quot;&gt;启动服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%AE%BE%E7%BD%AE%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF%E6%9C%8D%E5%8A%A1&quot;&gt;设置开机自启服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%85%B6%E4%BB%96%E9%97%AE%E9%A2%98&quot;&gt;其他问题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A4%A7%E5%8A%9F%E5%91%8A%E6%88%90&quot;&gt;大功告成&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;

&lt;h2 id=&quot;前提&quot;&gt;&lt;a href=&quot;#前提&quot; class=&quot;headerlink&quot; title=&quot;前提&quot;&gt;&lt;/a&gt;前提&lt;/h2&gt;&lt;p&gt;我是用的是目前树莓派官网提供的最新 Raspbian Linux 操作系统，如果你安装的是Ubuntu for Arm等其它系统，请不要完全按照本文进行操作，请变通！如果遇到问题可以在底部留言给我。&lt;/p&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Centos" scheme="https://blog.yeefire.com/tags/Centos/"/>
    
    <category term="Python" scheme="https://blog.yeefire.com/tags/Python/"/>
    
    <category term="RedHat" scheme="https://blog.yeefire.com/tags/RedHat/"/>
    
    <category term="42Team" scheme="https://blog.yeefire.com/tags/42Team/"/>
    
    <category term="Raspberry" scheme="https://blog.yeefire.com/tags/Raspberry/"/>
    
    <category term="树莓派" scheme="https://blog.yeefire.com/tags/%E6%A0%91%E8%8E%93%E6%B4%BE/"/>
    
    <category term="资源分享" scheme="https://blog.yeefire.com/tags/%E8%B5%84%E6%BA%90%E5%88%86%E4%BA%AB/"/>
    
  </entry>
  
  <entry>
    <title>HTTP与HTTPS区别随笔</title>
    <link href="https://blog.yeefire.com/2020_02/HTTPS_HTTP.html"/>
    <id>https://blog.yeefire.com/2020_02/HTTPS_HTTP.html</id>
    <published>2020-02-21T06:13:41.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="超文本传输安全协议-HTTPS"><a href="#超文本传输安全协议-HTTPS" class="headerlink" title="超文本传输安全协议(HTTPS)"></a>超文本传输安全协议(HTTPS)</h1><p><strong>超文本传输安全协议</strong>(<strong>H</strong>yper<strong>T</strong>ext <strong>T</strong>ransfer <strong>P</strong>rotocol <strong>S</strong>ecure),缩写<strong>HTTPS</strong>，也常称为：HTTP over TLS、HTTP over SSL 或 HTTP Secure。是一种计算机网络进行安全通信的传输协议。HTTPS经由HTTP协议进行通信，但是利用SSL/TLS来加密之间传输的数据包。HTTPS开发的主要目的是提供对网络服务器的身份认证，保护交换数据的隐私与完整性。这个协议由**网景公司(Netscape)**在1994年首次提出。</p><p>在2010年末后HTTPS开始广泛使用，以保证网页浏览的私密性。</p><p>还有一种安全超文本传输协议(S-HTTP)的HTTP安全策划三农户实现，但是HTTPS的广泛应用实现了HTTP的安全传输，S-HTTP并没有得到广泛的支持。</p><span id="more"></span><h2 id="HTTP-和-HTTPS-的主要差异"><a href="#HTTP-和-HTTPS-的主要差异" class="headerlink" title="HTTP 和 HTTPS 的主要差异"></a>HTTP 和 HTTPS 的主要差异</h2><p>HTTP的URL是由<code>http://</code>起始与默认使用端口<code>80</code>，而HTTPS的URL则是由<code>https://</code>起始与默认使用端口<code>443</code>。</p><h2 id="HTTP-和-HTTPS-协议层"><a href="#HTTP-和-HTTPS-协议层" class="headerlink" title="HTTP 和 HTTPS 协议层"></a>HTTP 和 HTTPS 协议层</h2><p>HTTP协议和安全协议同属于应用层（OSI模型的最高层），具体来讲，安全协议工作在HTTP之下，传输层之上：安全协议向运行HTTP的进程提供一个类似于TCP的套接字，供进程向其中注入报文，安全协议将报文加密并注入运输层套接字；或是从运输层获取加密报文，解密后交给对应的进程。严格地讲，HTTPS并不是一个单独的协议，而是对工作在一加密连接（TLS或SSL）上的常规HTTP协议的称呼。</p><p>HTTPS报文中的任何东西都被加密，包括所有报头和荷载。入股被攻击者攻击，大多数情况下那个攻击者所能知道的只有在两者之间有一连接这一事实。</p><h2 id="提供服务"><a href="#提供服务" class="headerlink" title="提供服务"></a>提供服务</h2><p>要使一网络服务器准备好接受HTTPS连接，管理员必须创建一数字证书，并交由证书颁发机构签名以使浏览器接受。证书颁发机构会验证数字证书持有人和其声明的为同一人。浏览器通常都预装了证书颁发机构的证书，所以他们可以验证该签名。</p><h3 id="获得证书"><a href="#获得证书" class="headerlink" title="获得证书"></a>获得证书</h3><p>由证书颁发机构签发的证书有免费的，也有收费数美元到数千美元的。一个组织或团体也有可能有自己的证书，尤其是当浏览器来访问他们自己的网站时，如学校、公司等会使用自己的证书。</p><h1 id="总结HTTPS和HTTP的区别"><a href="#总结HTTPS和HTTP的区别" class="headerlink" title="总结HTTPS和HTTP的区别"></a>总结HTTPS和HTTP的区别</h1><p>https协议需要到CA申请证书，需要交费。</p><p>http是超文本传输协议，信息是明文传输，https 则是具有安全性的ssl加密传输协议。</p><p>http和https使用的是完全不同的连接方式用的端口也不一样，前者是80，后者是443。</p><p>http的连接很简单，是无状态的。</p><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群<span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;超文本传输安全协议-HTTPS&quot;&gt;&lt;a href=&quot;#超文本传输安全协议-HTTPS&quot; class=&quot;headerlink&quot; title=&quot;超文本传输安全协议(HTTPS)&quot;&gt;&lt;/a&gt;超文本传输安全协议(HTTPS)&lt;/h1&gt;&lt;p&gt;&lt;strong&gt;超文本传输安全协议&lt;/strong&gt;(&lt;strong&gt;H&lt;/strong&gt;yper&lt;strong&gt;T&lt;/strong&gt;ext &lt;strong&gt;T&lt;/strong&gt;ransfer &lt;strong&gt;P&lt;/strong&gt;rotocol &lt;strong&gt;S&lt;/strong&gt;ecure),缩写&lt;strong&gt;HTTPS&lt;/strong&gt;，也常称为：HTTP over TLS、HTTP over SSL 或 HTTP Secure。是一种计算机网络进行安全通信的传输协议。HTTPS经由HTTP协议进行通信，但是利用SSL/TLS来加密之间传输的数据包。HTTPS开发的主要目的是提供对网络服务器的身份认证，保护交换数据的隐私与完整性。这个协议由**网景公司(Netscape)**在1994年首次提出。&lt;/p&gt;
&lt;p&gt;在2010年末后HTTPS开始广泛使用，以保证网页浏览的私密性。&lt;/p&gt;
&lt;p&gt;还有一种安全超文本传输协议(S-HTTP)的HTTP安全策划三农户实现，但是HTTPS的广泛应用实现了HTTP的安全传输，S-HTTP并没有得到广泛的支持。&lt;/p&gt;</summary>
    
    
    
    
    <category term="HTTP" scheme="https://blog.yeefire.com/tags/HTTP/"/>
    
    <category term="HTTPS" scheme="https://blog.yeefire.com/tags/HTTPS/"/>
    
  </entry>
  
  <entry>
    <title>Bash/Shell学习笔记</title>
    <link href="https://blog.yeefire.com/2020_02/Linux_Bash_Shell.html"/>
    <id>https://blog.yeefire.com/2020_02/Linux_Bash_Shell.html</id>
    <published>2020-02-21T05:32:47.000Z</published>
    <updated>2021-09-06T02:05:41.000Z</updated>
    
    <content type="html"><![CDATA[<h1 id="Bash-Shell学习笔记"><a href="#Bash-Shell学习笔记" class="headerlink" title="Bash/Shell学习笔记"></a>Bash/Shell学习笔记</h1><!-- TOC --><ul><li><a href="#bashshell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0">Bash/Shell学习笔记</a><ul><li><a href="#bash%E8%84%9A%E6%9C%AC%E7%9A%84%E5%A3%B0%E6%98%8E">Bash脚本的声明</a></li><li><a href="#%E5%8F%98%E9%87%8F">变量</a><ul><li><a href="#%E5%AE%9A%E4%B9%89%E5%8F%98%E9%87%8F">定义变量</a></li><li><a href="#%E5%AE%9A%E4%B9%89%E6%9C%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8F%98%E9%87%8F">定义有类型的变量</a></li><li><a href="#%E5%8F%98%E9%87%8F%E7%9A%84%E5%88%A0%E9%99%A4">变量的删除</a></li><li><a href="#%E5%8F%98%E9%87%8F%E7%9A%84%E6%9B%BF%E6%8D%A2">变量的替换</a></li><li><a href="#%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F%E5%92%8C%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F">局部变量和全局变量</a><ul><li><a href="#%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F">局部变量</a></li></ul></li><li><a href="#%E5%8F%98%E9%87%8F%E7%9A%84%E6%B5%8B%E8%AF%95">变量的测试</a></li></ul></li><li><a href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%A4%84%E7%90%86">字符串的处理</a><ul><li><a href="#%E8%AE%A1%E7%AE%97%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E9%95%BF%E5%BA%A6">计算字符串的长度</a></li><li><a href="#%E6%8A%BD%E5%8F%96%E5%AD%90%E4%B8%B2">抽取子串</a></li></ul></li><li><a href="#%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2%E5%92%8C%E6%95%B0%E5%AD%A6%E8%BF%90%E7%AE%97">命令替换和数学运算</a><ul><li><a href="#%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2">命令替换</a></li><li><a href="#%E6%95%B0%E5%AD%A6%E8%AE%A1%E7%AE%97">数学计算</a><ul><li><a href="#1%E7%94%A8-%E6%9D%A5%E8%A1%A8%E8%BE%BE%E6%95%B0%E5%AD%A6%E8%AE%A1%E7%AE%97%E5%92%8C%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%E6%97%B6%E8%A6%81%E6%B3%A8%E6%84%8F%E6%8B%AC%E5%8F%B7%E7%9A%84%E4%B8%AA%E6%95%B0">1、<strong>用$(( ))来表达数学计算,和命令替换一起使用时要注意括号的个数</strong></a></li><li><a href="#2%E4%BD%BF%E7%94%A8bc%E6%9D%A5%E5%A4%84%E7%90%86%E6%B5%AE%E7%82%B9%E5%9E%8B%E6%95%B0%E5%AD%A6%E8%BF%90%E7%AE%97">2、<strong>使用bc来处理浮点型数学运算</strong></a></li></ul></li></ul></li><li><a href="#%E5%87%BD%E6%95%B0">函数</a><ul><li><a href="#%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0">定义函数</a></li><li><a href="#%E5%87%BD%E6%95%B0%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC">函数的返回值</a></li><li><a href="#%E5%87%BD%E6%95%B0%E5%BA%93">函数库</a></li></ul></li><li><a href="#%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD%E5%88%86%E6%94%AF">条件、判断、分支</a><ul><li><a href="#if%E5%88%A4%E6%96%AD">if判断</a></li><li><a href="#while%E5%BE%AA%E7%8E%AF">while循环</a></li></ul></li><li><a href="#sed-%E6%B5%81%E7%BC%96%E8%BE%91%E5%99%A8">sed 流编辑器</a><ul><li><a href="#%E7%AE%80%E4%BB%8B">简介：</a></li><li><a href="#%E9%80%89%E9%A1%B9-option%E5%B8%B8%E7%94%A8">选项 option(常用)</a></li><li><a href="#sed-%E7%9A%84%E5%8C%B9%E9%85%8D%E6%A8%A1%E5%BC%8F">sed 的匹配模式</a></li><li><a href="#sed-%E7%9A%84%E5%A2%9E%E5%88%A0%E6%94%B9%E6%9F%A5">sed 的增删改查</a></li><li><a href="#sed-%E7%9A%84%E6%98%BE%E7%A4%BA%E8%A1%8C%E5%8F%B7">sed 的显示行号</a></li></ul></li><li><a href="#awk-%E6%96%87%E6%9C%AC%E5%A4%84%E7%90%86%E5%99%A8">awk 文本处理器</a><ul><li><a href="#%E8%AF%AD%E6%B3%95%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E">语法格式说明</a></li><li><a href="#%E5%86%85%E7%BD%AE%E5%8F%98%E9%87%8F">内置变量</a></li><li><a href="#%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA-printf">格式化输出 printf</a></li><li><a href="#awk-%E5%8C%B9%E9%85%8D%E6%A8%A1%E5%BC%8F">awk 匹配模式</a><ul><li><a href="#%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%8C%B9%E9%85%8D">正则表达式匹配</a></li><li><a href="#%E5%85%B3%E7%B3%BB%E8%BF%90%E7%AE%97%E7%AC%A6%E5%8C%B9%E9%85%8D">关系运算符匹配</a></li></ul></li><li><a href="#awk%E4%B8%AD%E7%9A%84%E5%88%A4%E6%96%AD%E4%B8%8E%E5%BE%AA%E7%8E%AF">awk中的判断与循环</a><ul><li><a href="#if%E5%88%A4%E6%96%AD-1">if判断</a></li></ul></li><li><a href="#awk%E7%9A%84%E5%BE%AA%E7%8E%AF">awk的循环</a></li></ul></li></ul></li></ul><!-- /TOC --><span id="more"></span><h2 id="Bash脚本的声明"><a href="#Bash脚本的声明" class="headerlink" title="Bash脚本的声明"></a>Bash脚本的声明</h2><p>在我们写.sh文件时要在文档头部做出<code>#!/bin/bash</code>的声明。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;Hello World&quot;</span></span><br><span class="line">……</span><br><span class="line"><span class="comment">#</span></span><br></pre></td></tr></table></figure><p>如上所示，写出声明后我们的bash脚本才可以正常的运行。<br>其实第一行<code>#!/bin/bash</code>写错或者不写时，系统会有一个默认的解释器进行解释，此处为bash，但是为了标准化我们要加上它！<br>笔记其余的地方我都会省略这个声明，但是在读者写代码时记得要在你自己写的代码里加上这段声明~</p><h2 id="变量"><a href="#变量" class="headerlink" title="变量"></a>变量</h2><h3 id="定义变量"><a href="#定义变量" class="headerlink" title="定义变量"></a>定义变量</h3><ul><li><p><code>var=Hello World!</code> 就是这么简单就声明了一个全局变量。</p></li><li><p><code>varnum=32</code> 但是要注意的是:这样直接声明的变量不论存入的数据是什么类型，都会当做字符串对待。</p></li><li><p>例如：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"> varnum=10</span><br><span class="line"> varnum2=<span class="variable">$varnum</span> + 10</span><br><span class="line"> <span class="built_in">echo</span> <span class="variable">$varnum2</span></span><br><span class="line">输出：10 + 10</span><br></pre></td></tr></table></figure></li></ul><p>可以看出，直接对变量进行增加或进行数学运算是不行的，因为直接声明的变量的类型就是字符串！如果想对变量进行数学运算那么你可能需要<code>declare</code>来帮助你给定义好的变量加上它们应有的“变量类型”</p><h3 id="定义有类型的变量"><a href="#定义有类型的变量" class="headerlink" title="定义有类型的变量"></a>定义有类型的变量</h3><ul><li><p><code>declare [+/-][rxi][变量名称＝设置值]</code></p><ul><li>参数说明：</li><li>+/-：+ 为取消相应的属性 - 为添加相应的属性</li><li>rxi：r 为只读变量（常量） x 为环境常量(在Bash脚本中也可以使用外面的定义的变量) i 为数值类型</li></ul></li><li><p>例如：</p>  <figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="built_in">declare</span> -i numsum</span><br><span class="line">numtest=30</span><br><span class="line">numsum=<span class="variable">$numtest</span>+10</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$numsum</span></span><br><span class="line">输出：40</span><br></pre></td></tr></table></figure></li></ul><p>可以看出如果我们给numsum这个变量设置好了他的类型，那么在输出的时候就会根据类型对其进行输出。<br><code>declare</code>也可以更改已经声明好的变量的类型，不是必须要通过<code>declare</code>声明的变量才有效果。</p><ul><li><p>例如：</p>  <figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">var=300</span><br><span class="line"><span class="built_in">declare</span> -i var</span><br></pre></td></tr></table></figure></li></ul><p>也可以将var变量设置为数值型。<br><strong>注意：假如上面的var这个变量值为文本型或不是数值型或数学表达式的话会将其原有的变量值替换为0，而且无法找回原来的变量内容！</strong></p><h3 id="变量的删除"><a href="#变量的删除" class="headerlink" title="变量的删除"></a>变量的删除</h3><ul><li><code>$&#123; variable#[匹配符]  &#125;</code> 从这个变量的<strong>前面</strong>开始删除存储的信息，删除符合匹配条件的<strong>第一个</strong>。</li><li><code>$&#123; variable##[匹配符]  &#125;</code> 从这个变量的<strong>前面</strong>开始删除存储的信息，删除符合匹配条件的<strong>最长匹配</strong></li><li><code>$&#123; variable%[匹配符]  &#125;</code> 从这个变量的<strong>后面</strong>开始删除存储的信息，删除符合匹配条件的<strong>第一个</strong></li><li><code>$&#123; variable%%[匹配符]  &#125;</code> 从这个变量的<strong>后面</strong>开始删除存储的信息，删除符合匹配条件的<strong>最长匹配</strong></li></ul><h3 id="变量的替换"><a href="#变量的替换" class="headerlink" title="变量的替换"></a>变量的替换</h3><ul><li><code>var1=$&#123; variable/要替换的内容/替换为  &#125;</code> 从这个变量前面仅寻找要替换的<strong>第一个</strong>内容，之后替换为新的内容并赋值到一个新变量上。</li><li><code>var2=$&#123; variable//要替换的内容/替换为  &#125;</code> 从这个变量前面寻找要替换的<strong>全部</strong>内容，之后替换为新的内容并赋值到一个新变量上。</li></ul><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">var1=<span class="variable">$&#123; PATH/bin/Bin  &#125;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$var1</span></span><br><span class="line">    输出  /usr/local/Bin:/usr/bin:/bin:/usr/sbin:/sbin:/Applications/VMware Fusion.app/Contents/Public:/usr/local/mysql/bin</span><br><span class="line">var2=<span class="variable">$&#123; PATH//bin/Bin  &#125;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$var2</span></span><br><span class="line">    输出  /usr/local/Bin:/usr/Bin:/Bin:/usr/sBin:/sBin:/Applications/VMware Fusion.app/Contents/Public:/usr/local/mysql/Bin</span><br></pre></td></tr></table></figure><h3 id="局部变量和全局变量"><a href="#局部变量和全局变量" class="headerlink" title="局部变量和全局变量"></a>局部变量和全局变量</h3><ul><li><p>不做特殊声明，Shell中变量都是全局变量</p><h4 id="局部变量"><a href="#局部变量" class="headerlink" title="局部变量"></a>局部变量</h4></li><li><p>定义局部变量时，使用local关键字</p></li><li><p>如果函数内与函数外变量名重复，那么在函数内会覆盖函数外的全局变量。</p></li><li><p>局部变量使用<code>local</code>关键字声明</p></li><li><p><code>local var_local=&quot;Hello World&quot;</code></p></li><li><p>例子：</p>  <figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">var1=<span class="string">&quot;Hello World&quot;</span></span><br><span class="line"><span class="keyword">function</span> new</span><br><span class="line">&#123; </span><br><span class="line">        <span class="built_in">local</span> var2=<span class="string">&quot;Local Var&quot;</span></span><br><span class="line">        var3=<span class="string">&quot;Public Var&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line"><span class="comment"># 调用函数</span></span><br><span class="line">new</span><br><span class="line"><span class="built_in">echo</span> var1=<span class="variable">$var1</span></span><br><span class="line"><span class="built_in">echo</span> var2=<span class="variable">$var2</span></span><br><span class="line"><span class="built_in">echo</span> var3=<span class="variable">$var3</span></span><br><span class="line">    输出</span><br><span class="line">    var1=Hello World</span><br><span class="line">    var2=</span><br><span class="line">    var3=Public Var</span><br></pre></td></tr></table></figure><p>  通过例子可以看出用<code>local</code>关键字声明出的var2变量在其所在函数外是无法使用的。</p></li></ul><h3 id="变量的测试"><a href="#变量的测试" class="headerlink" title="变量的测试"></a>变量的测试</h3><p>很少会用到，一般来说我们使用if-else来进行替换变量的测试，只不过if-else麻烦一些。变量的检查一般用于初始化变量。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">str1=test1</span><br><span class="line">var1=<span class="variable">$&#123; str1-default  &#125;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$var1</span></span><br><span class="line">    test1</span><br><span class="line">var2=<span class="variable">$&#123; xxx-default  &#125;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$var2</span></span><br><span class="line">    default</span><br></pre></td></tr></table></figure><h2 id="字符串的处理"><a href="#字符串的处理" class="headerlink" title="字符串的处理"></a>字符串的处理</h2><h3 id="计算字符串的长度"><a href="#计算字符串的长度" class="headerlink" title="计算字符串的长度"></a>计算字符串的长度</h3><ul><li><code>echo $&#123; #varstr  &#125;</code> 输出varstr字符串变量的字符长度</li></ul><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">varstr=teststring-HelloWorld!</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$&#123; #varstr  &#125;</span></span><br><span class="line">    输出  22</span><br></pre></td></tr></table></figure><h3 id="抽取子串"><a href="#抽取子串" class="headerlink" title="抽取子串"></a>抽取子串</h3><ul><li><code>$&#123; varstr:num1  &#125;</code> 截取从 num1 开始到末尾的所有字符</li><li><code>$&#123; varstr:num1:num2  &#125;</code> 从 num1 开始截取之后的 num2 个字符</li><li><code>$&#123; varstr: -num1  &#125;</code> 从<strong>末尾向前</strong>截取从倒数 num1 个字符开始到末尾的所有字符（<strong>注意冒号后有空格</strong>）</li><li><code>$&#123; varstr: -num1:-num2  &#125;</code> 从<strong>末尾向前</strong>截取 num2 到 num1 之间的所有字符（<strong>注意 -num1 要小于 -num2，下面有例子方便理解）</strong></li><li><code>$&#123; varstr: -num1:num2  &#125;</code> 从末尾倒数第num1个字符开始向后截取 num2 个字符</li><li><code>$&#123; varstr:num1:-num2  &#125;</code> 从开头第 num1 个的字符截取到倒数第 num2 个字符</li></ul><p><strong>注意：以这种方式抽取字符串索引是从0开始的，上面所提到的所有数字都是以索引的形式体现。所有符号都是英文，并且在num为负值时在冒号（:）的后面要有一个空格</strong></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">varstr=Hello,World!</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$&#123; varstr:3  &#125;</span></span><br><span class="line">    输出 lo,World!</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$&#123; varstr:3:6  &#125;</span></span><br><span class="line">    输出 lo,Wor</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$&#123; varstr: -6  &#125;</span></span><br><span class="line">    输出 World!</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$&#123; varstr: -6:-3  &#125;</span></span><br><span class="line">    输出 Wor</span><br><span class="line"><span class="built_in">echo</span> <span class="variable">$&#123; varstr:0:-7  &#125;</span></span><br><span class="line">    输出 Hello</span><br></pre></td></tr></table></figure><h2 id="命令替换和数学运算"><a href="#命令替换和数学运算" class="headerlink" title="命令替换和数学运算"></a>命令替换和数学运算</h2><h3 id="命令替换"><a href="#命令替换" class="headerlink" title="命令替换"></a>命令替换</h3><table><thead><tr><th></th><th>实现</th><th align="left">备注</th></tr></thead><tbody><tr><td>方法一</td><td>$()</td><td align="left"></td></tr><tr><td>方法二</td><td>``</td><td align="left">注意是反引号，不是单引号</td></tr></tbody></table><p>在上面已经用到了命令替换，简单来说在用echo输出的时候如果使用命令替换，就会先执行命令，之后把返回值再输出回来。</p><ul><li>比如：获得今年是第几年</li><li><code>echo 今年是第 $(date +%Y) 年</code><ul><li>输出 今年是第 2019 年</li></ul></li></ul><h3 id="数学计算"><a href="#数学计算" class="headerlink" title="数学计算"></a>数学计算</h3><p>因为数学计算和命令替换的bash语法很相近，所以一起学习效果会好些吧。</p><h4 id="1、用-来表达数学计算-和命令替换一起使用时要注意括号的个数"><a href="#1、用-来表达数学计算-和命令替换一起使用时要注意括号的个数" class="headerlink" title="1、用$(( ))来表达数学计算,和命令替换一起使用时要注意括号的个数"></a>1、<strong>用$(( ))来表达数学计算,和命令替换一起使用时要注意括号的个数</strong></h4><ul><li>比如：获得明年的年数</li><li><code>echo 明年是第 $(( $(date +%Y) +1))年</code><ul><li>输出 明年是第 2020年</li></ul></li></ul><h4 id="2、使用bc来处理浮点型数学运算"><a href="#2、使用bc来处理浮点型数学运算" class="headerlink" title="2、使用bc来处理浮点型数学运算"></a>2、<strong>使用bc来处理浮点型数学运算</strong></h4><ul><li><p>比如：</p></li><li><p><code>echo &quot;3.14*3.14&quot; | bc</code></p><ul><li>输出：9.85 （黑人问号？不对啊，怎么精度只有2位？）</li></ul></li><li><p>*注意咯，使用bc时默认保留小数点两位，如果可以整除的时候这两位也给你省去了！如果想保留更高精度的数，你需要使用<code>scale</code>。**</p></li></ul><p><strong>浮点数的小数位数是由内建变量scale控制的。必须将这个值设置为你希望在计算结果中保留的小数位，否则无法得到期望的结果</strong></p><ul><li>比如:</li><li><code>echo &quot;scale=6;3.14*3.14&quot; | bc </code><ul><li>输出：9.8596</li><li>精度设置为小数点后6位，但是后两位位是0，所以隐藏掉了。</li></ul></li></ul><h2 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h2><h3 id="定义函数"><a href="#定义函数" class="headerlink" title="定义函数"></a>定义函数</h3><p>  定义函数有两种方法：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment">#第一种</span></span><br><span class="line"><span class="keyword">function</span> f1</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;这是第一种定义函数的方法&quot;</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;传入参数<span class="variable">$1</span>&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line"><span class="comment">#第二种</span></span><br><span class="line"><span class="function"><span class="title">f2</span></span>()</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;这是第二种定义函数的方法&quot;</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;传入参数<span class="variable">$1</span>&quot;</span></span><br><span class="line">  &#125;</span><br><span class="line"><span class="comment">#调用f1函数并传参</span></span><br><span class="line">f1 <span class="string">&quot;lalalal&quot;</span></span><br><span class="line"><span class="comment">#调用f2函数并传参</span></span><br><span class="line">f2 <span class="string">&quot;lalallalal&quot;</span></span><br><span class="line">  输出：</span><br><span class="line">      这是第一种定义函数的方法</span><br><span class="line">      传入参数lalalal</span><br><span class="line">      这是第二种定义函数的方法</span><br><span class="line">      传入参数lalallalal</span><br></pre></td></tr></table></figure><h3 id="函数的返回值"><a href="#函数的返回值" class="headerlink" title="函数的返回值"></a>函数的返回值</h3><p>函数有两种返回值的方法</p><table><thead><tr><th>代码</th><th align="left">备注</th></tr></thead><tbody><tr><td>return</td><td align="left"><code>return通常用来返回执行状态！执行成功返回 0 执行失败返回 1 ，返回值范围(0~255)</code></td></tr><tr><td>echo</td><td align="left"><code>echo通常用来返回字符串或一个列表</code></td></tr></tbody></table><h3 id="函数库"><a href="#函数库" class="headerlink" title="函数库"></a>函数库</h3><ul><li>使用函数库，我们可以避免对一段代码重复的书写，我们可以将常有的一些方法封装到函数库中。</li><li>写好的函数库一般不直接执行，而是由其他的脚本进行调用。</li></ul><p>例如现在要定义一个函数库，要满足以下几个函数：</p><ul><li><p>1、加法函数add</p></li><li><p>2、减法函数reduce</p></li><li><p>3、乘法函数multiple</p></li><li><p>4、除法函数divide</p></li><li><p>5、打印系统的运行情况的函数sys_info,该函数用来显示内存运行情况。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">function</span> add</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">echo</span> $((<span class="variable">$1</span>+<span class="variable">$2</span>))</span><br><span class="line">  &#125;</span><br><span class="line"><span class="keyword">function</span> reduce</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">echo</span> $((<span class="variable">$1</span>-<span class="variable">$2</span>))</span><br><span class="line">  &#125;</span><br><span class="line"><span class="keyword">function</span> multiple</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">echo</span> $((<span class="variable">$1</span>\*<span class="variable">$2</span>))</span><br><span class="line">  &#125;</span><br><span class="line"><span class="keyword">function</span> divide</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">echo</span> $((<span class="variable">$1</span>/<span class="variable">$2</span>))</span><br><span class="line">  &#125;</span><br><span class="line"><span class="keyword">function</span> sys_info</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;内存的情况：&quot;</span></span><br><span class="line">    <span class="built_in">echo</span> `free -m`</span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;=================================&quot;</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;硬盘剩余空间：&quot;</span></span><br><span class="line">    <span class="built_in">echo</span> `<span class="built_in">df</span> -h`</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure></li></ul><p><strong>OK,我们写好了一个函数库，把它命名为lib_test。现在需要来写一个普通脚本去调用我们的函数库。</strong></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#我们用一个.表示要调用函数库，空格后面是函数库的位置。我这里的函数库和脚本文件在同级目录，所以用./lib_test来访问函数库</span></span><br><span class="line">. ./lib_test</span><br><span class="line"></span><br><span class="line">add 1 3</span><br><span class="line">reduce 5 2</span><br><span class="line">multiple 5 2</span><br><span class="line">divide 9 3</span><br><span class="line">sys_info</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="条件、判断、分支"><a href="#条件、判断、分支" class="headerlink" title="条件、判断、分支"></a>条件、判断、分支</h2><h3 id="if判断"><a href="#if判断" class="headerlink" title="if判断"></a>if判断</h3><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span> [ 条件语句 ];<span class="keyword">then</span></span><br><span class="line">    满足条件执行的内容</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">if</span> [ 条件语句 ];<span class="keyword">then</span></span><br><span class="line">    第一个<span class="keyword">if</span>条件不满足，但第二个条件满足执行的内容</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">    都不满足条件后执行内容</span><br><span class="line"><span class="keyword">fi</span></span><br></pre></td></tr></table></figure><ul><li>bash/shell 对空格非常敏感</li><li>如果按照下面的例子练习if语句时运行报错那么请耐心仔细检查空格或语法。</li></ul><p><strong>现在我们通过一个实例来学习if</strong></p><p>要求：</p><ul><li><p>1、检测nginx服务是否正在运行</p></li><li><p>2、如果检测到nginx服务已经宕掉，那么重新启动它！</p></li><li><p>3、在测试的时候先把nginx服务手动停止<code>service nginx stop</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="comment">#</span></span><br><span class="line"><span class="keyword">if</span> [ `ps -ef | grep nginx | grep -v grep | <span class="built_in">wc</span> -l` -eq 0 ];<span class="keyword">then</span></span><br><span class="line">    <span class="comment">#检查nginx进程，如果没有进程的话(grep与wc筛选后没有任何内容)，那么就启动它吧！</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;Nginx服务已宕掉！&quot;</span></span><br><span class="line">    service nginx start</span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;Nginx已经重新启动！&quot;</span></span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;Nginx服务正常&quot;</span></span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line">    输出：</span><br><span class="line">    Nginx服务已宕掉！</span><br><span class="line">    Starting nginx...  <span class="keyword">done</span></span><br><span class="line">    Nginx已经重新启动</span><br></pre></td></tr></table></figure></li></ul><h3 id="while循环"><a href="#while循环" class="headerlink" title="while循环"></a>while循环</h3><p>刚才学习了if条件判断，我们可以来监测nginx服务是否宕掉，但是它需要我们每次都执行它这个脚本才能够去检测nginx。那么如果知道了while循环，是不是就可以循环去监测它了？</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">while</span> 条件语句</span><br><span class="line"><span class="keyword">do</span></span><br><span class="line">    满足条件执行的内容</span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></table></figure><p>例子要求：那么我们在if的例子基础上来完善一下它，让它每隔1分钟就检测一下Nginx服务</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">while</span> <span class="literal">true</span></span><br><span class="line"><span class="keyword">do</span></span><br><span class="line">    <span class="keyword">if</span> [ `ps -ef | grep nginx | grep -v grep | <span class="built_in">wc</span> -l` -eq 0 ];<span class="keyword">then</span></span><br><span class="line">        <span class="comment">#检查nginx进程，如果没有进程的话(grep与wc筛选后没有任何内容)，那么就启动它吧！</span></span><br><span class="line">        <span class="built_in">echo</span> <span class="string">&quot;Nginx服务已宕掉！&quot;</span></span><br><span class="line">        service nginx start</span><br><span class="line">        <span class="built_in">echo</span> <span class="string">&quot;Nginx已经重新启动！&quot;</span></span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">        <span class="built_in">echo</span> <span class="string">&quot;Nginx服务正常&quot;</span></span><br><span class="line">    <span class="keyword">fi</span></span><br><span class="line">    <span class="comment"># 60秒后再次执行循环体</span></span><br><span class="line">    <span class="built_in">sleep</span> 60</span><br><span class="line"><span class="keyword">done</span></span><br></pre></td></tr></table></figure><p>我们使用while-true死循环来重复监测Nginx服务，每次循环过后都休眠60s后再次执行循环体！</p><h2 id="sed-流编辑器"><a href="#sed-流编辑器" class="headerlink" title="sed 流编辑器"></a>sed 流编辑器</h2><ul><li><code>第一种形式：stdout | sed [option] &quot;pattern command&quot;</code></li><li><code>第二种形式：sed [option] &quot;pattern command&quot; fileaddress </code><br><em><code>stdout</code>意思为通过管道 <code>|</code> 将文本传入给后面的命令。</em></li></ul><h3 id="简介："><a href="#简介：" class="headerlink" title="简介："></a>简介：</h3><blockquote><p>Linux sed 命令是利用脚本来处理文本文件。<br>sed 可依照脚本的指令来处理、编辑文本文件。<br>sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等。</p></blockquote><h3 id="选项-option-常用"><a href="#选项-option-常用" class="headerlink" title="选项 option(常用)"></a>选项 option(常用)</h3><table><thead><tr><th>选项</th><th align="left">含义</th></tr></thead><tbody><tr><td>-n</td><td align="left">只打印模式匹配行</td></tr><tr><td>-e</td><td align="left">直接在命令行进行sed编辑，默认选项</td></tr><tr><td>-f</td><td align="left">编辑的操作方式保存在文件中，指定文件执行</td></tr><tr><td>-r</td><td align="left">支持扩展正则表达式</td></tr><tr><td>-i</td><td align="left">直接修改文件内容（将所作的修改保存到文件中）</td></tr></tbody></table><p><strong>需要注意的是sed在处理文本时默认每一行都会输出出来，如果只想打印与自己设置好的匹行，需要选项中使用<code>-n</code></strong></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 我们先创建一个用来测试的文本</span></span><br><span class="line">    <span class="built_in">echo</span> <span class="string">&quot;I Like python \nI Like Python \nI Like PYTHON&quot;</span> &gt; text.txt</span><br><span class="line"><span class="comment"># 现在我们直接使用sed来输出text.txt文件里面的内容</span></span><br><span class="line">    sed n text.txt</span><br><span class="line">        输出：</span><br><span class="line">            I Like python</span><br><span class="line">            I Like Python</span><br><span class="line">            I Like PYTHON</span><br><span class="line"><span class="comment"># 现在我们来进行过滤，我们只要小写的python匹配行</span></span><br><span class="line">    sed <span class="string">&#x27;/python/p&#x27;</span> text.txt</span><br><span class="line">        输出：</span><br><span class="line">        I Like python</span><br><span class="line">        I Like python</span><br><span class="line">        I Like Python</span><br><span class="line">        I Like PYTHON</span><br><span class="line">        你会发现为什么I Like python会输出两行，而且还把其他的输出出来了？</span><br><span class="line">        需要注意的是sed在处理文本时默认每一行都会输出出来，如果只想打印与自己设置好的匹行，需要选项中使用`-n`</span><br><span class="line"><span class="comment"># 那么我们加上 -n 选项再试试</span></span><br><span class="line">    sed -n <span class="string">&#x27;/python/p&#x27;</span> text.txt</span><br><span class="line">        输出：</span><br><span class="line">        I Like python</span><br><span class="line">        这回没有问题了，去掉非匹配行，留下的就是我们想要的！</span><br><span class="line"><span class="comment"># 如果我既要 python也要PYTHON?</span></span><br><span class="line">    sed -n -e <span class="string">&#x27;/python/p&#x27;</span> -e <span class="string">&#x27;/PYTHON/p&#x27;</span> text.txt</span><br><span class="line">        输出：</span><br><span class="line">        I Like python</span><br><span class="line">        I Like PYTHON</span><br><span class="line">        使用 -e 可以连接两个或多个匹配规则</span><br></pre></td></tr></table></figure><h3 id="sed-的匹配模式"><a href="#sed-的匹配模式" class="headerlink" title="sed 的匹配模式"></a>sed 的匹配模式</h3><table><thead><tr><th>匹配模式</th><th align="left">作用</th><th align="left">注意</th></tr></thead><tbody><tr><td><code>8p</code></td><td align="left">打印第8行的内容</td><td align="left"></td></tr><tr><td><code>8,10p</code></td><td align="left">打印第8行到第10行的内容</td><td align="left">包含第8行和第10行</td></tr><tr><td><code>8,+5p</code></td><td align="left">打印第8行和其之后的5行</td><td align="left">包含第8行</td></tr><tr><td><code>/正则表达式/p</code></td><td align="left">打印匹配正则表达式的行</td><td align="left"></td></tr><tr><td><code>/正则表达式_1/,/正则表达式_2/p</code></td><td align="left">打印匹配正则表达式1和2之间的行</td><td align="left"></td></tr><tr><td><code>8,/正则表达式/p</code></td><td align="left">打印第8行起直到匹配到正则表达式匹配行之间的所有内容</td><td align="left"></td></tr><tr><td><code>/正则表达式/,8p</code></td><td align="left">打印从匹配到正则表达式开始到第8行之间的所有内容</td><td align="left"></td></tr></tbody></table><h3 id="sed-的增删改查"><a href="#sed-的增删改查" class="headerlink" title="sed 的增删改查"></a>sed 的增删改查</h3><table><thead><tr><th>功能</th><th>指令</th><th align="left">备注</th></tr></thead><tbody><tr><td>查</td><td><code>p</code></td><td align="left">打印匹配的内容</td></tr><tr><td>删</td><td><code>d</code></td><td align="left">删除匹配的内容</td></tr><tr><td>增</td><td><code>a</code></td><td align="left">在匹配行的后一行追加内容</td></tr><tr><td>增</td><td><code>i</code></td><td align="left">在匹配行的前一行增加一行内容</td></tr><tr><td>改</td><td><code>s/匹配模式/要修改的内容/</code></td><td align="left">查找符合匹配模式的字符串，将其匹配到的<strong>第一个</strong>字符串进行替换</td></tr><tr><td>改</td><td><code>s/匹配模式/要修改的内容/g</code></td><td align="left">查找符合匹配模式的字符串，将匹配到的<strong>所有</strong>的字符串都进行替换</td></tr><tr><td>改</td><td><code>s/匹配模式/要修改的内容/2g</code></td><td align="left">只替换从第二个符合匹配模式后面的所有字符串</td></tr><tr><td>改</td><td><code>s/匹配模式/要修改的内容/ig</code></td><td align="left">忽略大小写查找符合匹配模式的字符串，将匹配到的所有字符串都进行替换</td></tr></tbody></table><h3 id="sed-的显示行号"><a href="#sed-的显示行号" class="headerlink" title="sed 的显示行号"></a>sed 的显示行号</h3><ul><li><code>=</code> 可以显示输出的行号</li></ul><p>例如：<br><code>sed = /etc/passwd</code></p><p>以上是sed流编辑器的学习内容和笔记。</p><h2 id="awk-文本处理器"><a href="#awk-文本处理器" class="headerlink" title="awk 文本处理器"></a>awk 文本处理器</h2><p><strong>awk 是一个文本处理工具，通常用于处理数据或者生成结果报告</strong></p><ul><li><code>第一种形式：awk [BEGIN&#123;   &#125;]匹配模式&#123; command命令  &#125;[END&#123;   &#125;] 文件路径</code></li><li><code>第二种形式：stdout | awk [BEGIN&#123;   &#125;]匹配模式&#123; command命令  &#125;[END&#123;   &#125;]</code><br><em><code>stdout</code>意思为通过管道 <code>|</code> 将文本传入给后面的命令。</em></li></ul><h3 id="语法格式说明"><a href="#语法格式说明" class="headerlink" title="语法格式说明"></a>语法格式说明</h3><table><thead><tr><th>语法格式</th><th align="left">解释</th></tr></thead><tbody><tr><td><code>BEGIN&#123;   &#125;</code></td><td align="left">正式处理数据之前执行</td></tr><tr><td><code>pattern</code></td><td align="left">匹配格式</td></tr><tr><td><code>&#123; command  &#125;</code></td><td align="left">处理命令</td></tr><tr><td><code>END</code></td><td align="left">处理完所有匹配数据后执行</td></tr></tbody></table><p>一行简单的awk命令：<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;&#123; print $1  &#125;&#39; /etc/passwd</code><br><br>它输出的是passwd中所有用户的用户名。那么<code>FS</code>,<code>print</code>,<code>$1</code>…都代表什么意思？这里引入awk的<strong>内置变量</strong>以及<strong>command命令</strong></p><h3 id="内置变量"><a href="#内置变量" class="headerlink" title="内置变量"></a>内置变量</h3><table><thead><tr><th>内置变量</th><th align="left">含义</th></tr></thead><tbody><tr><td><code>$0</code></td><td align="left">整行内容</td></tr><tr><td><code>$1-$n</code></td><td align="left">当前行的第1-n个字段</td></tr><tr><td><code>NF</code></td><td align="left">当前行的字段<strong>个数</strong>，也就是有多少列</td></tr><tr><td><code>NR</code></td><td align="left">当前行的行号，从1开始计数</td></tr><tr><td><code>FNR</code></td><td align="left">在处理多个文件时，每个文件的行号单独计数不累加，每个文件从1开始计数</td></tr><tr><td><code>FS</code></td><td align="left">输入字段的分隔符。不指定时默认以空格或者tab键分割</td></tr><tr><td><code>RS</code></td><td align="left">输入行的分隔符。不指定时默认为回车换行</td></tr><tr><td><code>OFS</code></td><td align="left">输出字段分隔符。默认为空格</td></tr><tr><td><code>ORS</code></td><td align="left">输出行分隔符。默认为回车换行</td></tr></tbody></table><h3 id="格式化输出-printf"><a href="#格式化输出-printf" class="headerlink" title="格式化输出 printf"></a>格式化输出 printf</h3><table><thead><tr><th>格式符</th><th align="left">含义</th></tr></thead><tbody><tr><td><code>%s</code></td><td align="left">打印字符串</td></tr><tr><td><code>%d</code></td><td align="left">打印10进制数</td></tr><tr><td><code>%f</code></td><td align="left">打印浮点数</td></tr><tr><td><code>%x</code></td><td align="left">打印16进制数</td></tr><tr><td><code>%o</code></td><td align="left">打印8进制数</td></tr><tr><td><code>%e</code></td><td align="left">打印数字的科学技术法格式</td></tr><tr><td><code>%c</code></td><td align="left">打印单个字符的ACSII码</td></tr></tbody></table><table><thead><tr><th>修饰符</th><th align="left">含义</th></tr></thead><tbody><tr><td><code>-</code></td><td align="left">左对齐</td></tr><tr><td><code>+</code></td><td align="left">右对齐</td></tr><tr><td><code># </code></td><td align="left">显示8进制在前面加0，16进制在前面加0x</td></tr></tbody></table><p>例子：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 1、以字符串的形式打印/etc/passwd中的第7个字段，以“:”作为分隔符。</span></span><br><span class="line">awk <span class="string">&#x27;BEGIN&#123; FS=&quot;:&quot;  &#125;&#123; printf &quot;%s&quot;,$7  &#125;&#x27;</span> /etc/passwd</span><br><span class="line"><span class="comment"># 2、以字符串的形式打印/etc/passwd中的第7个字段，以“:”作为分隔符，要求每个字段间以换行回车隔开。</span></span><br><span class="line">awk <span class="string">&#x27;BEGIN&#123; FS=&quot;:&quot;  &#125;&#123; printf &quot;%s\n&quot;,$7  &#125;&#x27;</span> /etc/passwd</span><br></pre></td></tr></table></figure><h3 id="awk-匹配模式"><a href="#awk-匹配模式" class="headerlink" title="awk 匹配模式"></a>awk 匹配模式</h3><ul><li>第一种匹配模式:正则表达式匹配</li><li>第二种匹配模式:关系运算匹配</li></ul><h4 id="正则表达式匹配"><a href="#正则表达式匹配" class="headerlink" title="正则表达式匹配"></a>正则表达式匹配</h4><p>1、匹配/etc/passwd文件行中含有root字符串的所有行<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;/root/&#123; print $0  &#125;&#39; /etc/passwd</code><br>2、匹配/etc/passwd文件行中以sshd开头的所有行<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;/^sshd/&#123; print $0  &#125;&#39; /etc/passwd</code></p><h4 id="关系运算符匹配"><a href="#关系运算符匹配" class="headerlink" title="关系运算符匹配"></a>关系运算符匹配</h4><table><thead><tr><th>关系运算符</th><th align="left">解释</th></tr></thead><tbody><tr><td>&lt;</td><td align="left">小于</td></tr><tr><td>&gt;</td><td align="left">大于</td></tr><tr><td>&lt;=</td><td align="left">小于等于</td></tr><tr><td>&gt;=</td><td align="left">大于等于</td></tr><tr><td>==</td><td align="left">等于</td></tr><tr><td>!=</td><td align="left">不等于（可用于字符串）</td></tr><tr><td>~</td><td align="left">匹配正则表达式</td></tr><tr><td>!~</td><td align="left">不匹配正则表达式</td></tr></tbody></table><table><thead><tr><th>匹配表达式（只与关系运算符连用）</th><th align="left">解释</th></tr></thead><tbody><tr><td>&amp;#124&amp;#124</td><td align="left">或</td></tr><tr><td><code>&amp;&amp;</code></td><td align="left">与</td></tr><tr><td><code>!</code></td><td align="left">非</td></tr></tbody></table><p>例子：</p><ul><li>1、以<code>:</code>为分隔符，匹配/etc/passwd文件中第三个字段小于50的所有行信息<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;$3&lt;50&#123; print $0  &#125;&#39; /etc/passwd</code></li><li>2、以<code>:</code>为分隔符，匹配/etc/passwd文件中第三个字段等于0的行信息<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;$3==0&#123; print $0  &#125;&#39; /etc/passwd</code></li><li>3、以<code>:</code>为分隔符，匹配/etc/passwd文件中第七个字段不等于<code>/bin/bash</code>所有行信息<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;$7!=&quot;/bin/bash&quot;&#123; print $0  &#125;&#39; /etc/passwd</code></li><li>4、通过匹配正则表达式，匹配/etc/passwd中以root开头的所有行信息<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;$1~/^root/&#123; print $0  &#125;&#39; /etc/passwd</code></li><li>5、以<code>:</code>为分隔符，匹配/etc/passwd文件中第一个字段等于root或sshd的所有行信息<br><code>awk &#39;BEGIN&#123; FS=&quot;:&quot;  &#125;$1==&quot;root&quot;||$1==&quot;sshd&quot;&#123; print $0  &#125;&#39; /etc/passwd</code></li></ul><h3 id="awk中的判断与循环"><a href="#awk中的判断与循环" class="headerlink" title="awk中的判断与循环"></a>awk中的判断与循环</h3><h4 id="if判断-1"><a href="#if判断-1" class="headerlink" title="if判断"></a>if判断</h4><p>awk的if判断与C语言基本一致。下面是awk中if语句格式的举例：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line"><span class="keyword">if</span>(<span class="variable">$3</span>&gt;50)</span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">print</span> <span class="variable">$0</span></span><br><span class="line">  &#125;</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">&#123; </span><br><span class="line">    <span class="built_in">printf</span> <span class="string">&quot;%s%s%s\n&quot;</span>,<span class="string">&quot;该用户：&quot;</span>,<span class="variable">$1</span>,<span class="string">&quot;的UID小于50&quot;</span></span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>如果现在要求输出UID大于50的用户信息要咋办呢？可以看下面的这个例子。</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">awk <span class="string">&#x27;BEGIN&#123; FS=&quot;:&quot;  &#125;</span></span><br><span class="line"><span class="string">&#123; </span></span><br><span class="line"><span class="string">    if($3&gt;50)</span></span><br><span class="line"><span class="string">    &#123; </span></span><br><span class="line"><span class="string">        print $0</span></span><br><span class="line"><span class="string">      &#125;</span></span><br><span class="line"><span class="string">    else</span></span><br><span class="line"><span class="string">    &#123; </span></span><br><span class="line"><span class="string">        printf &quot;%s%s%s\n&quot;,&quot;该用户：&quot;,$1,&quot;的UID小于50&quot;</span></span><br><span class="line"><span class="string">      &#125;</span></span><br><span class="line"><span class="string">  &#125;&#x27;</span> /etc/passwd</span><br></pre></td></tr></table></figure><p>将上面的命令直接复制到终端里便可以运行，但是这样是不是编写起来有些不太方便？</p><p>所以我更愿意将上面的一些命令抽象出一个awk脚本，然后让<code>awk -f</code>去运行这个脚本，这样思路和结构也会更清楚一些。</p><p>那现在来建立一个awk脚本：<code>vim if-else.awk</code>进入编辑模式，键入以下内容：</p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">BEGIN&#123; FS=<span class="string">&quot;:&quot;</span>  &#125;</span><br><span class="line">&#123; </span><br><span class="line">    <span class="keyword">if</span>(<span class="variable">$3</span>&gt;50)</span><br><span class="line">    &#123; </span><br><span class="line">        <span class="built_in">print</span> <span class="variable">$0</span></span><br><span class="line">      &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123; </span><br><span class="line">        <span class="built_in">printf</span> <span class="string">&quot;%s%s%s\n&quot;</span>,<span class="string">&quot;该用户：&quot;</span>,<span class="variable">$1</span>,<span class="string">&quot;的UID小于50&quot;</span></span><br><span class="line">      &#125;</span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p>保存后我们可以使用<code>-f</code>选项来使用这个awk脚本：</p><p><code>awk -f if-else.awk /etc/passwd</code></p><p>这样一来命令也很清晰很多了，舒服的一批！</p><h3 id="awk的循环"><a href="#awk的循环" class="headerlink" title="awk的循环"></a>awk的循环</h3><p>拿一个从1一直加到100的这个小学问题来当做学习循环的例子吧～</p><p>1、while循环：</p><p><code>vim while.awk</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">BEGIN&#123; </span><br><span class="line">    <span class="keyword">while</span>(i&lt;=100)</span><br><span class="line">    &#123; </span><br><span class="line">        <span class="built_in">sum</span>+=i</span><br><span class="line">        i++</span><br><span class="line">      &#125;</span><br><span class="line">    <span class="built_in">print</span> <span class="built_in">sum</span></span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><p><code>awk -f while.awk</code></p><ul><li>输出：5050</li></ul><p>2、do-while循环：</p><p><code>vim do-while.awk</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">BEGIN&#123; </span><br><span class="line">    <span class="keyword">do</span>&#123; </span><br><span class="line">        <span class="built_in">sum</span>+=i</span><br><span class="line">        i++</span><br><span class="line">      &#125;</span><br><span class="line">    <span class="keyword">while</span>(i&lt;=100)</span><br><span class="line">    <span class="built_in">print</span> <span class="built_in">sum</span></span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><ul><li>输出：5050</li></ul><p>3、for循环：</p><p><code>vim for.awk</code></p><figure class="highlight bash"><table><tr><td class="code"><pre><span class="line">BEGIN&#123; </span><br><span class="line">    <span class="keyword">for</span>(i=1;i&lt;=100;i++)&#123; </span><br><span class="line">        <span class="built_in">sum</span>+=i</span><br><span class="line">      &#125;</span><br><span class="line">    <span class="built_in">print</span> <span class="built_in">sum</span></span><br><span class="line">  &#125;</span><br></pre></td></tr></table></figure><ul><li>输出：5050</li></ul><hr><p>我是一名Linux初学者，如果你与我一样喜欢折腾，喜欢Linux，那么请加入我的电报群<span class="exturl" data-url="aHR0cHM6Ly90Lm1lL3llZWZpcmVfYmxvZw==" title="https://t.me/yeefire_blog">https://t.me/yeefire_blog<i class="fa fa-external-link"></i></span>，在这里畅所欲言，共同学习进步。</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;Bash-Shell学习笔记&quot;&gt;&lt;a href=&quot;#Bash-Shell学习笔记&quot; class=&quot;headerlink&quot; title=&quot;Bash/Shell学习笔记&quot;&gt;&lt;/a&gt;Bash/Shell学习笔记&lt;/h1&gt;&lt;!-- TOC --&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#bashshell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0&quot;&gt;Bash/Shell学习笔记&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#bash%E8%84%9A%E6%9C%AC%E7%9A%84%E5%A3%B0%E6%98%8E&quot;&gt;Bash脚本的声明&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F&quot;&gt;变量&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%9A%E4%B9%89%E5%8F%98%E9%87%8F&quot;&gt;定义变量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%9A%E4%B9%89%E6%9C%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8F%98%E9%87%8F&quot;&gt;定义有类型的变量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F%E7%9A%84%E5%88%A0%E9%99%A4&quot;&gt;变量的删除&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F%E7%9A%84%E6%9B%BF%E6%8D%A2&quot;&gt;变量的替换&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F%E5%92%8C%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F&quot;&gt;局部变量和全局变量&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B1%80%E9%83%A8%E5%8F%98%E9%87%8F&quot;&gt;局部变量&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F%E7%9A%84%E6%B5%8B%E8%AF%95&quot;&gt;变量的测试&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%A4%84%E7%90%86&quot;&gt;字符串的处理&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%AE%A1%E7%AE%97%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E9%95%BF%E5%BA%A6&quot;&gt;计算字符串的长度&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8A%BD%E5%8F%96%E5%AD%90%E4%B8%B2&quot;&gt;抽取子串&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2%E5%92%8C%E6%95%B0%E5%AD%A6%E8%BF%90%E7%AE%97&quot;&gt;命令替换和数学运算&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2&quot;&gt;命令替换&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%95%B0%E5%AD%A6%E8%AE%A1%E7%AE%97&quot;&gt;数学计算&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1%E7%94%A8-%E6%9D%A5%E8%A1%A8%E8%BE%BE%E6%95%B0%E5%AD%A6%E8%AE%A1%E7%AE%97%E5%92%8C%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%E6%97%B6%E8%A6%81%E6%B3%A8%E6%84%8F%E6%8B%AC%E5%8F%B7%E7%9A%84%E4%B8%AA%E6%95%B0&quot;&gt;1、&lt;strong&gt;用$(( ))来表达数学计算,和命令替换一起使用时要注意括号的个数&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2%E4%BD%BF%E7%94%A8bc%E6%9D%A5%E5%A4%84%E7%90%86%E6%B5%AE%E7%82%B9%E5%9E%8B%E6%95%B0%E5%AD%A6%E8%BF%90%E7%AE%97&quot;&gt;2、&lt;strong&gt;使用bc来处理浮点型数学运算&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%87%BD%E6%95%B0&quot;&gt;函数&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%9A%E4%B9%89%E5%87%BD%E6%95%B0&quot;&gt;定义函数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%87%BD%E6%95%B0%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC&quot;&gt;函数的返回值&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%87%BD%E6%95%B0%E5%BA%93&quot;&gt;函数库&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD%E5%88%86%E6%94%AF&quot;&gt;条件、判断、分支&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#if%E5%88%A4%E6%96%AD&quot;&gt;if判断&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#while%E5%BE%AA%E7%8E%AF&quot;&gt;while循环&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sed-%E6%B5%81%E7%BC%96%E8%BE%91%E5%99%A8&quot;&gt;sed 流编辑器&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%AE%80%E4%BB%8B&quot;&gt;简介：&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%80%89%E9%A1%B9-option%E5%B8%B8%E7%94%A8&quot;&gt;选项 option(常用)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sed-%E7%9A%84%E5%8C%B9%E9%85%8D%E6%A8%A1%E5%BC%8F&quot;&gt;sed 的匹配模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sed-%E7%9A%84%E5%A2%9E%E5%88%A0%E6%94%B9%E6%9F%A5&quot;&gt;sed 的增删改查&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sed-%E7%9A%84%E6%98%BE%E7%A4%BA%E8%A1%8C%E5%8F%B7&quot;&gt;sed 的显示行号&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#awk-%E6%96%87%E6%9C%AC%E5%A4%84%E7%90%86%E5%99%A8&quot;&gt;awk 文本处理器&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%AF%AD%E6%B3%95%E6%A0%BC%E5%BC%8F%E8%AF%B4%E6%98%8E&quot;&gt;语法格式说明&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%86%85%E7%BD%AE%E5%8F%98%E9%87%8F&quot;&gt;内置变量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%A0%BC%E5%BC%8F%E5%8C%96%E8%BE%93%E5%87%BA-printf&quot;&gt;格式化输出 printf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#awk-%E5%8C%B9%E9%85%8D%E6%A8%A1%E5%BC%8F&quot;&gt;awk 匹配模式&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%8C%B9%E9%85%8D&quot;&gt;正则表达式匹配&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%85%B3%E7%B3%BB%E8%BF%90%E7%AE%97%E7%AC%A6%E5%8C%B9%E9%85%8D&quot;&gt;关系运算符匹配&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#awk%E4%B8%AD%E7%9A%84%E5%88%A4%E6%96%AD%E4%B8%8E%E5%BE%AA%E7%8E%AF&quot;&gt;awk中的判断与循环&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#if%E5%88%A4%E6%96%AD-1&quot;&gt;if判断&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#awk%E7%9A%84%E5%BE%AA%E7%8E%AF&quot;&gt;awk的循环&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- /TOC --&gt;</summary>
    
    
    
    
    <category term="Linux" scheme="https://blog.yeefire.com/tags/Linux/"/>
    
    <category term="Bash" scheme="https://blog.yeefire.com/tags/Bash/"/>
    
    <category term="Linux技术" scheme="https://blog.yeefire.com/tags/Linux%E6%8A%80%E6%9C%AF/"/>
    
  </entry>
  
</feed>
