1、ansible基础及ad-hoc使用

1、ansible基础及ad-hoc使用

简介

作用:
批量执行远程命令
批量配置软件服务
实现软件开发功能,jumpserver底层使用ansible
编程高级的IT任务,Ansible的Playbook是一门编程语言,可以用来描绘一套IT架构

特点:
无代理,只需要学习客户端,底层为ssh
灵活:playbook可以实现类似于编程的复杂语言

使用方式:
AD-Hoc 单台命令
Playbook YAML
先将主机加入清单列表(inventory)通过控制端通过python模块连接网络与受控端相连(通过Python的ping方式),将模块托送到被控端,被控端解析后执行模块内容,因为基于TCP的SSH协议,所以安全可靠。对不同的主机或不同的主机组进行不同的动作

ansible安装

安装镜像源(至少配置epel)
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum makecache
yum -y install ansible
ansible --version

1、ansible基础及ad-hoc使用

配置文件在 /etc/ansible/ansible.cfg (可以根据优先级修改)
配置模块查找路径在 /root/ansible/plugins/modules,执行时可以查看到
python版本不能大于等于3,否则失效

配置文件优先级顺序:
环境变量ANSIBLE_CONFIG
项目目录 ./ansible.cfg
用户家目录 .ansible.cfg
/etc/ansible/ansible.cfg

配置清单

基于密码方式执行

在家目录下创建清单列表,建立在hosts文件中
mkdir /root/project ; vim /root/project/hosts

[ljh]
192.168.1.11 ansible_ssh_user=root ansible_ssh_pass='123'
192.168.1.12 ansible_ssh_user=root ansible_ssh_pass='123'

-i 指定hosts文件夹
ansible ljh -m ping -i /root/project/hosts

初次连接会出现报错

1、ansible基础及ad-hoc使用

无法使用SSH密码而不是密钥,因为主机密钥检查已启用,而sshpass不支持此功能。请将此主机的指纹添加到已知的 hosts文件以管理此主机。

解决方式1:每台主机都ssh进行连接一遍,再执行

解决方式2:将Ansible配置文件中的host_key_checking =False参数注释打开即可
vim /etc/ansible/ansible.cfg

1、ansible基础及ad-hoc使用

再次执行ansible ljh -m ping -i /root/project/hosts

1、ansible基础及ad-hoc使用

配置文件修改为其他方式:

直接在后端指定端口和密码和用户

方式一:
[webservers]
192.168.1.11 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='123'
192.168.1.12 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='123'

使用匹配方式合并主机名或IP

方式二:
[webservers]
web[1:2].ljh.com ansible_ssh_pass='123'

将密码统一写到var模块中

方式三:
[webservers]
web[1:2].ljh.com
[webserver:vars]
ansible_ssh_pass='123'

基于密钥方式(推荐)

ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
ssh-copy-id  -i ~/.ssh/id_rsa.pub root@192.168.1.11
ssh-copy-id  -i ~/.ssh/id_rsa.pub root@192.168.1.12
ssh-copy-id  -i ~/.ssh/id_rsa.pub root@192.168.1.13

把hosts配置文件中的密码删除
vim /root/project/hosts

[ljh]
192.168.1.11
192.168.1.12
1、ansible基础及ad-hoc使用

再次执行
ansible ljh -m ping -i /root/project/hosts

1、ansible基础及ad-hoc使用

多个主机组清单

修改配置文件

1、ansible基础及ad-hoc使用

--list-hosts 查看清单主机数量;all 查看所有清单的所有主机数量

ansible ljh -m ping -i /root/project/hosts --list-hosts
ansible gyc -m ping -i /root/project/hosts --list-hosts
ansible all -m ping -i /root/project/hosts --list-hosts

1、ansible基础及ad-hoc使用

主机组嵌套使用方式

修改配置文件

1、ansible基础及ad-hoc使用

意为ljh和gyc都属于ljhgyc的子组,操作ljhgyc组即可操作ljh组和gyc组

1、ansible基础及ad-hoc使用

ansible 常见的优化策略:

1.修改ansible的并发数

