Loading

Ansible批量管理Docker集群架构

1. 项目前期规划准备

角色 主机名 公网IP 私网IP 服务 备注
负载均衡 lb01 10.0.0.12 172.16.1.12 跑1个nginx进行负载均衡
web服务器 web05 10.0.0.13 172.16.1.13 跑2个nginx+1个php运行kodexp
web服务器 web06 10.0.0.14 172.16.1.14 跑2个nginx+1个php运行kodexp
web服务器 web07 10.0.0.15 172.16.1.15 跑2个nginx+1个php运行wordpress
web服务器 web08 10.0.0.16 172.16.1.16 跑2个nginx+1个php运行wordpress
数据库与缓存 db01 10.0.0.17 172.16.1.17 跑redis、mysql数据库
存储 nfs01 10.0.0.18 172.16.1.18 跑存储服务
私有仓库 reg 10.0.0.19 172.16.1.19 docker跑个registry仓库
批量管理机 devops 10.0.0.20 172.16.1.20 跑python3版本的ansible

各主机hosts解析如下:

127.0.0.1  localhost localhost.localdomain
172.16.1.12 lb01
172.16.1.13 web05
172.16.1.14 web06
172.16.1.15 web07
172.16.1.16 web08
172.16.1.17 db01
172.16.1.18 nfs01
172.16.1.19 reg reg.yinjay.com
172.16.1.20 devops devops.yinjay.com

2. 管理机环境准备

1.安装python3、pip3、rust

yum install -y python3 python3-pip rust

2.升级pip与配置pip源

pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip
pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

3.pip3安装ansible与docker

pip3 install setuptools_rust ansible docker

#安装完查看版本,要有下列
[root@devops ~]# pip3 list | egrep 'ansible|docker'
ansible            4.10.0
ansible-core       2.11.12
docker             5.0.3

4.配置Ansible环境变量、主机列表和密钥认证

环境变量

cat >>/etc/profile<<EOF
export ANSIBLE_INVENTORY=./hosts
EOF

#使环境变量生效
source /etc/profile

分发公钥给各主机

[root@devops docker]# cat fenfa_pub.sh
#!/bin/bash
#desc:一键自动化创建和分发密钥

ip_list="172.16.1.12 172.16.1.13 172.16.1.14 172.16.1.15 172.16.1.16 172.16.1.17 172.16.1.18 172.16.1.19"
ssh_root_pass="123456"
echo '-----------------------------------'
echo '1.创建key'
echo '-----------------------------------'

ssh-keygen -f ~/.ssh/id_rsa -P ''

echo '-----------------------------------'
echo '2.分发pub key'


for ip in $ip_list
do
  sshpass -p$ssh_root_pass ssh-copy-id -i ~/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@$ip
done

echo '-----------------------------------'
echo '3.已完成分发!'

#开始分发
[root@devops docker]# sh fenfa_pub.sh

记得安装sshpass


主机列表

[root@devops ~]# mkdir -p /ansible/docker
[root@devops ~]# cd /ansible/docker/
[root@devops docker]# cat hosts
[lb]
172.16.1.12 hostname=lb01

[web]
172.16.1.13 hostname=web05
172.16.1.14 hostname=web06
172.16.1.15 hostname=web07
172.16.1.16 hostname=web08

[db]
172.16.1.17 hostname=db01

[nfs]
172.16.1.18 hostname=nfs01

[reg]
172.16.1.19 hostname=reg

测试被控端是否成功免密ping通,没有问题!

image-20230419134355370


3. 基础环境准备

先创建一个roles规范的目录进行存放基础环境配置的ansible剧本

[root@devops docker]# mkdir -p sys_basic/{tasks,templates,files,handlers} group_vars/all/

在sys_basic/files下创建以下两个文件

#hosts文件
[root@devops docker]# cat sys_basic/files/hosts
127.0.0.1  localhost localhost.localdomain
172.16.1.12 lb01
172.16.1.13 web05
172.16.1.14 web06
172.16.1.15 web07
172.16.1.16 web08
172.16.1.17 db01
172.16.1.18 nfs01
172.16.1.19 reg reg.yinjay.com
172.16.1.20 devops devops.yinjay.com

