章节目录
安装Apache所需的模块
安装 : dnf、yum、shell
配置 : copy、file、 template、user、lineinfile
启动 :service
写playbook 的步骤
1、实现功能
2、拆分
3、优化
4、测试
playbook 要具备通用性、幂等性
准备环境
两台虚拟主机
控制主机 | contaol | 192.168.229.143 |
---|---|---|
受控主机 | web.example.com | 192.168.229.130 |
控制主机操作
配置阿里yum源
#配置阿里yum源
[root@localhost ~]# cd /etc/yum.repos.d/
[root@localhost yum.repos.d]# curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
[root@localhost yum.repos.d]# sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
#清除缓存
[root@localhost yum.repos.d]# dnf clean all
#建立缓存
[root@localhost yum.repos.d]# dnf makecache
安装Ansible
#列出ansible
[root@localhost ~]# dnf list all|grep ansible
....省略N
ansible-pcp.noarch 2.2.1-1.el8 AppStream
centos-release-ansible-29.noarch 1-2.el8 extras #需要这个安装Ansible源
....省略N
#安装ansible源
[root@localhost ~]# dnf -y install centos-release-ansible-29
#清除缓存
[root@localhost ~]# dnf clean all
#建立缓存
[root@localhost ~]# dnf makecache
# 安装ansible
[root@localhost ~]# dnf -y install ansible
#查看版本号
[root@localhost ~]# ansible --version
ansible 2.9.27
config file = /etc/ansible/ansible.cfg
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Sep 9 2021, 07:49:02) [GCC 8.5.0 20210514 (Red Hat 8.5.0-3)]
[root@localhost ~]#
更改主机名
#控制主机
[root@localhost ~]# hostnamectl set-hostname contaol
[root@localhost ~]# bash
[root@contaol ~]#
配置域名
#配置域名
[root@control ~]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.229.130 web.example.com
设置免密登录
#生成密钥
[root@control ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:lGi0P/Q0JK/KwpjB5iVlYnWGmh8bBbSsP03em6+W67o root@control.example.com
The key's randomart image is:
+---[RSA 3072]----+
| .+o+ . . |
| o.=.o = |
| oo=.+ + + |
| oo=o. + + . |
| *..+. S . |
| o Oo= o . |
| + = = .. |
| o oo |
| E=*+. |
+----[SHA256]-----+
#使用 ssh-copy-id 将公钥复制到远程系统上的正确位置
[root@control ~]# ssh-copy-id root@web.example.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host 'web.example.com (192.168.229.130)' can't be established.
ECDSA key fingerprint is SHA256:mntQBTppC7e+5Uh8MyZHFW3FuKZzpoS46G0j2C+O8U4.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@web.example.com's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@web.example.com'"
and check to make sure that only the key(s) you wanted were added.
#登录到受管主机并修改主机名
[root@localhost ~]# ip addr show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:f6:e7:cf brd ff:ff:ff:ff:ff:ff
inet 192.168.229.130/24 brd 192.168.229.255 scope global dynamic noprefixroute ens160
valid_lft 1780sec preferred_lft 1780sec
inet6 fe80::20c:29ff:fef6:e7cf/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@localhost ~]# hostnamectl set-hostname web.example.com
[root@localhost ~]# bash
[root@web ~]#
Ansible准备工作
配置一个通用性的playbook
#创建playbook目录
[root@control opt]# mkdir playbook
#创建通用性的目录
[root@control opt]# mkdir general
创建httpd目录
[root@control opt]# mkdir httpd
[root@control opt]# ls
general httpd playbook
#进入到general目录
#把ansible.cfg文件复制到当前目录下
[root@control opt]# cd general
[root@control general]# cp /etc/ansible/ansible.cfg .
[root@control general]# ls
ansible.cfg
#修改ansible.cfg文件
[root@control general]# vim ansible.cfg
inventory = inventory #改为inventory
#library = /usr/share/my_modules/
#创建清单文件
[root@control general]# vim inventory
[webservers] #主机组
web.example.com #主机
# ping 是否能和受控主机通信
[root@control general]# ansible web.example.com -m ping
web.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
#需要变量、创建vars目录
[root@control general]# mkdir vars
[root@control general]# ls
ansible.cfg files install.yml inventory vars yum.yml
[root@control general]# vim vars/apache.yml
apache_depend_pkg:
- openssl-devel
- pcre-devel
- expat-devel
- make
- gcc
- gcc-c++
# 创建一个模板脚本的内容install.sh.j2
[root@control general]# vim files/install.sh.j2
#!/bin/bash
cd /opt/
sed -i '/$RM "$cfgfile"/d' apr-1.7.0/configure
cd apr-1.7.0
./configure --prefix=/usr/local/apr && \
make && make install && \
cd ../apr-util-1.6.1
./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && \
make && make install && \
cd ../httpd-2.4.53
./configure --prefix={{ install_dir }} \
--enable-so \
--enable-ssl \
--enable-cgi \
--enable-rewrite \
--with-zlib \
--with-pcre \
--with-apr=/usr/local/apr \
--with-apr-util=/usr/local/apr-util/ \
--enable-modules=most \
--enable-mpms-shared=all \
--with-mpm=prefork && \
make && make install
# 创建模板文件
## 复制到当前目录并改名为httpd.service
[root@control files]# cp /usr/lib/systemd/system/sshd.service httpd.service
## 改为模板文件
[root@control files]# mv httpd.service{,.j2}
[root@control files]# ls
apr-1.7.0.tar.gz CentOS-Base.repo httpd.service.j2 web
apr-util-1.6.1.tar.gz httpd-2.4.53.tar.gz install.sh.j2
## httpd.service内容
[root@control files]# cat httpd.service
[Unit]
Description=httpd server daemon
After=network.target sshd-keygen.target
[Service]
Type=forking
ExecStart={{ install_dir }}/bin/apachectl start
ExecStop={{ install_dir }}/bin/apachectl stop
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
创建安装apache.yml文件
# 安装apache #通用性
[root@control general]# vim install.yml
- name: creare user #创建用户
user:
name: apache
state: present
create_home: no
system: yes
shell: /sbin/nologin
- name: install dependency packages #下载依赖包
yum:
name: "{{ apache_depend_pkg }}"
state: present
- name: provide software package #把Apr、apr-util、httpd包传到受控机、并解压
unarchive: #这个模块有传输过去后解压功能
src: "{{ item }}"
dest: /opt/
loop: "{{ apache_sof_pkg }}"
- name: test {{ install_dir }} is exist # 判断这个变量的值是否存在
command: test -d {{ install_dir }} # 把结果放到result里
register: result
ignore_errors: yes # 忽略错误防止报错后不执行后面的命令
- name: provide script #把脚本模块传到受控机
template:
src: files/install.sh.j2
dest: /opt/install.sh
owner: root
group: root
mode: 0755
- name: install apache # 安装httpd
shell: /opt/install.sh
when: result['rc'] != 0 #这跟上面result对应,如果等于0不安装,不等于0安装
ignore_errors: yes #忽略错误防止报错后不执行后面的命令
- name: provide apache service file #提供service文件
template:
src: files/httpd.service.j2
dest: /usr/lib/systemd/system/httpd.service
# 创建主配置文件main,yml
[root@control general]# vim main.yml
---
- hosts: webservers
gather_facts: no
vars_files:
- vars/apache.yml
tasks:
- include_tasks: install.yml #包含install.yml这个文件
# 测试一下是否报错
[root@control general]# ansible-playbook main.yml
创建关闭防火墙的.yml文件
# 创建关闭防火墙.yml文件
## 若有受控主机需要关闭防火墙的可以使用include_tasks关键字包含进入
[root@control general]# cat off_firewalld.yml
- name: off firewalld
service:
name: firewalld
state: stopped
enabled: no
测试安装文件是否有通用性
两台主机
控制主机 | control | 192.168.229.143 |
---|---|---|
受控主机 | test.example.com | 192.168.229.146 |
配置域名
[root@control httpd]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.229.146 test.example.com
192.168.229.130 web.example.com
设置免密登录
设置免密登录
#生成密钥
[root@control ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:fbBgTOEOBsQ4pUysuvv52rIkP0opRF2CYquU14KQIL4 root@control.example.com
The key's randomart image is:
+---[RSA 3072]----+
|+oo*+. o. |
|*==.+. + |
|++*o. o = . |
|o=.o o + o o |
|+E. . S o . |
|+ . . |
|o+. |
|++oo |
|o+**o |
+----[SHA256]-----+
#使用 ssh-copy-id 将公钥复制到远程系统上的正确位置
[root@control ~]# ssh-copy-id root@test.example.com
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host 'test.example.com (192.168.229.146)' can't be established.
ECDSA key fingerprint is SHA256:x8YxiCK7qYayF5FU6DHFKwC+yv7GQoBYPFRIQ6IOSuo.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@test.example.com's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@test.example.com'"
and check to make sure that only the key(s) you wanted were added.
#登录到受管主机并修改主机名
[root@control ~]# ssh root@test.example.com
[root@localhost ~]# ip addr show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:1c:4f:61 brd ff:ff:ff:ff:ff:ff
inet 192.168.229.146/24 brd 192.168.229.255 scope global dynamic noprefixroute ens160
valid_lft 1144sec preferred_lft 1144sec
inet6 fe80::20c:29ff:fe1c:4f61/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@localhost ~]# hostnamectl set-hostname test.example.com
[root@localhost ~]# bash
[root@test ~]#
准备工作
# 创建httpd目录
[root@control playbook]# mkdir httpd
[root@control playbook]# ls
general httpd
#进入httpd目录
## 把配置文件复制到当前目录
[root@control httpd]# cp ../general/ansible.cfg .
ansible.cfg
#创建清单文件
[root@control httpd]# vim inventory
[webservers]
test.example.com
# ping 是否能通信
[root@control httpd]# ansible test.example.com -m ping
test.example.com | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
#把general的files目录复制到httpd下面
[root@control httpd]# cp -r ../general/files/ .
[root@control httpd]# ls
ansible.cfg files inventory main.yml vars
# 把yum源复制到受控主机
[root@control httpd]# ansible test.example.com -m copy -a 'src=files/CentOS-Base.repo dest=/etc/yum.repos.d/'
# 把general的vars目录复制到当前目录下
[root@control httpd]# cp -r ../general/vars .
[root@control httpd]# ls
ansible.cfg files inventory main.yml vars
创建main.yml文件
#创建main.yml文件
[root@control httpd]# cat main.yml
---
- hosts: test.example.com
gather_facts: no
vars_files:
- vars/apache.yml
tasks:
- include_tasks: ../general/install.yml #包含general项目的安装、这一步就是安装apache
# 运行是否会报错
[root@control httpd]# ansible-playbook main.yml
........省略N
test.example.com : ok=8 changed=6 unreachable=0 failed=0 skipped=0 rescued=0 ignored=1
配置虚拟主机文件
#把httpd.vhosts.conf文件复制到当前目录
[root@control httpd]# scp test.example.com:/usr/local/apache/conf/extra/httpd-vhosts.conf files/httpd-vhosts.conf
[root@control httpd]# ls files/httpd-vhosts.conf
files/httpd-vhosts.conf
# 改为模板文件
[root@control httpd]# ls files/
apr-1.7.0.tar.gz CentOS-Base.repo httpd.service.j2 install.sh.j2
apr-util-1.6.1.tar.gz httpd-2.4.53.tar.gz httpd-vhosts.conf.j2 web
# 编辑httpd-vhosts.conf.j2
[root@control httpd]# cat files/httpd-vhosts.conf.j2
<VirtualHost *:{{ PORT }}>
DocumentRoot "{{ install_dir }}/htdocs/web"
ServerName {{ web_domain }}
ErrorLog "logs/{{ web_domain }}-error_log"
CustomLog "logs/{{ web_domain }}-access_log" common
</VirtualHost>
# vars/apache.yml内容
[root@control httpd]# cat vars/apache.yml
apache_depend_pkg:
- openssl-devel
- pcre-devel
- expat-devel
- libtool
- make
- gcc
- gcc-c++
apache_sof_pkg:
- apr-1.7.0.tar.gz
- apr-util-1.6.1.tar.gz
- httpd-2.4.53.tar.gz
install_dir: /usr/local/apache
PORT: 80
web_domain: test.example.com
目录vars的内容
# vars/apache.yml内容
[root@control httpd]# ls vars/
apache.yml
[root@control httpd]# cat vars/apache.yml
apache_depend_pkg:
- openssl-devel
- pcre-devel
- expat-devel
- libtool
- make
- gcc
- gcc-c++
apache_sof_pkg:
- apr-1.7.0.tar.gz
- apr-util-1.6.1.tar.gz
- httpd-2.4.53.tar.gz
install_dir: /usr/local/apache
PORT: 80
web_domain: test.example.com
目录files的内容
[root@control httpd]# ls files/
apr-1.7.0.tar.gz CentOS-Base.repo httpd.service.j2 install.sh.j2
apr-util-1.6.1.tar.gz httpd-2.4.53.tar.gz httpd-vhosts.conf.j2 web
# httpd.service.j2 == service文件
# install.sh.j2 == 安装脚本
# httpd-vhosts.conf.j2 == 虚拟主机文件
# web == 网站
main.yml最终效果
# main.yml最终的内容
[root@control httpd]# cat main.yml
---
- hosts: test.example.com #受控主机
gather_facts: no #关闭事实
vars_files: #变量
- vars/apache.yml
tasks:
- include_tasks: ../general/off_firewalld.yml #包含关闭防火墙文件
- include_tasks: ../general/install.yml #包含安装apache
- name: provide template file #把虚拟主机文件传到受控机
template:
src: files/httpd-vhosts.conf.j2
dest: "{{ install_dir }}/conf/extra/httpd-vhosts.conf"
notify: #更改配置文件后重启
- restart httpd
- name: Including virtual hosts #让httpd配置文件有>
lineinfile:
path: "{{ install_dir }}/conf/httpd.conf"
line: Include conf/extra/httpd-vhosts.conf # >有这一行
state: present
notify: #更改配置文件后重启
- restart httpd
- name: provide web # 提供网站
copy:
src: files/web
dest: "{{ install_dir }}/htdocs/"
- name: start httpd #启动apache并、开机自启
service:
name: httpd
state: started
enabled: yes
handlers: #更改配置文件后重启
- name: restart httpd
service:
name: httpd
state: restarted
# 运行main.yml
[root@control httpd]# ansible-playbook main.yml
......省略N
test.example.com : ok=14 changed=5 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
访问
test.example.com