Docker 高级命令
Compose
Docker Compose
使用的YAML
定义多服务应用,也可以使用JSON
。
命令
Docker Compose
会使用目录名作为项目名称,而且会在所有资源名称加上前缀目录名_
。
启动 up
docker-compose up
-d, --detach 在后台运行
停止并移除 down
docker-compose down
--rmi TYPE :'all' 移除所有相关的镜像。 'local': 移除没image字段的镜像
-v, --volumes : 删除在'volumes'部分中声明的命名卷和附加到容器的匿名卷。
查看状态 ps
docker-compose psf
列出进程 top
docker-compose top
停止 stop
stop命令会停止容器但是不会删除资源
docker-compose stop
删除容器 rm
删除相关的容器和网络,但是不会删除卷和镜像
docker-compose rm
重启 restart
docker-compose restart
语法
点击这里查看更多示例
Version
这个是必须指定的,而且总是位于第一行,他定义了文件格式的版本。
版本之间的兼容关系见此链接。
version: "3.2"
Services
用于定义不同的服务。compose会将每个服务部署在各自的容器中,而且key作为容器名字的一部分。
- build
.
指定docker基于当前目录下Dockerfile
中定义的指令来构建新镜像。 - command 启动的命令
- ports 指定映射的端口
- networks 使
docker
可以将服务连接到指定的网络上,这个网络应该是已存在的。或者在Network
中定义的网络,对于overlay
来说,还需要定义一个attachable
,这样独立的容器才能链接上它(compose
部署的不是服务而是容器)。 - volumes 挂载卷,卷应该是已存在的,或者在下面定义的。
- image 指定一个镜像
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
- logvolume01:/var/log
links:
- redis
redis:
image: redis
Networks
用于指引Docker
创建新的网络,默认情况下会创建一个bridge
网络。
networks:
over-bet:
driver: overlay
attachable: true
Volumes
用于指引Docker
创建新的卷。
volumes:
logvolume01: {}
volumes:
- .:/code
- logvolume01:/var/log
Stack
Docker Stack
适用于大规模场景和生产环境。
Stack
文件就是Docker Compose
文件,但是要求version
必须大于3.0。
Stack
与Compose
不同的是,Stack
不支持构建,部署之前,所有的必须都要构建完成。
命令
部署 deploy
docker stack deploy -c file.yml STACK
# -c, Compose的位置,不指定则从stdin读取
# --with-registry-auth 发送 registry 认证信息到 Swarm agents(用于从私有仓库部署)
管理
如果想要对service
进行操作,不推荐直接使用命令,推荐是修改yml
文件,然后重新部署。在重新部署中,只会更新存在表更的部分。
docker stack ls
docker stack ps
docker stack rm # 删除不会有确认,要谨慎。而且不会删除卷。
查看服务
docker stack services
语法
image
这个是唯一的必填字段。
image: ....
stop_grace_period
这个属性可以调整从发出SIGTERM
信号到发出SIGKILL
信号的时间间隔,默认是10秒。
stop_grace_period: 2m30s
volumes
用于挂载提前创建的卷,或主机目录到某个服务副本中。
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
ports
默认情况下,所有的端口映射都是Ingress
模式,如果想要使用Host
模式,则要使用完整语法的写法。
ports:
- "80:80"
ports:
- target: 80
publish: 80
mode: host
secrets
密钥以普通文本的形式挂载到服务副本中。文件名就是target
属性定义的名称。路径为/run/secrets/NAME
。
secrets:
- source: revprox_cert
target: revprox_cert
- source: revprox_key
target: revprox_key
服务内的 networks
指定副本连接的网络,网络相关定义必须位于顶级关键字neitowrk
下, 如果不存在,会默认以overlay新建一个。
networks:
- front-tier
networks:
- front-tier
- back-tier
- payment
environment
这个关键字允许用户在服务副本中注入环境变量。
environment:
USER: gordonuser
DB_PASSWORD_FILE: /run/secrets/postgres_password
DB: atsea
deploy
定义部署约束。部署约束是一种拓扑感知定时任务,目前swarm允许通过以下几种方式进行调度
- 节点ID 例如:
node.id==123
- 节点名称 例如:
node.hostname==abc
- 节点角色 例如:
node.role!=manager
- 节点引擎标签 例如:
engine.labels.operatingsystem==ubuntu20.04
- 节点自定义标签 例如:
node.labels.zone==p1
deploy:
replicas: 2
update_config: # 定义了服务在滚动升级的时候具体如何才做
parallelism: 2 # 每次更新的副本数
failure_action: rollback # 回滚,默认是pause,升级失败后阻止其他副本升级,还可以是continue
placement:
constraints:
- 'node.role == worker'
restart_policy: # 定义了容器异常退出的重启策略
condition: on-failure # 非0返回值退出会立即重启(on-failure)
delay: 5s # 每次启动间隔
max_attempts: 3 # 最多重试次数
window: 120s # 等待最多120秒来检测是否启动成功
volumes
密钥管理
只有swarm的管理节点才能使用docker secret
命令。
密钥以普通文本的形式挂载到服务副本中。文件名就是配置文件中target
属性定义的名称。
路径为/run/secrets/NAME
。
创建密钥
docker secret create [OPTIONS] SECRET [file|-]
# -d, --driver string Secret driver
# -l, --label list Secret labels
# --template-driver string Template driver
echo file.crt | docker secret create SECRET -
docker secret create SECRET file.crt
列出密钥
docker secret ls
删除密钥
docker secret rm SECRET
docker secret remove SECRET
Swarm
Raft共识算法
HA(高可用)
swarm
节点内置HA
支持,swarm
使用raft共识算法
实现节点管理。
使用HA
要注意:
- 部署奇数个管理节点
- 不要部署太多管理节点
- 3 个 Manager 节点最多可以同时容忍 1 个 Manager 节点失效的情况下保证高可用。
- 5 个 Manager 节点最多可以同时容忍 2 个 Manager 节点失效的情况下保证高可用。
- N 个 Manager 节点最多可以同时容忍 (N−1)/2个 Manager 节点失效的情况下保证高可用。
- Docker 建议的情况下,使用 7 个 Manager 节点就够了,否则会降低集群的性能。
服务命令
创建服务
docker service create
--name NAME
-p ...
--replicas N
--mode global # 使用全局模式,,每个节点只运行一个副本
--network NETWORKNAME
-d # 立即退出而不是等待服务完成
IMAGE
# -p, --publish
# -p 80:80
# --publish published=80,target=80,mode=host
列出服务
docker service ls
# ID NAME MODE REPLICAS IMAGE PORTS
# xio5zrmcc7p0 nginx replicated 5/5 nginx:latest *:4480->80/tcp
# u0hfbk889yc4 test replicated 1/1 redis:latest
查看服务
docker service ps NAME
docker service inspect NAME # 查看更详细的信息
服务的扩缩容
docker service scale NAME=N
删除服务
docker service rm NAME
滚动升级
docker service
--images IMAGE
--update-parallelism N
--update-delay TIME
NAME
查看日志
docker service logs NAME
如果使用第三方日志驱动,需要相应的日至平台工具查看日志。在创建的时候指定--logodriver
和--log-opts
可以强某一个服务使用不同的日志驱动。
集群命令
创建集群
docker swarm init
--advertise-addr 10.0.0.1:2377 # 指定其他节点连接到当前管理节点的IP和端口
--listen-addr 10.0.0.1:2377 # 指定用来承载Swarm流量的IP和端口
其他帮助信息使用docker swarm init --help
输出。
列出节点
docker node ls
管理节点
- 将节点提为管理节点
docker node promote <NODE>
- 将节点从管理者降级为普通节点
docker node demote <NODE>
- 删除节点
docker node rm [-f] <NODE> [<NODE>...]
更新节点
更新节点的功能包括:
-
修改节点可用性
docker node update --availability <TYPE> <NODENAME> # TYPE 可以是以下三个值 # active : 正常工作的节点,可以给节点分配任务 # pause : 不会分配新的任务,但是现有任务会正常运行 # drain : 不会分配新的任务,关闭现有任务并将其安排在其他节点上。
-
修改节点的
LABEL
docker node update --label-add LABEL NODENAME # 给指定节点加入一个值为空的标签。 docker node update --label-add foo --label-add bar worker1 # 增加两个标签。 docker node update --label-add type=queue worker1 # 增加一个KV为 type=>queue 的标签。 docker node update --label-rm LABEL NODENAME # 删除指定节点的一个标签。
-
列出节点的
LABEL
# 列出所有节点
docker node ls -q | xargs docker node inspect \
-f '{{ .ID }} [{{ .Description.Hostname }}]: {{ .Spec.Labels }}'
# 列出单个节点
docker node inspect -f '{{ .Spec.Labels }}' <NODE>
-
设置管理节点
docker node update --role worker NODENAME docker node update --role manager NODENAME
锁定和解锁Swarm
开启锁定后,管理节点重启后需要解锁才能使用。因为用于加密swarm
节点之间通信的TLS
密钥和用于加密和解密磁盘上的Raft
日志的密钥会加载到每个管理器节点的内存中。Docker
使用所谓的 autolock
保护这些密钥。
- 开启锁定
docker swarm update --autoload=true
# OR
# 在创建的时候加入 --autoload
- 关闭锁定
docker swarm unlock
- 查看当前的解锁密钥
docker swarm unlock-key
- 轮换密钥
docker swarm unlock-key --rotate
加入集群
可以使用下文的列出加入密钥获取接入的命令。
docker swarm join --token <KEY>
# --availability <string> 节点的可用状态 ("active"|"pause"|"drain") (默认是 active)
KEY由四个字段组成,使用字符-
进行分割。
PREFIX - VERSION - SWARM ID -TOKEN
- PREFIX :永远是
SWMTKN
,这样可以方便的匹配,避免发布到公共环境。 - VERSION :表示了
swarm
的版本信息。 - SWARM ID :是
swarm
认证信息的哈希值。 - TOKEN :决定令牌是管理者还是工作者的准入令牌
对于join
命令,要注意两个选项,分别是:
--advertise-addr
向外通告的地址。--listen-addr
监听的地址。
如果服务器获取的是一个局域网地址,就需要注意这两个参数,配置错误可能会导致overlay
网络错误。
加入集群前,要注意设置主机名:
hostnamectl set-hostname <你想要的主机名>
加入成功后docker会返回类似的结果,代表加入成功。
This node joined a swarm as a worker.
列出加入密钥
docker swarm join-token worker # 列出作为worker加入此次节点的token
docker swarm join-token manager # 列出作为manager加入此次节点的token
退出集群
docker swarm leave
# 管理节点退出要加 -f
Overlay网络
overlay
只能在swarm
的管理节点可见
创建网络
docker network create -d/--driver overlay NAME
Docker 安全
Name Space
Linux Docker
使用下列内核命名空间
- PID
每个容器都拥有自己的进程树。命名空间内看不到其他容器的进程树。
- NET
Docker
使用这个命名空间提供隔离的网络栈。每个网络栈都有自己的接口
,ID地址
,端口地址
和路由表
。
- MNT
每个容器都有互相隔离的根目录。
- IPC
IPC
提供共享内存,不同容器间也是独立的。
- USER
Docker
允许用户使用这个命名映射用户到主机不同的用户上。
- UTS
使用UTS
命名空间提供每个主机自己的主机名称。
Control Group
控制组用于限额限制
Capability
这个机制用来保证,用于在以root用户运行容器的同时,还移除非必须的root能力
Seccomp
Docker使用过滤模式的Seccomp来限制容器对宿主机内核发起的系统调用。
Linux 命名空间
相关内容请见文章 “Linux命名文件"
Docker 注意事项
-
Docker
套接字位置unix://var/run/docker.sock
-
判断自己是不是在Docker容器内部 A.
cat /proc/1/cgroup | grep docker
B.ls /.dockerenv
-
不要把 docker的
sock
文件挂载到docker
内部,或把docker
的api
暴露给公网。 -
高危参数
--privileged
谨慎使用。 -
注意以下参数的使用
--cap-add=SYS_ADMIN 启动时,允许执行mount特权操作,需获得资源挂载进行利用。
--net=host 启动时,绕过Network Namespace
--pid=host 启动时,绕过PID Namespace
--ipc=host 启动时,绕过IPC Namespace