#docker镜像加速和私有仓库配置
[root@devops docker]# cat sys_basic/files/daemon.json
{
  "registry-mirrors": ["https://k313isum.mirror.aliyuncs.com"],
  "insecure-registries": ["reg.yinjay.com:5000"]

}

在sys_basic/tasks目录下编写一个main.yml,具体内容如下:

[root@devops docker]# cat sys_basic/tasks/main.yml
- name: 1. yum安装常用工具和docker必备依赖
  yum:
    name:
      - tree
      - vim
      - wget
      - bash-completion
      - bash-completion-extras
      - net-tools
      - telnet
      - device-mapper-persistent-data
      - lvm2
      - yum-utils
      - python3
      - python3-pip

- name: 2. 分发hosts文件
  copy:
    src: hosts
    dest: /etc/hosts
    backup: yes

- name: 3. 安装python3的docker依赖
  command: pip3 install docker==5.0.3

- name: 4. 开启内核转发
  shell:
    cmd: |
        echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
        sysctl -p

- name: 5. 配置docker源
  shell:
    cmd: |
        yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
        sed -i 's+https://download.docker.com+https://mirrors.tuna.tsinghua.edu.cn/docker-ce+' /etc/yum.repos.d/docker-ce.repo

- name: 6. 安装docker-ce,docker-compose
  yum:
    name:
      - docker-ce
      - docker-compose

- name: 7. 配置docker镜像加速、私有仓库
  copy:
    src: daemon.json
    dest: /etc/docker/daemon.json
    backup: yes

- name: 8. 启动docker并设置开机自启
  systemd:
    name: docker
    enabled: yes
    state: started

- name: 9. 修改主机名
  hostname:
    name: "{{hostname}}"

编写入口文件,跑起sys_basic剧本,这里定义了一个变量是指定ansible用python哪个版本进行执行。

[root@devops docker]# pwd
/ansible/docker
[root@devops docker]# cat top.yml
- hosts: all
  vars:
    ansible_python_interpreter: /usr/bin/python2
  roles:
    - role: sys_basic

#执行剧本 -f指定线程数
[root@devops docker]# ansible-playbook top.yml -f 10

4. 数据库及缓存准备

先创建一个roles规范的目录进行存放数据库配置的ansible剧本

[root@devops docker]# mkdir -p db/{tasks,templates,files,handlers}

在db/files下创建以下文件

[root@devops docker]# cat db/files/mysql.repo
[mysql-connectors-community]
name=MySQL Connectors Community
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-connectors-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

[mysql-tools-community]
name=MySQL Tools Community
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-tools-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

[mysql-5.7-community]
name=MySQL 5.7 Community Server
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/mysql-5.7-community-el7-$basearch/
enabled=1
gpgcheck=1
gpgkey=https://repo.mysql.com/RPM-GPG-KEY-mysql-2022

在db/tasks目录下编写一个main.yml,具体内容如下:

[root@devops docker]# cat db/tasks/main.yml
- name: 1. 配置mysql的yum源
  copy:
    src: mysql.repo
    dest: /etc/yum.repos.d/mysql.repo
    backup: yes

- name: 2. 安装MySQL 5.7
  yum:
    name:
      - mysql-community-server
    state: installed

- name: 3. 安装Python的数据库模块
  pip:
    name: PyMySQL
    executable: pip3

- name: 4. 启动MySQL并设置开机自启
  systemd:
    name: mysqld
    enabled: yes
    state: started

- name: 5. 获取MySQL默认密码
  shell: awk '/temporary password/{print $NF}' /var/log/mysqld.log
  register: db_root_pass

- name: MySQL默认密码如下
  debug:
    msg: "{{db_root_pass.stdout}}"

- name: 6. 设置root密码
  shell:
    cmd: mysql -uroot -p"{{db_root_pass.stdout}}" -e "alter user root@localhost identified by 'Huawei@123';flush privileges;" --connect-expired-password
  ignore_errors: yes

- name: 7. 删除用户
  mysql_user:
    name: ""
    host: "{{item}}"
    login_user: root
    login_password: "Huawei@123"
    state: absent
  ignore_errors: yes
  with_items:
    - "{{ansible_hostname}}"
    - localhost

