Docker-编排

一、Docker compose

用于单机容器编排,运行多个服务

官方文档:https://docs.docker.com/compose/compose-file/

1.安装

方法1:

下载地址:https://github.com/docker/compose/releases

curl -L https://github.com/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

方法2:

yum install python-devel python2-pip -y
pip install docker-compose -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

卸载

rm /usr/local/bin/docker-compose

2.基本语法

官方文档:

https://docs.docker.com/compose/

https://docs.docker.com/compose/compose-file/

  • build

指定镜像构建时的dockerfile目录,格式一般为绝对路径目录或相对路径目录(dockerfile需要命名为Dockerfile)

build: /path/to/build/dir
#或者
build: ./dir
  • image

指定要启动容器的镜像

如果镜像不存在,compose尝试拉它.

image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd
  • environment

设置镜像变量,保存变量信息到镜像里面

environment:
  RACK_ENV: development
  SHOW: 'true'
#或
environment:
  - RACK_ENV=development
  - SHOW=true
  • expose

这个标签与Dockerfile中的 EXPOSE 指令一样,

用于指定暴露的端口,但只将端口暴露给连接的服务,而不暴露给主机.

expose:
 - "3000"
 - "8000"
  • ports

映射端口,可以使用 HOST:CONTAINER 的方式指定端口,也可以指定容器端口(选择临时主机端口),宿主机会随机映射端口

ports:
 - "3000"
 - "3000-3005"
 - "8000:8000"
 - "9090-9091:8080-8081"
 - "49100:22"
 - "127.0.0.1:8001:8001"
 - "127.0.0.1:5000-5010:5000-5010"
 - "6060:6060/udp"
  • restart

指定Docker容器的重启策略

默认值为 no ,即在任何情况下都不会重新启动容器

当值为 always 时,容器退出时总是重新启动;

当值为 on-failure时,当出现 on-failure 报错(非正常退出,退出状态非0),才会重启容器

当值为unless-stopped时, 在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

restart: "no"
restart: always
restart: on-failure
restart: on-failure:3
restart: unless-stopped
  • volume

数据卷挂载,可以直接使用 HOST:CONTAINER 这样的格式

或者使用 HOST:CONTAINER:ro 这样的格式,ro代表数据卷是只读的

volumes:
  # 只是指定一个路径,Docker 会自动在创建一个数据卷(这个路径是容器内部的)。
  - /var/lib/mysql

  # 使用绝对路径挂载数据卷
  - /opt/data:/var/lib/mysql

  # 以Compose配置文件为为数据卷挂载到容器。
  - ./cache:/tmp/cache

  # 使用用户的相对路径(~/ 表示的目录是 /home/<用户目录>/ 或者 /root/)。
  - ~/configs:/etc/configs/:ro

  # 已经存在的命名的数据卷。
  - datavolume:/var/lib/mysql
  • depends_on

此标签解决了容器的依赖、启动先后的问题

version: '3'
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: mysql
  • links

链接到其它服务的中的容器, 与link连接一样效果,会连接到其它服务中的容器

web:
  links:
   - db
   - db:database
   - redis

3.使用

注意:需要在工作目录中执行

#启动
docker-compose up -d 
#关闭
docker-compose stop
#删除
docker-compose rm
#查看运行的服务
docker-compose ps
#查看服务运行的日志
docker-compose logs -f 
#查看服务的依赖的镜像
docker-compose images 

4.案例

(1)wordpress

# vim docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    volumes:
      - "./data:/var/lib/mysql"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    expose:
      - "3306"

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    links:
      - db
    ports:
      - "8010:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_PASSWORD: wordpress

启动容器

 docker-compose up -d

关闭

docker-compose stop
docker-compose rm

(2)haproxy

创建配置文件

#vim haproxy.cfg
global
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice

defaults
  log global
  mode http
  option httplog
  option dontlognull
  timeout connect 5000ms
  timeout client 50000ms
  timeout server 50000ms
  stats uri /status

frontend balancer
    bind 0.0.0.0:80
    mode http
    default_backend web_backends

backend web_backends
    mode http
    option forwardfor
    balance roundrobin
    server web1 web1:80 check
    server web2 web2:80 check
    server web3 web3:80 check
    option httpchk GET /
    http-check expect status 200
# vim docker-compose.yml
web1:
  image: httpd:latest
  volumes:
    - ./httpd1:/usr/local/apache2/htdocs/
  expose:
    - 80

web2:
  image: httpd:latest
  volumes:
    - ./httpd2:/usr/local/apache2/htdocs/
  expose:
    - 80