Ansible默认只会创建5个进程并发执行任务,所以一次任务只能同时控制5台机器执行。
如果有大量的机器需要控制,例如20台,Ansible执行一个任务时会先在其中5台上执行,执行成功后再执行下一批5台,直到全部机器执行完毕。
使用 -f 选项可以指定进程数,指定的进程数量多一些,不仅会实现全并发,对异步的轮训poll也会有正面影响。
#forks=5
forks=200

2.关闭ansible的SSH密钥检测

ansible默认是以ssh来实现远程推送执行的,是基于ssh秘钥检测,会检测远程主机的公钥,并记录在本地中known_host文件中,下次访问主机时,会核对公钥,如果公钥不同,openssh会发出警告,如果相同,会提示输入密码。
host_key_checking = False #关闭StrictHostKeyChecking检查 默认是关闭的

3.openssh连接优化

使用OpenSSH服务时,默认服务器端配置文件UseDNS=YES状态,该选项会导致服务器根据客户端的IP地址进行DNS PTR反向解析,得到客户端的主机名,然后根据获取到的主机名进行DNS正向A记录查询,并验证该IP是否与原始IP一致

vim /etc/ssh/sshd_config

1、ansible基础及ad-hoc使用

5.ssh pipelining加速ansible

pipeline是openssh的一个特性,ssh pipelining 是一个加速Ansible执行速度的简单方法。
在ansible执行每个任务的整个流程中,有一个过程是将临时任务文件put到远程的ansible客户机上,然后通过ssh连接过去远程执行这个任务。
如果开启了pipelining,一个任务的所有动作都在一个ssh会话中完成,也会省去sftp到远端的过程,它会直接将要执行的任务在ssh会话中进行。
ssh pipelining 默认是关闭!!!之所以默认关闭是为了兼容不同的sudo 配置,主要是 requiretty 选项。如果不使用sudo,建议开启!
打开此选项可以减少ansible执行没有传输时ssh在被控机器上执行任务的连接数。

1、ansible基础及ad-hoc使用
sed -i '/^pipelining/s/False/True/g' /etc/ansible/ansible.cf

6.Ansible Facts缓存优化

Ansible-playbook 在执行过程中,默认会执行Gather facts,如果不需要获取客户端的fact数据的话,可以关闭获取fact数据功能,关闭之后可以加快ansible-playbook的执行效率。如需关闭fact功能,在playbook yaml文件中加入如下代码即可:

gather_facts: False

如果又想提高速度,又想收集facts,就需要在playbook中配置facts缓存,将换成信息存储到json 中,redis中,memcached中

ad-hoc

什么是ad-hoc
ad-hoc简而言之就是和“临时命令”,执行完即结束,并不会保存
列出模块:
ansible-doc -l

基础配置文件:

1、ansible基础及ad-hoc使用

命令格式:

1、ansible基础及ad-hoc使用

使用command执行命令执行

1、ansible基础及ad-hoc使用

但发现一台一台显示,默认为一台一台

一些概念:

Ansible默认只会创建5个进程并发执行任务,所以一次任务只能同时控制5台机器执行。如果有大量的机器需要控制,例如20台,Ansible执行一个任务时会先在其中5台上执行,执行成功后再执行下一批5台,直到全部机器执行完毕。使用-f选项可以指定进程数,指定的进程数量多一些,不仅会实现全并发,对异步的轮训poll也会有正面影响。

Ansible默认是同步阻塞模式,它会等待所有的机器都执行完毕才会在前台返回。Ansible可以采取异步执行模式。异步模式下,Ansible会将节点的任务丢在后台,每台被控制的机器都有一个job_id,Ansible会根据这个job_id去轮训该机器上任务的执行情况,例如某机器上此任务中的某一个阶段是否完成,是否进入下一个阶段等。即使任务早就结束了,但只有轮训检查到任务结束后才认为该job结束。Ansible可以指定任务检查的时间间隔,默认是10秒。除非指定任务检查的间隔为0,否则会等待所有任务都完成后,Ansible端才会释放占用的shell。如果指定时间间隔为0,则Ansible会立即返回(至少得连接上目标主机,任务发布成功之后立即返回),并不会去检查它的任务进度。

Ansible的同步模式与异步模式

