Centos7安装Docker
卸载旧版本
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
安装依赖包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
添加国内yum源
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装Docker CE
sudo yum makecache fast
sudo yum install docker-ce
启动Docker CE
sudo systemctl enable docker
sudo systemctl start docker
镜像加速
1 | cat /etc/docker/daemon.json |
Docker镜像
获取镜像
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
运行
docker run -it --rm ubuntu:18.04 bash
- -it -i交互式操作 -t 终端
- –rm 退出时将其删除
- ubuntu:18.04 以ubuntu:18.04作为基础启动容器
- bash 启动后执行命令
列出镜像
docker image ls
镜像体积
docker system df
虚悬镜像
docker image prune
中间层镜像
docker image ls -a
列出部分镜像
docker image ls ubuntu
以特定格式显示
1 | #列出所有镜像ID |
- 删除本地镜像
docker image rm [选项] <镜像1> [<镜像2> ...]
- 构建镜像(commit 慎用)
1 | #以nginx为基础镜像启动一个名为webserver的容器 映射80端口 |
- 用Dockerfile 定制镜像
Dockerfile是一个文本文件 包含一条条指令(Instruction)每条指令构建一层
1 | mkdir mynginx |
- 镜像构建上下文(Context)
1 | #构建在服务端由Docker引擎完成 构建时将指定路径下内容打包 上传给Docker引擎 然后展开构建 |
- docker build 用法
1 | #Git repo 进行构建 |
Dockerfile 指令详解
COPY 复制文件
COPY [--chown=<user>:<group>] <源路径>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]
- 例子
COPY package.json /usr/src/app/
COPY home.txt /mydir/
COPY --chown=555:mygroup files* /mydir/
ADD 高级复制文件
1
2#复制压缩包会自动解压
ADD test.tar.gz /- CMD 容器启动命令
CMD <命令>
CMD ["可执行文件", "参数1", "参数2"...]
- 例子
CMD echo $HOME
CMD ["nginx", "-g", "daemon off;"]
- 例子
- ENTRYPOINT 入口点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#1、场景一 带参数
cat Dockerfile
FROM ubuntu:18.04
RUN apt-get update \
&& apt-get install -y curl \
&& rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["curl", "-s", "https://ip.ropon.top"]
docker build -t myip .
#测试
docker run myip -i
docker run myip
#2、场景2 预处理
FROM alpine:3.4
...
RUN addgroup -S redis && adduser -S -G redis redis
...
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 6379
CMD [ "redis-server" ]ENV 设置环境变量
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
- 例子
1
2
3
4
5
6
7ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NOD
E_VERSION-linux-x64.tar.xz" && curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS25
6.txt.asc" && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.tx
t.asc && grep " node-v$NODE_VERSION-linux-x64.tar.xz\$" SHASUMS256.t
xt | sha256sum -c - && tar -xJf "node-v$NODE_VERSION-linux-x64.tar.xz" -C /usr/loc
al --strip-components=1 && rm "node-v$NODE_VERSION-linux-x64.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt && ln -s /usr/local/bin/node/usr/local/bin/nodejsARG 构建参数
ARG <参数名>[=<默认值>]
VOLUME 定义匿名卷
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
- 例子
#向/data 写入信息不会记录容器存储层 VOLUME /data
- 例子
EXPOSE 声明端口
EXPOSE <端口1> [<端口2>...]
WORKDIR 指定工作目录
WORKDIR <工作目录路径>
USER 指定当前用户
USER <用户名>[:<用户组>]
- 例子
1
2
3RUN groupadd -r redis && useradd -r -g redis redis
USER redis
RUN [ "redis-server" ]- HEALTHCHECK 健康检查
HEALTHCHECK [选项] CMD <命令>
- 例子
1
2
3
4
5
6
7
8FROM ubuntu:18.04
RUN apt-get update && apt-get install -y nginx curl && rm -rf /var/lib/apt/lists/*
HEALTHCHECK --interval=5s --timeout=3s CMD curl -fs http://localhost/ || exit 1
CMD ["nginx", "-g", "daemon off;"]
#启动容器测试
docker run -d --name web -p 80:80 nginx:V4
#查看健康状态
docker inspect --format '{{json .State.Health}}' web | python -m json.toolONBUILD 为了定制当前镜像而准备
ONBUILD <其它指令>
例子
1
2
3
4
5
6
7FROM node:slim
RUN mkdir /app
WORKDIR /app
ONBUILD COPY ./package.json /app
ONBUILD RUN [ "npm", "install" ]
ONBUILD COPY . /app/
CMD [ "npm", "start" ]多阶段构建镜像
1 | FROM scratch |
Docker容器
启动容器
docker run
- 新建并启动
1
2
3
4#新建一个容器
docker run ubuntu:18.04 /bin/echo "hello world"
#新建一个容器启动一个终端 用于交互
docker run -t -i ubuntu:18.04 /bin/bash- 启动已终止容器
docker container start
- 后台运行
docker run -d
终止容器
docker container stop
进入容器
使用-d 参数时 容器启动后回进入后台 可使用docker attach 或 docker exec(exit退出时容器不会因此停止)
导出和导入容器
- 导出容器
docker export 7691a814370e > ubuntu.tar
- 导入容器
cat ubuntu.tar | docker import - test/ubuntu:v1.0
- 导出容器
删除容器
docker container rm 或docker rm 强制删除-f
docker container prune 清理所有终止容器
拉取镜像
docker search centos 搜索镜像
docker pull ansible/centos7-ansible 拉取镜像
私有仓库
1 | #安装运行docker-registry |
- 私有仓库上传、搜索、下载镜像
1 | #标记镜像 |
Docker数据管理
- 数据卷
docker volume create my-vol 创建一个数据卷
docker run -P -it --name web --mount source=my-vol,target=/webapp ubuntu:18.04 /bin/bash 启动一个挂载数据卷的容器
docker inspect web 查看数据卷的具体信息
docker volume rm my-vol 删除数据卷
docker volume prune 去拿过来无主的数据卷
- 挂载主机目录
docker run -it --name web --mount type=bind,source=/home/docker,target=/webapp ubuntu:18.04 /bin/bash
默认读写 可--mount type=bind,source=/home/docker,target=/webapp,readonly 配置只读
- 应用
1 | #记录容器内的操作日志 |
Docker 网络
外部访问容器
-p 指定端口映射 -p 8080:80 -P会随机映射一个49000~49900
映射所有接口地址
-p 5000:5000
映射到指定地址的指定端口
-p 127.0.0.1:5000:5000
映射指定地址的任意端口
-p 127.0.0.1::5000
-p 127.0.0.1:5000:5000/udp 标记指定udp端口
查看映射端口配置
docker port nostalgic_morse 5000
容器互联
新建网络
docker network create -d bridge my-net
连接容器
docker run -it --rm --name test01 --network my-net centos:7 /bin/bash
docker run -it --rm --name test02 --network my-net centos:7 /bin/bash
配置 DNS
1
2
3
4
5
6
7
8
9
10
11
12
13
14cat /etc/docker/daemon.json
"dns": [
"119.29.29.29".
"114.114.114.114"
]
#设置主机名
-h name
docker run -h testname
#设置dns
--dns=119.29.29.29
docker run --dns=119.29.29.29
#配置dns搜索域
--dns-search=west.cn
docker run --dns-search=west.cn高级网络配置
1
2docker启动时 --> 会在主机自动创建一个docker0虚拟网桥(bridge 软件交换机)
一端eth0 另外一端是vethXXXX快速配置指南
1
2
3
4
5
6
7
8
9
10
11
12
13
14-b 指定容器挂载的网桥
--bip=CIDR 定制docker0的掩码
-H SOCKET docker服务端接收命令的通道
--icc=true|false 是否支持容器间通信
--ip-forward=true|false
--iptables=true|false 是否运行docker添加iptables规则
--mtu=BYTES 容器网络中MTU
--dns=223.5.5.5
--dns-search=west.cn
-h hostname
--link=CONTAINER_NAME:ALIAS 添加到另外一个容器的连接
--net=bridge|none|container:NAME_OR_ID|host 配置容器桥接模式
-p SEPC 映射容器端口到宿主主机
-P 映射容器所有端口到宿主主机容器访问控制
1
2
3
4
5
6
7
8
9
10#容器访问外部网络
#打开系统转发
cat /etc/sysctl.conf
net.ipv4.ip_forward=1
#容器之间访问
#所有容器都会被连接到docker0网桥上
#本地系统防火墙是否运行通过
#访问所有端口
默认情况下,不同容器之间是允许网络互通
为了安全,可在/etc/docker/daemon.json配置"icc": false访问指定端口
1
2-icc=false 关闭网络访问后 还可通过 --link=CONTAINER_NAME:ALIAS 访问容器开放端口
配置docker0网桥
1
docker服务默认会创建一个docker0网桥 还给docker0网桥设置IP地址和子网掩码
自定义网桥
1
2
3
4
5
6
7
8
9
10
11#删除旧网桥
yum install -y bridge-utils
systemctl stop docker
ip link set dev docker0 down
brctl delbr docker0
#创建一个网桥
brctl addbr bridge0
ip addr add 192.168.5.1/24 dev bridge0
ip link set dev bridge0 up
#在/etc/docker/daemon.json配置
"bridge": "bridge0"
Compose
- 安装
yum install -y docker-compose
- 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32mkdir -p /root/mypython
cd /root/mypython
cat app.py
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! 该页面已被访问 {} 次。\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
cat Dockerfile
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]
cat docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
#运行compose项目
docker-compose up - 命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#命令选项
-f 指定使用的compose模板文件 默认docker-compose.yml
-p 指定项目名称 默认使用目录名作为项目名称
--x-networking 使用docker的可插拔网络后端特性
--x-networking-driver DRIVER 指定网络后端的驱动 默认bridge
--verbose 输出更多调试信息
-v 打印版本并退出
#命令使用
build 构建项目中服务容器
--force-rm 删除构建过程中的临时容器
--no-cache 构建过程中不使用cache
--pull 始终尝试通过pull获取新版本的镜像
config 检查compose文件格式是否正确
down 停止up命令所启动的容器并移除网络
exec 进入指定的容器
images 列出compose文件中包含的镜像
kill -s参数指定发送的信号 docker-compose kill -s SIGINT 强制停止所有容器
logs 查看服务容器的输出
pause 暂停一个服务容器
port 输出某个容器端口锁映射的公共端口
ps 列出项目中目前所有容器 -q参数 只打印容器ID信息
pull 拉取服务依赖的镜像 --ignore-pull-failures 忽略拉取过程中的错误
push 推送服务依赖的镜像到docker镜像仓库
restart 重启项目中的服务
rm 删除所有服务容器
run 在指定服务商执行命令
scale 设置指定服务运行的容器个数 docker-compose scale web=3 db=2
start 启动已经存在的服务容器
stop 停止已经处于运行状态的容器
top 查看各个服务容器内的运行的进程
unpause 恢复暂停中的服务
up 自动完成包括构建镜像 创建服务 启动服务 - compose模板文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50build Dockerfile所在文件夹的路径
cap_add cap_drop 指定容器内核能力分配
#拥有所有能力
cap_add:
- ALL
#去掉NET_ADMIN能力
cap_drop:
- NET_ADMIN
command 覆盖容器启动后默认执行命令
command: echo "hello world"
configs 仅用于swarm mode
cgroup_parent 指定父cgroup 继承改组的资源限制
container_name 指定容器名称
deploy 仅用于swarm node
devices 指定设备映射关系
depends_on 解决容器依赖 启动先后
services:
web:
build: .
depends_on:
- db
- redis
dns 自定义dns
dns: 114.114.114.114
dns:
- 8.8.8.8
- 114.114.114.114
dns_search 配置dns搜索域
tmpfs 挂载一个tmpfs文件系统到容器
env_file 从文件中获取环境变量
environment 设置环境变量
expose 暴露端口 但不映射到宿主机
external_links
extra_hosts 指定额外的host名称映射信息
healthcheck 通过命令检查容器是否正常运行
image 指定镜像名称或镜像ID
labels 为容器添加元信息
logging 配置日志选项
network_mode 设置网络模式
networks 配置容器连接的网络
pid
ports 暴露端口信息
secrets 储存敏感数据
security_opt 配置标签的用户名和角色名
stop_signal 设置另外一个信号来停止容器
sysctls 配置容器内核参数
ulimits 指定容器的限制值
volumes 配置挂载数据卷 HOST:CONTAINER:ro
volumes:
- /var/lib/mysql/:ro - 例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19mkdir -p /root/mydjango
cd /root/mydjango
cat Dockerfile
FROM python:3.6-alpine
ENV PYTHONUNBUFFERED 1
WORKDIR /code
ADD . /code/
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/
cat docker-compose.yml
version: '3'
services:
web:
build: .
command: python3 manage.py runserver 0.0.0.0:8080
volumes:
- .:/code
ports:
- "8080:8080"
Docker Machine
- 安装
1
2
3curl -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine - 使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22active 查看活跃的docker主机
config 输出连接的配置信息
create 创建一个docker主机
env 显示连接某主机需要的环境变量
inspect 获取主机更多信息
ip 获取主机地址
kill 停止某主机
ls 列出所有管理的主机
provision 重新设置一个已存在的主机
regenerate-certs 为某个主机重新生成TLS认证信息
restart 重启主机
rm 删除某台主机
ssh SSH到主机上执行命令
scp 在主机之间复制文件
mount 挂载主机目录到本地
start 启动主机
status 查看主机状态
stop 停止主机
upgrade 更新主机docker版本为最新
url 获取主机URL
version 输出docker-machine版本信息
help 输出帮助信息
Docker Swarm
Swarm 集群管理编排工具
docker swarm
初始化集群
1
2
3
4
5
6#初始化
docker swarm init --advertise-addr 172.16.7.127
#增加工作节点
docker swarm join --token xxxxxx 172.16.7.127:2377
#查看集群
docker node ls部署服务
1
2
3
4
5
6
7
8
9
10
11
12
13#新建服务
docker service create --replicas 3 -p 80:80 --name nginx nginx:V3
#查看服务
docker service ls
#查看某个服务的日志
docker service logs nginx
#服务伸缩
#增加
docker service scale nginx=8
#减少
docker service scale nginx=2
#删除服务
docker service rm nginxSwarm集群使用compose文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52version: '3'
services:
wordpress:
image: wordpress
ports:
- 80:80
networks:
- overlay
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
deploy:
mode: replicated
replicas: 3
db:
image: mysql
networks:
- overlay
volumes:
- db-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
deploy:
placement:
constraints: [node.role == manager]
visualizer:
image: dockersamples/visualizer:stable
ports:
- 8080:8080
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement:
constraints: [node.role == manager]
volumes:
db-data:
networks:
overlay:
#部署服务
docker stack deploy -c docker-compose.yml wordpress
#查看服务
docker stack ls
#移除服务
docker stack down 服务名Swarm集群管理敏感数据
1
2
3
4#创建secret
openssl rand -base64 20 | docker secret create mysql_password -
#查看secret
docker secret ls创建MySQL服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27docker network create -d overlay mysql_private
docker service create \
--name mysql \
--replicas 1 \
--network mysql_private \
--mount type=volume,source=mydata,destination=/var/lib/mysql \
--secret source=mysql_root_password,target=mysql_root_password \
--secret source=mysql_password,target=mysql_password \
-e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" \
-e MYSQL_PASSWORD_FILE="/run/secrets/mysql_password" \
-e MYSQL_USER="wordpress" \
-e MYSQL_DATABASE="wordpress" \
mysql:latest
docker service create \
--name wordpress \
--replicas 1 \
--network mysql_private \
-p 3000:80 \
--mount type=volume,source=wpdata,destination=/var/www/html \
--secret source=mysql_password,target=wp_db_password,mode=0400 \
-e WORDPRESS_DB_USER="wordpress" \
-e WORDPRESS_DB_PASSWORD_FILE="/run/secrets/wp_db_password"\
-e WORDPRESS_DB_HOST="mysql:3306" \
-e WORDPRESS_DB_NAME="wordpress" \
wordpress:latestSwarm集群中管理配置数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14#新建redis.conf文件
cat redis.conf
port 6380
#创建config
docker config create redis.conf redis.conf
#查看config
docker config ls
#创建redis服务
docker service create \
--name redis \
--config redis.conf \
-p 6379:6380 \
redis:latest \
redis-server /redis.confSwarm mode与滚动升级
1
2
3
4
5
6
7
8
9#之前已通过命令创建nginx服务
docker service create --name nginx --replicas 2 -p 80:80 nginx:1.13.7-alpine
#升级
docker service update \
--image nginx:1.13.12-alpine \
nginx
#回滚
docker service rollback nginxetcd集群
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47version: '3'
networks:
byfn:
services:
etcd1:
image: quay.io/coreos/etcd
container_name: etcd1
command: etcd -name etcd1 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
ports:
- 2379
- 2380
networks:
- byfn
etcd2:
image: quay.io/coreos/etcd
container_name: etcd2
command: etcd -name etcd2 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
ports:
- 2379
- 2380
networks:
- byfn
etcd3:
image: quay.io/coreos/etcd
container_name: etcd3
command: etcd -name etcd3 -advertise-client-urls http://0.0.0.0:2379 -listen-client-urls http://0.0.0.0:2379 -listen-peer-urls http://0.0.0.0:2380 -initial-cluster-token etcd-cluster -initial-cluster "etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380" -initial-cluster-state new
ports:
- 2379
- 2380
networks:
- byfn
#查看集群状态
docker exec -t etcd1 etcdctl member list
#etcd操作
#set 设置值
etcdctl put /testdir/testkey "Hello world"
#put 更新值
etcdctl update /testdir/testkey "Hello world 666"
#get 获取值
etcdctl get /testdir/testkey
#更多命令可查--help
etcdctl --helpk8s
1
2
3#快速上手
#启动etcd服务
docker run --net=host -d gcr.io/google_containers/etcd:2.0.9 /usr/local/bin/etcd --addr=127.0.0.1:4001 --bind-addr=0.0.0.0:4001 --data-dir=/var/etcd/data