Docker进阶
1、Docker Compose
简介
Docker Compose 用来轻松地管理容器,定义运行多个容器。
官方文档:https://docs.docker.com/compose/

Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。使用Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用单个命令,您可以从配置中创建并启动所有服务。
三步骤:
- 使用 Dockerfile 定义应用程序的环境,保证项目在任何地方可以运行
- 编写
docker-compose.yml文件,定义组成应用程序的服务 - 使用
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

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

2、添加执行权限
chmod +x /usr/local/bin/docker-compose
3、测试是否安装成功
docker-compose -v

体验
地址: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

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

7、测试
curl localhost:9000

8、查看网络规则
docker network ls

自动生成一个网络,项目中的内容都在同个网络下,可通过服务名进行访问,例如 上述例子中 python 代码连接 redis 直接使用服务名称
cache = redis.Redis(host='redis', port=6379)
查看网络配置,可看到两个容器服务处于用一个网段中
docker network inspect composetest_default

如果在同一个网络下,我们可以直接通过服务名进行连接
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/

结构
# 3层结构
version: '' # 1、版本
service: # 2、服务
[服务1]:
# 服务配置
images:
build:
network:
...
[服务2]:
...
[服务3]:
...
# 3、其他配置 网络/卷、全局配置
volumes:
networks:
configs:
service 层可用命令可在官方文档中查看

常用服务命令
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

4、访问测试

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

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

实战:计数器
1、创建 SpringBoot 项目,选择 web 和 redis

2、创建 Controller 层

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

8、连接测试
curl localhost:9000/hello

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)

manager 节点才能进行集群的操作
搭建集群
常用命令
docker swarm --help

初始化集群
docker swarm init --help

# 获取内网地址
ip addr

# --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 # 加入成为工作节点


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

Raft 协议
保证大多数节点存活才可以用,集群至少大于3台
例如:当前有三个主机一个从机,挂了一台主机还能正常使用,而当挂了两台主机,则整个集群不能正常使用了

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

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

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

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

集群,保证可用,至少需要3个主节点,大于1台管理节点存活
Raft协议:保证大多数节点存活,才可以使用,高可用
使用
弹性、扩缩容
创建服务
# 类似 run 一个镜像
docker service create -p 9000:80 --name my-nginx nginx

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

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

可以查看该服务运行在那个节点上,如果在节点服务器上进行 docker rm 删除容器,并不会对服务进行影响,还是会重新生成一个容器运行
服务运行的节点是随机分布的,也就是在第一台主机启动的服务,可能会运行在第二台从机上
更新服务
# 更新服务为 3 个副本,进行负载均衡,副本数量可以多于服务器数量
docker service update --replicas 3 my-nginx
# 只要再次更新为 1 个副本,则多余的副本容器会自动删除
docker service update --replicas 1 my-nginx
因为当前只配置了一台机器,所以 3 个副本都运行在一台机器上

如果配置了集群,只要使用集群中的任意一台机器就可以进行访问该服务
一个服务可以有多个副本,从而实现动态扩缩容,高可用
扩缩容
# 跟 update 更新副本数差不多
docker service scale my-nginx=5

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

命令 -> 管理 -> api -> 调度 -> 工作节点(创建Task容器维护)
node
就是一个 docker 节点,多个节点就组成了一个网络集群
service
服务,可以在管理节点或者工作节点来运行,用户访问

task
容器内的命令,细节人物

服务副本与全局服务

调整 service 以什么方式运行 replicated 和 global
# 在创建服务的时候可以执行工作模式
docker service create --mode replicated --name mytom1 tomcat:7 # 默认
docker service create --mode global --name mytom2 tomcat:7
replicated 只有在工作节点才可以使用
global 所有节点可以使用
查看 Docker 网络
docker network ls

ingress:是特殊的 overlay 网络,具有负载均衡的功能
# 查看网络配置
docker network inspect ingress

Peers 中可以查看到所有节点的网络信息
3、Docker Stack
docker-compose 单机部署项目
Docker Stack 部署,集群部署
# 单机
docker-compose up -d wordpress.yml
# 集群
docker stack deploy wordpress.yml

4、Docker Secret
安全、配置密码、证书

5、Docker Config

- 本文链接:https://lxjblog.gitee.io/2022/06/14/Docker%E8%BF%9B%E9%98%B6/
- 版权声明:本博客所有文章除特别声明外,均默认采用 许可协议。