同步模式: 如果节点数太多,ansible无法一次在所有远程节点上执行任务,那么将先在一部分节点上执行一个任务(每一批节点的数量取决于fork进程数量,默认为5个,可设置),直到这一批所有节点上该任务完全执行完毕才会接入下一个批节点,直到所有节点将该任务都执行完毕,然后重新回到第一批节点开始执行第二个任务。依次类推,直到所有节点执行完所有任务,ansible端才会释放shell。这是默认同步模式,也就是说在未执行完毕时,ansible是占用当前shell的,任务执行完后,释放shell了才可以输入其他命令做其他动作。

异步模式:假如fork控制的并发进程数为5,远程控制节点为24个,则ansible一开始会将5个节点的任务扔在后台,并每隔一段时间去检查这些节点的任务完成情况,当某节点完成不会立即返回,而是继续等待直到5个进程都空闲了,才会将这5个节点的结果返回给ansible端,ansible会继续将下一批5个节点的任务扔在后台并每隔一段时间进行检查,依次类推,直到完成所有任务。
在异步模式下,如果设置的检查时间间隔为0,在将每一批节点的任务丢到后台后都会立即返回ansible,并立即将下一批节点的任务丢到后台,直到所有任务都丢到后台完后,才返回ansible端,ansible才会立即释放占用的shell。即此时ansible是不会管各个节点任务执行情况的,不管执行成功或失败。因此在轮训检查时间内,ansible仍然正在运行(尽管某批任务已经被放到后台执行了),当前shell进程仍被占用处于睡眠状态,只有指定的检查时间间隔为0,才会尽快将所有任务放到后台并释放shell

Ansible的异步和轮询  [ async、poll ]

Ansible有时候要执行等待时间很长的操作,这个操作可能要持续很长时间,设置超过ssh的timeout。这种情况下可以选择在step中指定async和poll来实现异步操作。

async参数值:代表了这个任务执行时间的上限值。即任务执行所用时间如果超出这个时间,则认为任务失败。此参数若未设置,则为同步执行。
poll参数值:代表了任务异步执行时轮询的时间间隔。

Ansible的并发限制 

当ansible清单文件里设置的组里有很多机器,可以限制一下ansible任务的并发。ansible的并发功能可以在ansible.cfg里修改配置,也可以在playbook中限制服务端的并发数量,这是ansible经常用到的一个关键功能。ansible默认情况下只会创建5个进程,所以一次任务只能同时控制5台机器执行。如果有大量的机器需要控制,或者希望减少进程数,那就可以采取异步执行(async),ansible的模块可以把task放进后台,然后轮询它(poll)

使用async和poll这两个关键字便可以并行运行一个任务,即在所有机器上一次性运行。async这个关键字会触发ansible并行运作任务,async的值是ansible等待运行这个任务的最大超时值(如果执行超时任务会强制中断导致失败),而poll就是ansible检查这个任务是否完成的频率时间。

实验:

下面是一个失败的例子:

1、ansible基础及ad-hoc使用

因为ansible的任务(就是上面配置中的shell动作)操作时间(10s)超过了最大等待时长(5s)

如果将上面的async异步等待时间设置为大于10s,比如12s,则执行就成功

1、ansible基础及ad-hoc使用

或者将上面的poll数值设置为0,即不用等待ansible任务执行的结果,立即执行下一个step,即只需要将任务命令推送到ansible客户机上,不需要等待任务执行完成就立即执行下一个step

下面这个依然可以成功

1、ansible基础及ad-hoc使用

Anisble默认是同步阻塞模式,他会等待所以机器执行完毕后才会向前台返回。Ansible默认只会创建5个进程执行并发任务。

简单总结下,适合使用到ansible的polling特性的场景
Anisble除了支持同步模式外还支持异步模式。下面的这种情况需要使用的异步特性
(1)当我们有一个task需要运行很长的时间,而且这个task可能会达到timeout时。
(2)当我们有一个任务需要在大量的机器上运行时
(3)当我们有一个任务不需要等待它完成时

如果想要增加返回速度
vim /etc/ansible/ansible.cfg

1、ansible基础及ad-hoc使用

代表一次性返回多少台主机的并发数量这里默认是5
可以使用-f指定一次性显示多少台,比如一次性显示2台
ansible ljh -m command -a "w" -i hosts -f 2