- name: 8. 创建数据库
  mysql_db:
    name: "{{item}}"
    login_user: root
    login_password: "Huawei@123"
    state: present
  loop:
    - blog
    - kodbox

- name: 9. 创建用户
  mysql_user:
    name: "{{item}}"
    host: 172.%
    password: "{{item}}"
    priv: "{{item}}.*:ALL"
    login_user: root
    login_password: "Huawei@123"
    state: present
  loop:
    - blog
    - kodbox

- name: 10. 安装redis
  yum:
    name: redis

- name: 11. 修改redis配置
  lineinfile:
    path: /etc/redis.conf
    regexp: '^bind'
    line: "bind {{ansible_all_ipv4_addresses[1]}} 127.0.0.1 "

- name: 12. 启动redis并设置开机自启
  systemd:
    name: redis
    enabled: yes
    state: started

第11步是找到bind开头的行进行整体替换,其中ansible_all_ipv4_addresses[1]取的是172.16.1.17这个地址!


编写入口文件,跑起db剧本,这里将之前的剧本暂且注释。

[root@devops docker]# cat top.yml
#- hosts: all
#  vars:
#    ansible_python_interpreter: /usr/bin/python2
#  roles:
#    - role: sys_basic


- hosts: db
  vars:
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - role: db

#执行剧本
[root@devops docker]# ansible-playbook top.yml

5. NFS存储准备

先创建一个roles规范的目录进行存放存储配置的ansible剧本

[root@devops docker]# mkdir -p nfs/{tasks,templates,files,handlers}

在nfs/tasks目录下编写一个main.yml,具体内容如下:

[root@devops docker]# cat nfs/tasks/main.yml
- name: 1. 安装rpcbind和nfs-utils
  yum:
    name:
      - rpcbind
      - nfs-utils
    state: installed

- name: 2. 启动rpcbind、nfs并设置开机自启
  systemd:
    name: "{{item}}"
    enabled: yes
    state: started
  with_items:
    - rpcbind
    - nfs

- name: 3. 创建共享目录
  file:
    path: "{{item}}"
    owner: nfsnobody
    group: nfsnobody
    state: directory
  loop:
    - /data/wordpress
    - /data/kodbox

- name: 4. 配置nfs服务端
  shell:
    cmd: echo "{{item}} 172.16.1.0/24(rw,all_squash)" >> /etc/exports
  loop:
    - /data/wordpress
    - /data/kodbox

- name: 5. 重新加载nfs配置文件
  systemd:
    name: nfs
    state: reloaded

编写入口文件,跑起nfs剧本,这里将之前的剧本暂且注释。

[root@devops docker]# cat top.yml
#- hosts: all
#  vars:
#    ansible_python_interpreter: /usr/bin/python2
#  roles:
#    - role: sys_basic


#- hosts: db
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: db


- hosts: nfs
  vars:
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - role: nfs

6. 私有镜像仓库准备

在reg主机上进行创建存放yml文件的目录,编写一个私有镜像仓库的容器编排yml文件。

[root@reg ~]# mkdir -p /docker/compose/01-registry
[root@reg ~]# cat /docker/compose/01-registry/docker-compose.yml
version: "3.3"
services:
  registry_image:
    image: "registry:latest"
    ports:
      - "5000:5000"
    volumes:
      - "/data/images:/var/lib/registry"
    restart: always

启动私有镜像仓库

image-20230419203854393

如果没有在docker-compose.yml当前目录,则 -f 指定文件所在路径即可。


7. 制作web和php镜像

7.1 制作web镜像

建立一个存放制作web镜像Dockerfile文件和相关配置、程序的目录

[root@reg ~]# mkdir -p /docker/Dockerfile/nginx

编写nginx.conf配置文件

[root@reg nginx]# cat nginx.conf
user nginx;
worker_processes auto;

