Bootstrap

容器自动化:docker-compose

ansible一键部署docker-compus+lnmp+lnmt项目

一、docker-compose

我们知道使用一个dockerfile模板文件可以定义一个单独的应用容器,如果需要定义多个容器就需要服务编排,服务编排有多种技术方案。

1.1、docker-compose简介

docker-compose项目是docker官方的开源项目,负责实现对docker容器集群的快速编排
docker-compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器(container)。docekr-compse运行目录下的所有文件(docker-compose.yml,extends文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中包含多个服务,每个服务中定义了容器运行的镜像、参数、以来。一个服务当中可包括多个容器实例,Docker-compose并没有解决负载均衡的问题,因此需要借助其他工具实现服务发现及负载均衡,比如consul
dokcer-compose的工程配置文件默认为docker-compose。yml,可通过环境变量compose_file或-f参数自定义配置文件,其定义了多个有依赖关系的服务及每个服务运行的容器
使用一个dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器。在工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如是要实现一个web项目,除了web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等
conpsoe允许用户通过一个单独的docker-compose.yml模板文件(yaml格式)来定义一组相关联的应用容器为一个项目(project)
docker-compose项目由python编写,调用docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持docker API,就可以在其上利用compose来进行编排管理

1.2、YAML 文件格式及编写注意事项

YAML是一种标记语言,它可以很直观的展示数据序列化格式,可读性高。类似于XML数据藐视语言,语法比XML简单的很多。YAML数据结构通过缩进来表示,连续的项目通过减号来表示,键值对用冒号分割,数组用中括号[]括起来,hash用花括号{}括起来。
使用YAML时需要注意下面事项

  • 大小写敏感
  • 通过缩进表示层级关系
  • 不支持制表符tab键缩进,只能使用空格缩进
  • 缩进的空格数目不重要,只要相同层级左对齐,通常开头缩进2个空格
  • 用#号注释
  • 符号字符后缩进1个空格,如冒号、逗号、横杠
  • 如果包含特殊字符用单引号硬起来会作为普通字符串处理,双引号:特殊字符作为本身想表示的意思

1.3、docker compose配置常用字段

字段 描述
build 指定dockerfile文件名,要制定dockerfile文件需要在build标签的子级标签中使用dockerfile标签指定
dockerfile 构建镜像上下文路径
context 可以是dockerfile的路径,或是指向git仓库的url地址
image 指定镜像
command 执行命令,覆盖容器启动后默认执行的命令
container name 指定容器名称,由于容器名称是唯一的,如果指定自定义名称,则无法scale
deploy 指定部署和运行服务相关配置,只能在swarm模式使用
environment 添加环境变量
networks 加入网络,引入顶级networks下条目
ports 暴露容器端口,与-p相同,但端口不能低于60
volumes 挂载一个宿主机目录或命令卷到容器,命令卷要在顶级volumes定义卷名称
volumes_from 从另一个服务或容器挂载卷,可选参数:ro和:rw
hsotname 容器主机名
sysctls 在容器内设置内核参数
links 连接到另一个容器,-服务名称[:服务别名]
restart 重启策略,默认no,always,no-failure,unless-stoped
  1. no,默认策略,在容器退出时不重启容器
  2. on-failure:在容器非正常退出时(退出装填非0),才会重启容器
  3. on-failure:3:在容器非正常退出时重启容器,最多重启3次
  4. always:在容器退出时总是重启容器
  5. unless-stoped:在容器退出时总是重启容器,但是不考虑在docker守护进程启动时就已经停止了的容器

1.4、docker compose常用命令

字段 描述
build 重新构建服务
ps 列出容器
up 创建和启动容器
exec 在容器里面执行命令
scale 制定一个服务容器启动数量
top 显示容器进程
logs 产看容器输出
down 删除容器、网络、数据卷和镜像

二、ansible部署环境

[root@localhost roles]# tree
.
├── docker
│   ├── files
│   ├── handlers
│   │   └── main.yaml
│   ├── tasks
│   │   └── main.yaml
│   ├── templates
│   │   └── daemon.json.j2
│   └── vars
│       └── main.yaml
├── docker-compose
│   ├── files
│   │   └── docker-compose-linux-x86_64
│   ├── handlers
│   ├── tasks
│   │   └── main.yaml
│   ├── templates
│   └── vars
├── docker-compose-lnmp
│   ├── files
│   │   └── compose_lnmp.tar.gz
│   ├── handlers
│   ├── tasks
│   │   └── main.yaml
│   ├── templates
│   └── vars
├── docker-compose-lnmt
│   ├── files
│   │   └── compose_lnmt.tar.gz
│   ├── handlers
│   ├── tasks
│   │   └── main.yaml
│   ├── templates
│   └── vars
├── jdk
│   ├── files
│   │   ├── auto-jdk.sh
│   │   └── jdk-8u60-linux-x64.tar.gz
│   ├── handlers
│   ├── tasks
│   │   └── main.yaml
│   ├── templates
│   └── vars
└── main.yaml

30 directories, 14 files

2.1主剧本main.yaml

[root@localhost roles]# cat main.yaml 
---
 - hosts: lnmp
   gather_facts: True
   roles:
   - docker
   - docker-compose 
   - docker-compose-lnmp
   tasks:
   - name: start docker-lnmp
     shell: docker-compose -f /root/docker-compose-lnmp/docker-compose.yaml up -d
 
 - host: lnmt
   gather_facts: True
   roles:
   - docker
   - docker-compose
   - jdk
   - docker-compose-lnmt
   task:
   - name: start docker-lnmt
     shell: docker-compose -f /root/docker-compose-lnmt/docker-compose.yaml up -d

2.2docker安装

[root@localhost docker]# cd tasks/
[root@localhost tasks]# 
[root@localhost tasks]# ls
main.yaml
[root@localhost tasks]# cat main.yaml 
- name: install required packages
  yum:
    name: 
      - yum-utils
      - device-mapper-persistent-data
      - lvm2
    state: present

- name: add docker repo to /etc/yum.repos.d
  shell: yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
  register: result              

- name: install docker-ce
  yum:
    name: docker-ce
    state: present

- name: create /etc/docker
  file:
    path: /etc/docker       
    state: directory

- name: start docker service
  systemd:                         
    name: docker
    state: started
    enabled: true

- name: provide docker-ce configfile
  template:
    src: daemon.json.j2                 
    dest: /etc/docker/daemon.json
  notify: restart docker              

[root@localhost handlers]# cat main.yaml 
- name: restart docker
  systemd:
    name: docker
    state: restarted        
    enabled: true

[root@localhost templates]# cat daemon.json.j2 
{
  "registry-mirrors": ["https://cbd49ltj.mirror.aliyuncs.com"]
}

2.3docker-compose安装

[root@localhost docker-compose]# tree
.
├── files
│   └── docker-compose-linux-x86_64
├── handlers
├── tasks
│   └── main.yaml
├── templates
└── vars

5 directories, 2 files

[root@localhost tasks]# cat main.yaml 
 - name: copy docker-compose-linux-x86_64 to /usr/local/bin
   copy: src=docker-compose-linux-x86_64 dest=/usr/local/bin/docker-compose-linux-x86_64

 - name: install docker-compose
   shell: cd /usr/local/bin && mv docker-compose-linux-x86_64 docker-compose && chmod +x docker-compose

2.4安装jdk

[root@localhost jdk]# tree
.
├── files
│   ├── auto-jdk.sh
│   └── jdk-8u60-linux-x64.tar.gz
├── handlers
├── tasks
│   └── main.yaml
├── templates
└── vars

5 directories, 3 files
[root@localhost jdk]# cat files/auto-jdk.sh 
#!/bin/bash                                                                                                                                        
# install tomcat

# 部署Java环境JDK

cd ~
tar xf jdk-8u60-linux-x64.tar.gz -C /usr/local/

[ $? -eq 0 ] && ln -s /usr/local/jdk1.8.0_60 /usr/local/jdk || exit 2

# 配置Java环境变量

sed -i.ori '$a export JAVA_HOME=/usr/local/jdk\nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH\nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar' /etc/bashrc

chown -R root.root /usr/local/jdk/

source /etc/bashrc

##########变量可能不刷新需要手动刷新一下环境变量#########

##############或者创建软连接来刷新变量###############

[root@localhost jdk]# cat tasks/main.yaml 
--- 
 - name: copy-jdk
   copy: src=jdk-8u60-linux-x64.tar.gz dest=/root/
 - name: sh auto-jdk.sh
   script: auto-jdk.sh
 - name: 刷新变量
   shell: source /etc/bashrc

2.5拷贝ldocker-compose-lnmp到目标服务器

[root@localhost docker-compose-lnmp]# tree
.
├── files
│   └── compose_lnmp.tar.gz
├── handlers
├── tasks
│   └── main.yaml
├── templates
└── vars

5 directories, 2 files
[root@localhost docker-compose-lnmp]# cat tasks/main.yaml 
---
 - name: copy-docker-compose-lnmp
   copy: src=compose_lnmp.tar.gz dest=/root/
 - name: 
   shell: tar xf compose_lnmp.tar.gz

2.6拷贝ldocker-compose-lnmt到目标服务器

[root@localhost docker-compose-lnmt]# tree
.
├── files
│   └── compose_lnmt.tar.gz
├── handlers
├── tasks
│   └── main.yaml
├── templates
└── vars

5 directories, 2 files

[root@localhost docker-compose-lnmt]# cat tasks/main.yaml 
---
 - name: copy-docker-compose-lnmpt
   copy: src=compose_lnmt.tar.gz dest=/root/

 - name: 
   shell: tar xf compose_lnmt.tar.gz

三丶docker-compos 部署lnmp

[root@docker ~]# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf #开启ipv4转发
[root@localhost compose_lnmp]# ls
docker-compose.yml  mysql  nginx  php  wwwroot

3.1docker-compose.yml(主剧本)

[root@localhost compose_lnmp]# cat docker-compose.yml 
version: '3'
services:
  nginx:
    container_name: nginx
    build:
      context: ./nginx
      dockerfile: Dockerfile
    ports:
      - 80:80
      - 443:443
    networks:
      lnmp:
        ipv4_address: 172.20.0.10
    volumes:
      - ./wwwroot:/usr/local/nginx/html
  mysql:
    container_name: mysql
    image: mysql:5.6
    ports: 
      - 3306:3306
    networks:
      lnmp:
        ipv4_address: 172.20.0.20
    volumes:
      - ./mysql/db-data:/usr/local/mysql
    command: --character-set-server=utf8
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: wordpress
      MYSQL_USER: user
      MYSQL_PASSWORD: user123
  php:
    container_name: php
    build:
      context: ./php
      dockerfile: Dockerfile
    ports:
      - 9000:9000                
    networks:
      lnmp:
        ipv4_address: 172.20.0.30
    volumes:
      - ./wwwroot:/usr/local/nginx/html
    depends_on:
      - nginx
      - mysql
networks:
  lnmp: 
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

代码解析

  • version: ‘3’:指定了Docker Compose文件的版本。
  • services: 开始定义各个服务。
    • nginx: 定义了一个名为nginx的服务。
      • container_name: 指定容器的名称为nginx。
      • build: 指定构建该服务容器时的上下文路径和Dockerfile文件。
      • ports: 将主机的80端口和443端口映射到容器的对应端口。
      • networks: 指定该服务连接到的网络及其IPv4地址。
      • volumes: 将主机的./wwwroot目录挂载到容器的/

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;