提示颜色信息说明:
帽子绿:对远程节点不进行相应修改,或者只是对远程节点信息进行查看
翔黄色:对远程节点进行相应修改
浅紫色:表示对命令执行发出警告信息(可能存在的问题,给你一下建议)
深红色:执行操作命令有异常

模块

一般使用到的模块分为

命令  command(默认) shell模块  scripts脚本模块
安装  yum模块
配置  copy模块
     file 模块创建目录
     get_url 类似于wget
启动  service 和 systemd模块
用户  user group模块
任务  cron模块
挂载  mount
防火墙  firewall selinux
解压缩模块  unarchive模块

 command模块只能调用一条命令,shell模块可以使用管道
ansible ljh -m shell -a "df -h | grep /$" -f 2

1、ansible基础及ad-hoc使用

shell模块
shell几乎可以支持所有命令

yum模块
查看模块
ansible-doc yum
可以查看EXAMPLE

选项
name --指定要安装的软件名称
state --指定使用yum的方法
installed(present) --安装软件包
removed,(absent) --移除软件包
latest --安装最新软件包

通过示例练习yum
1:安装当前最新apache软件,如果存在则不安装
ansible ljh -m yum -a "name=httpd state=latest" -i /root/project/hosts

2:安装当前最新的apache软件,通过epel仓库安装
ansible ljh -m yum -a "name=httpd state=latest enablerepo=epel" -i /root/project/hosts

3:通过公网URL安装rpm软件
ansible ljh -m yum -a "name=https://mirrors.aliyun.com/zabbix/zabbix/5.1/rhel/7/x86_64/zabbix-agent-5.2.0-0.1alpha1.el7.x86_64.rpm state=latest" -i /root/project/hosts
装一个zabbix-agent,去受控端看看

1、ansible基础及ad-hoc使用

4:更新所有的软件包,单排除和kernel相关的
ansible ljh -m yum -a "name=* state=latest exclude=kernel" -i /root/project/hosts 可以使用匹配

5:删除apache软件
ansible ljh -m yum -a "name=httpd state=absent" -i /root/project/hosts

copy模块
作用:推送,拷贝

选项
src --推送数据源文件信息
content --直接批量在被管理端文件中添加内容
dest --推送数据的目标路径
group --将本地文件推送到远端,指定文件属组信息
owner --将本地文件推送到远端,指定文件属主信息
mode --将本地文件推送到远端,指定文件权限信息
backup --是否保存原来的文件
get_url --从公网下载文件

练习:

1、将本地修改过的httpd.conf发送到受控端

受控端
scp /etc/httpd/conf/httpd.conf 192.168.1.10:/root/

服务端:
vim /root/httpd.conf
修改端口为8000
ansible ljh -m copy -a "src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=644" -i /root/project/hosts

客户端查看发现配置文件中端口被修改

如果服务端想要客户端备份被修改的文件而不是覆盖,使用backup=yes即可

先把服务端httpd配置文件端口修改成9988
ansible ljh -m copy -a "src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=644 backup=yes" -i /root/project/hosts

会有备份提示

1、ansible基础及ad-hoc使用

客户端查看

1、ansible基础及ad-hoc使用

存在备份文件,查看后为之前的配置文件

1、ansible基础及ad-hoc使用

2、使用content调用copy模块添加httpd默认主页到受控端
ansible ljh -m copy -a "content='http-server' dest=/var/www/html/index.html" -i /root/project/hosts

3、在rsync创建一个密码文件,修改属主属组权限
添加rsync认证文件和rsync客户端密码文件
ansible backup -m copy -a "content='rsync_backup:1' dest=/etc/rsync.password owner=root group=root mode=600"(写入backup一个密码文件,内容为“rsync_backup:1”放在目录/etc/rsync.password下,属主为root,属组为root,权限修改为600)

添加客户端密码文件
ansible ljh -m copy -a "content='123' dest=/etc/rsync.pass owner=root group=root mode=600"

get_url模块
从公网拉取文件
ansible ljh -m get_url -a "url=http://fj.xuliangwei.com/public/ip.txt dest=/var/www/html/ip.txt" -i /root/project/hosts