error_log   /var/log/nginx/error.log notice;
pid         /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include         /etc/nginx/mime.types;
    default_type    application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log      /var/log/nginx/access.log main;
    sendfile        on;

    keepalive_timeout 65;

    include /etc/nginx/conf.d/*.conf;
}

编写wordpress网站的配置文件

[root@reg nginx]# cat wp.yinjay.com.conf
server {
    listen 80;
    server_name wp.yinjay.com;
    root /app/code/wp;

    location / {
        index index.php;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }

}

编写kodbox网站的配置文件

[root@reg nginx]# cat kodbox.yinjay.com.conf
server {
    listen 80;
    server_name kodbox.yinjay.com;
    root /app/code/kod;

    location / {
        index index.php;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }

}

上传wordpress和kodbox网站源码包到/docker/Dockerfile/nginx目录下(要求解压后不能在某个目录下)

[root@reg nginx]# ll *.tar.gz
-rw-r--r-- 1 root root 31366724 Apr 19 09:04 kodbox.tar.gz
-rw-r--r-- 1 root root 19462260 Apr 19 09:06 wordpress.tar.gz

编写web的Dockerfile文件,下面内容就是替换原镜像里nginx.conf配置,再拷贝两个网站配置到conf.d目录下。同时将两个网站源码进行解压到各目录下,并设置网站目录下文件所有者。

[root@reg nginx]# cat Dockerfile
FROM nginx:1.20.2-alpine
LABEL maintainer="nginx szgetshell@163.com" author="YinJayChen"

COPY nginx.conf /etc/nginx/nginx.conf
COPY *.yinjay.com.conf /etc/nginx/conf.d/

ENV Kod_Code="kodbox.tar.gz" \
    Wp_Code="wordpress.tar.gz"

ADD ${Kod_Code} /app/code/kod/
ADD ${Wp_Code} /app/code/wp/

RUN chown -R nginx.nginx /app/code/*

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 80

STOPSIGNAL SIGQUIT

CMD ["nginx", "-g", "daemon off;"]

Dockerfile构建web镜像
#在/docker/Dockerfile/nginx目录下执行
[root@reg nginx]# docker build -t web:nginx_v1 .

image-20230420194605215


给镜像打上tag,推送到私有镜像仓库上

#打上tag
docker tag web:nginx_v1 reg.yinjay.com:5000/web/nginx:1.20.2

#推送
docker push reg.yinjay.com:5000/web/nginx:1.20.2

image-20230420195336159


7.2 制作php镜像

建立一个存放制作php镜像Dockerfile文件和相关配置、程序的目录

[root@reg ~]# mkdir -p /docker/Dockerfile/php

编写php的www.conf,最重要是修改那个redis的IP,指向部署redis服务的宿主机

[root@reg php]# cat www.conf
[www]
user = nginx
group = nginx
listen = 0.0.0.0:9000
listen.owner = nginx
listen.group = nginx
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
php_value[session.save_handler] = redis
php_value[session.save_path] = tcp://172.16.1.17:6379

上传wordpress和kodbox网站源码包到/docker/Dockerfile/php目录下(要求解压后不能在某个目录下),与web镜像的网站程序代码保持一致!

[root@reg php]# ll *.tar.gz
-rw-r--r-- 1 root root 31366724 Apr 19 09:36 kodbox.tar.gz
-rw-r--r-- 1 root root 19462260 Apr 19 09:36 wordpress.tar.gz

编写php的Dockerfile文件,下面内容就是在php-fpm镜像上进行php对redis的支持,下载redis的php支持包,然后解压并进行下载安装依赖。添加php-fpm程序运行所需要的用户和拷贝php所需要的www.conf配置进行覆盖,还需要拷贝wordpress、kodbox网站源码包进行解压并更改网站程序目录的所有者。

为什么php镜像也需要网站代码?因为请求到了nginx上,匹配上location,需要将请求交由给php进行处理,那php在处理解析时就需要这些网站代码。

[root@reg php]# cat Dockerfile
FROM php:7.4-fpm-alpine
LABEL Description="php redis" Author="YinJayChen"

ENV URL https://pecl.php.net/get/redis-5.3.7.tgz
ENV DIR /usr/src/php/ext/
ENV Kod_Code=kodbox.tar.gz \
    Wp_Code=wordpress.tar.gz
ENV Redis_Ip=172.16.4.17

COPY www.conf /usr/local/etc/php-fpm.d/www.conf
ADD ${Kod_Code} /app/code/kod/
ADD ${Wp_Code} /app/code/wp/

RUN  sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apk/repositories \
    && apk add zlib-dev libpng-dev libwebp-dev libjpeg-turbo-dev freetype-dev \
    && docker-php-source extract \
    && wget -P /tmp ${URL} \
    && tar xf /tmp/redis-5.3.7.tgz -C ${DIR}/ \
    && mv ${DIR}/redis-5.3.7 ${DIR}/redis \
    && cd ${DIR}/gd \
    && docker-php-ext-configure gd --enable-gd --with-webp --with-jpeg --with-freetype \
    && docker-php-ext-install gd \
    && cd ${DIR} \
    && docker-php-ext-install mysqli pdo_mysql redis \
    && addgroup -g 101 nginx \
    && adduser -s /sbin/nologin -D -S -H -u 101 -G nginx nginx \
    && rm -rf /var/cache/* /tmp/* /usr/src/php \
    && chown -R nginx.nginx /app/code/*

EXPOSE 9000

CMD ["php-fpm"]

Dockerfile构建php镜像

#在/docker/Dockerfile/php目录下执行
[root@reg php]# docker build -t php:v1 .

image-20230420204736978

给镜像打上tag,推送到私有镜像仓库上

#打上tag
docker tag php:v1 reg.yinjay.com:5000/php/php7.4-fpm:v1

#推送
docker push reg.yinjay.com:5000/php/php7.4-fpm:v1

image-20230420205336277


7.3 联调web和php

通过docker-compose联调web服务和php服务,测试容器web、php是否正常。在reg主机上进行创建存放yml文件的目录,编写一个web和php的容器编排yml文件。


编排的内容主要是启动两个web容器,映射到宿主机的80、81端口。将宿主机本地的数据目录映射到两个网站程序的数据目录,实现数据持久化。同时通过links方式给web_php这个服务起个别名,web容器内的nginx配置可以直接进行名称解析。当然php容器也需要映射数据目录!

在nginx配置下的 fastcgi_pass php:9000; 就用了这种方式,这样不用担心启动后容器IP改变!

[root@reg ~]# mkdir -p /docker/compose/web
[root@reg web]# cat docker-compose.yml
version: "3.3"
services:
  web_ngx_a:
    image: "reg.yinjay.com:5000/web/nginx:1.20.2"
    ports:
      - "80:80"
    volumes:
      - "/data/wp:/app/code/wp/wp-content/uploads/"
      - "/data/kod:/app/code/kod/data/files/"
    links:
      - "web_php:php"
    restart: always

  web_ngx_b:
    image: "reg.yinjay.com:5000/web/nginx:1.20.2"
    ports:
      - "81:80"
    volumes:
      - "/data/wp:/app/code/wp/wp-content/uploads/"
      - "/data/kod:/app/code/kod/data/files/"
    links:
      - "web_php:php"
    restart: always

  web_php:
    image: "reg.yinjay.com:5000/php/php7.4-fpm:v1"
    volumes:
      - "/data/wp:/app/code/wp/wp-content/uploads/"
      - "/data/kod:/app/code/kod/data/files/"
    restart: always

将数据目录进行挂载,否则安装kodbox会出现错误。

image-20230422171156833


通过docker-compose启动容器组

[root@reg web]# docker-compose up -d

image-20230420214239014


在物理机上添加两条host解析

10.0.0.19 wp.yinjay.com
10.0.0.19 kodbox.yinjay.com

物理机浏览器访问wp.yinjay.com、kodbox.yinjay.com均没问题,同时访问wp.yinjay.com:81、kodbox.yinjay.com:81也是没问题!

image-20230420214653950

image-20230420214641215


执行安装

image-20230422171517675

image-20230422171541283

image-20230422171641975

image-20230422171710158

image-20230422171731375


网站初始化成功后,将php容器中的两个网站代码进行拉取到/docker/Dockerfile/nginx目录下。

[root@reg ~]# docker cp web_web_php_1:/app/code/kod /docker/Dockerfile/nginx/kod
[root@reg ~]# docker cp web_web_php_1:/app/code/wp /docker/Dockerfile/nginx/wp

备份网站源代码

[root@reg ~]# cd /docker/Dockerfile/nginx/
[root@reg nginx]# mv kodbox.tar.gz kodbox-init.tar.gz
[root@reg nginx]# mv wordpress.tar.gz wordpress-init.tar.gz

[root@reg web]# cd /docker/Dockerfile/php/
[root@reg php]# mv kodbox.tar.gz kodbox-init.tar.gz
[root@reg php]# mv wordpress.tar.gz wordpress-init.tar.gz

打包两个网站已经初始化好的代码

[root@reg php]# cd /docker/Dockerfile/nginx/kod
[root@reg kod]# tar zcf ../kodbox.tar.gz *
[root@reg kod]# cd ../wp/
[root@reg wp]# tar zcf ../wordpress.tar.gz *
[root@reg wp]# cd ..
[root@reg nginx]# rm -rf wp/
[root@reg nginx]# rm -rf kod/
#拷贝到php目录下,构建镜像也需要用已经初始化的代码
[root@reg nginx]# cp kodbox.tar.gz ../php/
[root@reg nginx]# cp wordpress.tar.gz ../php/
#卸除挂载
[root@reg nginx]# umount /data/kod
[root@reg nginx]# umount /data/wp

为什么要打包php容器里的代码呢?因为真正初始化的操作是在php容器内,相关配置已写入到文件中。在下一步将进行自动构建以该网站代码为基础构建镜像,实现分发到各主机上能够开箱即用运行起网站。


8. 自动构建镜像剧本准备

先创建一个roles规范的目录存放自动构建镜像推送到私有仓库的ansible剧本

[root@devops docker]# mkdir -p reg/{tasks,templates,files,handlers}

将reg主机上刚刚测试构建镜像成功的Dockerfile和相关代码、配套文件等拉取到devops主机上

[root@reg ~]# tree /docker/Dockerfile/
/docker/Dockerfile/
├── nginx
│   ├── Dockerfile
│   ├── kodbox-init.tar.gz
│   ├── kodbox.tar.gz
│   ├── kodbox.yinjay.com.conf
│   ├── nginx.conf
│   ├── wordpress-init.tar.gz
│   ├── wordpress.tar.gz
│   └── wp.yinjay.com.conf
└── php
    ├── Dockerfile
    ├── kodbox-init.tar.gz
    ├── kodbox.tar.gz
    ├── wordpress-init.tar.gz
    ├── wordpress.tar.gz
    └── www.conf


#拉取到devops主机上
[root@devops ~]# scp -r root@172.16.1.19:/docker/Dockerfile/* /ansible/docker/reg/files/

#查看拉取是否完整
[root@devops ~]# tree /ansible/docker/reg/files/
├── nginx
│   ├── Dockerfile
│   ├── kodbox-init.tar.gz
│   ├── kodbox.tar.gz
│   ├── kodbox.yinjay.com.conf
│   ├── nginx.conf
│   ├── wordpress-init.tar.gz
│   ├── wordpress.tar.gz
│   └── wp.yinjay.com.conf
└── php
    ├── Dockerfile
    ├── kodbox-init.tar.gz
    ├── kodbox.tar.gz
    ├── wordpress-init.tar.gz
    ├── wordpress.tar.gz
    └── www.conf

然后在/ansible/docker/reg/files目录下编写私有仓库的编排容器文件,实现自启动私有仓库,后续构建镜像进行自动推送到私有仓库。

[root@devops ~]# cat /ansible/docker/reg/files/reg-docker-compose.yml
version: "3.3"
services:
  registry_image:
    image: "registry:latest"
    ports:
      - "5000:5000"
    volumes:
      - "/data/reg-images:/var/lib/registry"
    restart: always

在reg/tasks目录下编写一个main.yml,具体内容如下:

[root@devops ~]# cat /ansible/docker/reg/tasks/main.yml
- name: 1. 创建存放Dockerfile及代码、配置文件的目录
  file:
    path: "{{ item }}"
    state: directory
  loop:
    - /docker/compose
    - /docker/Dockerfile

- name: 2. 分发registry compose容器编排文件
  copy:
    src: reg-docker-compose.yml
    dest: /docker/compose/reg-docker-compose.yml
    backup: yes

- name: 3. 运行容器编排文件创建私有仓库
  docker_compose:
    project_src: /docker/compose/
    files: reg-docker-compose.yml
    state: present

- name: 4. 发送Dockerfile及代码、配置文件
  copy:
    src: "{{ item }}"
    dest: "/docker/Dockerfile/"
  loop:
    - nginx
    - php

- name: 5. 构建web镜像及推送到私有仓库
  docker_image:
    build:
      path: "/docker/Dockerfile/nginx"
    name: "reg.yinjay.com:5000/web/nginx"
    tag: v2.0
    push: yes
    source: build


- name: 6. 构建php镜像及推送到私有仓库
  docker_image:
    build:
      path: "/docker/Dockerfile/php"
    name: "reg.yinjay.com:5000/php/php7.4-fpm"
    tag: v2.0
    push: yes
    source: build

停止reg主机上刚刚测试的私有仓库容器和web、php容器

[root@reg ~]# cd /docker/compose/01-registry/
[root@reg 01-registry]# docker-compose stop
Stopping 01registry_registry_image_1 ... done
[root@reg 01-registry]# cd /docker/compose/web/
[root@reg web]# docker-compose stop
Stopping web_web_ngx_a_1 ... done
Stopping web_web_ngx_b_1 ... done
Stopping web_web_php_1   ... done

[root@reg ~]# docker ps -a
CONTAINER ID   IMAGE                                   COMMAND                  CREATED        STATUS                     PORTS     NAMES
ada807d8c5b9   reg.yinjay.com:5000/web/nginx:1.20.2    "/docker-entrypoint.…"   37 hours ago   Exited (0) 3 minutes ago             web_web_ngx_a_1
e9e71bedfb1c   reg.yinjay.com:5000/web/nginx:1.20.2    "/docker-entrypoint.…"   37 hours ago   Exited (0) 3 minutes ago             web_web_ngx_b_1
52cc09c2fcb3   reg.yinjay.com:5000/php/php7.4-fpm:v1   "docker-php-entrypoi…"   37 hours ago   Exited (0) 3 minutes ago             web_web_php_1
299bd6f282b1   registry:latest                         "/entrypoint.sh /etc…"   2 days ago     Exited (2) 4 minutes ago             01registry_registry_image_1

将reg主机上的/docker目录暂且改名备份,便于剧本测试

[root@reg ~]# mv /docker/ /docker-bak

编写入口文件,跑起reg剧本,这里将之前的剧本暂且注释。

[root@devops docker]# cat top.yml
#- hosts: all
#  vars:
#    ansible_python_interpreter: /usr/bin/python2
#  roles:
#    - role: sys_basic


#- hosts: db
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: db


#- hosts: nfs
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: nfs

- hosts: reg
  vars:
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - role: reg
    
#执行剧本
[root@devops docker]# ansible-playbook top.yml

脚本执行完后查看reg主机docker镜像和容器情况,是没问题的

image-20230422202402168


通过查询私有仓库接口,也得知web、php镜像推送到私有仓库上了。

image-20230422111947519


9. 批量运行编排容器剧本准备

先创建一个roles规范的目录存放批量运行编排容器的ansible剧本

[root@devops docker]# mkdir -p web/{tasks,templates,files,handlers}

在web/files下编写web和php的容器编排文件

[root@devops docker]# cat web/files/web-docker-compose.yml
version: "3.3"
services:
  web_ngx_a:
    image: "reg.yinjay.com:5000/web/nginx:v2.0"
    ports:
      - "80:80"
    volumes:
      - "/data/wp:/app/code/wp/wp-content/uploads/"
      - "/data/kod:/app/code/kod/data/files/"
    links:
      - "web_php:php"
    restart: always

  web_ngx_b:
    image: "reg.yinjay.com:5000/web/nginx:v2.0"
    ports:
      - "81:80"
    volumes:
      - "/data/wp:/app/code/wp/wp-content/uploads/"
      - "/data/kod:/app/code/kod/data/files/"
    links:
      - "web_php:php"
    restart: always

  web_php:
    image: "reg.yinjay.com:5000/php/php7.4-fpm:v2.0"
    volumes:
      - "/data/wp:/app/code/wp/wp-content/uploads/"
      - "/data/kod:/app/code/kod/data/files/"
    restart: always

在web/tasks目录下编写一个main.yml,具体内容如下:

[root@devops docker]# cat web/tasks/main.yml
- name: 1. 安装nfs客户端
  yum:
    name: nfs-utils
    state: installed

- name: 2. 创建数据目录
  file:
    path: "{{ item }}"
    state: directory
  loop:
    - "/data/wp"
    - "/data/kod"

- name: 3. 挂载NFS共享存储到数据目录
  mount:
    src: "{{ item.s }}"
    path: "{{ item.d }}"
    fstype: nfs
    state: mounted
  loop:
    - { s: "172.16.1.18:/data/wordpress", d: "/data/wp" }
    - { s: "172.16.1.18:/data/kodbox", d: "/data/kod" }

- name: 4. 创建存放容器编排文件的目录
  file:
    path: /docker/compose
    state: directory

- name: 5. 分发容器编排文件
  copy:
    src: web-docker-compose.yml
    dest: /docker/compose

- name: 6. 通过容器编排docker-compose启动容器
  docker_compose:
    project_src: /docker/compose
    files: web-docker-compose.yml
    state: present

编写入口文件,跑起web剧本,这里将之前的剧本暂且注释。

[root@devops docker]# cat top.yml
#- hosts: all
#  vars:
#    ansible_python_interpreter: /usr/bin/python2
#  roles:
#    - role: sys_basic


#- hosts: db
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: db


#- hosts: nfs
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: nfs

#- hosts: reg
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: reg

- hosts: web
  vars:
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - role: web

#执行剧本
[root@devops docker]# ansible-playbook top.yml

通过ansible批量查询都已正常跑起容器

image-20230422114728590


11. web接入负载均衡剧本准备

先创建一个roles规范的目录存放web接入负载均衡的ansible剧本

[root@devops docker]#  mkdir -p lb/{tasks,templates,files,handlers}

在lb/files下编写两个负载均衡配置

[root@devops docker]# cat lb/files/wp.yinjay.com.conf
upstream wp_web_pools {
    server web05:80;
    server web06:80;
    server web07:80;
    server web08:80;
}

server {
    listen 80;
    server_name wp.yinjay.com;
    location / {
        proxy_pass http://wp_web_pools;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-Ip $remote_addr;
    }
}

[root@devops docker]# cat lb/files/kodbox.yinjay.com.conf
upstream kodbox_web_pools {
    server web05:81;
    server web06:81;
    server web07:81;
    server web08:81;
}

server {
    listen 80;
    server_name kodbox.yinjay.com;
    location / {
        proxy_pass http://kodbox_web_pools;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-Ip $remote_addr;
    }
}

在lb/handlers目录下编写一个main.yml,用于触发重新加载配置。具体内容如下:

[root@devops docker]# cat lb/handlers/main.yml
- name: reload_nginx
  systemd:
    name: nginx
    state: reloaded

在lb/tasks目录下编写一个main.yml,具体内容如下:

[root@devops docker]# cat lb/tasks/main.yml
- name: 1. 负载均衡主机安装nginx
  yum:
    name: nginx

- name: 2. 运行nginx并设置开机自启
  systemd:
    name: nginx
    enabled: yes
    state: started

- name: 3. 分发负载均衡配置文件并重新加载配置
  copy:
    src: "{{ item }}"
    dest: /etc/nginx/conf.d/
  loop:
    - wp.yinjay.com.conf
    - kodbox.yinjay.com.conf

  notify:
    - reload_nginx

编写入口文件,跑起lb剧本,这里将之前的剧本暂且注释。

[root@devops docker]# cat top.yml
#- hosts: all
#  vars:
#    ansible_python_interpreter: /usr/bin/python2
#  roles:
#    - role: sys_basic


#- hosts: db
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: db


#- hosts: nfs
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: nfs

#- hosts: reg
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: reg
#
#- hosts: web
#  vars:
#    ansible_python_interpreter: /usr/bin/python3
#  roles:
#    - role: web

- hosts: lb
  vars:
    ansible_python_interpreter: /usr/bin/python3
  roles:
    - role: lb

#执行剧本
[root@devops docker]# ansible-playbook top.yml

12. 综合测试

在物理机上添加这两条host记录

10.0.0.12 wp.yinjay.com
10.0.0.12 kodbox.yinjay.com

进行浏览器访问测试,上传文件等。然后将容器关闭启动或者从访问日志来看是否有进行负载。

posted @ 2023-09-16 15:44  YinJayChen  阅读(25)  评论(0编辑  收藏  举报