环境准备
主机名 | ip | 操作系统 |
---|---|---|
node-master(manager) | 192.168.0.1 | CentOS7.5 |
node-slave1(worker) | 192.168.0.2 | CentOS7.5 |
node-slave2(worker) | 192.168.0.3 | CentOS7.5 |
批量搭建-Machine
docker-machine 简介
- Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境。Docker Machine 是一个工具,无论是Mac,Windows或是Linux,它都会自动创建主机,在主机上安装Docker-Engine,然后配置docker client,每个被管理的主机(machine)都是一个Docker主机和一个配置过的client的组合。它允许你在虚拟宿主机上或者远程机器上安装 Docker Engine ,并使用docker-machine 命令管理这些docker-machine节点。
总之,docker-machine就是帮助你快速去创建安装docker环境的工具。
Docker Machine 与 Docker Engine概念上的区别
Docker Engine 主要用来接收和处理docker命令请求的。
Docker Machine则主要用来远程安装docker并管理这些被docker化的主机。
docker-machine特性
批量安装:Docker Machine 能让你在各种 Linux 机子上配置多个远程 Docker 主机。
如果你想在本地运行 docker 命令比较简单地,只在本地配置一个 Docker Engine 即可。但是如果现在你有十几二十个远程服务器都想要配置多个 Docker 主机,那么总不能一个个配置过去,这时候你就可以使用 Docker Machine 了,它能帮助你高效的完成配置。简化部署的复杂度:Docker Machine是一个简化安装Docker环境的工具。例如,在ubuntu安装一个docker环境要按照这个系统配置教程来装,哪天又换了CentOS系统,又要按照这个系统配置教程装。市场上主流Linux系统版本很多,每次安装岂不有些麻烦。使用Machine工具就简单很多,一两条命令即可在主流Linux系统上安装Docker环境,用户不用考虑什么操作系统。
集中管理:使用 Docker Machine 的 docker-machine 命令,我们可以很方便地启动、检查、停止和重新托管主机、升级 Docker 客户端和守护程序,并配置 Docker 客户端与主机通信。
docker-machine安装
- docker-machine安装在管理节点上(node-master)
[root@node-master ~] curl -L https://github.com/docker/machine/releases/download/v0.14.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine && \
> install /tmp/docker-machine /usr/local/bin/docker-machine
# 完成后查看版本信息
[root@node-master ~] docker-machine -v
docker-machine version 0.14.0, build 89b8332
docker-machine 简单使用
docker-machine create
- 创建machine
(1) 利用docker-machine在worker节点创建machine:node-slave1(192.168.0.2)
创建machine也就是安装docker到远程主机上,要求能够无密码远程登陆主机,在这里免密登陆就不再多说。
一切准备就绪以后,执行docker-machine create命令创建node-slave1。因为我们是往普通的 Linux 中部署 docker,所以使用 generic driver。—generic-ip-address 指定目标系统的 IP,并命名为 node-slave1。命令执行过程如下:
[root@node-master ~] docker-machine create --driver generic --generic-ip-address=192.168.0.2 node-slave1
Creating CA: /root/.docker/machine/certs/ca.pem
Creating client certificate: /root/.docker/machine/certs/cert.pem
Running pre-create checks...
Creating machine...
(node-slave1 No SSH key specified. Assuming an existing key at the default location.
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 ubuntu(systemd...
Installing Docker...
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 node-slave1
(2) 使用同样的方法创建 node-slave2(192.168.0.3)
[root@node-master ~] docker-machine create --driver generic --generic-ip-address=192.168.0.3 node-slave2
docker-machine ls
- 查看可用的machine
[root@node-master ~] docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node-slave1 - generic Running tcp://192.168.0.2:2376 v18.09.0
node-slave2 - generic Running tcp://192.168.0.3:2376 v18.09.0
docker-machine env
- 查看节点环境变量
[root@node-master ~] docker-machine env node-slave1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.0.2:2376"
export DOCKER_CERT_PATH="/root/.docker/machine/machines/node-slave1"
export DOCKER_MACHINE_NAME="node-slave1"
# Run this command to configure your shell:
# eval $(docker-machine env node-slave1
docker-machine ssh
- 利用ssh登录到node-slave1,可以在此节点上进行docker相关操作
[root@node-master ~] docker-machine ssh node-slave1
Last login: Tue Apr 2 15:11:31 2019 from 192.168.0.1
[root@node-slave1 ~]
# 查看node-slave1的docker版本
[root@node-slave1 ~] docker -v
Docker version 18.09.0, build 4d60db4
docker-machine rm
- 删除machine
[root@node-master ~] docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node-slave1 - generic Running tcp://192.168.0.1:2376 v18.09.0
node-slave2 - generic Running tcp://192.168.0.2:2376 v18.09.0
[root@node-master ~] docker-machine rm node-slave1
About to remove node-slave1
Are you sure? (y/n): y
Successfully removed node-slave1
[root@node-master ~] docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node-slave2 - generic Running tcp://192.168.0.2:2376 v18.09.0
docker-machine inspect
- 输出主机信息
[root@node-master ~] docker-machine inspect node-slave1
{
"DriverName": "virtualbox",
"Driver": {
"MachineName": "docker-host-128be8d287b2028316c0ad5714b90bcfc11f998056f2f790f7c1f43f3d1e6eda",
"SSHPort": 55834,
"Memory": 1024,
"DiskSize": 20000,
"Boot2DockerURL": "",
"IPAddress": "192.168.5.99"
},
...
}
docker-machine ip
- 获取一台或多台计算机的IP地址
[root@node-master ~] docker-machine ip node-slave1
192.168.0.1
$ docker-machine ip node-slave1 node-slave2
192.168.0.1
192.168.0.2
docker-machine kill
- 停止某个Docker主机
[root@node-master ~] docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node-slave1 - generic Running tcp://192.168.0.1:2376 v18.09.0
node-slave2 - generic Running tcp://192.168.0.2:2376 v18.09.0
[root@node-master ~] docker-machine kill node-slave1
[root@node-master ~] docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
node-slave1 - generic Stopped tcp://192.168.0.1:2376 v18.09.0
node-slave2 - generic Running tcp://192.168.0.2:2376 v18.09.0
docker-machine 小结
- docker machine的本来目的很简单,是安装管理多台host上的docker engine,将这些host取一个简短的名字方便后续操作。是一个辅助类的自动化小工具。
集群管理-Swarm
docker-swarm简介
Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。
在swarm集群中每台服务器上都装有Docker并且开启了基于HTTP的DockerAPI。这个集群中有一个SwarmManager的管理者,用来管理集群中的容器资源。管理者的管理对象不是服务器层面而是集群层面的,也就是说通过Manager,我们只能笼统地向集群发出指令而不能具体到某台具体的服务器上要干什么(这也是Swarm的根本所在。
概念
名词
- swarm:是一组docker引擎的集群
- node:是单个docker引擎的实例,可以在一个物理机上也可以在多个
- application:应用
- manager node:部署应用的时候会有一个manager node管理节点
- Worker nodes:对应的就是Worker nodes工作节点
- service:服务,实际上是”生产中的容器”,扩展服务会更改运行该软件的容器实例的数量,从而为流程中的服务分配更多计算资源。
命令
- docker swarm:集群管理,子命令有 init, join,join-token, leave, update
- docker node:节点管理,子命令有 demote, inspect,ls, promote, rm, ps, update
- docker service:服务管理,子命令有 create, inspect, ps, ls ,rm , scale, update
- docker stack/deploy:用于多应用部署,是创建多容器的应用程序,而不是单个容器的二进制结果
docker-swarm特性
- 高可用:中心化设计,可大规模部署,支持HA
- 弹性服务:管理节点收集集群中所有的信息,进行感知和调度,在节点挂掉后重新调度上面的container
- 多主机联网:指定overlay 网络,swarm管理器自动将地址分配给覆盖网络上的容器
- 服务发现:service
- 负载均衡:使用内建DNS Round-Robin实现集群内的负载均衡,也支持外部负载均衡
- 回滚更新:高可用和故障恢复机制意味着用户可以创建超过一个master的Swarm
docker-swarm初始化
- 管理节点初始化swarm
[root@node-master ~] docker swarm init --advertise-addr 192.168.0.1
Swarm initialized: current node (41atspd62he1vshs4jmhpyufj is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3vcmes47gkyl5rl2d74ina12q5xi8z2xsmvsdx0l3gjg4qw68t-9krjzbsmruk11rqe0l93izbek 192.168.0.1:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
# 如果不知道或者忘记了Swarm Manager节点的Token信息,可以在Manager节点上执行以下命令查看Worker节点连接所需要的Token信息。
[root@node-master ~] docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3vcmes47gkyl5rl2d74ina12q5xi8z2xsmvsdx0l3gjg4qw68t-9krjzbsmruk11rqe0l93izbek 192.168.0.1:2377
docker-swarm 基本操作
docker node ls
- 查看swarm集群中节点信息
# 初始化完成以后,查看此时的节点信息
[root@node-master ~] docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
wdrka781dbx105geltnosjiuy * node-master Ready Active Leader 18.09.0
docker swarm join
- 将work节点加入swarm集群有两种方法:
方法一:在work节点上直接执行加入swarm集群的命令
方法二:在管理节点上利用docker-machine ssh
命令加入swarm集群
这两种方法本质上来说是一样的。
(1) 登录到node-slave1主机上,执行前面创建swarm时输出的命令(方法一):
[root@node-slave1 ~] docker swarm join \
> --token SWMTKN-1-3vcmes47gkyl5rl2d74ina12q5xi8z2xsmvsdx0l3gjg4qw68t-9krjzbsmruk11rqe0l93izbe \
> 192.168.0.1:2377
This node joined a swarm as a worker.
(2) 将node-slave2节点加入swarm集群(方法二)
[root@node-master ~]docker-machine ssh node-slave2 "docker swarm join \
> --token SWMTKN-1-3vcmes47gkyl5rl2d74ina12q5xi8z2xsmvsdx0l3gjg4qw68t-9krjzbsmruk11rqe0l93izbe \
> 192.168.0.1:2377"
This node joined a swarm as a worker.
- 此刻在manager节点上查看集群节点的状态:
[root@node-master ~] docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
tmnvs3oospj1ywtrfw4bsmkc4 node-slave1 Ready Active 18.09.0
uc4tyvbt5de5m2smorufx1l88 node-slave2 Ready Active 18.09.0
wdrka781dbx105geltnosjiuy * node-master Ready Active Leader 18.09.0
docker network create overlay
- docker swarm 跨主机通信,在manager节点创建overlay网络
在主节点上创建overlay网络之后,worker节点可以通过—network swarm_net的方式在创建容器的时候使用该网络,当在worker节点按上述方式运行容器并使用该网络之后,即可通过docker network ls在此worker节点上查看到该网络,这样所有使用该网络的节点均可进行通信。
# 此处必须要添加--attachable参数,否则不能用于容器
[root@node-master ~] docker network create -d overlay --attachable swarm_net
mogwnajy85od1y4zp4fryrp3y
动态伸缩/自动负载-Service
docker service create
docker swarm强大之处,通过它能够直接实现负载均衡、主备、容灾等功能。它可以自动创建一个应用,应用包含一系列的服务,每一个服务简单的说是一个镜像创建几个容器,这些容器集合起来能够实现某些特定的功能,并且无需用户指定这些容器运行在哪些节点上,swarm会自动分配,甚至会在不同的节点上跳转,当某worker节点挂掉的时候其上运行的所有容器也会自动迁移到其他节点上。
- 创建redis服务
在这里我们可以使用上面创建的overlay网络
[root@node-master ~] docker service create --replicas 3 --name redis redis:alpine --network swarm_net
jmxs79vpd77v5gx3c6bv5wfos
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
# 查看服务docker service ls
[root@node-master ~] docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
jmxs79vpd77v redis replicated 3/3 redis
# 查看服务分布状况
[root@node-master ~] docker service ps redis
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l3qem6u0ejqj redis.1 redis:alpine node-master Running Running 42 seconds ago
1027zn4any5u redis.2 redis:alpine node-slave1 Running Running 40 seconds ago
z4k53hp19nex redis.3 redis:alpine node-slave2 Running Running 41 seconds ago
docker service scale
- 添加或减少实例可以使用 scale 命令
[root@node-master ~] docker service scale redis=4
redis scaled to 4
overall progress: 4 out of 4 tasks
1/4: running [==================================================>]
2/4: running [==================================================>]
3/4: running [==================================================>]
4/4: running [==================================================>]
verify: Service converged
[root@node-master ~] docker service ps redis
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
l3qem6u0ejqj redis.1 redis:alpine node-master Running Running 2 hours ago
1027zn4any5u redis.2 redis:alpine node-slave1 Running Running 2 hours ago
z4k53hp19nex redis.3 redis:alpine node-slave2 Running Running 2 hours ago
ttvl625rv1kd redis.4 redis:alpine node-slave1 Running Running about a minute ago
服务集合-Stack
stack介绍
单机模式下,我们可以使用 Docker Compose 来编排多个服务(compose的用法在后面我们会详细介绍),而刚刚介绍的Docker Swarm 只能实现对单个服务的简单部署。于是出现了Docker Stack ,通过 Docker Stack 我们只需对已有的 docker-compose.yml 配置文件稍加改造就可以完成 Docker 集群环境下的多服务编排。
stack使用说明
我们以在Swarm集群中部署web和redis为例进行说明。
创建overlay网络
首先,创建我们swarm集群中需要用到的overlay网络
$ docker network create -d --driver overlay web_overlay
te99n7r4y9npyhvm03vtx42p2
编辑docker-compose.yaml
在swarm集群中使用docker-compose.yaml,在文件里,我们使用上面创建的overlay网络web_overlay, 共创建了两个服务nginx和redis,分别都有三个复制因子。后面我们会对compose作详细介绍。
version: '3'
services:
nginx:
image: "nginx:alpine"
deploy:
replicas: 3
ports:
- "5000:5000"
networks:
- default
redis:
image: "redis:alpine"
deploy:
replicas: 3
resources:
limits:
cpus:'0.1'
memory:50M
restart_policy:
condition: on-failure
networks:
- default
networks:
default:
external:
name: web_overlay
部署栈
- 部署栈使用docker stack deploy,其中 -c 参数指定 compose 文件名
>
docker stack deploy -c docker-stack.yml web
- 部署成功后查看详情
$ docker stack ls
NAME SERVICES ORCHESTRATOR
web 2 Swarm
$ docker stack ps web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
6wwcc61zhut1 web_nginx.1 nginx:alpine node-slave1 Running Running 11 hours ago
7su7pucq5b36 web_redis.1 redis:alpine node-master Running Running 11 hours ago
x8eyzbjtesf4 web_nginx.2 nginx:alpine node-slave2 Running Running 11 hours ago
vq0crezcpn8q web_redis.2 redis:alpine node-slave1 Running Running 11 hours ago
docker-stack命令
命令 | 描述 |
---|---|
docker stack deploy | 部署新的堆栈或更新现有堆栈 |
docker stack ls | 列出现有堆栈 |
docker stack ps | 列出堆栈中的任务 |
docker stack rm | 删除一个或多个堆栈 |
docker stack services | 列出堆栈中的服务 |
统一配置-Config
为什么要用Docker-Config
使用Docker Config并不是在制作镜像的时候使用嵌入式配置,或者使用使用volume。
在镜像中嵌入配置
$ cat Dockerfile
FROM redis:alpine
RUN curl /xx/xx/redis.conf /etc/redis/redis.conf
在上述中,是将本地编辑的redis.conf文件放到/etc/redis/redis.conf中,这样也可以实现我们对配置的修改,但是如果参数过多,配置和替换起来将会耗费更多的时间,也较为复杂,并不是最好最安全的方式。
利用挂载修改配置
当然,我们可以直接挂载文件到容器中,那并不优雅,但的确能解决一部分问题。如果需要频繁的修改文件,且变量替换也无法满足,也不想挂载文件,那现在就可以参考本节的docker config。
Docker-Config使用
创建config
- 编辑redis的配置文件redis.conf
vim redis.conf
- 使用 docker config create 命令创建config
>
docker config create my_config redis.conf
$ docker config ls
my_config
my_config: 代表的config的名称
redis.conf: 代表本地编写的config文件
创建服务时直接使用config
创建redis服务并授予其访问配置的权限。默认情况下,容器可以访问配置/my-config,但也可以使用该target选项自定义容器上的文件名。
>
docker service create --name redis --config my-config redis:alpine
如果服务启动成功代表我们的config就可以正常使用了
docker_compose config配置
version: '3'
services:
redis:
image: redis:alpine
....
configs:
- source: redis
target: /etc/redis/redis.conf
configs:
redis:
external: true
config的名称为redis,在全局配置中则填写redis,在局部配置中附加配置即可
updata
当需要修改配置的内容时,创建新配置(使用docker config create)然后更新服务以删除先前配置的config,并添加对新配置是一种常见模式。服务命令—config-rm和—config-add
- 我们重新创建一个redis1的config文件
$ docker config create redis1 redis.conf
a4soto5rw4if4h7ir8jfrasyv
- 更新配置文件
先删除掉redis的config,而后添加redis1,这个过程会更新redis容器
$ docker service update --config-rm redis --config-add src=redis1,target=/etc/redis/redis.conf redis
redis_redis
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
- 查看更新
>
docker exec -it redis cat /etc/redis/redis.conf
"This is a new config"
Docker-Config命令
命令 | 描述 |
---|---|
docker config create | 创建配置文件 |
docker config inspect | 显示一个或多个配置的详细信息 |
docker config ls | 列出所有配置 |
docker config rm | 删除一个或多个配置 |
统一密码-Secret
secret介绍
在 Docker Swarm 服务中, Secret 是一种 BLOB(二进制大对象) 数据, 就像密码、SSH 私钥、 SSL 证书或那些不应该未加密就直接存储在 Dockerfile 或应用程序代码中的数据。在 Docker 1.13 及更高版本中,可以使用 Docker Secrets 集中管理这些数据,并将其安全地传输给需要访问的容器。 一个给定的 Secret 只能被那些已被授予明确访问权限的服务使用,并且只能在这些服务任务正在运行的情况下。
不想在镜像或代码中管理的任何敏感数据,都可以使用 Secret 来管理,比如:
- 用户名和密码
- TLS certificates and keys
- SSH keys
- 其他重要数据
提醒:Docker Secret 仅对Swarm服务有效,对独立的容器是无用的。如需使用,可以启动1个副本的服务来使用 Docker Secret。
Docker Secret基本操作
友情提示:“需Swarm Manage权限才能操作!”
创建Secret
以存储mysql的root用户密码为例
>
echo 'admin' docker secret create my-pw -
在服务中使用secret
>
$ docker service craete --name mysql_db \
-d \
-- secret my-pw \
-e MYSQL_ROOOT_PASSWORD_FILE=/run/secrets/my-pw \
mariadb
# 创建完成后检查服务状态
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
ouq2xbuu3jrp mysql_db replicated 1/1 mariadb:latest
# 通过docker exec命令进入容器内部,查看/run/secrets/目录下的secret文件
$ docker exec -it {容器ID/名称} bash
root@32ab97f50413:/# cat /run/secrets/
admin
# 验证secret是否正确使用
$ docker exec -it mysql -h host_ip -uroot -p
Enter password: # 输入secret设定的密码
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.21 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
Docker Compose 中使用secret
用上面同样的方法生成secret:my-pw
docker-compose.yml
文件如下version: '3'
services:
db:
image: mariadb
....
secret:
- my-pw
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/my-pw
deploy:
replicas: 1
secrets:
my-pw:
external: true
- 部署服务
>
docker stack deploy -c docker_compose.yml mysql
- 查看部署情况
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
xa450wyt625o mysql_db replicated 1/1 mariadb:latest
检验secret是否正确使用同上。
secret更新
以上面为例,我们创建了mysql_db服务,在服务里使用了secret文件my-pw。
- 此时通过更新服务从正在运行的服务中删除对secret的访问权限。
>
docker service update --secret-rm my-pw mysql_db
- 验证服务不再有权访问该机密。 ```bash $ docker container exec -it $(docker ps —filter name=mysql_db -q) cat /run/secrets/my-pw cat: cant open ‘/run/secrets/my-pw’: No such file or directory
从docker中删除该secret
docker secret rm my-pw
-
创建新的secret,并通过service更新添加到服务内使用。
```bash
# 创建新的secret
echo 'asd123' docker secret create new-pw -
# 更新secret,在这里source指的是新创建的secret,target是指首次创建secret的名称
$ docker service update \
--secret-add source=new-pw,target=my-pw \
mysql
Docker Secret 命令
命令 | 描述 |
---|---|
docker secret create | 创建一个secret |
docker secret inspect | 描述一个或者更多的secret信息 |
docker secret ls | 列出所有的secret |
docker secret rm | 删除一个或者更多的secret |