1、ansible基础及ad-hoc使用

拉取图片
https://c-ssl.duitang.com/uploads/item/201708/05/20170805115638_Fmfi8.jpeg

1、ansible基础及ad-hoc使用

可以使用md5校验

unarchive模块

unarchive模块的参数用于指定要解压的文件、解压的目标位置以及其他相关选项。

以下是unarchive模块的一些重要参数:

  • src(必需):要解压的归档文件的路径。可以是本地文件系统上的路径,也可以是远程主机上的路径。
  • dest(必需):解压文件的目标位置。可以是本地文件系统上的路径,也可以是远程主机上的路径。
  • copy(可选):是否将归档文件复制到远程主机。默认为yes。
  • remote_src(可选):是否将归档文件从远程主机复制到目标位置。默认为no。
  • creates(可选):指定解压后的文件或目录是否应该存在。如果存在,将跳过解压步骤。可以是文件或目录的路径。
  • extra_opts(可选):用于指定额外的选项和参数。可以是解压命令的任何有效选项。

除了上述参数外,unarchive模块还提供了一些其他参数,如owner,group,mode等,用于指定解压后的文件的所有权和权限。

file模块
作用:创建目录、文件和授权

选项
path + state=touch 创建文件
path + state=directory 创建目录
path + owner + group +mode 修改属主属组和权限

创建ljh.html文件(path、touch)
ansible ljh -m file -a "path=/var/www/html/ljh.html state=touch owner=apache group=apache mode=644" -i /root/project/hosts

创建ljh目录(path,directory)
ansible ljh -m file -a "path=/var/www/html/ljh state=directory owner=apache group=apache mode=755" -i /root/project/hosts

递归修改html目录权限
ansible ljh -m file -a "path=/var/www/html/ owner=apache group=apache mode=755 recurse=yes" -i /root/project/hosts

service模块
类似于yum,使用name和state搭配
state 指定服务状态时停止或是运行,停止和运行指令要写成过去时
started 启动
stopped 停止
restarted 重启
reloaded 重载
enabled 是否让服务开机自启动

练习
1:开启httpd服务
ansible ljh -m service -a "name=httpd state=started " -i /root/project/hosts
2:关闭httpd服务
ansible ljh -m service -a "name=httpd state=stopped " -i /root/project/hosts
3:重启httpd
ansible ljh -m service -a "name=httpd state=restarted " -i /root/project/hosts
4:重载 httpd
ansible ljh -m service -a "name=httpd state=reloaded " -i /root/project/hosts
5:httpd服务开机自启/不自启
ansible ljh -m service -a "name=httpd enabled=yes(no) " -i /root/project/hosts

小扩展:将之前的httpd服务写成一个playbook
vim httpd.yaml

- hosts: ljh 
  tasks:
    - name: Install httpd Server
      yum: name=httpd state=present

    - name: Configure Httpd Server
      copy: src=./httpd.conf dest=/etc/httpd/conf/httpd.conf owner=root group=root mode=644
      notify: Restart Httpd Server
   
    - name: Systemd Httpd Server
      service: name=httpd state=started enabled=yes

  handlers:
    - name: Restart Httpd Server
      service: name=Httpd state=restarted

ansible-playbook httpd.yaml -i /root/project/hosts

group模块
选项:
name:组名
state:操作(absent)
gid:指定组id
system=yes/no 是否创建系统用户

创建一个名为news的用户组,gid为9999
ansible ljh -m group -a "name=news gid=9999" -i /root/project/hosts

创建一个名为http的系统用户组,gid为8888
ansible ljh -m group -a "name=http system=yes gid=8888" -i /root/project/hosts

删除news组
ansible ljh -m group -a "name=news state=absent" -i /root/project/hosts

user模块
选项:
name= 指定名字
group= 指定组
create_home=yes/no 是否创建家目录
home= 指定家目录
shell=/sbin/nologin 指定bash环境,创建系统用户
system=yes/no 是否创建系统用户
remove=yes 删除家目录
state=absent 删除用户

创建名字为gyc用户,uid为1040,组id为adm
ansible ljh -m user -a "name=gyc uid=1040 group=adm" -i /root/project/hosts

