容器启动之后,初始状态会为 starting (启动中)。Docker Engine会等待 interval 时间,开始执行健康检查命令,并周期性执行。如果单次检查返回值非0或者运行需要比指定 timeout 时间还长,则本次检查被认为失败。如果健康检查连续失败超过了 retries 重试次数,状态就会变为 unhealthy (不健康)。
在Swarm模式下,Swarm manager会监控服务task的健康状态,如果容器进入 unhealthy 状态,它会停止容器并且重新启动一个新容器来取代它。这个过程中会自动更新服务的 load balancer (routing mesh) 后端或者 DNS记录,可以保障服务的可用性。
实例
使用dockerfile创建一个运行nginx的镜像
vim my_nginx/Dockerfile
FROM 192.168.1.10:5000/centos:7 ##私有仓库镜像 可以直接下公共的
RUN yum -y install wget
RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install nginx
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx","-g", "daemon off;"]
运行dockerfile
docker build -t '192.168.1.10:5000/my_nginx' .
创建服务
docker service create --name mynginx --health-cmd "curl -f http://localhost||exit 1" --health-timeout 5s --health-interval 8s 192.168.1.10:5000/my_nginx
##查看容器状态
docker service ps mynginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
jaz9josszudb mynginx.1 192.168.1.10:5000/my_nginx:latest node2 Running Running 20 seconds ago
##在node2节点上查看
[root@node2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8bd7baa7aa02 192.168.1.10:5000/my_nginx:latest "nginx -g 'daemon of…" 2 minutes ago Up 2 minutes (healthy) 80/tcp mynginx.1.jaz9josszudbxdlype6xok88j
##状态为 证明容器健康检查正常
Up 2 minutes (healthy)
再创建一个服务访问一个没有的网页
docker service create --name mynginx1 --health-cmd "curl -f http://localhost/nopage ||exit 1" --health-timeout 5s --health-interval 8s 192.168.1.10:5000/my_nginx
jsbkurvtk6uhvx75gluov8mug
overall progress: 0 out of 1 tasks
1/1: starting [============================================> ]
##查看服务状态
docker service ps mynginx1
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
qw9mbvipitjj mynginx1.1 192.168.1.10:5000/my_nginx:latest swarm Running Starting less than a second ago
isry2k4h1gaw \_ mynginx1.1 192.168.1.10:5000/my_nginx:latest swarm Shutdown Complete 5 seconds ago
yq8llifq9jmx \_ mynginx1.1 192.168.1.10:5000/my_nginx:latest swarm Shutdown Complete 35 seconds ago
pzlo7tvqc7zx \_ mynginx1.1 192.168.1.10:5000/my_nginx:latest swarm Shutdown Complete about a minute ago
证明当进入 unhealthy 状态时,他会停止这个容器,再重新创建一个容器,选择不同的节点直到成功。
在 Docker Swarm 服务中, Secret 是一种 BLOB(二进制大对象) 数据, 就像密码、SSH 私钥、 SSL 证书或那些不应该未加密就直接存储在 Dockerfile 或应用程序代码中的数据。在 Docker 1.13 及更高版本中,可以使用 Docker Secrets 集中管理这些数据,并将其安全地传输给需要访问的容器。 一个给定的 Secret 只能被那些已被授予明确访问权限的服务使用,并且只能在这些服务任务正在运行的情况下。
提醒: Docker Secret 仅对 Swarm 服务有效,对独立的容器是无用的。如需使用,可以启动 1 个副本的服务来使用 Docker Secret。
创建
docker secret create --help
Usage: docker secret create [OPTIONS] SECRET [file|-] ##可以使用文件或者标准输入的方式
##标准输入
echo "123.com" | docker secret create my_secret -
o7rgzr3dpgauiq8yags8d7xuy
##文件
echo "123.com" > psword.txt
docker secret create secret1 psword.txt
查看
docker secret ls
ID NAME DRIVER CREATED UPDATED
o7rgzr3dpgauiq8yags8d7xuy my_secret 2 minutes ago 2 minutes ago
n471rw9f0l1oksizv4jf5vw3p secret1 32 seconds ago 32 seconds ago
删除
docker secret rm secret1
secret1
例子:创建一个mysql服务使用secret传入密码
docker service create --name mysql --secret source=my_secret,target=mysql_root_password -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" 192.168.1.10:5000/mysql:5.7
##参数详解
--secret source=my_secret,target=mysql_root_password
--secret source=使用的secret
target=mysql_root_password 标签
-e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" 以变量的方式传入密码
##/run/secrets/ 这个路径在容器中不变 后面密码名称对应标签名
验证
docker service ps mysql
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
urj4ks85iylx mysql.1 192.168.1.10:5000/mysql:5.7 node2 Running Running 2 minutes ago
##在node2节点上进入容器验证密码
[root@node2 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb20d62b4846 192.168.1.10:5000/mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 3306/tcp, 33060/tcp mysql.1.urj4ks85iylxk5985tnp5demv
docker exec -it mysql.1.urj4ks85iylxk5985tnp5demv bash
root@bb20d62b4846:/# cat /run/secrets/mysql_root_password
123.com
mysql -uroot -p123.com
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.30 MySQL Community Server (GPL)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
创建一个mysql service,将密码保存在secret中。创建一个wordpress,使用secret连接mysql service。目的是避免在image中存放敏感信息。
下载wordpress镜像
docker pull wordpress
docker tag wordpress 192.168.1.10:5000/wordpress
docker push 192.168.1.10:5000/wordpress
创建网络
docker network create --driver overlay my_net
创建secret
##用于root用户登录
openssl rand -base64 20 | docker secret create my_secret2 -
##用于wordpress用户登录
openssl rand -base64 20 > password.txt
docker secret create my_secret3 password.txt
创建mysql service
docker service create --name wpmysql --network my_net \
--secret source=my_secret2,target=mysql_root_password \ ##root用户密码
--secret source=my_secret3,target=mysql_user_password \ ##wordpress用户密码
-e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" \ ##指定root用户密码
-e MYSQL_PASSWORD_FILE="/run/secrets/mysql_user_password" \ ##指定wordpress用户密码
-e MYSQL_DATABASE='wordpress' \ ##创建数据库
-e MYSQL_USER="wordpress" \ ##创建用户
192.168.1.10:5000/mysql:5.7
创建wordpress service
docker service create --name wordpress --network my_net \
--publish 8080:80 \
--secret source=my_secret3,target=wp_db_password \ ##wordpress用户密码
-e WORDPRESS_DB_HOST="wpmysql:3306" \ ##指定mysql service
-e WORDPRESS_DB_NAME="wordpress" \ ##指定数据库名称
-e WORDPRESS_DB_USER="wordpress" \ ##指定用户
-e WORDPRESS_DB_PASSWORD_FILE="/run/secrets/wp_db_password"\ ##指定密码
192.168.1.10:5000/wordpress
验证 ip:8080
单机模式下,我们可以使用 Docker Compose 来编排多个服务,而 Docker Swarm 只能实现对单个服务的简单部署。本文的主角 Docker Stack ,通过 Docker Stack 我们只需对已有的 docker-compose.yml 配置文件稍加改造就可以完成 Docker 集群环境下的多服务编排。
命令 | 描述 |
---|---|
docker stack deploy | 部署新的或更新现有 |
docker stack ls | 列出现有的 |
docker stack ps | 列出任务 |
docker stack rm | 删除一个或多个 |
docker stack services | 列出服务 |
方便理解继续部署wordpress
创建目录
mkdir wordpress
cd wordpress
创建secret
openssl rand -base64 20 > db_root_password.txt
openssl rand -base64 20 > db_password.txt
创建yml
vim docker-compose.yml
version: "3.1" ##与compose不同必须3版本以上
services:
db:
image: 192.168.1.10:5000/mysql:5.7 ##镜像
volumes:
- db_data:/var/lib/mysql
environment: ##变量 与命令行操作一样
MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
MYSQL_PASSWORD_FILE: /run/secrets/db_password
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
secrets: ##使用的secret
- db_root_password
- db_password
wordpress:
depends_on:
- db
image: 192.168.1.10:5000/wordpress
ports: ##端口
- "9999:80"
environment: ##变量
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD_FILE: /run/secrets/db_password
secrets: ##使用的secrets
- db_password
deploy: ##使用副本集模块
mode: replicated
replicas: 3
secrets: ##定义secrets路径
db_root_password:
file: db_root_password.txt
db_password:
file: db_password.txt
volumes:
db_data:
运行
docker stack deploy -c docker-compose.yml test
Creating network test_default
Creating secret test_db_root_password
Creating secret test_db_password
Creating service test_wordpress
Creating service test_db
查看
docker stack ls
NAME SERVICES ORCHESTRATOR
test 2 Swarm
docker stack services test
ID NAME MODE REPLICAS IMAGE PORTS
2xk05892oibh test_wordpress replicated 3/3 192.168.1.10:5000/wordpress:latest *:9999->80/tcp
7e685a7e317b test_db replicated 1/1 192.168.1.10:5000/mysql:5.7
验证:
ip:9999