web3:
  image: httpd:latest
  volumes:
    - ./httpd3:/usr/local/apache2/htdocs/
  expose:
    - 80

haproxy:
  image: haproxy:latest
  volumes:
    - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
  links:
    - web1
    - web2
    - web3
  ports:
    - "80:80"
  expose:
    - "80"

启动应用

docker-compose up -d

测试

echo "web1" > httpd1/index.html
echo "web2" > httpd2/index.html
echo "web3" > httpd3/index.html

访问

查看是否实现负载均衡:http://10.1.1.31

查看状态:http://10.1.1.31/status

二、Docker swarm

Docker Swarm是Docker官方提供的一款集群管理工具,容器编排

Swarm和Kubernetes比较类似,但是更加轻,具有的功能也较kubernetes更少一些

1.相关概念

节点 (node):

  • 管理节点(manager node) 负责管理集群中的节点并向工作节点分配任务
  • 工作节点(worker node) 接收管理节点分配的任务,运行任务

服务(services): 在工作节点运行的,由多个任务共同组成

任务(task): 运行在工作节点上容器或容器中包含应用,是集群中调度最小管理单元

路由网格(route mesh)

2.集群构建

机器准备

Ip主机名描述
10.1.1.21vm1管理节点
10.1.1.22vm2工作节点
10.1.1.23vm3工作节点
10.1.1.24vm4harbor仓库

环境准备,添加harbor仓库,添加阿里镜像加速

vim /etc/docker/daemon.json
{
        "registry-mirrors": ["https://42h8kzrh.mirror.aliyuncs.com"],
        "insecure-registries": ["10.1.1.24"]
}

添加主机名绑定

#vim /etc/hosts
10.1.1.21 m1.tigeru.cn m1
10.1.1.22 m2.tigeru.cn m2
10.1.1.23 m3.tigeru.cn m3
10.1.1.24 m4.tigeru.cn m4

同步时间

nptdaet ntp1.aliyun.com

manager节点初始化swarm集群

[root@m1 ~]# docker swarm init --listen-addr 10.1.1.21:2377
Swarm initialized: current node (v71hlv4h4emqhiqzy571brl3a) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-08r3o37medwqspa5y9h8x75zywdz4jvmfb9um7jt7ww6lts97w-2oxerybv2cfqe5nvzdy9o89vc 10.1.1.21:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

添加worker节点

[root@m2 ~]# docker swarm join --token SWMTKN-1-08r3o37medwqspa5y9h8x75zywdz4jvmfb9um7jt7ww6lts97w-2oxerybv2cfqe5nvzdy9o89vc 10.1.1.21:2377
This node joined a swarm as a worker.

[root@m3 ~]# docker swarm join --token SWMTKN-1-08r3o37medwqspa5y9h8x75zywdz4jvmfb9um7jt7ww6lts97w-2oxerybv2cfqe5nvzdy9o89vc 10.1.1.21:2377
This node joined a swarm as a worker.

验证

docker node ls

节点删除

#第一步:node节点先leave
docker swarm leave
#第二步:删除
docker swarm rm nodeid

3.服务

#1.发布服务
docker service create --replicas 2 --publish 80:80 --name nginx_service 10.1.1.24/library/nginx:v1

#2.查看服务
docker service ls
docker node ps --filter "desired-state=running" $(docker node ls -q)
docker service ps nginx_service

#3.更新版本
docker service update --image 10.1.1.24/library/nginx:v2 nginx_service

#4.更新服务,滚动间隔更新
docker service update --replicas 4 --image 10.1.1.24/library/nginx:v1  --update-parallelism 2 --update-delay 10s  nginx_service
# --update-parallelism :表示同时更新的容器数量
# --update-delay :表示更新的时间间隔

#5.裁剪服务
docker service scale nginx_service=1
#6.扩展服务
docker service scale nginx_service=5

#7.删除服务
docker service rm nginx_service

4.本地存储

创建存储目录(m1,m2,m3)

mkdir /data/nginxdata -p

发布服务

docker service create  --replicas 3 --mount "type=bind,source=/data/nginxdata,target=/usr/share/nginx/html" --publish 80:80 --name nginx_service 10.1.1.24/library/nginx:v1

5.网络存储卷

准备nfs服务器

#安装软件
yum install nfs-utils rpcbind -y
#创建共享目录
mkdir /opt/dockervolume 
#设置共享目录
vim /etc/exports
/opt/dockervolume       *(rw,no_root_squash,sync)
#启动服务
systemctl restart rpcbind nfs-server
systemctl enble rpcbind nfs-server

