一. Docker概述
1. Docker为什么出现?
开发:我在我的电脑上可以运行!
运维:环境配置十分麻烦!
Docker:带着环境打包部署上线
2. Docker简介
容器虚拟化技术、
隔离、快速、轻便
2013年 Docker开源
Go语言
C-S架构:Server端 Docker守护进程
3. Docker的功能
1.应用更快交付和部署DevOps
2.应用更便捷的升级和扩缩容
3.更简单的系统运维
4.更高效的计算资源利用
二. Docker安装
参考官方文档:https://docs.docker.com/
配置阿里云镜像加速:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
三. Docker常用命令
官方文档:https://docs.docker.com/reference/
1. 帮助命令
docker version
docker info
docker <命令> --help
2. 镜像命令
dockerHub镜像仓库: https://hub.docker.com/
docker images //-a -q
docker search mysql //--filter=STARS=3000
docker pull mysql:5.7
docker rmi -f 镜像ID 镜像ID 镜像ID
docker rmi -f $(docker images -aq)
3. 容器命令
docker run centos
--name=”Name” -d后台运行 -it /bin/bash交互式进入容器
-p 指定端口映射关系 -P 随机指定端口
docker ps
-a -n=1 -q
exit:停止容器并退出
Ctrl+P+Q:不停止容器退出
docker rm -f 容器ID
docker rm -f $(docker ps -aq)
docker start 容器ID
docker restart 容器ID
docker stop 容器ID //停止容器
docker kill 容器ID //强制停止容器
4. 查看容器日志/进程/元数据
docker run -d centos //后台启动容器
docker run -d centos -c "while true;do echo yuntong;sleep 2;done" //生成日志
docker logs -t -f --tail 10 容器ID //查看日志
docker top 容器ID //查看容器中进程信息
docker inspect 容器ID //查看元数据
5. 进入容器/拷贝
docker exec -it 容器ID /bin/bash //开启一个新的终端进行交互
docker attach 容器ID //直接进入容器当前终端
docker cp 容器ID:容器内路径 宿主机路径
6. 可视化portainer
docker run -d -p 8088:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock --privileged=true portainer/portainer
四. Docker镜像
1. 联合文件系统UnionFS
共用、分层
bootfs rootfs
2. commit镜像
使用commit命令提交一个容器为新的镜像
docker commit -m="add webapps" -a="yuntong" 2abfa51e2644 tomcat02:1.0
五. 容器数据卷
1. 为什么容器数据卷?
数据持久化、同步、共享
docker volume ls # 查看数据卷
docker vokume inspect 卷名 # 详细信息,可查看挂载路径
2. 数据卷挂载
1.数据默认是双向同步的
2.容器删除,宿主机数据不会消失
3.不指定宿主机路径的挂载,默认路径为 /var/lib/docker/volumes/xxx
方式一:-v参数指定
docker run -d -v 宿主机路径:容器路径 -P nginx # 指定路径挂载
docker run -d -v 容器路径 -P nginx # 匿名挂载
docker run -d -v 卷名:容器路径 -P nginx # 具名挂载
拓展:
docker run -d -v 卷名:容器路径:ro -P nginx # 只能通过宿主机操作挂载路径,容器内部无法操作
docker run -d -v 卷名:容器路径:rw -P nginx
方式二:DockerFile方式
docker build -f <DockerFile> -t <镜像名>:版本 .
3. 容器数据卷
使用 --volumes-from 实现数据同步
docker run -it --name docker02 --volumes-from docker01 yuntong/centos:1.0
六. DockerFile
1. DockerFile介绍
用于构建Docker镜像
步骤:
1.编写Dockerfile文件
2.docker build 一个镜像
3.docker run 运行镜像
4.docker push 发布镜像
2. DockerFile指令
docker history <镜像ID> #查看docker镜像构建过程
FROM # 基础镜像
MAINTAINER # 作者:姓名<邮箱>
ENV # 设置环境变量
WORKDIR # 设置工作路径
EXPOSE # 暴露端口
VOLUME # 挂载数据卷
RUN # 构建镜像时执行的命令
CMD # 容器运行时的命令,覆盖
ENTRYPOINT # 容器运行时的命令,可追加
COPY # 文件拷贝
ADD # 添加文件自动解压
3. 实战:自定义Tomcat镜像
1.编写Dockerfile文件
已准备压缩包:apache-tomcat-9.0.41.tar.gz jdk-8u60-linux-x64.tar.gz
FROM centos
MAINTAINER yuntong<2099366926@qq.com>
COPY Readme.txt /usr/local/Readme.txt
ADD apache-tomcat-9.0.41.tar.gz /usr/local/
ADD jdk-8u60-linux-x64.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_60
ENV CLASSPATH $JAVA_HOME/lib/dt.jar;$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.41
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.41
ENV PATH $PATH;$JAVA_HOME/bin;$CATALINA_HOME/lib;$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.41/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.41/bin/logs/catalina.out
2.构建镜像
docker build -t diytomcat .
3.运行自定义tomcat
docker run -d -p 9090:8080 --name ytzhaotomcat -v /home/zyt/build/tomcat/test:usr/local/apache-tomcat-9.0.41/webapps/test -v /home/zyt/build/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.41/logs diytomcat
4. 镜像发布
发布到DockerHub
docker tag a1829fc75f7e zhaoyuntong123/tomcat:1.0 # 打标签
docker login -u zhaoyuntong123 # 登陆dockerhub
docker push zhaoyuntong123/tomcat:1.0 # 发布镜像(zhaoyuntong123为dockerhub用户名)
发布到阿里云
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories
5. 镜像备份恢复
docker save -o myTomcat.tar diytomcat:latest
docker load < myTomcat.tar
七. Docker网络
1. Docker0
Docker0相当于一个路由器,所有容器同属于一个局域网,通过Docker0互联。
Docker0为每一个容器分配一个IP地址。
Docker0与容器之间:使用Linux虚拟网络设备veth-pair进行连接。
2. 容器互联–link(不推荐)
场景:mysql容器重启,docker0会重新分配一个ip给mysql,之前依赖于mysql的服务就无法通过之前的ip访问mysql了。这个高可用问题待解决。
解决方式:配置容器互联
docker run -d -P --name tomcat03 --link tomcat02 tomcat # 配置容器互联--link
# 原理:tomcat03在/etc/hosts中配置了映射关系
root@zyt-vm:/#docker exec -it tomcat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 tomcat02 2cb18eb24a2d
172.17.0.4 16c903c4d7fc
# 单向配置就只能单向连通
root@zyt-vm:/#docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.193 ms
root@zyt-vm:/#docker exec -it tomcat02 ping tomcat03
3. 容器互联-自定义网络(推荐)
docker network ls
docker network inspect <网络ID>
网络模式
bridge:桥接模式 (默认),docker0充当交换机的角色。
host:容器使用宿主机的网络和端口
none:不配置网络
container:容器网络联通(用得少,局限性大)
# 创建一个网络
docker network create -d bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
# 使用这个网络
docker run -d -P --name tomcat02 --net mynet tomcat
docker run -d -P --name tomcat03 --net mynet tomcat
# 自定义的网络无需使用--link就可以直接使用服务名相互访问
root@zyt-vm:/# docker exec -it tomcat02 ping tomcat03
PING tomcat03 (192.168.0.4) 56(84) bytes of data.
64 bytes from tomcat03.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.214 ms
root@zyt-vm:/# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.070 ms
4. 网络连通
mysql集群使用一个net,redis集群使用一个net,他们之间网络隔离,不同的集群之间网络如何联通?
docker network connect mynet tomcat01 # 打通网络
# 原理:connect之后,直接将tomcat01直接加入到了mynet网络中(相当于给tomcat01又配了一个公网网卡)
root@zyt-vm:/# docker network inspect f2a173f5e5df
"Containers": {
"330a22ff5b73719cb21dca66a1d0d03cb63273e1801bbfcef839877281b4b12e": {
"Name": "tomcat01-net",
"EndpointID": "aba595ba49f842769450989ce50a973964a03eb56f56a3a29131d8f2055ae3d4",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"38a9671009d5d8d867d393da72f7f3cadfdaaa0d0cb7b860430dca0cd74ba04a": {
"Name": "tomcat01",
"EndpointID": "3638cc1da67bfe609f5fd0cba9230cfe0320f2731895d1555607285eddb7076c",
"MacAddress": "02:42:c0:a8:00:04",
"IPv4Address": "192.168.0.4/16",
"IPv6Address": ""
},
5. 实战:部署redis集群
# 创建redis网络
docker network create redis --subnet 172.38.0.0/16
# 创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done
#启动六个redis容器
docker run -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /mydata/redis/node-1/data:/data \
-v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
# 进入其中一个容器
docker exec -it redis-1 /bin/sh
#创建redis集群
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
#查看redis集群状态
redis-cli -c
cluster info
cluster nodes
6. SpringBoot微服务打包Docker镜像
# 1.构建SpringBoot项目
# 2.打包应用
# 3.编写Dockerfile
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
# 4.构建镜像
# 5.发布运行