Docker进阶

1、Docker Compose

简介

Docker Compose 用来轻松地管理容器,定义运行多个容器。

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

image-20220611212002445

Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用单个命令,您可以从配置中创建并启动所有服务。

三步骤:

  1. 使用 Dockerfile 定义应用程序的环境,保证项目在任何地方可以运行
  2. 编写 docker-compose.yml 文件,定义组成应用程序的服务
  3. 使用 docker-compose up命令启动并运行整个应用程序

作用:批量容器编排

例子

version: "3.9" 
services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
      - logvolume01:/var/log
    links:
      - redis
  redis:
    image: redis
volumes:

安装

官方文档:https://docs.docker.com/compose/install/compose-plugin/#install-the-plugin-manually

image-20220611215920739

1、下载 DockerCompose

curl -SL https://github.com/docker/compose/releases/download/v2.6.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

# 建议使用国内的安装源,速度更快
curl -SL https://get.daocloud.io/docker/compose/releases/download/v2.6.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

image-20220611220342275

2、添加执行权限

chmod +x /usr/local/bin/docker-compose

3、测试是否安装成功

docker-compose -v

image-20220611221101348

体验

地址:https://docs.docker.com/compose/gettingstarted/

1、创建路径

cd /usr/local/docker
mkdir composetest
cd composetest

2、创建 python 应用app.py

import time

import redis
from flask import Flask

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

def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen { }  times.\n'.format(count)

3、创建 requirements.txt 文件

flask
redis

4、创建 Dockerfile 文件

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

5、编写 docker-compose.yml 文件

version: "3.9"
services:
  web:
    build: .
    ports:
      - "9000:5000"
  redis:
    image: "redis:alpine"

6、启动服务测试 docker-compose up

image-20220612001911578

Container composetest-redis-1 Recreated

Container composetest-web-1 Recreated

以上内容代表服务启动起来了,容器的默认命名为 [文件名]-[服务]-[数字],数字代表多个服务器,_数字 代表副本数量

image-20220612002439621

7、测试

curl localhost:9000

image-20220612001946180

8、查看网络规则

docker network ls

image-20220612002859554

自动生成一个网络,项目中的内容都在同个网络下,可通过服务名进行访问,例如 上述例子中 python 代码连接 redis 直接使用服务名称

cache = redis.Redis(host='redis', port=6379)

查看网络配置,可看到两个容器服务处于用一个网段中

docker network inspect composetest_default

image-20220612003335260

如果在同一个网络下,我们可以直接通过服务名进行连接

compose 服务命令

1、直接启动服务

docker-compose up

2、后台启动

docker-compose up -d

3、停止后台服务

# 在服务的 yml 文件所在的路径执行
docker-compose stop

4、停止前台服务直接 ctrl + c 即可

5、移除容器并删除使用的数据卷

docker-compose down --volumes

Docker 小结

1、Docker 镜像,run => 容器

2、Dockerfile 构建镜像(服务打包)

3、docker-compose 启动项目(编排、多个微服务/环境)

4、Docker 网络配置

yaml规则

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

image-20220612005324530

结构

# 3层结构
version: ''        # 1、版本
service:        # 2、服务
    [服务1]: 
        # 服务配置
        images:
        build:
        network:
        ...
    [服务2]:
        ...
    [服务3]:
        ...
# 3、其他配置 网络/卷、全局配置
volumes:
networks:
configs:

service 层可用命令可在官方文档中查看

image-20220612005847888

常用服务命令

1、指定路径和 dockerfile 文件

build:
  context: .
  dockerfile: Dockerfile-alternate

2、设置容器名称

container_name: my-web-container

3、设置依赖关系(启动顺序)depends_on

version: "3.9"
services:
  web:
    build: .
    depends_on:
      - db
      - redis
  redis:
    image: redis
  db:
    image: postgres

4、暴漏端口

expose:
  - "3000"
  - "8000"

总之,在 dockerfile 中使用的命令,在 compose 中同样可以有相应的命令可进行使用

开源项目测试

博客

官方文档:https://docs.docker.com/samples/wordpress/

1、创建新的文件夹

cd /usr/local/docker
mkdir my_wordpress
cd my_wordpress

2、编写 docker-compose.yml 文件

version: "3.9"

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
    volumes:
      - wordpress_data:/var/www/html
    ports:
      - "9000:80"
    restart: always
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: wordpress
      WORDPRESS_DB_NAME: wordpress
volumes:
  db_data: { } 
  wordpress_data: { } 

3、启动项目

docker-compose up

image-20220612011354764

4、访问测试

image-20220612011438383

5、进行基本的配置之后就可以登录到博客的后台了

image-20220612011623260

6、只要再次访问 9000 端口就可以进行博客的首页

image-20220612011719257

实战:计数器

1、创建 SpringBoot 项目,选择 web 和 redis

image-20220612135726715

2、创建 Controller 层

image-20220612141059493

3、修改配置文件 application.yml

spring:
  application:
    name: "compose_test"
  redis:
    host: redis        # 直接使用容器名作为 host,所以不能本地启动
server:
  port: 9000

4、创建 Dockerfile 文件

FROM java:8

COPY *.jar /app.jar

CMD ["--server.port=8080"]

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "/app.jar"]

5、创建 docker-compose.yml 文件

version: "3.9"
services:
  web:
    build: .
    depends_on:
      - redis
    ports:
      - "9000:8080"
  redis:
    image: "redis"

