七、Docker Compose

1.简介

使用一个 Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
使用Compose基本上是一个三步过程:
1.用一个定义你的应用程序的环境,Dockerfile这样它就可以在任何地方再现。
2.定义组成您的应用程序的服务,docker-compose.yml 以便它们可以在隔离的环境中一起运行。
3.运行docker-compose up和撰写启动并运行您的整个应用程序。

2.安装

在Linux上安装直接从官方GitHub Release处下载编译好的二进制文件。

[root@dockertest ~]# curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
[root@dockertest ~]# chmod +x /usr/local/bin/docker-compose
[root@dockertest ~]# docker-compose --version
docker-compose version 1.21.2, build a133471
#需要卸载时直接删除二进制文件即可

3.入门使用

①.新建文件夹并创建一个app.py文件

[root@dockertest ~]# mkdir test
[root@dockertest ~]# cd test/
[root@dockertest test]# cat app.py 
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    count = redis.incr('hits')
    return 'Hello World! 该页面已被访问 {} 次。\n'.format(count)
if __name__ == "__main__":
    app.run(host="0.0.0.0", debug=True)

②.创建一个Dockerfile文件

[root@dockertest test]# cat Dockerfile 
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]

③.创建一个docker-compose.yml文件

[root@dockertest test]# cat docker-compose.yml 
version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"
#这个compose文件定义了两个服务,web和redis。
#web服务使用当前目录中的Dockerfile构建镜像,并映射5000端口。
#redis服务使用公共库中的redis镜像

④.运行compose项目

[root@dockertest test]# docker-compose up

⑥.访问
Docker学习与实践 Ⅲ

刷新页面可以看见数字增加
切换终端查看运行的容器

