Docker概述
Docker流程
java -- apk -- 发布(应用商店) -- 下载使用apk -- 安装即可用
java -- jar(环境) -- 打包项目带上环境(镜像) -- Docker仓库(商店) -- 下载发布镜像 -- 直接运行
Docker每个月都会更新一个版本
官网地址: https://www.docker.com/
文档地址: https://docs.docker.com/
仓库地址: https://hub.docker.com/
Docker容器技术 和 虚拟机技术 区别
传统虚拟机:
虚拟出一套硬件,运行一个完整的操作系统,然后在系统中安装和运行软件。
Docker容器:
1.容器内的应用直接运行在宿主机内核,容器没有自己内核。
2.不需要虚拟硬件。
3.每个容器间都是相互隔离,有自己的文件系统,互不影响。
Docker优势
应用更快速的交付和部署
传统: 一堆稳稳当,安装程序。
Docker: 打包镜像发布测试,一键运行。
更便捷的升级和扩缩容
项目打包为镜像,快速扩展缩容服务器。
更简单的系统运维
开发和测试环境都是高度一致。
更高效的计算资源利用
Docker是内核级别的虚拟化,可以在一个物理机上运行多个容器实例。
Docker安装
Docker基本组成
镜像(image):
Docker镜像好比是一个模版,通过这个模版床架内容器服务
容器(container):
dokcer利用容器技术,独立运行一个或者一个组应用,通过镜像来创建
仓库(repository)
存放镜像的地方
仓库分为公有仓库和私有仓库
Docker Hub(默认是国外的)
安装Docker
准备环境:
- CentOS 7
- Xshell
- 查看环境
系统内核
root@docker01 ~ 11:10:03
# uname -r
3.10.0-957.el7.x86_64
系统版本
root@docker01 ~ 11:10:14
# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
卸载旧的版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
需要的安装包
yum install -y yum-utils
设置镜像仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo # 默认是国外
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新软件包索引
yum makecache fast
安装docker相关
yum install docker-ce docker-ce-cli containerd.io
卸载
yum remove docker-ce docker-ce-cli containerd.io
清除资源
rm -rf /var/lib/docker
默认工作路径
/var/lib/docker
配置镜像加速器
底层原理
Docker是一个Client - Server 结构的系统 , docker的守护进程运行在主机上,通过Socket从客户端访问。
D ockerServer 接受到Docker-Client的指令,就会执行命令。
Docker为什么比VM快?
- Docker比虚拟机更少的抽象层
- Docker利用宿主机内核,VM需要Guest OS。
所以说,新建一个Docker容器不需要像虚拟机一样重新加载一个操作系统,避免引导。
虚拟机加载Guest OS,分钟级。
Docker是利用宿主机操作系统,省略了这个过程,秒级。
Docker命令
帮助命令
docker version #显示docker版本信息
docker info #显示docker系统信息,包括镜像和容器数量
docker 命令 --help #帮助命令
Docker命令文档:https://docs.docker.com/reference/
镜像命令
docker search 搜索镜像,优先选择官方,start数量多.
docker image pull == docker pull 下载镜像
docker image push == docker push 上传镜像
docker image save == docker save 导出镜像
docker image load == docker load 导入镜像
docker image ls == docker images 查看镜像列表
docker image rm == docker rmi 删除镜像
docker image tag == docker tag 给镜像打标签
docker image inspect == docker inspect 查看属性
docker image prune == docker prune 清理无效文件
容器命令
docker container run == docker run 创建并运行容器
root@docker01 ~ 08:34:37
# docker run -d -p 80:80 nginx:latest
fcd3aa110723d9d5a98edf77968190dac455ec80e2a43fdd0e767d6af2782b1a
root@docker01 ~ 08:35:37
# docker exec -it fcd3aa110723d9d5a98edf77968190dac455ec80e2a43fdd0e767d6af2782b1a /bin/bash
root@fcd3aa110723:/usr/share/nginx/html# echo 'hello world' > index.html
root@fcd3aa110723:/usr/share/nginx/html# exit
docker container create == docker create 创建容器
docker container start == docker start 启动容器
docker container stop == docker stop 停止容器
docker container kil1 == docker kill 强制停止容器
docker container restart == docker restart 重启容器
docker container ls == docker ps 查看容器列表
docker container rm == docker rm 删除容器
docker container exec == docker exec 进入正在运行的容器(进入一个新的终端)
docker container attach == docker attach 进入正在运行的容器(进入正在执行的终端)
docker container cp == docker cp 在容器和宿主机之间相互拷贝文件
docker container logs == docker logs 查看容器日志
-t 显示时间戳
-f 跟踪跟踪日志输出
--tail 7 查看前7行日志
docker container inspect == docker inspect 查看容器信息
ctrl+p+q 退出不停止
37e8b3c587ee
操作命令
Docker镜像
安装一个nginx容器
docker run -d -p 80:80 nginx:latest
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fcd3aa110723 nginx:latest "/docker-entrypoint.…" 35 minutes ago Up 35 minutes 0.0.0.0:80->80/tcp adoring_lewin
docker exec -it fcd3aa110723d9d5a98edf77968190dac455ec80e2a43fdd0e767d6af2782b1a /bin/bash
root@fcd3aa110723:/# cd usr/share/nginx/html
root@fcd3aa110723:/# echo 'hello world' > index.html
打包成一个容器
docker commit -a='wy' -m='hello world' fcd3aa110723 nginx:v1.2
运行刚打包的容器
docker run -d -p 80:80 nginx:v1.2
c64efd6e7ff2ced5ece56a79a72dacb48ad49c2e31610675b5abfc0ae4dd91d9
安装一个tomcat容器
docker run -d -p 8080:8080 tomcat:latest
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fcd3aa110723 nginx:latest "/docker-entrypoint.…" 38 minutes ago Up 38 minutes 0.0.0.0:80->80/tcp adoring_lewin
3cb6abe0a3ed tomcat:latest "catalina.sh run" 41 minutes ago Up 41 minutes 0.0.0.0:8080->8080/tcp silly_bouman
docker exec -it 3cb6abe0a3ed /bin/bash
cp -r webapps.dist/* webapps/
打包成一个容器
docker commit -a='wy' -m='tomcat' 3cb6abe0a3ed tomcat:v1.2
sha256:f725922835ec53c0a992a7880decc0a6f1b6f8490aaa377b1012eaed22cf16e4
运行刚打包的容器
docker run -d -p 8080:8080 tomcat:v1.2
8b17a6e6a1e2b9b194ae3e8f8cc5b080095f7c8486038b83a110b42bce59bdbd
容器数据卷
容器之间可以有一个数据共享技术,Docker容器中产生的数据,同步到本地。
这就是技术卷技术,目录的挂载,将容器内的目录,挂载到本利Linux上面。
总结: 容器的持久化和同步操作,容器间也可以数据共享。
使用数据卷
方式一:直接使用命令挂载 -v
docker run -it -v 本机目录:容器目录
测试
docker run -d -v /home/nginx:/usr/share/nginx/html -p 80:80 nginx:v1.2
3a4d6cba22153840d5675d06eb0ea4ca49e762a23502de551fbec5f6e0d71c93
docker inspect 3a4d6cba2215
"Mounts": [
{
"Type": "bind",
"Source": "/home/nginx", #主机地址
"Destination": "/usr/share/nginx/html", #容器内地址
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3a4d6cba2215 nginx:v1.2 "/docker-entrypoint.…" 13 seconds ago Up 12 seconds 0.0.0.0:80->80/tcp crazy_black
docker stop 3a4d6cba2215
echo 'mmmmmmmmmmmmmmm' > index.html
docker start 3a4d6cba2215
好处:以后修改只需要在本地修改即可,容器内会自动同步。
具名和匿名挂载
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载
具名挂载可以方便的找到一个卷,大多数情况在使用具名挂载
通过 -v 容器内路径:ro/rw 改编读写权限
ro readonly #只读
rw readwrite #可读可写
一旦设定了容器权限,容器对挂载出来的内容就有限定了
docker run -d -v /home/nginx:/usr/share/nginx/html:ro -p 80:80 nginx:v1.2
# ro 只能通过宿主机彩操作,容器内就无法操作了。
docker run -d -v /home/nginx:/usr/share/nginx/html:rw -p 80:80 nginx:v1.2
Dockerfile就是用来构建docker镜像的构建文件,命令脚本。
通过脚本可以生成镜像,镜像是一层一层的,脚本是一个一个的命令,每个命令都是一层。
创建一个dockerfile文件
# dockerfile名字可以随机,建议dockerfile开头
# 文件中内容 指令(大写) 参数
# vim dockerfilr-centos
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "holle world"
CMD /bin/bash
构建dockerfile
# docker build -f dockerfilr-centos -t wy/centos:v1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 0d120b6ccaa8
Step 2/4 : VOLUME ["volume01","volume02"]
---> Running in 5737234e6cfb
Removing intermediate container 5737234e6cfb
---> 61e9e7c4ace8
Step 3/4 : CMD echo "holle world"
---> Running in ca560b309504
Removing intermediate container ca560b309504
---> c96aba035644
Step 4/4 : CMD /bin/bash
---> Running in daec985a6ac6
Removing intermediate container daec985a6ac6
---> f85f3aeafa67
Successfully built f85f3aeafa67
Successfully tagged wy/centos:v1.0
查看构建的docker镜像
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wy/centos v1.0 f85f3aeafa67 About a minute ago 215MB
启动构建的容器
[root@734457d72775 /]# ls -l
total 0
drwxr-xr-x 2 root root 6 Sep 2 04:19 volume01
drwxr-xr-x 2 root root 6 Sep 2 04:19 volume02
# 这个卷和宿主机有一个同步目录
查看挂载卷
# docker inspect 6428be746951
"Mounts": [
{
"Type": "volume",
"Name": "8bf5bdafc25c9291491ace27e6ddfbead8036828fcfebcaa3424de95d0914ab1",
"Source": "/var/lib/docker/volumes/8bf5bdafc25c9291491ace27e6ddfbead8036828fcfebcaa3424de95d0914ab1/_data",
"Destination": "volume02",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
},
{
"Type": "volume",
"Name": "9d700514efd314c391ddeb504062f8c8968c8c2656fe9f908cf1f9bf6fd4ddd4",
"Source": "/var/lib/docker/volumes/9d700514efd314c391ddeb504062f8c8968c8c2656fe9f908cf1f9bf6fd4ddd4/_data",
"Destination": "volume01",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
验证挂载
[root@6428be746951 /]# cd volume01
[root@6428be746951 volume01]# touch test.txt
root@docker01 /var/lib/docker/volumes/9d700514efd314c391ddeb504062f8c8968c8c2656fe9f908cf1f9bf6fd4ddd4/_data 12:23:04
# ll
total 0
-rw-r--r-- 1 root root 0 Sep 2 12:21 test.txt
数据卷容器
# docker run -it --name docker wy/centos:v1.0 /bin/bash
# docker run -it --name docker01 --volumes-from docker wy/centos:v1.0 /bin/bash
[root@af53077fc3da /]# cd volume01
[root@af53077fc3da volume01]# touch 1.txt
[root@8e0006d2ad12 /]# cd volume01
[root@8e0006d2ad12 volume01]# touch 2.txt
[root@af53077fc3da volume01]# ls
1.txt 2.txt
[root@8e0006d2ad12 volume01]# ls
1.txt 2.txt
之后启动容器挂载也会同步挂载目录的文件
# docker run -it --name docker02 --volumes-from docker wy/centos:v1.0 /bin/bash
[root@7b37e8356f01 /]# cd volume01
[root@7b37e8356f01 volume01]# ls
1.txt 2.txt
结论:
容器之间配置信息传递,数据卷容器的生命周期一直持续到没有容器为止。
但是一旦持久化到本地,本地数据是不会删除的。
DockerFile
DockerFile介绍
dockerfile是用来构建docker镜像文件,命令参数脚本。
构建步骤:
- 编写一个dockerfile 文件
- docker build 构建镜像
- docker run 运行镜像
- docker push 发布镜像
DockerFile构建过程
基础知识
- 每个指令都是必须大写
- 之星从上到下顺序执行
- # 表示注释
- 每一个指令都会创建提交一个新的镜像层,并提交。
dockerfile是面向开发的,要发布项目,作镜像,就需要编写dockerdile文件。
Docker镜像逐渐成为企业交付的标准,必须掌握。
DockerFile:构建文件,定义了一切的步骤,源代码。
DockerImages:通过DockerFile构建生成的镜像,最终发布和运行的产品。
Docker容器:容器就是镜像运行起来提供服务。
DockerFile的指令
FROM #指定基础镜像 centos
MAINTAINER #镜像是谁写的
RUN #镜像构建时候需要运行的命令
ADD #步骤 nginx压缩包
WORKDIR #镜像工作目录
VOLUME #挂载目录
EXPOST #暴露端口
CMD #指定这个容器启动时候要运行的命令,只有最后一个会生效,可被代替
ENTRYPOINT #指定这个容器启动时候要运行的命令,可以追加
ONBUILD #当构建镜像被继承DockerFile这个时候就会运行ONBULD的指令。触发指令
COPY #类似ADD,将文件拷贝到镜像中
ENV #构建时候设置环境变量
RUN #运行
测试
Docker Hub 中99%镜像都是冲FROM scrath这个基础镜像过来的,然后配置需要的软件和配置进行构建的。
Docker网络原理
原理:
每启动一个docker容器,docker容器就会分配一个ip,只要安装docker,就会有一个网卡docker0.
桥接模式,使用的技术是evth-pair技术。
启动一个容器就会有一对网卡
70: vethd96a362@if69
evth-pair 就是一对的虚拟设备接口,它们出现都是成对的,一端连了协议,一端彼此相连。
正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的。
结论:tomcat01和tomcat02是公用的一个路由器,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给容器分配一个默认可用的IP。
docker使用的是linux的桥接,宿主机中士一个docker容器的网桥docker0
docker中所有的网络接口都是虚拟的,虚拟的转发效率高。
只要容器删除,对应的一对网桥就没了。
自定义网络
查看所有docker网络
# docker network ls
NETWORK ID NAME DRIVER SCOPE
b5dc3b970355 bridge bridge local
8f2cd56d3d7a host host local
6cf585b80b32 none null local
网络模式
bridge : 桥接 docker(默认)
none : 不配置网络
host : 和宿主机共享网络
contauner : 容器网络连通(用的少,局限性很大)
测试
# 直接启动的命令 --net bridge会默认启动,这个就是docker0
docker run -d -P --name nginx web
docker run -d -P --name nginx --net bridge web
# docker0 特点,默认,域名不能访问,--link可以打通连接。
创建自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 wy
--driver bridge #桥接
--subnet 192.168.0.0/16 #子网地址
gateway 192.168.0.1 #网关
docker network ls
NETWORK ID NAME DRIVER SCOPE
b5dc3b970355 bridge bridge local
8f2cd56d3d7a host host local
6cf585b80b32 none null local
6b00d8a3c691 wy bridge local
启动指定网络容器
docker run -d -P --name nginx-wy-net --net wy nginx
663cc3ffd3fe11ca7dbe4ebf29182db49e4e2fcc3d1ece9935ac0053a754343f
查看自定义网络
docker network inspect wy
...
"Containers": {
"663cc3ffd3fe11ca7dbe4ebf29182db49e4e2fcc3d1ece9935ac0053a754343f": {
"Name": "nginx-wy-net",
"EndpointID": "c95995e3f208f55d9624a68a4c2e7ba674827517a2695ad35ebb51d6ca394515",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
使用自定义网络,不适用–link也可以ping通容器名。
root@docker01 ~ 09:16:48
# docker run -d -P --name tomcat-net-01 --network wy tomcat
Unable to find image 'tomcat:latest' locally
latest: Pulling from library/tomcat
d6ff36c9ec48: Pull complete
c958d65b3090: Pull complete
edaf0a6b092f: Pull complete
80931cf68816: Pull complete
bf04b6bbed0c: Pull complete
8bf847804f9e: Pull complete
6bf89641a7f2: Pull complete
3e97fae54404: Pull complete
10dee6830d45: Pull complete
680b26b7a444: Pull complete
Digest: sha256:cbdcddc4ca9b47e42c7d0c2db78cbc0f7a8b4bbe1fa395f4a53c5a236db29146
Status: Downloaded newer image for tomcat:latest
c741558c4cd9c2681092b763a1da52670ce8e5529ca2b1555523aaed9b232bcd
root@docker01 ~ 09:18:19
# docker run -d -P --name tomcat-net-02 --network wy tomcat
c70897d4f58e37495e1eb8f40564a0aa9241e117522af7b0da358bdf3feb748e
root@docker01 ~ 09:18:24
# docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.wy (192.168.0.3): icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from tomcat-net-02.wy (192.168.0.3): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from tomcat-net-02.wy (192.168.0.3): icmp_seq=3 ttl=64 time=0.039 ms
测试tomcat-01 打通wy
# docker network connect --help
Usage: docker network connect [OPTIONS] NETWORK CONTAINER
Connect a container to a network
Options:
--alias strings Add network-scoped alias for the container
--driver-opt strings driver options for the network
--ip string IPv4 address (e.g., 172.30.100.104)
--ip6 string IPv6 address (e.g., 2001:db8::33)
--link list Add link to another container
--link-local-ip strings Add a link-local address for the container
连通测试
docker network connect wy tomcat-01
docker inspect wy
...
"Containers": {
"3e14f6e69eaec8859e2f7c08e8e8b08c0b46116c7012f935afea1061377424c1": {
"Name": "tomcat-01",
"EndpointID": "d73e85df36cad5e15cbe33d72490b9291ff25cd3975e4a314224b640fbb8dbed",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
"c70897d4f58e37495e1eb8f40564a0aa9241e117522af7b0da358bdf3feb748e": {
"Name": "tomcat-net-02",
"EndpointID": "93c417ec17a4c3deb336f1cecb10948f1af1bb944f5119fa9c4b385a1acb0e90",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"c741558c4cd9c2681092b763a1da52670ce8e5529ca2b1555523aaed9b232bcd": {
"Name": "tomcat-net-01",
"EndpointID": "7e132b966f0857d989559ec6adb0dcc6ef101b89d39d8e00149aba04d1916496",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
...
连通之后就是将tomcat01 放到了wy网络下
一个容器两个ip地址。
网卡和网卡是不能连通的,但是容器和网卡可以连通。
docker exec -it tomcat-01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.wy (192.168.0.2): icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from tomcat-net-01.wy (192.168.0.2): icmp_seq=2 ttl=64 time=0.060 ms
结论:假设要跨网络操作,就需要使用docker network connect 连通。
实战搭建redis集群
创建虚拟网卡
docker network create redis --subnet 172.38.0.0/16
8b1d0469809421a821079f74e9de5e3bb37257e81b03e7276156564f9add1122
docker network ls
NETWORK ID NAME DRIVER SCOPE
b5dc3b970355 bridge bridge local
8f2cd56d3d7a host host local
6cf585b80b32 none null local
8b1d04698094 redis bridge local
通过脚本创建6个redis配置
for port in `seq 1 6`;\
do \
mkdir -p /redisdata/redis/node-${port}/conf
touch /redisdata/redis/node-${port}/conf/redis.conf
cat << EOF >/redisdata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /redisdata/redis/node-${port}/data:/data \
-v /redisdata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --network redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf; \
done
创建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
连接集群查看集群
/data # redis-cli -c
127.0.0.1:6379> CLUSTER NODES
7fecd5c591884301d46baa2ae6ecf103d4a9e7d2 172.38.0.16:6379@16379 slave cd0bf96ccdfa3e876081ec0d3d1a8e285bb78dc4 0 1599099113348 6 connected
16bd9e562436f149926470e1f862e33dd4f0be70 172.38.0.15:6379@16379 slave 1fe38e4dcd5e85b7d9a1b62135f1dd64db9bf7c2 0 1599099115357 5 connected
1fe38e4dcd5e85b7d9a1b62135f1dd64db9bf7c2 172.38.0.11:6379@16379 myself,master - 0 1599099113000 1 connected 0-5460
cd0bf96ccdfa3e876081ec0d3d1a8e285bb78dc4 172.38.0.12:6379@16379 master - 0 1599099114352 2 connected 5461-10922
eb94ef7939631fd561cd0e4dd2c8e44b3693ea80 172.38.0.14:6379@16379 slave aba1c566bdfe413be0cf5e855abeda62b0c8b2d3 0 1599099112000 4 connected
aba1c566bdfe413be0cf5e855abeda62b0c8b2d3 172.38.0.13:6379@16379 master - 0 1599099112344 3 connected 10923-16383
IDEA整合docker
Docker Compose
介绍
docker 需要DockerFile build run 手动操作,单个容器。
docker-compose 高效管理容器,定义运行多个容器。
docker-compose 官方介绍
1. 定义、运行多个容器。
2. YAML file 配置文件。
3. single command 命令。
docker-compose使用 有三个步骤
1. 定义一个DockerFile 保证项目在任何地方运行。
2. docker-compose.yaml 文件定义一个服务
3. docker-compos up 启动项目
作用:批量容器编排
docker-compose.yml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
environment:
FLASK_ENV: development
redis:
image: "redis:alpine"
compos重要概念
- 服务services,容器应用(web、redis.mysql)
- 项目project,一组关联的容器。
安装
compose是docker官方开源项目,需要安装
官方源
curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
国内源
curl -L https://get.daocloud.io/docker/compose/releases/download/1.26.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
安装检查
root@docker01 ~ 09:19:13
# docker-compose version
/usr/lib/python2.7/site-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.25.10) or chardet (2.2.1) doesn't match a supported version!
RequestsDependencyWarning)
/usr/lib64/python2.7/site-packages/cryptography/__init__.py:39: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
CryptographyDeprecationWarning,
docker-compose version 1.26.2, build unknown
docker-py version: 4.2.2
CPython version: 2.7.5
OpenSSL version: OpenSSL 1.0.2k-fips 26 Jan 2017
docker-compose使用
- 创建项目目录
mkdir composetest
cd composetest
- 在项目文件夹中创建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)
- 在项目目录中创建requirements.txt
flask
redis
- 在项目目录中创建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"]
- 在项目目录中创建docker-compose.yaml
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
- 在项目目录中运行
docker-compose up
YAML规则
docker-compose.yaml 核心。
https://docs.docker.com/compose/compose-file/
# 3层
verion: '' # 版本
services: # 服务
服务1:web
#服务配置
images
build
network
服务2:redis
服务2:mysql
#其他配置
volumes:
metwokers:
configs:
- 编写项目微服务
- DockerFile构建镜像
- docker-compose.yaml编排项目
- 发布到服务器 docker-compose up
Docker Swarm
https://docs.docker.com/engine/swarm/
工作模式
manager 管理节点
worker 工作节点
所有操作都在manager节点上操作
主节点至少3台
搭建集群
- 在docker01上初始化节点
docker swarm init --advertise-addr 172.16.1.81
- 生成管理节点令牌
root@docker01 ~ 11:22:55
# docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-49l056888wwwsc2en541631tnhe5rqy0n1gzp0esfh6d2zyb5f-btmtiaapcd0jtrwo3rb1xln3j 172.16.1.81:2377
- 生成工作节点令牌
root@docker01 ~ 11:20:03
# docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-49l056888wwwsc2en541631tnhe5rqy0n1gzp0esfh6d2zyb5f-cme1d44fk3bwztfif6w1iv8mt 172.16.1.81:2377
- 将docker02加入到集群管理节点
root@docker02 ~ 09:16:40
# docker swarm join --token SWMTKN-1-49l056888wwwsc2en541631tnhe5rqy0n1gzp0esfh6d2zyb5f-btmtiaapcd0jtrwo3rb1xln3j 172.16.1.81:2377
This node joined a swarm as a manager.
- 将docker03、docker04加入到集群工作节点
root@docker03 ~ 09:16:42
# docker swarm join --token SWMTKN-1-49l056888wwwsc2en541631tnhe5rqy0n1gzp0esfh6d2zyb5f-cme1d44fk3bwztfif6w1iv8mt 172.16.1.81:2377
This node joined a swarm as a worker.
docker04也一样
- 查看集群
root@docker01 ~ 11:23:25
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
kyoo95nk4pj4smkwj2vmmazk2 * docker01 Ready Active Leader 19.03.12
rw64x1byeteqw1xvourn0hfts docker02 Ready Active Reachable 19.03.12
rbio9r3cj7u5nyceerhw6x5uw docker03 Ready Active 19.03.12
5vtgmlvymixqpo6vex7xo01pu docker04 Ready Active 19.03.12
- 将docker03离开集群
root@docker03 ~ 11:16:18
# docker swarm leave
Node left the swarm.
root@docker01 ~ 11:43:29
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
kyoo95nk4pj4smkwj2vmmazk2 * docker01 Ready Active Leader 19.03.12
rw64x1byeteqw1xvourn0hfts docker02 Ready Active Reachable 19.03.12
rbio9r3cj7u5nyceerhw6x5uw docker03 Down Active 19.03.12
5vtgmlvymixqpo6vex7xo01pu docker04 Ready Active 19.03.12
- 将docker03加入管理节点
root@docker03 ~ 11:44:18
# docker swarm join --token SWMTKN-1-49l056888wwwsc2en541631tnhe5rqy0n1gzp0esfh6d2zyb5f-btmtiaapcd0jtrwo3rb1xln3j 172.16.1.81:2377
This node joined a swarm as a manager.
root@docker01 ~ 11:46:33
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
kyoo95nk4pj4smkwj2vmmazk2 * docker01 Ready Active Leader 19.03.12
rw64x1byeteqw1xvourn0hfts docker02 Ready Active Reachable 19.03.12
99mbynkn2zi4jxm0hvjgabvi1 docker03 Ready Active Reachable 19.03.12
rbio9r3cj7u5nyceerhw6x5uw docker03 Down Active 19.03.12
5vtgmlvymixqpo6vex7xo01pu docker04 Ready Active 19.03.12
Raft协议
保证大多数节点存活才可以使用。节点数>1,所以集群主节点至少大于3台。
- 关闭主节点docker01、docker02,docker03主节点不可以使用,集群不可用。
root@docker01 ~ 11:53:11
# systemctl stop docker
root@docker02 ~ 11:43:22
# systemctl stop docker
root@docker03 ~ 11:52:41
# docker node ls
Error response from daemon: rpc error: code = Unknown desc = The swarm does not have a leader. It's possible that too few managers are online. Make sure more than half of the managers are online.
- work节点就是工作用的不可以执行
root@docker04 ~ 09:16:43
# docker node ls
Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
弹性扩缩容
- 在集群中创建一个nginx容器
root@docker01 ~ 12:11:51
# docker service create -p 80:80 --name my-nginx nginx
i0xqaq3f6npyr02soxtvfi2lh
overall progress: 1 out of 1 tasks
1/1: running
verify: Service converged
root@docker01 ~ 12:25:58
# curl 172.16.1.81
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 创建多个副本进行扩容
扩容:
root@docker01 ~ 12:26:55
# docker service update --replicas 7 my-nginx
my-nginx
overall progress: 7 out of 7 tasks
1/7: running
2/7: running
3/7: running
4/7: running
5/7: running
6/7: running
7/7: running
verify: Service converged
docker01
root@docker01 ~ 12:29:03
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d37f00f5ffd7 nginx:latest "/docker-entrypoint.…" 22 seconds ago Up 9 seconds 80/tcp my-nginx.4.y1uv5z470k2yt6k5uplve5lgl
d6f01a62f8e1 nginx:latest "/docker-entrypoint.…" 22 seconds ago Up 9 seconds 80/tcp my-nginx.3.bblgdgumye2rg7itzdam641o2
docker02
root@docker02 ~ 12:08:34
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
581a1e34e753 nginx:latest "/docker-entrypoint.…" 22 seconds ago Up 16 seconds 80/tcp my-nginx.5.29h4q3mpm4txvjipi10v1mwef
docker03
root@docker03 ~ 12:08:07
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56461cfd2f02 nginx:latest "/docker-entrypoint.…" 22 seconds ago Up 10 seconds 80/tcp my-nginx.7.izdriqdabe0u5fij22c1d6jzs
5a7ee06df790 nginx:latest "/docker-entrypoint.…" 22 seconds ago Up 10 seconds 80/tcp my-nginx.6.wyic44g3opnjh4ljmynko7hqb
docker04
root@docker04 ~ 12:29:08
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6bcabb2e5594 nginx:latest "/docker-entrypoint.…" 29 seconds ago Up 28 seconds 80/tcp my-nginx.2.4giauzwkv13t5qyniqt8txwei
bf26fdf4a324 nginx:latest "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 80/tcp my-nginx.1.j8wxd5zvfj1xfaz8oh7lnmbp4
缩容
root@docker01 ~ 12:38:07
# docker service update --replicas 1 my-nginx
my-nginx
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
只有docker04上有一个nginx 容器了
root@docker04 ~ 12:37:07
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bf26fdf4a324 nginx:latest "/docker-entrypoint.…" 12 minutes ago Up 12 minutes 80/tcp my-nginx.1.j8wxd5zvfj1xfaz8oh7lnmbp4
服务,集群中任意的节点都可以访问,服务可以有多个副本动态扩缩容实现高可用。
总结
swarm
集群的管理和编号。docker 可以初始化一个swarm集群,其他节点可以加入。(管理节点,工作节点)
node
就是一个docker节点,多个节点就组成一个网络集群。
service
任务,可以在管理节点或者工作节点来运行。
task
容器内的命令。
命令 -> 管理-> api-> 调度-> 工作节点(创建task容器维护创建)