6、进行项目打包并将 jar、Dcokerfile、docker-compose.yml 上传到服务器上

7、一键启动

docker-compose up

image-20220612143623408

8、连接测试

curl localhost:9000/hello

image-20220612145921176

9、项目重新部署打包

docker-compose up --build

发现重启 compose 之后,还是直接启动之前的容器,会保存之前的数据

2、Docker Swarm

官方文档:https://docs.docker.com/engine/swarm/

工作模式

Docker Engine 1.12引入了swarm模式,允许您创建一个由一个或多个Docker引擎组成的集群,称为swarm。swarm由一个或多个节点组成。

有两种类型的节点:管理节点(managers)和工作节点(workers)

image-20220613212357174

manager 节点才能进行集群的操作

搭建集群

常用命令

docker swarm --help

image-20220613213054215

初始化集群

docker swarm init --help

image-20220613213313928

# 获取内网地址
ip addr

image-20220613213447363

# --advertise-addr 配置内网地址
docker swarm init --advertise-addr 172.16.188.148

# 执行完成之后可以得到一个命令,在其他服务器上执行即可加入这个节点
docker swarm join --token SWMTKN-1-05omhvuv44nfctrsm6jqsq0cokxs0uz734due8rr07xlsggcuw-cwx00zgvejflq0py5br086s4z 172.16.188.148:2377

# 并且可通过以下方式获取加入节点的命令
docker swarm join-token manager        # 加入成为管理员节点
docker swarm join-token worker        # 加入成为工作节点

image-20220613213645891

image-20220613213831821

查看节点列表

# 只有管理员节点才能执行
docker swarm node ls

image-20220613214950514

Raft 协议

保证大多数节点存活才可以用,集群至少大于3台

例如:当前有三个主机一个从机,挂了一台主机还能正常使用,而当挂了两台主机,则整个集群不能正常使用了

image-20220613221831826

测试

使用双主双重集群的情况下,将 leader 主机停止之后,另一台主机并不能使用

image-20220613215840966

重启 leader 主机之后,发现这个主机还存在集群中,但是 leader 节点成为另一台主机

image-20220613215941902

# 从机离开集群,发现状态会变成 Down
docker swarm leave

image-20220613220200383

# 从机以管理员身份再次加入节点,发现会新增一个节点记录
docker swarm join --token SWMTKN-1-5ys7gikiqane73bcyuotibkc20amvmiuq2ddnkakii24exws94-1t8ozj44ia7fey9c63o2rw3fo 119.23.209.205:2377

image-20220613220530169

集群,保证可用,至少需要3个主节点,大于1台管理节点存活

Raft协议:保证大多数节点存活,才可以使用,高可用

使用

弹性、扩缩容

创建服务

# 类似 run 一个镜像
docker service create -p 9000:80 --name my-nginx nginx

image-20220613235542084

查看服务信息

# 查看所有服务,replicas 显示副本数量
docker service ls

image-20220613235845929

# 查看服务信息
docker service ps my-nginx

image-20220613235638633

可以查看该服务运行在那个节点上,如果在节点服务器上进行 docker rm 删除容器,并不会对服务进行影响,还是会重新生成一个容器运行

服务运行的节点是随机分布的,也就是在第一台主机启动的服务,可能会运行在第二台从机上

更新服务

# 更新服务为 3 个副本,进行负载均衡,副本数量可以多于服务器数量
docker service update --replicas 3 my-nginx

# 只要再次更新为 1 个副本,则多余的副本容器会自动删除
docker service update --replicas 1 my-nginx

因为当前只配置了一台机器,所以 3 个副本都运行在一台机器上

image-20220614000251199

如果配置了集群,只要使用集群中的任意一台机器就可以进行访问该服务

一个服务可以有多个副本,从而实现动态扩缩容,高可用

扩缩容

# 跟 update 更新副本数差不多
docker service scale my-nginx=5

image-20220614001056268

概念总结

概念

swarm

集群的管理和编号,docker 可以初始化一个 swarm 集群,其他节点可以加入(管理节点、工作节点)

image-20220614001826952

命令 -> 管理 -> api -> 调度 -> 工作节点(创建Task容器维护)

node

就是一个 docker 节点,多个节点就组成了一个网络集群

service

服务,可以在管理节点或者工作节点来运行,用户访问

image-20220614001653698

task

容器内的命令,细节人物

image-20220614001621899

服务副本与全局服务

image-20220614002250093

调整 service 以什么方式运行 replicatedglobal

# 在创建服务的时候可以执行工作模式
docker service create --mode replicated --name mytom1 tomcat:7    # 默认
docker service create --mode global --name mytom2 tomcat:7

replicated 只有在工作节点才可以使用

global 所有节点可以使用

查看 Docker 网络

docker network ls

image-20220614003643944

ingress:是特殊的 overlay 网络,具有负载均衡的功能

# 查看网络配置
docker network inspect ingress

image-20220614003744749

Peers 中可以查看到所有节点的网络信息

3、Docker Stack

docker-compose 单机部署项目

Docker Stack 部署,集群部署

# 单机
docker-compose up -d wordpress.yml

# 集群
docker stack deploy wordpress.yml

image-20220614004433455

4、Docker Secret

安全、配置密码、证书

image-20220614004516065

5、Docker Config

image-20220614004646869