BoyChai's Blog - 工具 https://blog.boychai.xyz/index.php/tag/%E5%B7%A5%E5%85%B7/ zh-CN Sat, 04 Jun 2022 15:17:00 +0000 Sat, 04 Jun 2022 15:17:00 +0000 Git-版本控制工具 https://blog.boychai.xyz/index.php/archives/17/ https://blog.boychai.xyz/index.php/archives/17/ Sat, 04 Jun 2022 15:17:00 +0000 BoyChai 概述

Git是一个开源免费的分布式版本控制系统,可以快速高效的来管理项目代码。

官网:https://git-scm.com/

安装

Windows

[vplayer status="true"]
[Video url="https://www.bilibili.com/video/BV1Rb4y1C7z1" title="采用b站UP:Houor的视频" /]
[/vplayer]

Linux

yum -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,如图

创建token

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之后会让你写一个仓库名称,之后这个仓库会以刚才的仓库名称变成你仓库里的一个项目,你可以自己任意更改提交克隆,当代码写好提交到自己fork的仓库之后,去对方的仓库里面点击pull requests

pull requestspull requests

创建一个之后会出现一个版本比较的一个东西,让你选择版本进行对比,第一个选择就是他的仓库,第二个就是自己fork的仓库,选择好之后会出现修改的内容对比,然后进行创建,创建之后对方会受到一个请求,当对方同意的时候代码就会自动合并到对方仓库里。

]]>
0 https://blog.boychai.xyz/index.php/archives/17/#comments https://blog.boychai.xyz/index.php/feed/tag/%E5%B7%A5%E5%85%B7/
IPTABLES-防火墙 https://blog.boychai.xyz/index.php/archives/11/ https://blog.boychai.xyz/index.php/archives/11/ Wed, 25 May 2022 03:40:00 +0000 BoyChai 概述

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_filter
nat表负责网络地址转换功能,内核模块:iptable_nat
mangle表解析报文,做出修改,重新封装的功能,内核模块:iptable_mangle
raw表关闭nat表上启用的链接追踪机制,内核模块:iptable_raw

链(chains)

链(chains)是规则(Policys)的容器。如果把表(tables)当作一套房子,那么链就是里面的房间,卧室,厨房,客厅什么的。
链有INPUT OUTPUT FORWARD PREROUTING POSTROUTING 不同的表有不同的链

规则(Policy)

规(Policy)则就是一条条过滤的语句用来控制流量动作的。

关于表和链

关系

filter表INPUT,FORWARD,OUTPUT
nat表PREROUTING,OUTPUT,POSTROUTING,INPUT(centos6没有)
mangle表PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
raw表PREROUTING,OUTPUT

Filter

主要是和自身有关,真正负责主机防火墙功能的(过滤流入流出主机的数据包)。Filter表是iptables默认使用的表,这个表定义了三个链(chains),工作场景主要是作为主机的防火墙。

INPUT链 负责过滤所有目标地址是本机地址的数据。通俗的讲,就是过滤进入主机的数据包。
FORWARD链 负责转发流经主机的数据包。起转发的作用,和nat关系很大,后面会详细介绍。 LVSNAT模式。net.ipv4.ip_forward = 0
OUTPUT链 处理所有源地址是本机地址的数据包。通俗的讲,就是处理从主机发去的数据包。

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 DROP

NAT表

注意

因为NAT是负责网络转换这块,最好是把内核的转发更能打开,不然路由链就不生效

cat /etc/sysctl.conf |grep net.ipv4.ip_forward
net.ipv4.ip_forward = 1
sysctl -p   //生效

SNAT

Ip转换 一般用于局域网做网管内网ip转换为可上网的ip 提供内网主机上网使用
命令:
Iptables -t nat -A POSTROUTING -s 源地址 -d 0.0.0.0/0 -j SNAT –to-source 转换的ip

DNAT

端口转发 一般用于端口转发做反向代理 可以防止内网主机完全暴露在公网环境中.
自己的端口转发
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 主机:端口

MASQUERADE

Ip伪装 一般用于局域网做网管内网ip转换为可上网的ip 提供内网主机上网使用
命令:
Iptables -t nat -A POSTROUTING -s 源地址 -d 0.0.0.0/0 -j MASQUERADE

]]>
0 https://blog.boychai.xyz/index.php/archives/11/#comments https://blog.boychai.xyz/index.php/feed/tag/%E5%B7%A5%E5%85%B7/
SYSTEMCTL-系统服务管理 https://blog.boychai.xyz/index.php/archives/10/ https://blog.boychai.xyz/index.php/archives/10/ Tue, 03 May 2022 06:45:00 +0000 BoyChai 概述

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]关联target

Unit

参数作用
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来指定
]]>
0 https://blog.boychai.xyz/index.php/archives/10/#comments https://blog.boychai.xyz/index.php/feed/tag/%E5%B7%A5%E5%85%B7/
Ansible-自动化运维工具 https://blog.boychai.xyz/index.php/archives/8/ https://blog.boychai.xyz/index.php/archives/8/ Sat, 05 Mar 2022 02:02:00 +0000 BoyChai 概述

Ansible 是一个极其简单的 IT 自动化平台,可让您的应用程序和系统更易于部署和维护。从代码部署到网络配置再到云管理,使用一种接近简单英语的语言,使用 SSH 实现一切自动化,无需在远程系统上安装代理。
GitHub:github.com/ansible/ansible
Ansible官网: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.113

hosts主机还有多种写法,具体请看本文的其他栏
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 ms

Shell和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剧本 类似和脚本一样 用来批量执行模块

使用palybook

Playbook有着严格的缩进写法,语法非常严谨,使用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文件
playbook1
这是执行除此之外还可以使用命令"ansible-playbook --syntax-check 文件"来检查文件语法是否有误
还有命令"ansible-playbook -C 文件"来运行测试,他会使用文件进行运行测试但不会在目的主机上发生实际改变

变量

变量的名称必须以字母开头,并且只能含有字母,数字和下划线.
通过vars声明变量通过“{{变量名}}”进行调用
playbook2
左边的就是使用变量写的,右边就是没用.实质效果一样
也可以通过指定一个变量文件来实现 参数:vars_files:文件名
playbook3
我这边定义的是相对目录下的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: "执行完成"

如下执行结果
playbokk4

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: "执行完成"

执行结果如下
playbook5

Roles角色

介绍

Ansible roles提供了便捷的方式让你能够轻松的重复利用ansible代码 可以在标准化的目录结构中大伯所有 任务 变量 文件 模板以及完成任务所需要的资源,这样我们只需要将roles从一个项目复制到另一个项目即可在play中直接调用并执行他
Roles目录结构
从第二排开始就是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目录

Galaxy

Galax是ansible的一个功能库 你可以使用其他人创建好的roles也可以分享自己的roles.
就像docker镜像库一样 需要什么功能就可以直接去下载使用
官方网站:https://galaxy.ansible.com
Ansible-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.html

tasks/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" 执行
vault

其他

hosts主机文件写法

一般写法:
[组名]
IP
域名
······
连续主机写法:
[组名]
1[a-f].example.com
······
父组写法:
[组名:children]
组名
组名
······

]]>
0 https://blog.boychai.xyz/index.php/archives/8/#comments https://blog.boychai.xyz/index.php/feed/tag/%E5%B7%A5%E5%85%B7/