主机 | ip | 属性 |
---|---|---|
node0 | 192.168.94.142 | 控制机 |
node1 | 192.168.94.141 | 受控机httpd |
node2 | 192.168.94.143 | 受控机mysql |
node3 | 192.168.94.144 | 受控机php |
1.映射ip
[root@node0 ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.94.141 node1
192.168.94.143 node2
192.168.94.144 node3
2.增加清单
设置为test组
[root@node0 ~]# vim /etc/ansible/inventory
[test]
node1
node2
node3
3.复制公钥至各受控机
[root@node0 ~] ssh-copy-id root@node2
[root@node0 ~] ssh-copy-id root@node2
[root@node0 ~] ssh-copy-id root@node3
4.测试
[root@node0 ~]# ansible test -m ping
node2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
node3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
5.批量配置yum源
[root@node0 ~]# ansible test -m get_url -a 'url=https://mirrors.aliyun.com/repo/Centos-8.repo dest=/etc/yum.repos.d/'
node1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum_dest": null,
"checksum_src": "4966466ad015ef3d2a3cc0b8252d43efbdcf2c94",
"dest": "/etc/yum.repos.d/Centos-8.repo",
"elapsed": 0,
"gid": 0,
"group": "root",
"md5sum": "d06fb7d5709727828bcaba7457ea673e",
"mode": "0644",
"msg": "OK (2595 bytes)",
"owner": "root",
"size": 2595,
"src": "/root/.ansible/tmp/ansible-tmp-1609930157.028933-4802-48489920245132/tmpm0o67n8u",
"state": "file",
"status_code": 200,
"uid": 0,
"url": "https://mirrors.aliyun.com/repo/Centos-8.repo"
}
node3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum_dest": null,
"checksum_src": "4966466ad015ef3d2a3cc0b8252d43efbdcf2c94",
"dest": "/etc/yum.repos.d/Centos-8.repo",
"elapsed": 0,
"gid": 0,
"group": "root",
"md5sum": "d06fb7d5709727828bcaba7457ea673e",
"mode": "0644",
"msg": "OK (2595 bytes)",
"owner": "root",
"secontext": "system_u:object_r:system_conf_t:s0",
"size": 2595,
"src": "/root/.ansible/tmp/ansible-tmp-1609930157.1517816-4806-186470275888078/tmpr722onkj",
"state": "file",
"status_code": 200,
"uid": 0,
"url": "https://mirrors.aliyun.com/repo/Centos-8.repo"
}
node2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"checksum_dest": null,
"checksum_src": "4966466ad015ef3d2a3cc0b8252d43efbdcf2c94",
"dest": "/etc/yum.repos.d/Centos-8.repo",
"elapsed": 0,
"gid": 0,
"group": "root",
"md5sum": "d06fb7d5709727828bcaba7457ea673e",
"mode": "0644",
"msg": "OK (2595 bytes)",
"owner": "root",
"secontext": "system_u:object_r:system_conf_t:s0",
"size": 2595,
"src": "/root/.ansible/tmp/ansible-tmp-1609930157.1607556-4804-85478380770909/tmpk85eft72",
"state": "file",
"status_code": 200,
"uid": 0,
"url": "https://mirrors.aliyun.com/repo/Centos-8.repo"
}
//验证
[root@node2 ~]# ll /etc/yum.repos.d/
total 8
-rw-r--r--. 1 root root 2595 Jan 6 18:49 Centos-8.repo
-rw-r--r--. 1 root root 358 Jan 6 18:15 redhat.repo
[root@node1 ~]# ll /etc/yum.repos.d/
total 36
-rw-r--r-- 1 root root 2595 Jan 6 18:49 Centos-8.repo
-rw-r--r--. 1 root root 2595 Jan 4 00:42 CentOS-Base.repo
[root@node3 ~]# ll /etc/yum.repos.d/
total 36
-rw-r--r-- 1 root root 2595 Jan 6 18:49 Centos-8.repo
-rw-r--r--. 1 root root 2595 Jan 4 00:42 CentOS-Base.repo
6.配置epel源
[root@node0 ~]# wget https://mirrors.aliyun.com/epel/epel-release-latest-8.noarch.rpm
[root@node0 ~]# yum -y install /root/epel-release-latest-8.noarch.rpm
7.批量配置repo,epel源
[root@node0 ~]# ansible all -m copy -a 'src=/etc/yum.repos.d/ dest=/etc/yum.repos.d/'
node3 | CHANGED => {
"changed": true,
"dest": "/etc/yum.repos.d/",
"src": "/etc/yum.repos.d/"
}
node2 | CHANGED => {
"changed": true,
"dest": "/etc/yum.repos.d/",
"src": "/etc/yum.repos.d/"
}
node1 | CHANGED => {
"changed": true,
"dest": "/etc/yum.repos.d/",
"src": "/etc/yum.repos.d/"
}
8.清除,生成缓存
[root@node0 ~]# ansible test -a 'yum clean all'
[root@node0 ~]# ansible test -a 'yum makecache'
httpd
node1
9.安装开发工具
[root@node0 ~]# ansible node1 -m yum -a 'name="@Development tools" state=present'
node1 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
...
"Removed: glibc-langpack-en-2.28-101.el8.x86_64"
]
}
10.创建apache用户
//系统用户无家目录不允许登录
[root@node0 ~]# ansible node1 -m user -a 'name=apache system=true shell=/sbin/nologin create_home=false state=present'
//查看用户
[root@node0 ~]# ansible node1 -a 'tail /etc/passwd'
node1 | CHANGED | rc=0 >>
...
apache:x:992:989::/home/apache:/sbin/nologin
11.下载并解压httpd相关安装包
//下载
[root@node0 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache/httpd/httpd-2.4.46.tar.bz2
[root@node0 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-1.7.0.tar.gz
[root@node0 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/apache//apr/apr-util-1.6.1.tar.gz
//整合到httpd文件夹里
[root@node0 ~]# mv apr-1.7.0.tar.gz httpd-2.4.46.tar.bz2 apr-util-1.6.1.tar.gz /httpd
//运用ansible命令远程复制至node1的root用户目录
[root@node0 httpd]# ansible node1 -m copy -a 'src=/root/httpd dest=/root'
node1 | SUCCESS => {
"changed": false,
"dest": "/root/",
"src": "/root/httpd"
}
//解压(如报错需安装bzip2)
[root@node0 ~]# ansible node1 -m shell -a 'tar xf /root/httpd/apr-1.7.0.tar.gz'
[WARNING]: Consider using the unarchive module rather than running 'tar'. If you need to use command because
unarchive is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node1 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node1 -m shell -a 'tar xf /root/httpd/apr-util-1.6.1.tar.gz'
[WARNING]: Consider using the unarchive module rather than running 'tar'. If you need to use command because
unarchive is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node1 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node1 -m shell -a 'tar xf /root/httpd/httpd-2.4.46.tar.bz2'
[WARNING]: Consider using the unarchive module rather than running 'tar'. If you need to use command because
unarchive is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node1 | CHANGED | rc=0 >>
12.安装
//安装apr
[root@node0 ~]# ansible node1 -m shell -a 'cd /root/apr-1.7.0 && ./configure --prefix=/usr/local/apr'
[root@node0 ~]# ansible node1 -m shell -a 'cd /root/apr-1.7.0 && make && make install'
node1 | CHANGED | rc=0 >>
//安装apr-util
[root@node0 ~]# ansible node1 -m shell -a 'cd /root/apr-util-1.6.1 && ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr'
node1 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node1 -m shell -a 'cd /root/apr-util-1.6.1 && make && make install'
node1 | CHANGED | rc=0 >>
//安装httpd
[root@node0 ~]# ansible node1 -m shell -a 'cd /root/httpd-2.4.46 && ./configure --prefix=/usr/local/apache --sysconfdir=/etc/httpd24
--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
--with-crypto'
[root@node0 ~]# ansible node1 -m shell -a 'cd /root/httpd-2.4.46 && make && make install'
13.配置
//添加环境变量
[root@node0 ~]# ansible node1 -m shell -a 'echo "export PATH=/usr/local/apache/bin:$PATH" > /etc/profile.d/httpd.sh'
node1 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node1 -m shell -a 'source /etc/profile.d/httpd.sh'
node1 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node1 -m shell -a 'echo $PATH'
node1 | CHANGED | rc=0 >>
/usr/local/apache/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
//创建软连接
[root@node0 ~]# ansible node1 -m shell -a 'ln -s /usr/local/apache/include /usr/local/include/httpd'
[WARNING]: Consider using the file module with state=link rather than running 'ln'. If you need to use command
because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node1 | CHANGED | rc=0 >>
//取消服务器名注释
[root@node0 ~]# ansible node1 -m shell -a 'sed -i '/#ServerName/s/#//g' /etc/httpd24/httpd.conf'
[WARNING]: Consider using the replace, lineinfile or template module rather than running 'sed'. If you need to use
command because replace, lineinfile or template is insufficient you can add 'warn: false' to this command task or
set 'command_warnings=False' in ansible.cfg to get rid of this message.
node1 | CHANGED | rc=0 >>
14.启动服务
//启用服务
[root@node0 ~]# ansible node1 -m shell -a '/usr/local/apache/bin/apachectl start'
node1 | CHANGED | rc=0 >>
//查看端口
[root@node0 ~]# ansible node1 -m shell -a 'ss -antl'
node1 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
LISTEN 0 128 *:80 *:*
mysql
node2
15.安装依赖包
[root@node0 ~]# ansible node2 -m yum -a 'name=ncurses-devel,openssl-devel,openssl,cmake,mariadb-devel,ncurses-compat-libs state=present'
16.创建mysql用户
[root@node0 ~]# ansible node2 -m user -a 'name=mysql system=true create_home=false shell=/sbin/nologin state=present'
node2 | CHANGED => {
...
[root@node0 ~]# ansible node2 -m shell -a 'id mysql'
node2 | CHANGED | rc=0 >>
uid=993(mysql) gid=990(mysql) groups=990(mysql)
17.下载mysql包
//下载
[root@node0 ~]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz
//远程传输至node2
[root@node0 ~]# scp /root/mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz 'root'@'node2':/root
mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz 100% 359MB 185.8MB/s 00:01
//查看
[root@node0 ~]# ansible node2 -a 'ls '
node2 | CHANGED | rc=0 >>
anaconda-ks.cfg
epel-release-latest-8.noarch.rpm
mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz
18.解压
//解压至usr/local
[root@node0 ~]# ansible node2 -m shell -a 'tar xf mysql-5.7.31-linux-glibc2.12-x86_64.tar.gz -C /usr/local/'
[WARNING]: Consider using the unarchive module rather than running 'tar'. If you need to use command because
unarchive is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node2 | CHANGED | rc=0 >>
//查看
[root@node0 ~]# ansible node2 -m shell -a 'ls /usr/local/|grep mysql'
node2 | CHANGED | rc=0 >>
mysql-5.7.31-linux-glibc2.12-x86_64
//创建软连接
//文件名简化
[root@node0 ~]# ansible node2 -m shell -a 'ln -s /usr/local/mysql-5.7.31-linux-glibc2.12-x86_64 /usr/local/mysql'
[WARNING]: Consider using the file module with state=link rather than running 'ln'. If you need to use command
because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node2 | CHANGED | rc=0 >>
//include
[root@node0 ~]# ansible node2 -m shell -a 'ln -s /usr/local/mysql/include /usr/local/include/mysql'
[WARNING]: Consider using the file module with state=link rather than running 'ln'. If you need to use command
because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node2 | CHANGED | rc=0 >>
//创建数据存放目录data
[root@node0 ~]# ansible node2 -m shell -a 'mkdir /opt/data'
19.更改属主,组
[root@node0 ~]# ansible node2 -m shell -a 'chown -R mysql.mysql /usr/local/mysql*'
[WARNING]: Consider using the file module with owner rather than running 'chown'. If you need to use command
because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node2 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node2 -m shell -a 'chown -R mysql.mysql /opt/data'
[WARNING]: Consider using the file module with owner rather than running 'chown'. If you need to use command
because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node2 | CHANGED | rc=0 >>
20.更改环境变量
[root@node0 ~]# ansible node2 -m shell -a 'echo "export PATH=/usr/local/mysql/bin:$PATH" > /etc/profile.d/mysql.sh'
node2 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node2 -m shell -a 'source /etc/profile.d/mysql.sh'
node2 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node2 -m shell -a 'which mysql'
node2 | CHANGED | rc=0 >>
/usr/local/mysql/bin/mysql
21.初始化数据库
[root@node0 ~]# ansible node2 -m shell -a '/usr/local/mysql/bin/mysqld --initialize --user=mysql --datadir=/opt/data
> '
node2 | CHANGED | rc=0 >>
... [Note] A temporary password is generated for root@localhost: qk:gv;ou6a<Z
//暂存临时密码
[root@node0 ~]# ansible node2 -m shell -a 'echo "qk:gv;ou6a<Z">/root/pass'
node2 | CHANGED | rc=0 >>
22.生成配置文件
//node0端编写
[root@node0 ~]# vim my.cnf
[mysqld]
basedir = /usr/local/mysql
datadir = /opt/data
socket = /tmp/mysql.sock
port = 3306
pid-file = /opt/data/mysql.pid
user = mysql
skip-name-resolve
//复制到node2端
[root@node0 ~]# ansible node2 -m copy -a 'src=/root/my.cnf dest=/etc/ '
//配置服务启动脚本
[root@node0 ~]# ansible node2 -m shell -a 'cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld'
//lineinfile生成两行目标
[root@node0 ~]# ansible node2 -m lineinfile -a 'path=/etc/init.d/mysqld line="basedir=/usr/local/mysql" create=yes'
node2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line added"
}
[root@node0 ~]# ansible node2 -m lineinfile -a 'path=/etc/init.d/mysqld line="datadir=/opt/data" create=yes'
node2 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line added"
}
23.启动服务
[root@node0 ~]# ansible node2 -m shell -a 'service mysqld start'
[WARNING]: Consider using the service module rather than running 'service'. If you need to use command because
service is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
node2 | CHANGED | rc=0 >>
Starting MySQL. SUCCESS! Logging to '/opt/data/node2.err'.
//查看端口是否启用
[root@node0 ~]# ansible node2 -m shell -a 'ss -antl'
node2 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 80 *:3306 *:*
LISTEN 0 128 [::]:22 [::]:*
24.修改密码
[root@node0 ~]# ansible node2 -m shell -a '/usr/local/mysql/bin/mysql --connect-expired-password -uroot -p"qk:gv;ou6a<Z" -e "set password=password("123456");"'
node2 | CHANGED | rc=0 >>
mysql: [Warning] Using a password on the command line interface can be insecure.
25.配置依赖库路径
[root@node0 ~]# ansible node2 -m shell -a 'echo "/usr/local/mysql/lib" > /etc/ld.so.conf.d/mysql.conf && ldconfig'
node2 | CHANGED | rc=0 >>
php
node3
26.导入gpg密钥
//根据红帽版本
[root@node3 rpm-gpg]# wget https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8
--2021-01-07 01:24:35-- https://archive.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-8
Resolving archive.fedoraproject.org (archive.fedoraproject.org)... 38.145.60.22, 38.145.60.24, 38.145.60.23
Connecting to archive.fedoraproject.org (archive.fedoraproject.org)|38.145.60.22|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1627 (1.6K)
Saving to: ‘RPM-GPG-KEY-EPEL-8’
RPM-GPG-KEY-EPEL-8 100%[===========================================================>] 1.59K --.-KB/s in 0s
2021-01-07 01:24:37 (54.4 MB/s) - ‘RPM-GPG-KEY-EPEL-8’ saved [1627/1627]
27.安装依赖包
[root@node0 ~]# ansible node3 -m yum -a 'name=libxml2,libxml2-devel,openssl,openssl-devel,bzip2,bzip2-devel,libcurl,libcurl-devel,libicu-devel,libjpeg,libjpeg-devel,libpng,libpng-devel,openldap-devel,pcre-devel,freetype,freetype-devel,gmp,gmp-devel,libmcrypt,libmcrypt-devel,readline,readline-devel,libxslt,libxslt-devel,mhash,mhash-devel,php-mysqlnd state=present'
node3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
28.安装php
[root@node0 ~]# ansible node3 -m yum -a 'name=php-* state=present'
node3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": true,
"msg": "",
"rc": 0,
"results": [
//查看版本
[root@node0 ~]# ansible node3 -m shell -a 'which php'
node3 | CHANGED | rc=0 >>
/usr/bin/php
[root@node0 ~]# ansible node3 -m shell -a 'php -v'
node3 | CHANGED | rc=0 >>
PHP 7.2.24 (cli) (built: Oct 22 2019 08:28:36) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.24, Copyright (c) 1999-2018, by Zend Technologies
29.启动php
[root@node0 ~]# ansible node3 -m shell -a 'systemctl start php-fpm'
node3 | CHANGED | rc=0 >>
30.配置
- apache端
//取消注释启用代理
[root@node0 ~]# ansible node1 -m shell -a 'sed -i "s/#LoadModule proxy_module modules/mod_proxy.so/LoadModule proxy_module modules/mod_proxy.so/g" /etc/httpd24/httpd.conf'
[WARNING]: Consider using the replace, lineinfile or template module rather than running 'sed'. If you need to use
command because replace, lineinfile or template is insufficient you can add 'warn: false' to this command task or
set 'command_warnings=False' in ansible.cfg to get rid of this message.
node1 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node1 -m shell -a 'sed -i "s/#LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so/LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so/g" /etc/httpd24/httpd.conf'
[WARNING]: Consider using the replace, lineinfile or template module rather than running 'sed'. If you need to use
command because replace, lineinfile or template is insufficient you can add 'warn: false' to this command task or
set 'command_warnings=False' in ansible.cfg to get rid of this message.
node1 | CHANGED | rc=0 >>
- php端
//添加端口
[root@node0 ~]# ansible node3 -m lineinfile -a 'path=/etc/php-fpm.d/www.conf line="listen = 127.0.0.1:9000" create=yes '
node3 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line added"
}
//重启服务查看端口
[root@node0 ~]# ansible node3 -m shell -a 'systemctl restart php-fpm'
node3 | CHANGED | rc=0 >>
[root@node0 ~]# ansible node3 -m shell -a 'ss -antl'
node3 | CHANGED | rc=0 >>
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 127.0.0.1:9000 0.0.0.0:*
LISTEN 0 128 [::]:22 [::]:*
[root@node0 ~]# vim index.php
<?php
phpinfo();
?>
//传输到node1
[root@node0 ~]# ansible node1 -m copy -a 'src=/root/index.php dest=/usr/local/apache/htdocs/test'
//更改htdocs目录下的属主组
[root@node0 ~]# ansible node1 -m shell -a 'chown -R apache.apache /usr/local/apache/htdocs/'
//关闭防火墙
[root@node0 ~]# ansible node1 -m shell -a 'systemctl stop firewalld && setenforce 0'
报错,待研究