[root@dockertest ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
7846aed7560e        redis:alpine        "docker-entrypoint.s…"   3 minutes ago       Up 2 minutes        6379/tcp                 test_redis_1
f7c8c051d057        test_web            "python app.py"          3 minutes ago       Up 2 minutes        0.0.0.0:5000->5000/tcp   test_web_1

⑦.停止

[root@dockertest test]# docker-compose down
Stopping test_redis_1 ... done
Stopping test_web_1   ... done
Removing test_redis_1 ... done
Removing test_web_1   ... done
Removing network test_default

4.实例:WordPress

①.创建一个文件夹并新建docker-compose.yml 文件

[root@dockertest ~]# mkdir wordpress
[root@dockertest ~]# cd wordpress/
[root@dockertest wordpress]# cat docker-compose.yml 
version: '3'
services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   wordpress:
     depends_on:
       - db
     image: wordpress:latest
     ports:
       - "8000:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
volumes:
    db_data:

②.构建和运行

[root@dockertest wordpress]# docker-compose up -d
Creating network "wordpress_default" with the default driver
Creating volume "wordpress_db_data" with default driver
Pulling db (mysql:5.7)...
5.7: Pulling from library/mysql
f2aa67a397c4: Pull complete
1accf44cb7e0: Pull complete
2d830ea9fa68: Pull complete
740584693b89: Pull complete
4d620357ec48: Pull complete
ac3b7158d73d: Pull complete
a48d784ee503: Pull complete
bf1194add2f3: Pull complete
0e5c74178a02: Pull complete
e9201d309436: Pull complete
bf1ac4524e8e: Pull complete
Digest: sha256:f030e84582d939d313fe2ef469b5c65ffd0f7dff3b4b98e6ec9ae2dccd83dcdf
Status: Downloaded newer image for mysql:5.7
Pulling wordpress (wordpress:latest)...
latest: Pulling from library/wordpress
f2aa67a397c4: Already exists
4c3122805fd6: Pull complete
98ce407ee18a: Pull complete
8a56b8f1ca72: Pull complete
3eb04e3939f2: Pull complete
f5ecc66c0a5f: Pull complete
30ebdb4a78e1: Pull complete
9e9c0e2ba7f1: Pull complete
da976026223e: Pull complete
c97e6cef8eb4: Pull complete
d7d37db38fe6: Pull complete
4fbe9ea008c2: Pull complete
b5247a62a2b6: Pull complete
a430e65efb58: Pull complete
9afdee095b5b: Pull complete
12d5f9a19746: Pull complete
f785e67a07ef: Pull complete
5663bbfd9606: Pull complete
ff13a5b7e05e: Pull complete
710c4b456373: Pull complete
Digest: sha256:b0460dba11737144b232a7794403d4052982f2332caeea82f618fc98d0547387
Status: Downloaded newer image for wordpress:latest
Creating wordpress_db_1 ... done
Creating wordpress_wordpress_1 ... done

③.访问

Docker学习与实践 Ⅲ


八、Docker Machine

1.安装

[root@dockertest ~]# curl -L https://github.com/docker/machine/releases/download/v0.15.0/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine 
[root@dockertest ~]# chmod +x /tmp/docker-machine 
[root@dockertest ~]# cp /tmp/docker-machine /usr/local/bin/docker-machine
[root@dockertest ~]# docker-machine -v
docker-machine version 0.15.0, build b48dc28d

2.在远程主机上安装Docker

①远程环境准备

a.新建一台远程主机并完成基础配置
b.配置到远程主机ssh免密登陆

②执行安装

[root@dockertest ~]# docker-machine create -d generic \
> --generic-ip-address=192.168.10.128 \
> --generic-ssh-user=root \
> --generic-ssh-key ~/.ssh/id_rsa \
> machine1
Running pre-create checks...
Creating machine...
(machine1) Importing SSH key...
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with centos...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env machine1
[root@dockertest ~]# docker-machine ls
NAME       ACTIVE   DRIVER    STATE     URL                                      SWARM   DOCKER        ERRORS
machine1   -              generic      Running   tcp://192.168.10.128:2376                   v18.05.0-ce   

③查看machine1的信息

[root@dockertest ~]# docker-machine env machine1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.10.128:2376"
export DOCKER_CERT_PATH="/root/.docker/machine/machines/machine1"
export DOCKER_MACHINE_NAME="machine1"
# Run this command to configure your shell: 
# eval $(docker-machine env machine1)

这个命令让本机的 Docker 客户端可以与远程的 Docker 服务器通信。
$ eval $( docker-machine env krdevdb)

④管理远程的 Docker

[root@dockertest ~]# eval $(docker-machine env machine1) #使用
[root@dockertest ~]# docker version 
Client:
 Version:   18.02.0-ce
 API version:   1.36
 Go version:    go1.9.3
 Git commit:    fc4de44
 Built: Wed Feb  7 21:14:12 2018
 OS/Arch:   linux/amd64
 Experimental:  false
 Orchestrator:  swarm

Server:
 Engine:
  Version:  18.05.0-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   f150324
  Built:    Wed May  9 22:18:36 2018
  OS/Arch:  linux/amd64
  Experimental: false

九、Docker Swarm

1.基本概念

节点:节点分为管理 ( manager ) 节点和工作 ( worker ) 节点。
a.管理节点用于 Swarm 集群的管理,一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader。
b.工作节点是任务执行节点,管理节点将服务 ( service ) 下发至工作节点执行。管理节点默认也作为工作节点。


服务和任务
a.任务 ( Task )是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。
b.服务 ( Services ) 是指一组任务的集合。服务有两种模式:
replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
global services 每个工作节点上运行一个任务
这两种模式通过 docker service create 的 --mode 参数指定。

2.创建swarm集群

①初始化集群

[root@dockertest ~]# docker swarm init

②获取其他worker要加入swarm集群时的token,并添加worker节点

[root@dockertest ~]# docker swarm join-token worker 
To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-67pzwc4zd5j7ld6aj998g6wm4r7rti8yrgbdbkminni6db40m5-9dzc38iwznkoun7j9pffosl5r 192.168.10.131:2377
[root@dockertest ~]# docker-machine ssh machine1
Last login: Thu Jun 28 03:17:25 2018 from 192.168.10.131
[root@machine1 ~]# docker swarm join --token SWMTKN-1-67pzwc4zd5j7ld6aj998g6wm4r7rti8yrgbdbkminni6db40m5-9dzc38iwznkoun7j9pffosl5r 192.168.10.131:2377This node joined a swarm as a worker.
[root@machine1 ~]# exit
logout
exit status 1
[root@dockertest ~]# docker node ls
ID                                                  HOSTNAME            STATUS         AVAILABILITY       MANAGER     STATUS
uapifqcukdehpmxxxamoq0i4a *   dockertest            Ready            Active                    Leader
8q9knaeijcb4k4ouznkksnh17       machine1              Ready            Active          

③获取其他manager要加入swarm集群时的token,并添加manager节点

[root@dockertest ~]# docker swarm join-token manager 
To add a manager to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-67pzwc4zd5j7ld6aj998g6wm4r7rti8yrgbdbkminni6db40m5-a1aecwco4cqt48naq68d9e9yp 192.168.10.131:2377

[root@dockertest ~]# docker-machine ssh machine2
Last login: Thu Jun 28 03:18:14 2018 from 192.168.10.131
[root@machine2 ~]# docker swarm join --token SWMTKN-1-67pzwc4zd5j7ld6aj998g6wm4r7rti8yrgbdbkminni6db40m5-a1aecwco4cqt48naq68d9e9yp 192.168.10.131:2377This node joined a swarm as a manager.
[root@machine2 ~]# exit
logout
[root@dockertest ~]# docker node ls
ID                                                 HOSTNAME            STATUS              AVAILABILITY       MANAGER    STATUS
uapifqcukdehpmxxxamoq0i4a *   dockertest          Ready                  Active                    Leader
8q9knaeijcb4k4ouznkksnh17       machine1            Ready                  Active              
uequcd364emrwk26dchkhuj5y     machine2            Ready                  Active                   Reachable

④worker节点移除

[root@dockertest ~]# docker node rm machine1
Error response from daemon: rpc error: code = FailedPrecondition desc = node 8q9knaeijcb4k4ouznkksnh17 is not down and can't be removed
[root@dockertest ~]# docker node rm --force machine1
machine1
[root@dockertest ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
uapifqcukdehpmxxxamoq0i4a *   dockertest          Ready               Active              Leader
uequcd364emrwk26dchkhuj5y     machine2            Ready               Active              Reachable

⑤manager节点移除

[root@dockertest ~]# docker node  demote machine2 
Manager machine2 demoted in the swarm.
[root@dockertest ~]# docker node rm --force machine2
machine2
[root@dockertest ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
uapifqcukdehpmxxxamoq0i4a *   dockertest          Ready               Active              Leader

3.部署服务

①新建服务

[root@dockertest ~]# docker service create --replicas 3 -p 80:80 --name nginx nginx
image nginx:latest could not be accessed on a registry to record
its digest. Each node will access nginx:latest independently,
possibly leading to different nodes running different
versions of the image.

592966n2mvgnzr1ti0v5p915h
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3: running   [==================================================>] 
3/3: running   [==================================================>] 
verify: Service converged 

②查看服务

[root@dockertest ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
592966n2mvgn        nginx               replicated          3/3                 nginx:latest        *:80->80/tcp
[root@dockertest ~]# docker service ps nginx 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
20s9dpyppxjc        nginx.1             nginx:latest        dockertest          Running             Running 3 minutes ago                       
fhnpdagl7eat        nginx.2             nginx:latest        machine1            Running             Running 7 minutes ago                       
v6tl3x9p6rt2        nginx.3             nginx:latest        machine2            Running             Running 8 minutes ago    

③移除服务

[root@dockertest ~]# docker service rm nginx 

④修改实例数

[root@dockertest ~]# docker service scale nginx=2
nginx scaled to 2
overall progress: 2 out of 2 tasks 
1/2: running   [==================================================>] 
2/2: running   [==================================================>] 
verify: Service converged 
[root@dockertest ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
p3mnb7lzvz0r        nginx               replicated          2/2                 nginx:latest        *:80->80/tcp

4.使用compose部署WordPress

①编辑docker-compose.yml

[root@dockertest wordpress]# cat docker-compose.yml
version: "3"

services:
  wordpress:
    image: wordpress
    ports:
      - 80:80
    networks:
      - overlay
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
    deploy:
      mode: replicated
      replicas: 3

  db:
    image: mysql
    networks:
       - overlay
    volumes:
      - db-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: somewordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    deploy:
      placement:
        constraints: [node.role == manager]

  visualizer:
    image: dockersamples/visualizer:stable
    ports:
      - "8080:8080"
    stop_grace_period: 1m30s
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      placement:
        constraints: [node.role == manager]

volumes:
  db-data:
networks:
  overlay:

②部署服务

[root@dockertest wordpress]# docker stack deploy -c docker-compose.yml wordpress
Creating network wordpress_overlay
Creating network wordpress_default
Creating service wordpress_wordpress
Creating service wordpress_db
Creating service wordpress_visualize

③查看运行情况

[root@dockertest wordpress]# docker stack ls
NAME                SERVICES
wordpress           3

在输入任一节点IP:8080查看运行状态
Docker学习与实践 Ⅲ

④移除服务

[root@dockertest wordpress]# docker stack down wordpress
Removing service wordpress_db
Removing service wordpress_visualizer
Removing service wordpress_wordpress
Removing network wordpress_default
Removing network wordpress_overlay
#该命令不会移除服务所使用的数据卷

#学习文档地址:https://github.com/yeasy/docker_practice/blob/master/SUMMARY.md