每台机器上创建存储卷(m1,m2,m3)

#安装 nfs
yum install nfs-utils

#创建本地卷
docker volume create --driver local --opt type=nfs --opt o=addr=10.1.1.24,rw --opt device=:/opt/dockervolume nginx_volume
#查看
docker volume ls 
docker volume inspect nginx_volume

发布服务

docker service create --replicas 3 --publish 80:80 --mount "type=volume,source=nginx_volume,target=/usr/share/nginx/html" --name nginx_service 10.1.1.24/library/nginx:v1

验证

df -h |tail -1

nfs服务器/opt/dockervolume目录修改文件index.html

6.服务互联与服务发现

在自建的overlay网络内,通过服务发现可以实现服务之间通过服务名(不用知道对方的IP)互联,而且不会受服务内副本个数和容器内IP变化等的影响

查看网络

docker network ls

自建一个overlay网络来实现服务发现

docker network create --driver overlay --subnet 192.168.100.0/24 self-network
# self-network  为自定义的网络名称
# --driver overlay指定为overlay类型
# --subnet 分配网段

测试

#启动服务
docker service create --replicas 3 --network self-network --publish 80:80 --name nginx_service 10.1.1.24/library/nginx:v1
#启动busybox
docker service create --name test --network self-network  busybox sleep 100000

通过ping服务名,可以发现ping出来的IP并不是启动的任何一个nginx容器的IP

docker exec test.1.kri3oj4myegcq61hug9boaq79 ping -c 2 nginx_service

7.Docker Stack

Docker集群容器编排工具

Docker-compose只能在一台主机发布

(1)基本操作

#部署新的堆栈
docker stack deploy -c stack1.yml stack1
#列出现有堆栈
docker stack ls
#列出堆栈中的任务
docker stack ps
#删除堆栈
docker stack rm stackName
#列出堆栈中的服务
docker stack services

(2)案例:wordpress

第一步:创建yml文件

# vim stack_wordpress.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: wordpress
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

  wordpress:
    depends_on:
      - db
    image: wordpress:latest
    ports:
      - "8010:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_PASSWORD: wordpress
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

第二步:发布

docker stack deploy -c stack_wordpress.yml stackWordpress

(3)案例:Nginx+visualizer+portainer

3个Nginx容器

1个visualizer

1个portainer

第一步:创建yml文件

#vim stack2.yml 
version: "3"
services:
  nginx:
    image: 10.1.1.24/library/nginx:v1
    ports:
      - 80:80
    deploy:
      mode: replicated
      replicas: 3

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

  portainer:
    image: portainer/portainer
    ports:
      - "9000:9000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

第二步:发布

docker stack deploy -c stack2.yml stack2

(4)案例:nginx+haproxy+nfs

第一步:搭建nfs服务

第二步:配置haproxy.cfg配置文件

#vim haproxy.cfg
global
  log 127.0.0.1 local0
  log 127.0.0.1 local1 notice

defaults
  log global
  mode http
  option httplog
  option dontlognull
  timeout connect 5000ms
  timeout client 50000ms
  timeout server 50000ms
  stats uri /status

frontend balancer
    bind 0.0.0.0:80
    mode http
    default_backend web_backends

backend web_backends
    mode http
    option forwardfor
    balance roundrobin
    server web1 nginx1:80 check
    server web2 nginx2:80 check
    server web3 nginx3:80 check
    option httpchk GET /
    http-check expect status 200

第三步:

创建编排文件

#vim stack3.yml
version: "3"
services:
  nginx1:
    image: 192.168.122.18/library/nginx:v1
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
    - "nginx_volume:/usr/share/nginx/html"

  nginx2:
    image: 192.168.122.18/library/nginx:v1
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
    - "nginx_volume:/usr/share/nginx/html"

  nginx3:
    image: 192.168.122.18/library/nginx:v1
    deploy:
      mode: replicated
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
    - "nginx_volume:/usr/share/nginx/html"

  haproxy:
    image: haproxy:latest
    volumes:
      - ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
    ports:
      - "80:80"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]

volumes:
  nginx_volume:
    driver: local
    driver_opts:
      type: "nfs"
      o: "addr=192.168.122.1,rw"
      device: ":/opt/dockervolume"

第四步:

启动

docker stack deploy -c stack3.yml stack3

测试

访问: http://10.1.1.21/

查看Haproxy状态:http://10.1.1.21/status

Last modification:June 24th, 2020 at 06:57 pm