BoyChai's Blog - 工具 https://blog.boychai.xyz/index.php/tag/%E5%B7%A5%E5%85%B7/ Git-版本控制工具 https://blog.boychai.xyz/index.php/archives/17/ 2022-06-04T15:17:00+00:00 概述Git是一个开源免费的分布式版本控制系统,可以快速高效的来管理项目代码。官网:https://git-scm.com/安装Windows[vplayer status="true"][Video url="https://www.bilibili.com/video/BV1Rb4y1C7z1" title="采用b站UP:Houor的视频" /][/vplayer]Linuxyum -y install git工作流程在本地主机会分三个区域,分别为工作区、暂存区、本地库,如果需要多人协作可以上传到一个远程仓库里面提供他人管理代码。区域作用工作区写代码的过程都会在工作区内完成,写完之后需要上传到暂存区暂存区代码写完之后需要放到暂存区,确定没有问题之后需要把版本信息和暂存区的内容上传到本地库本地库全部的版本都在本地库里面远程库远程仓库是整个团队中所有人都可以访问的地方。代码管理设置签名签名就是上传到本地库,远程仓库的时候的身份。$ git config --global user.name "BoyChai" $ git config --global user.email "1972567225@qq.com" $ git config --global --list初始化仓库默认本地是没有仓库的,这时候我们需要初始化一个仓库,进入到对应项目的目录执行命令"git init",例如$ mkdir project $ cd project/ $ git init Initialized empty Git repository in /root/project/.git/初始化好了之后会在本地创建一个".git"的目录,这个目录就是存放暂存区和本地库的地方。此时项目文件夹就是工作区。提交暂存区此时目录里创建一个文件可以通过命令"git add [file]"将文件提交到暂存区,例如$ echo 111 > test01 $ git add test01提交本地库提交完暂存区之后可以通过命令"git commit -m "[版本信息]""提交到本地库里面,例如$ git commit -m "test01" [master (root-commit) 776b640] test01 1 file changed, 1 insertion(+) create mode 100644 test01状态显示当前分支,并且查看在你上次提交之后是否有对文件进行再次修改。git status 记录通过命令"git log"显示历史提交记录,例如$ git log commit 4240a74fc27134b79addead798a10d8d4808ec91 Author: BoyChai <1972567225@qq.com> Date: Sat Jun 4 09:40:10 2022 -0400 test03 commit 93d1896fcc57d4b84733f70bffab8d68b56a2f0b Author: BoyChai <1972567225@qq.com> Date: Sat Jun 4 09:40:02 2022 -0400 test02 commit 776b640b6bf839f27a5ef099f33c11e66aa8f1da Author: BoyChai <1972567225@qq.com> Date: Sat Jun 4 09:38:43 2022 -0400 test01 也可以让他进行简易的输出提交记录”git log --pretty=onelint“或“git log --oneline”还可以使用命令“git reflog”来查看可引用的历史版本记录,他输出会带一个tag,输出内容如下[root@gitlab project]# git reflog 4240a74 HEAD@{0}: commit: test03 93d1896 HEAD@{1}: commit: test02 776b640 HEAD@{2}: commit (initial): test01回滚可以让代码回到历史的某个版本git reset --hard [版本ID]版本的ID可以使用查看记录的方法获得[root@gitlab project]# git reflog 4240a74 HEAD@{0}: commit: test03 93d1896 HEAD@{1}: commit: test02 776b640 HEAD@{2}: commit (initial): test01 [root@gitlab project]# git reset --hard 93d1896 //回滚到test02 HEAD is now at 93d1896 test02分支管理概述如果涉及团队开发合作可以使用分支来分配工作,在写代码的时候,如果有多个功能需要去实现而且是一个团队进行编写,都在一个主分支上编写代码可能并不是很好管理,这个时候可以通过分支来管理,把每一个功能都单独创建一个分支让一个人去编写或者几个人去编写,当这个功能完善的时候就可以和主分支进行合并。查看分支使用命令"git branch -v"来查看,例如$ git branch -v * master 93d1896 test02创建分支使用命令"git branch [分支名称]"来创建,例如$ git branch branch1 $ git branch -v branch1 93d1896 test02 * master 93d1896 test02切换分支使用命令"git checkout [分支名称]"来切换分支,例如$ git checkout branch1 Switched to branch 'branch1' $ git branch -v * branch1 93d1896 test02 master 93d1896 test02合并分支当分支的代码提交好了之后可以进行合并分支,合并分支需要将分支切换到master(主分支),然后使用命令"git merge [分支名称]"来合并分支,之后使用“commit”来提交,例如$ git branch -v * branch1 93d1896 test02 master 93d1896 test02 $ echo aaa > branch1_file01 $ git add branch1_file01 $ git commit -m "branch1_分支提交" [branch1 af08213] branch1_分支提交 1 file changed, 1 insertion(+) create mode 100644 branch1_file01 $ git checkout master Switched to branch 'master' $ git branch -v branch1 af08213 branch1_分支提交 * master 93d1896 test02 [root@gitlab project]# echo bbb > master_file1 [root@gitlab project]# git add master_file1 [root@gitlab project]# git commit -m "master提交" [master 731413b] master提交 1 file changed, 1 insertion(+) create mode 100644 master_file1 [root@gitlab project]# git branch -v branch1 af08213 branch1_分支提交 * master 731413b master提交 [root@gitlab project]# git merge branch1 //merge之后会弹出一下内容,第一行是写合并备注的,类似于命令"it commit -m"的备注 ---------------------------------------------------------------------------------- Merge branch 'branch1' # Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit. ---------------------------------------------------------------------------------- //保存之后显示 Merge made by the 'recursive' strategy. branch1_file01 | 1 + 1 file changed, 1 insertion(+) create mode 100644 branch1_file01 $ git commit # On branch master nothing to commit, working directory clean $ git branch -v branch1 af08213 branch1_分支提交 * master 6a764f1 Merge branch 'branch1'上面这个是主分支和分支都改变代码的情况下进行合并,如果没有改变主分支的代码就进行合并则不会弹出merge之后的内容分支代码冲突当分支和主分支的代码产生冲突该,例如$ git branch branch2 $ git checkout master Switched to branch 'master' $ cat > file.txt <<EOF > 111 > 222 > 444 > EOF $ cat file.txt 111 222 444 $ git add file.txt $ git commit -m "master_提交" [master d7e9855] master_提交 1 file changed, 3 insertions(+) create mode 100644 file.txt [root@gitlab project]# git checkout branch2 Switched to branch 'branch2' $ cat > file.txt <<EOF > 111 > 222 > 333 > 444 > EOF $ cat file.txt 111 222 333 444 $ git add file.txt $ git commit -m "branch2_提交" [branch2 3bac7d1] branch2_提交 1 file changed, 4 insertions(+) create mode 100644 file.txt此时master和分支branch2提交的最新版本的file.txt文件是有冲突的,这个时候进行合并会出现一下问题$ git checkout master Switched to branch 'master' [root@gitlab project]# git branch -v branch1 af08213 branch1_分支提交 branch2 3bac7d1 branch2_提交 * master d7e9855 master_提交 $ git merge branch2 Auto-merging file.txt CONFLICT (add/add): Merge conflict in file.txt Automatic merge failed; fix conflicts and then commit the result.此时查看冲突文件会发现文件里的内容发生了改变$ cat file.txt 111 222 <<<<<<< HEAD ======= 333 >>>>>>> branch2 444文件的意思就是中间出现了333这一行,如果想要保留branch2分支的内容则就改成这样$ cat file.txt 111 222 333 444如果不想保留branch2分支的内容则就删除对应内容,例如$ cat file.txt 111 222 444上面两种保留方式选择一种之后,使用命令"git add [冲突文件]"来解决冲突,并使用命令"git commit"进行合并$ cat file.txt 111 222 333 444 $ git add file.txt $ git commit -m "master-branch2解决冲突" [master 00721ab] master-branch2解决冲突 $ git branch -v branch1 af08213 branch1_分支提交 branch2 3bac7d1 branch2_提交 * master 00721ab master-branch2解决冲突远程仓库管理创建远程仓库远程仓库的类型有很多,Github,Gitee,Gitlab,Gogs等等,这里采用github作为示范,如图推送代码推送代码到github之前还需要一个用户token,打开github的settings -> Developer settings -> Personal access tokens -> Generate new token,日期我选的7天权限根据自己情况自己勾选,之后店家Generate token,如图之后当我们的代码已经提交完到本地库里了,我们可以通过命令"git push '仓库地址' '分支名称' "进行推送,推送过程中需要输入用户名和密码,这个密码实际上就是我们刚才创建的token,例如$ git push https://github.com/BoyChai/Git_test.git master Username for 'https://github.com': BoyChai Password for 'https://BoyChai@github.com': Counting objects: 20, done. Delta compression using up to 4 threads. Compressing objects: 100% (14/14), done. Writing objects: 100% (20/20), 1.53 KiB | 0 bytes/s, done. Total 20 (delta 7), reused 0 (delta 0) remote: Resolving deltas: 100% (7/7), done. To https://github.com/BoyChai/Git_test.git * [new branch] master -> master克隆代码当远程仓库发生改变想要同步到本地的时候可以使用命令"git pull '仓库地址' '分支名称' ",例如$ git pull https://github.com/BoyChai/Git_test.git master From https://github.com/BoyChai/Git_test * branch master -> FETCH_HEAD Already up-to-date.别名每次去推送、克隆代码的时候都需要输入一段很长的仓库地址,并不是很方便,可以使用命令"git remote add '别名' '仓库地址' "来创建别名,例如$ git remote add git_test https://github.com/BoyChai/Git_test.git $ git remote -v git_test https://github.com/BoyChai/Git_test.git (fetch) git_test https://github.com/BoyChai/Git_test.git (push)之后相关代码仓库地址的位置都可以替换成别名来操作,例如git push git_test master git pull git_test master团队协作团队协作需要在远程仓库里添加团队内部的人,在Github上的具体流程为 打开对应的项目 -> Settings -> Collaborators -> Add people点击Select a collaborator above之后会给一个链接,需要发给对方进行验证,通过之后就可以在此仓库进行协作了跨团队协作跨团队操作需要进行Fork操作,如图点击fork之后会让你写一个仓库名称,之后这个仓库会以刚才的仓库名称变成你仓库里的一个项目,你可以自己任意更改提交克隆,当代码写好提交到自己fork的仓库之后,去对方的仓库里面点击pull requests创建一个之后会出现一个版本比较的一个东西,让你选择版本进行对比,第一个选择就是他的仓库,第二个就是自己fork的仓库,选择好之后会出现修改的内容对比,然后进行创建,创建之后对方会受到一个请求,当对方同意的时候代码就会自动合并到对方仓库里。 IPTABLES-防火墙 https://blog.boychai.xyz/index.php/archives/11/ 2022-05-25T03:40:00+00:00 概述Netfilter/iptables(以下简称iptbales)是unix/linux自带的一款优秀切开放源代码的完全自由的基于包过滤的防护墙工具,他的功能十分强大,使用非常灵活,可以对流入和流出服务器的数据包进行很精细的控制。Iptables是linux2.4以2.6内核中集成的服务。其功能与安全性比其老一辈ipfwadm,ipchains强大的多(长江后浪推前浪),iptable主要是工作在OSI模型的二三四层,如果重新编译内核,iptables也可以支持7层控制(squid代理+iptables)。专业名词Netfilter/iptables可以把Netfilter/iptables看作一栋楼,里面存放着很多的表。表(tables)表(tables)是链的容器,即所有的链(chains)都属于其对应的表(tables)上,可以把表(iptables)当作一套房子。表有filter nat mangle raw四个表。表名作用filter表I负责过滤功能,内核模块:iptables_filternat表负责网络地址转换功能,内核模块:iptable_natmangle表解析报文,做出修改,重新封装的功能,内核模块:iptable_mangleraw表关闭nat表上启用的链接追踪机制,内核模块:iptable_raw链(chains)链(chains)是规则(Policys)的容器。如果把表(tables)当作一套房子,那么链就是里面的房间,卧室,厨房,客厅什么的。链有INPUT OUTPUT FORWARD PREROUTING POSTROUTING 不同的表有不同的链规则(Policy)规(Policy)则就是一条条过滤的语句用来控制流量动作的。关于表和链关系表链filter表INPUT,FORWARD,OUTPUTnat表PREROUTING,OUTPUT,POSTROUTING,INPUT(centos6没有)mangle表PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTINGraw表PREROUTING,OUTPUTFilter主要是和自身有关,真正负责主机防火墙功能的(过滤流入流出主机的数据包)。Filter表是iptables默认使用的表,这个表定义了三个链(chains),工作场景主要是作为主机的防火墙。INPUT链 负责过滤所有目标地址是本机地址的数据。通俗的讲,就是过滤进入主机的数据包。FORWARD链 负责转发流经主机的数据包。起转发的作用,和nat关系很大,后面会详细介绍。 LVSNAT模式。net.ipv4.ip_forward = 0OUTPUT链 处理所有源地址是本机地址的数据包。通俗的讲,就是处理从主机发去的数据包。NAT负责网络地址转换,即来源与目的ip地址和port的转换。主要应用于局域网共享上网或者特殊的端口转换服务相关。(和主机本身无关)NAT功能一般用于的场景用于做企业路由或网关,共享上网。做内部IP地址一对一映射,硬件防火墙映射IP到内部服务器,FTP服务。Web,单个端口映射,直接映射80端口OUTPUT链 和主机发出去的数据包有关。改变主机发出数据包的目标地址。PREROUTING链 在数据包到达防火墙时进行路由判断之前执行的规则,作用是改变数据包的目的地址,目的端口等。(通俗的说就是收信时,根据规则重写收件人的地址)POSTROUTING链 在数据包离开防火墙时进行路由判断之后的规则,作用改变数据包的源地址,源端口等。(通俗的说就是寄信的时候可以改变发件人的地址)Mangle主要负责修改数据包中特殊的路由标记,如TTL,TOS,MARK等。这个表定义了5个链INPUT FORWARD OUTPUT PREROUTING POSTROUTING这个表基本用不到知道即可RAW主要是用来控制数据包是否需要通过iptables来处理的一个表 比如web服务器流量很大80端口默认开着需要filter表的INPUT是否来通过 使用RAW表之后则这条就不需要经过iptables防火墙了直接忽略通 防止流量过高 iptables处理不过来提高服务器性能链只有两个PREROUTING和OUTPUT在表中数据包最早经过就是RAW所以可以让iptables不处理对应的数据包工作流程过滤流程iptables是采取包过滤机制工作的,所以它会对请求的数据包的包头数据进行分析、并根据我们预先设定的规则进行匹配来判断之后进行的动作。下图为过滤的流程图表链工作流程下图为较为具体的工作流程图下图为简易流程图平常我们其实只需要顾及到nat的prerouting、postrouting和filter的input、forward以他的一般是用不到命令注意CentOS6自带iptables 往后的版本应该都是改用firewalld防火墙了 使用iptables的话得stop服务或者mask服务 systemctl sotp/mask firwealld才行 之后不管是那个版本iptables应该都是自带的但是还缺一样东西iptables-services这个包安装之后才可以使用service iptables的命令来进行管理服务这个包很重要规则的动作丢弃比拒绝更好一些拒绝会回包丢弃是直接忽略还有一个理由就是说如果别人来判断你的主机是否存货拒绝的话就代表你的服务器存在 忽略的话他就会以为你这个东西不存在因为没有回包。服务管理systemctl start iptables //开启服务 systemctl stop iptables //关闭服务 systemctl enable iptables //设置开机自启 systemctl disable iptables //设置开机自动关闭 service iptables save //保存当前设置下次开机之后会生效Ps:在centos7版本之后默认不会安装iptables-services,如果需要使用服务管理则需要安装一下"yum -y install iptables-services",iptables默认会有一个配置表(/var/sysconfig/iptabels这个文件) 这个表记录这本机的所有的iptables配置 每次开机之后都会找这个文件使其里面的配置生效service iptables save就是把当前临时的配置保存到这个表里使下次重载或者重启时生效 这一步很重要规则管理iptables -L //列出表的规则 默认不加任何参数输出的时filter表的规则 iptables -F //清除所有的规则(无法清除默认的规则) iptables -X //删除用户自定义的链(用的很少) iptables -N //创建链(用的少) iptables -Z //把链的计数器清零规则配置iptables -t //指定表 iptables -t [表] -A //指定链以及添加规则的方式(在规则低端添加规则) iptables -t [表] -I //指定链以及添加规则的方式(在规则顶端添加规则) iptables -t [表] -D //指定链以及删除对应规则 iptables -t [表] -A/I [链] -p //指定ip协议tcp/udp iptables -t [表] -A/I [链] –p [tcp/udp] --dport //指定目标端口 iptables -t [表] -A/I [链] -i //指定流入网卡 iptables -t [表] -A/I [链] -o //指定流出网卡 iptables -t [表] -A/I [链] -s //指定源地址 iptables -t [表] -A/I [链] [相应参数] -j //指定动作(一共三种通过(ACCEPT) 拒绝(REJECT) 丢弃(DROP))例丢弃22端口(ssh)的链接 iptables -t filter -A INPUT -p tcp --dport 22 -j DROP丢弃某个IP的所有包 iptables -t filter -A INPUT -s [IPADDR] -j DROP除了某个IP的数据其他全部丢弃 iptables -t filter -A INPUT ! -s [IPADDR] -j DROP禁用整个网卡 iptables -t filter -A INPUT -i [网卡名称] -j DROP范围性丢弃端口链接 iptables -t filter -A INPUT -p tcp –dport [最小:最大] -j DROP丢弃多个端口的链接 iptables -t filter -A INPUT -p tcp -m multiport –dport [23,24,25...] -j DROPNAT表注意因为NAT是负责网络转换这块,最好是把内核的转发更能打开,不然路由链就不生效cat /etc/sysctl.conf |grep net.ipv4.ip_forward net.ipv4.ip_forward = 1 sysctl -p //生效SNATIp转换 一般用于局域网做网管内网ip转换为可上网的ip 提供内网主机上网使用命令:Iptables -t nat -A POSTROUTING -s 源地址 -d 0.0.0.0/0 -j SNAT –to-source 转换的ipDNAT端口转发 一般用于端口转发做反向代理 可以防止内网主机完全暴露在公网环境中.自己的端口转发IP tables -t nat -A PREROUTING -p tcp –dport 本机端口 -J REDIRECT –to-port 转到端口主机的端口转发Iptables -t nat -A PREROUTING -p tcp –dport 本机端口 -J DNAT –to-destination 主机:端口MASQUERADEIp伪装 一般用于局域网做网管内网ip转换为可上网的ip 提供内网主机上网使用命令:Iptables -t nat -A POSTROUTING -s 源地址 -d 0.0.0.0/0 -j MASQUERADE SYSTEMCTL-系统服务管理 https://blog.boychai.xyz/index.php/archives/10/ 2022-05-03T06:45:00+00:00 概述systemctl是一个systemd中其中一个工具,主要用于控制systemd系统和各种服务的管理。在Linux生态系统中,Systemd被部署到了大多数的标准Linux发行版中,只有为数不多的几个发行版尚未部署。Systemd通常是所有其它守护进程的父进程,但并非总是如此。相关目录目录用处 /usr/lib/systemd/system/每个服务最主要的启动脚本目录 /run/systemd/system/系统所生成的服务脚本目录,优先级比/usr/lib/systemd/system/高 /etc/systemd/system/自己创建的服务启动脚本目录,优先级/run/systemd/system/高服务类型服务类型全称用处service一般服务类型主要是系统服务,包括服务器本身所需要的本机服务以及网络服务,比较经常被使用到的服务大多是这种类型,所以,这也是最常见的类型。socket内部程序数据交换的插槽服务主要是IPC(Inter-processcommunication)的传输信息插槽(socketfile)功能。这种类型的服务通常在监控信息传递的插槽档,当有通过此插槽传递信息请求链接服务的时候,就依据当时的状态将该用户的请求传送到对应的daemon,若daemon尚未启动,则启动该daemon后再传送用户的请求。使用socket类型的服务一般是比较不会被用到的服务,因此在开机时通常会稍微延迟启动的时间。一般用于本机服务比较多,例如我们的图形界面很多的软件都是通过socket来进行本机程序数据交换的行为。target执行环境类型其实是一群unit的集合,例如multi-user.target其实就是一堆服务的集合。mount文件系统挂载相关的服务例如来自网络的自动挂载、NFS文件系统挂载等与文件系统相关性较高的程序管理。path监测特定文件或目录类型某些服务需要监测某些特定的目录来提供序列服务,例如最常见的打印服务,就是通过监测打印序列目录来启动打印功能。这时就得要.path的服务类型支持。timer循环执行的服务这个东西有点类似anacrontab,不过是由systemd主动提供的,比anacrontab更加有弹性服务管理目录使用启动服务systemclt start 服务名关闭服务systemclt stop 服务名重启服务systemclt restart 服务名重载服务systemclt reload 服务名开机自启动服务systemclt enable 服务名开机自关闭服务systemclt disable 服务名禁用服务systemclt mask 服务名取消禁用systemctl unmask 服务名服务状态systemctl status 服务名服务状态[root@localhost ~]# systemctl status firewlald Unit firewlald.service could not be found. [root@localhost ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2022-05-22 11:01:43 EDT; 7min ago Docs: man:firewalld(1) Main PID: 932 (firewalld) Tasks: 2 (limit: 11208) Memory: 35.0M CGroup: /system.slice/firewalld.service └─932 /usr/libexec/platform-python -s /usr/sbin/firewalld --nofork --nopid May 22 11:01:42 localhost.localdomain systemd[1]: Starting firewalld - dynamic firewall daemon... May 22 11:01:43 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon. May 22 11:01:43 localhost.localdomain firewalld[932]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It >已防火墙firewalld服务为例,Active:后面的就是服务当前的状态状态作用active(running)正有一个或多个程序正在被系统执行active(exited)仅执行一次就正常结束的服务,目前并没有任何程序在系统中执行active(waiting)正在执行当中,不过有需要等待其他的警告才能继续处理inactive服务没有运行dead程序已清除在第二行的vendor preset:的后面有一个值这个值是指当前服务默认的启动方式方式作用enabled开机时自动运行disabled开机时不运行static被关联的服务,不可以被自己启动,但是可以通过某些服务进行唤醒启动mask不允许被启动,被禁用了自定义服务概述自定义服务可以放到/etc/systemd/system/下,后缀名按照service来创建,列如test.service。文件内容分为三个部分,如下下表类作用[Unit]定义服务的说明,信息[UnitType]上面讲了服务类型,这里就是写服务类型的,不同的unit type就得要使用相对应的设置项目,本文只将service类型[Install]关联targetUnit参数作用Description用来写服务的简易说明的Documentation一般用来写官方文档的地址After声明某些服务,当那些服务开启之后自己才能启动,不是强制性的Before声明某些服务,声明的服务开启时服务需要开启自己,也不是强制性的Requires和After一样但是这个是强制性的Wants和Before一样但是这个是强制性的Conflicts声明服务,进行冲突检查,当声明的服务开启则自己不能启动Service参数作用Type启动的方式EnvironmentFile开启服务时的环境配置变量ExecStart开启服务的启动脚本ExecStop关闭服务的停止脚本ExecReload重置服务的重置脚本Restart当Restart=1的时候,当服务自动关闭时它会自动再开启一个服务除非是用 systemctl强制停止服务RemainAfterExit当RemainAfterExit=1的时候,服务停止时会自动启动TimeoutSec要改变服务状态时无法正常更改则会按照TimeoutSec设置的时间之后进入"强制结束"状态RestartSec和Restart差不多,这个可以设置时间,多久进行开启启动方式方式作用simple默认值,使用ExecStart来启动forking理解为做为某个进程的子进程oneshot与simple差不多,不过这个工作完后就结束了,不会常驻在内存中dbus与 simple 差不多,但是必须要活得一个D-Bus的值才可以运行,用这个方式启动的时候还需要设置一个BusName=才行idle要启动的时候必须要所有的工作都顺利执行完后才会执行,一般都是开机器最后运行的东西install参数作用WantedBy一般都是已*.targetunit为后缀的文件,指定这个服务是在某个targetunit下,一般来说,大多的服务性质 unit 都是附挂在multi-user.target下面。Also指出和服务一起安装或者被协助的单元。Alias进行一个链接的别名的意思,当设置开机自启的时候则服务会进行链接文件的创建,命名由Alias来指定 Ansible-自动化运维工具 https://blog.boychai.xyz/index.php/archives/8/ 2022-03-05T02:02:00+00:00 概述Ansible 是一个极其简单的 IT 自动化平台,可让您的应用程序和系统更易于部署和维护。从代码部署到网络配置再到云管理,使用一种接近简单英语的语言,使用 SSH 实现一切自动化,无需在远程系统上安装代理。GitHub:github.com/ansible/ansibleAnsible官网:www.ansible.com安装配置和使用安装配置好扩展源(epel-release)就可以使用yum安装了yum -y install ansible配置Ansible的配置文件存在优先级问题,默认状态下会使用/etc/ansible/ansible.cfg具体优先级关系如下:最高优先级是执行命令的当前目录下./ansible.cfg如果当前目录下找不到配置文件就会查找执行用户的家目录寻找~/.ansible.cfg以上位置就会选择默认的配置文件/etc/ansible/ansible.cfg [root@host ~]# cp /etc/ansible/ansible.cfg ~/.ansible.cfg [root@host ~]# vim ./anaconda-ks.cfg //找到defaults段,这段不取消注释则采用默认配置,下面的参数可以自己配置 inventory /etc/ansible/hosts //主机清单文件路径 roles_path /etc/ansible/roles //role存放目录 remote_user root //执行命令的用户 //找到privilege_escalation段,这一块主要是和提权相关这里取不取消注释无所谓可以按照自己环境来修改 become=True //是否开启提权 become_method=sudo //定义执行方式 become_user=root //定义执行用户 become_ask_pass=False //定义提示密码 使用配置hosts主机文件使用的时候需要定义host主机文件,里面是存放被控主机的ip地址,建议必须是使用可以ssh免密登录的主机。[root@host ~]# echo "" > /etc/ansible/hosts //清除hosts主机文件 [root@host ~]# vim /etc/ansible/hosts //编辑hosts主机文件,并向里面添加主机 [host] 192.168.1.112 [host2] 192.168.1.113hosts主机还有多种写法,具体请看本文的其他栏ps:写好主机文件之后的操作需要建立在ssh免密之后才可以执行,具体方法可以看文章的其他栏,有问题欢迎在评论区提问简单使用方法如下[root@host ~]# ansible all --list //列出所有主机 hosts (2): 192.168.1.112 192.168.1.113 [root@host ~]# ansible all -m ping //验证全部主机的连通性 192.168.1.112 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "ping": "pong" } 192.168.1.113 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "ping": "pong" } 常用模块使用方法[root@host ~]# ansible 组/主机 -m 模块 //使用-m参数来指定相应模块 模块使用文档ansible为每个模块都提供了文档使用命令ansible-doc -l 可以列出全部的ansible模块使用命令ansible-doc {模块名称} 可以查看对应模块的帮助文档ping模块测试主机的连通性直接使命令:ansible 主机/组 -m ping[root@host ~]# ansible all -m ping 192.168.1.113 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "ping": "pong" } 192.168.1.112 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": false, "ping": "pong" }返回pong则证明连通性没问题shell/command模块执行命令直接使命令:ansible 主机/组 -m shell/command -a "执行的命令"[root@host ~]# ansible all -m shell -a "ping baidu.com -c 1" 192.168.1.113 | CHANGED | rc=0 >> PING baidu.com (220.181.38.148) 56(84) bytes of data. 64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=50 time=18.5 ms --- baidu.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 18.489/18.489/18.489/0.000 ms 192.168.1.112 | CHANGED | rc=0 >> PING baidu.com (220.181.38.148) 56(84) bytes of data. 64 bytes from 220.181.38.148 (220.181.38.148): icmp_seq=1 ttl=50 time=17.6 ms --- baidu.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 17.597/17.597/17.597/0.000 msShell和Command都是执行命令 但是两者有一定的区别Command该模块命令里如果有一下字符部分执行不成功 “<” “>” “|” “&””;”Shell用法基本和command一样 不过时通过/bin/sh进行执行,所以shell模块可以执行任何命令,就像在本机执行命令一样,但是这样有潜在的shell注入的风险两个模块都要避免使用,你应该优先考虑ansible的模块其他参数可以查看ansible-doc来详细学习Script模块主要用于执行管理主机上的脚本 原理就是将shell复制到远程主机,再远程主机上执行使用命令:ansible 主机/组 -m script -a "控制端的脚本"[root@host ~]# echo "echo hello,world" > 1.sh [root@host ~]# ansible all -m script -a './1.sh' 192.168.1.112 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.1.112 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.1.112 closed." ], "stdout": "hello,world\r\n", "stdout_lines": [ "hello,world" ] } 192.168.1.113 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.1.113 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.1.113 closed." ], "stdout": "hello,world\r\n", "stdout_lines": [ "hello,world" ] }Stdout_lines参数就是实际机器返回的值其他参数可以查看ansible-doc来详细学习user模块主要用于管理用户使用命令:ansible 主机/组 -m user -a '参数'添加一个用户ansible 主机/组 -m user -a ‘name=admin state=present’state可以理解为动作 增加删除修改 默认state就是present[root@host ~]# ansible all -m user -a "name=admin state=present" 192.168.0.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "comment": "", "create_home": true, "group": 1000, "home": "/home/admin", "name": "admin", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1000 }使用命令:ansible 主机/组 -m user -a ‘name=admin state=absent’ 可以删除admin用户[root@host ~]# ansible all -m user -a "name=admin state=absent" 192.168.0.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "force": false, "name": "admin", "remove": false, "state": "absent" }其他可以查看ansible-doc来详细学习yum_repository模块主要用于批量更新yum源ansible 主机/组 -m yum_repository -a '参数'ansible 主机/组 -m yum_repository -a 'name="CentOS" description="CentOS" baseurl="file:///mntcdrom" enabled=yes gpgcheck=no'name 设置了文件名和文件中[]的内容description 设置了文件中name的内容baseurl 设置了文件中源的地址enabled 设置了enable参数gpgcheck 设置了是否需要密钥来验证包[root@host ~]# ansible all -m yum_repository -a 'name="CentOS" description="CentOS" baseurl="file:///mntcdrom" enabled=yes gpgcheck=no' 192.168.0.103 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/libexec/platform-python" }, "changed": true, "repo": "CentOS", "state": "present" } [root@host ~]# ssh root@192.168.0.103 Last login: Sun Apr 3 12:20:11 2022 from 192.168.0.102 [root@localhost ~]# cat /etc/yum.repos.d/CentOS.repo [CentOS] baseurl = file:///mntcdrom enabled = 1 gpgcheck = 0 name = CentOS他会在对控制主机里生成相应的yum源配置文件还有很多参数可以用ansible-doc yum_repository来查看文档yum模块主要是用来操作yum的ansible 主机/组 -m yum -a ‘参数’参数详解Name 包名State 选择是安装还是删除还是更新(present和installed是安装 latest是更新 removed和absent是移除)这是基本使用 还有很多参数详情请使用ansible-doc yum查看copy模块主要是用来批量传输文件的ansible 主机/组 -m copy -a ‘参数’src 写本地目录dest 客户端目录其他请使用ansible-doc copy查看service模块主要是用来管理服务用的ansible 主机/组 -m service -a ‘参数’name 包名state 设置状态(started开启 stopped关闭 restarted重启 reloaded重置)enabled 参数只有yes和no yes为开机自启 no就是开机不开启其他请使用ansible-doc service查看set-up模块主要是用来显示对应主机的facts变量的,写roles文件用的比较多ansible 主机/组 -m setup -a ‘参数’用来显示对应主机的facts变量使用参数 filter=’关键词 可以进行显示检索具体请使用ansible-doc setup来查看’firewalld模块用来管理firewalld防护墙ansible 主机/组 -m firewalld -a ‘参数’参数:Service 设置服务名称Permanent 是否永久更改(yes,no)State 是否放行(enabled,disabled)Zone 选择区域Port 设置端口(/tcp,/udp)其他具体请使用ansible-doc firewalld来查看template模块主要是用来复制jnja2文件的,jnja2文件后面会讲ansible 主机/组 –m template -a ‘参数’src 文件目录dest 复制后的文件目录其他参数请使用ansible-doc template查看debug模块主要是用来debug的输出信息ansible 主机/组 -m debug -a ‘参数’msg 输出内容var 输出变量其他请使用ansible-doc debug查看Playbook剧本Playbook剧本 类似和脚本一样 用来批量执行模块使用palybookPlaybook有着严格的缩进写法,语法非常严谨,使用yml文件来写[root@host test]# cat creatuser.yml --- - name: create user hosts: 192.168.0.103 tasks: - name: create admin user: name: admin state: present开头必须使用---一个-代表一个任务的开头如果一个块需要配置子参数则就需要严格缩进name是描述Hosts是主机清单Tasks是配置任务子任务中name是描述User则就代表user模块模块的子参数就不需要-了name则是user的配置参数运行playbook的命令是ansible-playbook palybook文件 这是执行除此之外还可以使用命令"ansible-playbook --syntax-check 文件"来检查文件语法是否有误还有命令"ansible-playbook -C 文件"来运行测试,他会使用文件进行运行测试但不会在目的主机上发生实际改变变量变量的名称必须以字母开头,并且只能含有字母,数字和下划线.通过vars声明变量通过“{{变量名}}”进行调用左边的就是使用变量写的,右边就是没用.实质效果一样也可以通过指定一个变量文件来实现 参数:vars_files:文件名我这边定义的是相对目录下的vars.yml 然后图的右边就是vars.yml文件的内容魔法变量魔法变量是ansible的内置变量,直接被定义好的,可以直接拿来使用.常见的魔法变量:hostvars 列出所有受管理的主机信息.啊如果没有收集facts信息则不会显示facts信息group_names 列出当前受管理主机所属的所有组groups 列出清单中所有组的字典/映射inventory_hostname 列出清单中所有配置的当前主机名称其他的可以使用setup模块进行查看Facts变量Facts变量用于采集客户端的信息,比如网络信息,主机名,硬件信息等.每次执行playbook时会对客户端主机进行数据采集实际上它是通过setup模块进行收集数据Ansible 主机/组 -m setup可以列出所有的facts变量When判断When就是判断 他只会判断某一条是否为true 否则跳过 可以理解为判断一个布尔类型When虽然不是一个模块但是他的缩进必须和模块对其 卸载tasks后面--- - name: create user hosts: 192.168.0.104 vars: run: true tasks: - name: create user user: name: admin state: present when: run 这是单条的判断 when会判断上面的值是否为true 是则执行不是则跳过--- - name: create user hosts: 192.168.0.104 tasks: - name: create user user: name: admin state: presend when: - ansible_distribution == "CentOS" and ansible_machine == "x86_64" - ansible_distribution == "CentOS" and ansible_machine == "RedHat"里面的两个值都是facts的变量,只有满足CentOS系统内核为x86和redhat的系统才会执行,否则跳过只有满足CentOS系统内核为x86和redhat的系统才会执行 否则跳过常用判断语句== 等于 < 小于 > 大于 <= 小于等于 >= 大于等于 != 不等于 is defined 变量是否定义,定义为true 未定义为false si not defined 变量是否定义,未定义为false魔法变量判断when: inventory_hostname in groups[“VMhost”]只有VMhost组中主机才会执行此操作Loop循环--- - name: create user hosts: 192.168.0.104 tasks: - name: create user user: name: "{{item.name}}" uid: "{{item.uid}}" state: presend loop: - name: admin1 uid: 3001 - name: admin2 uid: 3002 - name: admin3 uid: 3003 Item是循环变量 只要用loop循环执行变量就必须使用item 点的后面使用loop定义的内容 循环的开始都要用 – 表示Block块Ansble的playbook可以把多个和任务组成一个块,然后根据不同条件来执行这个块还能执行失败时执行其他命令Block 定义块 写的时候要求和任务(tasks)的name对齐Rescue 当上面的块执行失败时,该关键字下麦呢的任务将被执行Always 不管block是否执行成功之后都会执行这个任务--- - name: cat file hosts: 192.168.0.104 tasks: - name: cat a.txt block: - debug: msg: "查看文件" - shell: cat /1.txt rescue: - debug: msg: "我giao,查看失败,创建文件" - shell: echo hello,world > /1.txt - debug: msg: "查看文件" - shell: cat /1.txt always: - debug: msg: "执行完成"如下执行结果register命令返回以上一个block为例子,给他改一些东西--- - name: cat file hosts: 192.168.0.104 tasks: - name: cat a.txt block: - debug: msg: "查看文件" - shell: cat /1.txt - debug: var: cattxt register: cattxt rescue: - debug: msg: "我giao,查看失败,创建文件" - shell: echo hello,world > /1.txt - debug: msg: "查看文件" - shell: cat /1.txt always: - debug: msg: "执行完成"执行结果如下Roles角色介绍Ansible roles提供了便捷的方式让你能够轻松的重复利用ansible代码 可以在标准化的目录结构中大伯所有 任务 变量 文件 模板以及完成任务所需要的资源,这样我们只需要将roles从一个项目复制到另一个项目即可在play中直接调用并执行他从第二排开始就是roles的文件 文件中包含很多项目就是第三排的内容 然后第四行就是每个项目中的子目录 这几个子目录都有自己的作用Roles子目录Default: 此目录中main.yml文件定义新角色变量的默认值,该目录中定义的优先级较低,使用角色时可以覆盖这些变量Files: 存放角色任务中引用的静态文件Handlers: 此目录中main.yml 文件定义处理程序Meta: 此目录中main.yml 文件定义角色相关信息 如:作者,平台,依赖等等Tasks: 此目录中main.yml 文件定义角色中的任务Templates: 存放jinja2的模板文件Tests: 此目录中可以包含清单和test.yml(playbook)用于测试角色Vars: 此目录中main.yml文件定义角色使用的变量值,优先级高于default目录GalaxyGalax是ansible的一个功能库 你可以使用其他人创建好的roles也可以分享自己的roles.就像docker镜像库一样 需要什么功能就可以直接去下载使用官方网站:https://galaxy.ansible.comAnsible-galaxy install 包名默认安装会的话会自动安装到~/.ansible/roles/下 可以使用-p参数指定位置然后参数init可以自动生成roles目录Ansible-galaxy init 文件夹名字参数 -r 可以执行yml下载文件例如--- - src: roles文件地 name: 下载后的本地昵称 - src: roles文件地址 name: 下载后的本地昵称安装的时候可以使用命令Ansible-galaxy install -r yml.yml 进行下载装好的角色可以使用ansible-galaxy list查看J2详解J2全名为jinja2是python下一个被广泛运用的模板引擎,他的设计思想来源于Django的模板引擎,并拓展了其他语法和一系列强大的功能,ansible使用jinja2模板来启用动态表达式和访问变量。构成Jinja2模板的构成:数据 变量 表达式在使用jinja2模板时变量和表达式会被替代成对应的值,变量的值可以在plasybook中定义也可以直接调用facts事实,当然调用facts需要你编写的playbook开启了facts收集写法{{EXPR}} 用于装载表达式,比如变量,运算表达式,比较表达式{%EXPR%} 用于装载控制语句 比如if,for等{# #} 用于注释Ps:jinja2模板文件本身不需要指定文件扩展名,使用.j2为后缀名只是为了更方便我们管理jinja2的模板创建和使用角色使用命令"ansible-galaxy init galaxy"创建一个galaxy模板[root@Ansible roles]# ansible-galaxy init galaxy - Role galaxy was created successfully [root@Ansible roles]# ls galaxy [root@Ansible roles]# cd galaxy/ [root@Ansible galaxy]# ls defaults files handlers meta README.md tasks templates tests vars编辑tasks的main.yml文件写入以下内容--- # tasks file for galaxy - name: install apache yum: name: httpd - name: start httpd service: name: "{{item}}" state: started enabled: yes loop: - httpd - firewalld - name: set firewalld firewalld: service: http permanent: yes state: enabled immediate: yes - name: set index template: src: index.html.j2 dest: /var/www/html/index.htmltasks/main.yml文件只需要定义命令,不需要定义主机上面这个main文件是使用yum下载了一个httpd之后使用service开启了防火墙和httpd的服务,又实用防火墙模块放行了对应的服务,之后把j2文件复制到了对应的网站目录页面。之后写一个j2文件放到templates目录里,内容如下[root@Ansible galaxy]# cat templates/index.html.j2 Welcome to {{ansible_default_ipv4.address}}ansible_default_ipv4.address是facts变量中对应主机的ip写好之后我们来写一个playbook来运行写的roles--- - name: roles galaxy hosts: 192.168.0.104 roles: - /root/ansible/roles/galaxy运行结果如下,通过http访问返回内容Vault加密场景使用ansible的时候难免会有一些比较敏感的数据,比如密码,key等信息直接明文暴露显然不是很好,vault管理加密/解密yml(palybook)文件工具,有时编写的playbook文件中会存在重要敏感信息,考虑到安全,可以使用此工具进行加密!参数详解Ansible-vault [参数] [文件]Create: 创建Decrypt: 解密Edit: 编辑加密文件Encrypt: 加密rekey: 修改口令view: 查看加密之后执行playbook的时候需要附加–ask-vault-pass参数实例创建用户,用户信息使用vault进行加密,使其不能以明文的形式查看[root@Ansible ansible]# cat vault.yml --- - name: vault vars_file: ./userinfo.yml tasks: - name: create user user: name: "{{name}}" password: "{{password}}" [root@Ansible ansible]# cat userinfo.yml --- - name: "admin" password: "abc123" [root@Ansible ansible]# ansible-vault encrypt userinfo.yml New Vault password: Confirm New Vault password: Encryption successful [root@Ansible ansible]# cat userinfo.yml $ANSIBLE_VAULT;1.1;AES256 63356239383039396263323732396663333132616561323362636662383265626233643465376365 3838633930316666373234633533643065643238653239380a313530633763366262643135363336 62386533313439393761353966316534323464326533306564363565623737393766316231383035 6361363665333837320a316465306139373564623930303330623261343466366336653537333266 61386330336363366633633632303465613535303766653663363734663138393064646237363063 3431616565353131633931326531383262353234366131306130执行需要使用参数 "–ask-vault-pass" 执行其他hosts主机文件写法一般写法:[组名]IP域名······连续主机写法:[组名]1[a-f].example.com······父组写法:[组名:children]组名组名······