创建gyc用户,登录shell是/sbin/nologin,追加bin、sys两个组
ansible ljh -m user -a "name=gyc shell=/sbin/nologin groups=bin,sys" -i /root/project/hosts

客户端查看

1、ansible基础及ad-hoc使用

创建一个xxt用户,为其添加123作为登录密码,并创建家目录
生成密码为123的加密字符串
ansible localhost -m debug -a "msg={{'123'|password_hash('sha512','salt24')}}"
将‘123’使用hash算法加密,并加一把盐再次加密
结果:

1、ansible基础及ad-hoc使用

创建用户
ansible ljh -m user -a "name=xxt password=$6$salt24$llFp8.1zIb8N.hgyIW2I.NDNQYeV1EG9gIkpQQFOO6IpN2FnFvU5mFcg4nURnbraGpHOndUSOwtMft.XJurAD/" -i /root/project/hosts

移除xxt用户,并删除家目录
ansible ljh -m user -a "name=xxt state=absent remove=yes " -i /root/project/hosts

创建http用户,并为该用户创建2048字节私钥,存放在~/http/.ssh/id_rsa
ansible ljh -m user -a "name=http generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa " -i /root/project/hosts

1、ansible基础及ad-hoc使用

不指定用户组默认为users

cron模块
用来做定时任务
name=名字 +时间配置

添加定时任务,每分钟执行一次ls
ansible ljh -m cron -a "name=job1 job='ls >/dev/null'" -i /root/project/hosts
默认都是*,不用输入

添加定时任务,每凌晨两点和5点执行一次定时任务
ansible ljh -m cron -a "name=job2 minute=0 hour=2,5 job='ls >/dev/null'" -i /root/project/hosts

关闭定时任务
ansible ljh -m cron -a "name=job2 minute=0 hour=2,5 job='ls >/dev/null' disabled=yes" -i /root/project/hosts
任务之前会自动添加“#”进行注释

mount模块
挂载nfs
服务端(10)
yum -y install rpcbind nfs-utils
vim /etc/exports
/data 192.168.1.0/24(rw,sync,no_all_squash)
systemctl start nfs
mkdir /data

ansible操作
推荐使用
mounted:临时挂载+永久挂载
absent:临时卸载+永久卸载
不推荐:
present:只会将信息写入/etc/fstab
unmounted:临时卸载
练习:
挂载存储本地的/opt目录,并实现开机自动挂载
ansible ljh -m mount -a "src=192.168.1.10:/data path=/opt fstype=nfs opts=defaults state=mounted" -i /root/project/hosts
永久卸载nfs的挂载,会清理/etc/fstab
ansible ljh -m mount -a "src=192.168.1.10:/data path=/opt fstype=nfs opts=defaults state=absent" -i /root/project/hosts

selinux模块
关闭selinux
ansible ljh -m selinux -a "state=disabled" -i /root/project/hosts

firewalld模块
示例:
permanent 是否永久
immediate 是否立刻
state 开启或关闭

练习:
永久放行https的流量,只有重启才会生效
先把受控端的防火墙开启
ansible 192.168.1.12 -m firewalld -a "zone=public service=https permanent=yes state=enabled" -i /root/project/hosts
客户端
firewall-cmd --reload
firewall-cmd --list-all

1、ansible基础及ad-hoc使用

永久放行8080端口流量,只有重启才会生效
ansible 192.168.1.11 -m firewalld -a "zone=public port=8080/tcp permanent=yes state=enabled" -i /root/project/hosts
客户端
firewall-cmd --reload
firewall-cmd --list-all

放行8080-8090的所有tcp端口流量,临时和永久都生效
参数:immediate=yes
ansible 192.168.1.11 -m firewalld -a "zone=public port=8080-8090/tcp immediate=yes permanent=yes state=enabled" -i /root/project/hosts
客户端直接
firewall-cmd --list-all

常见的服务使用ansible流程

安装http服务(yum)
编写简单网页测试内容(copy)
启动服务并加入开机自启(service)
放行firewalld对应端口(firewalld)

发布者:LJH,转发请注明出处:https://www.ljh.cool/7042.html

(0)
上一篇 2021年7月21日 上午12:04
下一篇 2021年10月1日 上午12:57

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注