基础
常用命令
安装启动 docker
sudo yum install -y yum-utils
sudo yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's/download.docker.com/mirrors.aliyun.com\/docker-ce/g' /etc/yum.repos.d/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
systemctl enable docker # docker开机启动
systemctl stop firewalld && systemctl disable firewalld # 关闭防火墙
systemctl restart docker # 关闭防火墙后重启docker,如果不重启则docker的ip包转发功能无法使用。即使防火墙关了,docker会调用没和模块netfilter增加规则,所以能看到防火墙规则
iptables -L -n #多了docker的一些路由
复制代码
具体文档https://yeasy.gitbook.io/docker_practice/install/centos
设置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{ "registry-mirrors": ["https://0jcr2954.mirror.aliyuncs.com"] }
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
复制代码
镜像操作
docker images #显示镜像
docker search tomcat #搜索镜像
docker pull tomcat # 拉取镜像
docker pull mysql:5.7 # 下载指定版本
docker rmi hello-world #删除镜像
docker rmi -f bf7334 #删除镜像(bf7镜像id)
docker rmi -f $(docker images -aq) # 删除所有镜像
docker load -i tar包名称 # 加载 某个镜像
复制代码
容器启动停止
docker run -it tomcat # -i: 交互式操作。-t: 终端。
docker run -it tomcat:latest /bin/bash # 启动 镜像名tomcat, tag为latest的镜像
Exit # 容器停止并退出
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike apollo-configservice # 查看正在运行容器apollo-configservice的启动命令
ctrl+P+Q #容器不停止退出
docker run -d --name tomcat01 -p 8088:8080 tomcat # -d 指定容器的运行分离模式(后台) --name 启动的时候执行实例名称为tomcat01
docker rename tomcat1 tomcat2 # 吧tomcat1改成tomcat2
docker start b750bbbcfd88 # b750 容器id;使用 docker start 启动一个已停止的容器;
docker stop b750bbbcfd88 # b750 容器id;使用 docker stop停止容器;
docker kill b750bbbcfd88 # b750 容器id;强制停止
docker rm -f 1e560fca3906 # 删除容器
docker ps -a # 查看所有容器,包括已停止的容器
docker ps # 查看当前运行的容器
docker logs 实例id # 查看日志
docker run --restart=always -itd --name 容器名 镜像 /bin/bash # 容器开机启动
docker update --restart=always 容器名 # 更改重启策略,改为开机启动
docker run -it --cpuset -cpus 0,1 -m 128m centos # 启动centos镜像,限制只能再cpu0 和cpu1上跑,且内存最大不超过128m
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
70062327fc72 apollo-portal "/apollo-portal/scri…" 2 years ago Up 4 weeks 0.0.0.0:8070->8070/tcp apollo-portal
808793d179ee apollo-adminservice "/apollo-adminservic…" 2 years ago Up 4 weeks 0.0.0.0:8090->8090/tcp apollo-adminservice
7feade55a442 apollo-configservice "/apollo-configservi…" 2 years ago Up 4 weeks 0.0.0.0:8080->8080/tcp apollo-configservice
89f85b83a29b mysql:5.7.19 "docker-entrypoint.s…" 2 years ago Up 4 weeks 0.0.0.0:13306->3306/tcp mysql
docker exec -it b750bbbcfd88 /bin/sh #进入在运行的容器中执行命令,开启一个新的终端
docker attach b750bbbcfd88 #进入正在执行的终端,不会启动新的进程
docker run --name mysql-go -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:5.7 # 启动mysql带密码
复制代码
日志 &进程 &镜像元数据 &监控
docker logs -f -t --tail 20 83f60d01e043 # 83f容器id;查看容器日志
docker top 83f60d01e043 # 查看docker容器内的进程信息;
docker inspect 83f60d01e043 # 查看镜像元数据
docker stats # 查看容器占用cpu 内存情况
复制代码
拷贝
docker cp 容器id:容器内路径 目的主机路径 #吧容器内的文件拷贝到宿主机
复制代码
ADD 和 COPY 的区别 ADD 指令的功能是将主机构建环境(上下文)目录中的文件和目录、以及一个 URL 标记的文件 拷贝到镜像中。其格式是: ADD 源路径 目标路径如果源文件是个归档文件(压缩文件),则 docker 会自动帮解压 ADD /foo.tar.gz /tmp/上述指令会使 foo.tar.gz 压缩文件解压到容器的/tmp 目录。URL 下载和解压特性不能一起使用。任何压缩文件通过 URL 拷贝,都不会自动解压。目前 ADD 指令有点让人迷惑,有时候解压文件,有时候不解压文件,如果你想拷贝一个压缩文件,你会以为地解压。如果文件是某种不能识别的压缩文件,如果你想解压,你又会意外地复制它。这种解释似乎是 ADD 尝试做的太多了,让用户有些疑惑。很明显,没人想要打破向后兼容性。所以决定新增一个行为更加明确的指令。COPY 和 ADD 相似,但是功能少一些。在 Docker 1.0 发布时候,包括了新指令 COPY。不像是 ADD,COPY 更加直接了当,只复制文件或者目录到容器里。COPY 不支持 URL,也不会特别对待压缩文件。Docker 团队的建议是在大多数情况下使用 COPY。拷贝文件的原则:使用 COPY(除非你明确你需要 ADD)
Commit 提交
docker commit -a="mairongcong" -m="随便加了一个文件 webapps" 248541cf6089 tomcat008:1.0
# 提交容器新的版本镜像
复制代码
数据卷挂载
docker run -it -v /home/testmai:/home tomcat /bin/bash
# 挂载;为了容器的持久化和同步操作;容器之间数据共享;吧容器内的/home 目录挂到宿主机(物理机)上的/home/testmai 目录上,实现文件同步;双向绑定,反过来同理
docker run -d -p 3310:3306 -v /home/mysql/conf:/etc/mysql/conf.d -v /home/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 mysql:5.7
#mysql 数据卷挂载
复制代码
DockerFile
编写 dockerfile 文件
FROM centos
MAINTAINER mairongcong<rcmai@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo 'end------'
CMD /bin/bash
复制代码
#执行编译命令
docker build -f mydockerfile -t mycentos:0.1 .
复制代码
#查看是否构建成功
docker images
[root@VM_0_17_centos dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 0.1 c1d5e43eaa55 3 minutes ago 291MB
复制代码
#运行
docker run -it mycentos:0.1
复制代码
#查看镜像的构建过程
docker history c1d5e43eaa55
复制代码
#CMD 命令和 ENTRYPOINT 区别
FROM centos
CMD ["ls","-a"]
# CMD 命令一般的镜像都会提供容器启动时的默认命令,但是有些场景中用户并不想执行默认的命令。用户可以通过命令行参数的方式覆盖 CMD 指令提供的默认命令。比如通过下面命令创建的镜像:FROM ubuntuCMD [ "top" ]
在启动容器时我们通过命令行指定参数 ps aux 覆盖默认的 top 命令:
Docker run --rm test1 ps aux
复制代码
自制 tomcat 镜像
FROM centos
MAINTAINER mairongcong<rcmai@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u271-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.41.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_271
ENV CLASS_PATH $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/logs/catalina.out
复制代码
docker images
[root@VM_0_17_centos dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mytomcat latest dbfc7c2b1185 12 minutes ago 639MB
复制代码
docker run -d -p 9090:8080 --name maitomcat -v /home/mairongcong/build/tomcat/test:/usr/local/apache-tomcat-9.0.41/webapps/test -v/home/mairongcong/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.41/logs mytomcat
复制代码
ADD 指令的功能是将主机构建环境(上下文)目录中的文件和目录、以及一个 URL 标记的文件 拷贝到镜像中。其格式是: ADD 源路径 目标路径如果源文件是个归档文件(压缩文件),则 docker 会自动帮解压 ADD /foo.tar.gz /tmp/上述指令会使 foo.tar.gz 压缩文件解压到容器的/tmp 目录。URL 下载和解压特性不能一起使用。任何压缩文件通过 URL 拷贝,都不会自动解压。目前 ADD 指令有点让人迷惑,有时候解压文件,有时候不解压文件,如果你想拷贝一个压缩文件,你会以为地解压。如果文件是某种不能识别的压缩文件,如果你想解压,你又会意外地复制它。
这种解释似乎是 ADD 尝试做的太多了,让用户有些疑惑。很明显,没人想要打破向后兼容性。所以决定新增一个行为更加明确的指令。COPY 和 ADD 相似,但是功能少一些。在 Docker 1.0 发布时候,包括了新指令 COPY。不像是 ADD,COPY 更加直接了当,只复制文件或者目录到容器里。COPY 不支持 URL,也不会特别对待压缩文件。Docker 团队的建议是在大多数情况下使用 COPY。拷贝文件的原则:使用 COPY(除非你明确你需要 ADD)
从根本上说, ENTRYPOINT 和 CMD 都是让用户指定一个可执行程序, 这个可执行程序在 container 启动后自动启动. 实际上, 如果你想让自己制作的镜像自动运行程序(不需要在 docker run 后面添加命令行指定运行的命令), 你必须在 Dockerfile 里面, 使用 ENTRYPOINT 或者 CMD 命令比如执行运行一个没有调用 ENTRYPOINT 或者 CMD 的 docker 镜像, 一定返回错误 $ docker run alpineFATA[0000] Error response from daemon: No command specified 大部分 Linu 发行版的基础镜像里面调用 CMD 命令, 指定容器启动后执行/bin/sh 或/bin/bash. 这样镜像启动默认进入交互式的 shell
译注: 3 个不同的 Linux 镜像(ubuntu, busybox, debian)都在 Dockerfile 的最后调用 CMD '/bin/bash'启动 Linux 发行版的基础 container 后, 默认调用 shell 程序, 符合大多数人的习惯.但是, 作为开发者, 你希望在 docker 镜像启动后, 自动运行其他程序. 所以, 你需要用 CMD 或者 ENTRYPOINT 命令显式地指定具体的命令.
RUN、CMD 和 ENTRYPOINT 这三个 Dockerfile 指令看上去很类似,很容易混淆。本节将通过实践详细讨论它们的区别。简单的说:RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。ENTRYPOINT 配置容器启动时运行的命令。
Shell 和 Exec 格式我们可用两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式,二者在使用上有细微的区别。Shell 格式<instruction> <command>例如:RUN apt-get install python3 CMD echo "Hello world" ENTRYPOINT echo "Hello world" 当指令执行时,shell 格式底层会调用/bin/sh -c <command> 。例如下面的 Dockerfile 片段:ENV name Cloud Man ENTRYPOINT echo "Hello, name" 执行dockerrun<image>将输出:Hello,CloudMan 注意环境变量 name 已经被值 CloudMan 替换。下面来看Exec格式。Exec格式<instruction>["executable","param1","param2",...] 例如:RUN["apt−get","install","python3"] CMD["/bin/echo","Helloworld"]ENTRYPOINT["/bin/echo","Helloworld"] 当指令执行时,会直接调用<command>,不会被shell解析。例如下面的Dockerfile片段:ENVnameCloudMan ENTRYPOINT["/bin/echo","Hello,name"] 运行容器将输出:Hello, name 注意环境变量“name”没有被替换。如果希望使用环境变量,照如下修改ENVnameCloudMan ENTRYPOINT["/bin/sh","−c","echoHello,name"] 运行容器将输出:Hello, Cloud Man CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 则两种格式都可以。
下面看看 CMD 是如何工作的。Dockerfile 片段如下:CMD echo "Hello world" 运行容器 docker run -it [image]将输出:Hello world 但当后面加上一个命令,比如 docker run -it [image] /bin/bash,CMD 会被忽略掉,命令 bash 将被执行:root@10a32dc7d3d3:/#
ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。不同的地方在于 ENTRYPOINT 参数不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。
重点 ENTRYPOINT 的 Exec 格式用于设置要执行的命令及其参数,同时可通过 CMD 提供额外的参数。ENTRYPOINT 中的参数始终会被使用,而 CMD 的额外参数可以在容器启动时动态替换掉。比如下面的 Dockerfile 片段:ENTRYPOINT ["/bin/echo", "Hello"]CMD ["world"] 当容器通过 docker run -it [image] 启动时,输出为:Hello world 而如果通过 docker run -it [image] CloudMan 启动,则输出为:Hello CloudMan 参考文章 [https://www.jianshu.com/p/f0a0f6a43907]
Push 发布到 dockerHub
https://hub.docker.com/ # 注册账号
docker login username #登录
docker tag dbfc7c2b1185 mairongcong/mytomcat:1.0 # 打标签
docker push mairongcong/mytomcat:1.0 #提交镜像
复制代码
Push 发布到阿里云
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories # 创建命名空间
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories #创建镜像仓库
docker tag dbfc7c2b1185 mairongcong/mytomcat:1.0 # 打标签
docker push mairongcong/mytomcat:1.0 #提交镜像
复制代码
Save & Load
docker save -o my_tomcat_v3.tar mytomcat # 将指定镜像保存成 tar 归档文件
docker save 本地镜像名:镜像标签 | gzip > 导出的镜像名 # 压缩后的镜像
docker load < my_tomcat_v3.tar # 导入使用 docker save 命令导出的镜像;
复制代码
网络 evth-pair
[root@VM_0_17_centos WEB-INF]# ip addr
# 宿主机查看 网卡情况,有了一个docker0的网卡
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:6a:49:63:63 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
[root@VM_0_17_centos ]# docker ps # 查看已有容器
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4845a637cb1e mytomcat "/bin/sh -c '/usr/lo…" 41 hours ago Up 41 hours 0.0.0.0:9090->8080/tcp maitomcat3
[root@VM_0_17_centos WEB-INF]# docker exec -it maitomcat3 ip addr
#查看容器内的网络地址ip addr ;每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0 ,是桥接模式,使用了evth-pair 技术
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
96: eth0@if97: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@VM_0_17_centos WEB-INF]# docker run -d --name mytomcat04 dbfc7c2b1185
#再启动一个容器
[root@VM_0_17_centos WEB-INF]# docker exec -it 0b30c016ed6f ip addr
#查看多了一对网卡98 99 ,这些容器带来的网卡,都是一对一对的,就是evth-pair 技术,一端连着协议,一端彼此相连,有了这个特性,evth-pair充当桥梁,连接各种虚拟网络设备,docker之间的容器连接,都是使用了evth-pair 技术
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
98: eth0@if99: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:06 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.6/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
[root@VM_0_17_centos WEB-INF]# ip addr
99: veth8faa9cc@if98: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
link/ether 3e:e2:7b:fe:99:de brd ff:ff:ff:ff:ff:ff link-
netnsid 4
inet6 fe80::3ce2:7bff:fefe:99de/64 scope link
valid_lft forever preferred_lft forever
[root@VM_0_17_centos ]# docker exec -it maitomcat3 ping 172.17.0.6 #容器之间是可以ping通的; tomcat1 和tomcat2是公用的同一个路由器Docker0,所有的容器再不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip; 但是该命令无法支持高可用,只能具体ping ip ,不能ping 容器名称
复制代码
Link(不再建议使用)
root@VM_0_17_centos ]# docker exec -it maitomcat3 ping mytomcat04
# 无法ping通容器名
ping: mytomcat04: Name or service not known
[root@VM_0_17_centos ]# docker run -d -P --name maitomcat5 --link mytomcat04 mytomcat #启动容器时通过 --link 来解决对应的网络问题
d680bb22ed412f93b031f5314be9950642b8a17d5fb9c5719c55c1840caf64b6
[root@VM_0_17_centos ]# docker exec -it maitomcat5 ping mytomcat04
PING mytomcat04 (172.17.0.6) 56(84) bytes of data.
64 bytes from mytomcat04 (172.17.0.6): icmp_seq=1 ttl=64 time=0.075 ms
64 bytes from mytomcat04 (172.17.0.6): icmp_seq=2 ttl=64 time=0.043 ms
# link的原理就是在host中添加别名,吧ip 和 容器名做了一个映射
复制代码
自定义网络
优点自定义网络其实也是 bridge 模式,只不过两个容器之间可以通过名字来进行网络通信
查看所有的 docker 网络模式 1、bridge:bridge 之使用默认网桥,搭桥的方式连接各个容器网络 (默认都使用桥接模式)bridge 各个容器之间只能通过 ip 地址来互相访问,如果 ip 修改了,则无法通信。因此需要使用引用,或者一个 name 的方式来通信比较好。 docker0 问题,他不支持容器名链接访问。2、bridge 之使用自定义网桥 3、host 模式 4、container 模式 5、None 模式
5 种模式详细说明基于对 net namespace 的控制,docker 可以为在容器创建隔离的网络环境,在隔离的网络环境下,容器具有完全独立的网络栈,与宿主机隔离,也可以使容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要
按 docker 官方的说法,docker 容器的网络有五种模式:1)bridge 模式,--net=bridge(默认)这是 dokcer 网络的默认设置,为容器创建独立的网络命名空间,容器具有独立的网卡等所有单独的网络栈,是最常用的使用方式。在 docker run 启动容器的时候,如果不加--net 参数,就默认采用这种网络模式。安装完 docker,系统会自动添加一个供 docker 使用的网桥 docker0,我们创建一个新的容器时,容器通过 DHCP 获取一个与 docker0 同网段的 IP 地址,并默认连接到 docker0 网桥,以此实现容器与宿主机的网络互通。
2)host 模式,--net=host 这个模式下创建出来的容器,直接使用容器宿主机的网络命名空间。将不拥有自己独立的 Network Namespace,即没有独立的网络环境。它使用宿主机的 ip 和端口。
3)none 模式,--net=none 为容器创建独立网络命名空间,但不为它做任何网络配置,容器中只有 lo,用户可以在此基础上,对容器网络做任意定制。这个模式下,dokcer 不为容器进行任何网络配置。需要我们自己为容器添加网卡,配置 IP。因此,若想使用 pipework 配置 docker 容器的 ip 地址,必须要在 none 模式下才可以。
4)其他容器模式(即 container 模式),--net=container:NAME_or_ID 与 host 模式类似,只是容器将与指定的容器共享网络命名空间。这个模式就是指定一个已有的容器,共享该容器的 IP 和端口。除了网络方面两个容器共享,其他的如文件系统,进程等还是隔离开的。
5)用户自定义:docker 1.9 版本以后新增的特性,允许容器使用第三方的网络实现或者创建单独的 bridge 网络,提供网络隔离能力。
[root@VM_0_17_centos /]# docker network ls #查看所有的docker网络
NETWORK ID NAME DRIVER SCOPE
479307d3d0a1 bridge bridge local
cfc57d39c114 host host local
b076eb847244 none null local
复制代码
root@freeaihub:~# docker network create custom_network
b88fa50e25a2bc92517f353cf5c76e71a29eabc0ec19c3f8e60bbc8b8ad03340
# 或者如下
[root@VM_0_17_centos /]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet #创建自定义网络
94bab7ee5dee508e1198189d8a0b873d9482a7dc6c393ea4ce6c5d636012ed9e
[root@VM_0_17_centos /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
479307d3d0a1 bridge bridge local
cfc57d39c114 host host local
94bab7ee5dee mynet bridge local
[root@VM_0_17_centos /]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "94bab7ee5dee508e1198189d8a0b873d9482a7dc6c393ea4ce6c5d636012ed9e",
"Created": "2021-01-07T10:44:41.230831857+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
复制代码
@freeaihub:~# docker run -it --name bbox05 busybox
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
8ec32b265e94: Pull complete
# 或者
[root@VM_0_17_centos /]# docker run -d -P --name mytomcat06-net --net mynet mytomcat
efd84b353fdf77b6bf626c1a71103e7ef65c02982647c645c34237361d84c873
[root@VM_0_17_centos /]# docker run -d -P --name mytomcat07-net --net mynet mytomcat #启动另一个容器
e2f310e336b0e98457ec0371e2cc9cf6c86e7f430d2e509f2882b1e678f39f71
[root@VM_0_17_centos /]# docker network inspect mynet #查看网络情况,发现新增了
[
{
... ...
"Containers": {
"e2f310e336b0e98457ec0371e2cc9cf6c86e7f430d2e509f2882b1e678f39f71": {
"Name": "mytomcat07-net",
"EndpointID": "a15a172ce252af01bff6367d17a8a187f2152c83e4e483fbabd19e68694987ed",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"efd84b353fdf77b6bf626c1a71103e7ef65c02982647c645c34237361d84c873": {
"Name": "mytomcat06-net",
"EndpointID": "fa34004e05ad5fe8b1637e844a504731cdb9ab87384a7439082edfbdd2c7e05b",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
}
]
复制代码
[root@VM_0_17_centos /]# docker exec -it mytomcat07-net ping mytomcat06-net # 通过自定义网络的方式,发现不需要使用--link ,两个容器之间可以直接通过容器名 ping 通了;推荐使用这种自定义的方式使用,比如一个 redis 集群,那么就是一个网络,mysql 集群 也是一个独立的网络,两个网络之间互相隔离。PING mytomcat06-net (192.168.0.2) 56(84) bytes of data.64 bytes from mytomcat06-net.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.037 ms64 bytes from mytomcat06-net.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.046 ms 如果两个不同的网络之间,需要互通怎么办呢?测试两个不同网络的容器互通 root@VM_0_17_centos /]# docker network connect mynet mytomcat04 #把 mytomcat04 加入到 mynet 网络中,就可以实现 mytomcat04 可以访问 mynet 网络的所在容器了[root@VM_0_17_centos /]# docker network inspect mynet[{"Name": "mynet","Id": "94bab7ee5dee508e1198189d8a0b873d9482a7dc6c393ea4ce6c5d636012ed9e","Created": "2021-01-07T10:44:41.230831857+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "192.168.0.0/16","Gateway": "192.168.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"0b30c016ed6fc5a278bd8a3fad4794c068b0ccd237f81d6b53af28d380d0af66": {"Name": "mytomcat04","EndpointID": "b33d960f70ba94a631969e507ddf42d1aed2b12331b4cfa427fbb221cdf3fd20","MacAddress": "02:42:c0:a8:00:04","IPv4Address": "192.168.0.4/16","IPv6Address": ""},"e2f310e336b0e98457ec0371e2cc9cf6c86e7f430d2e509f2882b1e678f39f71": {"Name": "mytomcat07-net","EndpointID": "a15a172ce252af01bff6367d17a8a187f2152c83e4e483fbabd19e68694987ed","MacAddress": "02:42:c0:a8:00:03","IPv4Address": "192.168.0.3/16","IPv6Address": ""},"efd84b353fdf77b6bf626c1a71103e7ef65c02982647c645c34237361d84c873": {"Name": "mytomcat06-net","EndpointID": "fa34004e05ad5fe8b1637e844a504731cdb9ab87384a7439082edfbdd2c7e05b","MacAddress": "02:42:c0:a8:00:02","IPv4Address": "192.168.0.2/16","IPv6Address": ""}},"Options": {},"Labels": {}}][root@VM_0_17_centos /]# docker exec -it mytomcat04 ping mytomcat07-net #测试验证确实可以互通 PING mytomcat07-net (192.168.0.3) 56(84) bytes of data.64 bytes from mytomcat07-net.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.039 ms64 bytes from mytomcat07-net.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.049 ms[root@VM_0_17_centos /]# docker exec -it mytomcat07-net ping mytomcat04 # 测试验证可以互通 PING mytomcat04 (192.168.0.4) 56(84) bytes of data.64 bytes from mytomcat04.mynet (192.168.0.4): icmp_seq=1 ttl=64 time=0.050 ms#结论:假设要跨网络互相访问,需要使用 以上命令 docker network connect mynet mytomcat04
nginx 搭建
root@VM_0_17_centos /]# docker pull nginx
#拉取镜像
[root@control-plane nginx]# docker run --name mynginx -p 80:80 -d nginx:latest
# 启动镜像
[root@control-plane nginx]# ##导入的配置文件目录
[root@control-plane nginx]# docker cp mynginx:/etc/nginx/conf.d /data/application/workflow/nginx
[root@control-plane nginx]# docker cp mynginx:/etc/nginx/nginx.conf /data/application/workflow/nginx/nginx.conf
[root@control-plane nginx]# docker cp mynginx:/usr/share/nginx/html /data/application/workflow/nginx/
[root@control-plane nginx]# docker cp mynginx:/var/log/nginx /data/application/workflow/nginx/log
# 删除同名容器
[root@control-plane nginx]# docker rm -f mynginx
mynginx
#启动容器,并挂载对应目录
[root@control-plane nginx]# docker run -d --name mynginx -p 6061:80 -v /data/application/workflow/nginx/conf.d:/etc/nginx/conf.d -v /data/application/workflow/nginx/nginx.conf:/etc/nginx/nginx.conf -v /data/application/workflow/nginx/html:/usr/share/nginx/html -v /data/application/workflow/nginx/log:/var/log/nginx nginx:latest
复制代码
nginx 搭建问题记录
记得如果应用程序搭建再宿主机,但是 nginx 是用的 docker 容器,那么 nginx 做后端请求转发的时候,务必要把 proxy 写成宿主机的 docker0 ip , 不能写 127.0.0.1 ,如下,docker0 的 ip 是 172.17.0.1 ,
[root@control-plane workflow]# ifconfig
br-e4574af0585c: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.49.1 netmask 255.255.255.0 broadcast 192.168.49.255
inet6 fe80::42:36ff:fea2:ac72 prefixlen 64 scopeid 0x20<link>
ether 02:42:36:a2:ac:72 txqueuelen 0 (Ethernet)
RX packets 807 bytes 5706427 (5.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 953 bytes 131430 (128.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:92ff:fea8:9e6f prefixlen 64 scopeid 0x20<link>
复制代码
那么就的吧 nginx 对应的转发 ip 写成 172.17.0.1
server {
listen 80;
server_name 127.0.0.1;
location ~/api/ {
proxy_pass http://172.17.0.1:3030;
}
复制代码
Redis 集群
root@VM_0_17_centos /]# docker network create redis-net --subnet 172.38.0.0/16 # 新建redis集群的网络,名称为redis-net
66d8cf51ec6c00b4c92db05552375f1816fb324723866cff389103c9deb1e756
[root@VM_0_17_centos /]# docker network ls
NETWORK ID NAME DRIVER SCOPE
479307d3d0a1 bridge bridge local
cfc57d39c114 host host local
94bab7ee5dee mynet bridge local
b076eb847244 none null local
66d8cf51ec6c redis-net bridge local
[root@VM_0_17_centos /]# docker network inspect redis-net
[
{
"Name": "redis-net",
"Id": "66d8cf51ec6c00b4c92db05552375f1816fb324723866cff389103c9deb1e756",
"Created": "2021-01-07T11:11:49.616037596+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.38.0.0/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
#执行脚本,生成 6个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
[root@VM_0_17_centos conf]# 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-net --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf #启动redis 节点1容器
Unable to find image 'redis:5.0.9-alpine3.11' locally
5.0.9-alpine3.11: Pulling from library/redis
cbdbe7a5bc2a: Pull complete
dc0373118a0d: Pull complete
cfd369fe6256: Pull complete
3e45770272d9: Pull complete
558de8ea3153: Pull complete
a2c652551612: Pull complete
Digest: sha256:83a3af36d5e57f2901b4783c313720e5fa3ecf0424ba86ad9775e06a9a5e35d0
Status: Downloaded newer image for redis:5.0.9-alpine3.11
8db128a0d4c6c53484fc2ea43c9397e11161c771ba5214200212edf47f8f24d3
[root@VM_0_17_centos conf]# docker run -p 6372:6379 -p 16372:16379 --name redis-2 -v /mydata/redis/node-2/data:/data -v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf -d --net redis-net --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf #启动redis 节点2容器
#其他四个节点同理
[root@VM_0_17_centos conf]# docker run -p 6373:6379 -p 16373:16379 --name redis-3 -v /mydata/redis/node-3/data:/data -v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf -d --net redis-net --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
[root@VM_0_17_centos conf]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
facf9d559439 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 5 seconds ago Up 4 seconds 0.0.0.0:6376->6379/tcp, 0.0.0.0:16376->16379/tcp redis-6
23753ff70658 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 29 seconds ago Up 29 seconds 0.0.0.0:6375->6379/tcp, 0.0.0.0:16375->16379/tcp redis-5
fcabadb47f28 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 53 seconds ago Up 53 seconds 0.0.0.0:6374->6379/tcp, 0.0.0.0:16374->16379/tcp redis-4
c355b387c1e1 redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:6373->6379/tcp, 0.0.0.0:16373->16379/tcp redis-3
99d867807d1e redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 4 minutes ago Up 4 minutes 0.0.0.0:6372->6379/tcp, 0.0.0.0:16372->16379/tcp redis-2
ad34225fee1f redis:5.0.9-alpine3.11 "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 0.0.0.0:6371->6379/tcp, 0.0.0.0:16371->16379/tcp redis-1
/data # 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集群
/data # redis-cli -c
127.0.0.1:6379> set a aaaa
-> Redirected to slot [15495] located at 172.38.0.13:6379
OK
172.38.0.13:6379> get a
"aaaa"
172.38.0.13:6379> cluster info # 查看集群信息
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:3
cluster_stats_messages_ping_sent:169
cluster_stats_messages_pong_sent:175
cluster_stats_messages_meet_sent:4
cluster_stats_messages_sent:348
cluster_stats_messages_ping_received:174
cluster_stats_messages_pong_received:173
cluster_stats_messages_meet_received:1
cluster_stats_messages_received:348
172.38.0.13:6379> cluster nodes # 查看节点
a24f7707237aaf0e08695a73c0625f8580e92a05 172.38.0.15:6379@16379 slave 549e6d070cba073488cb6d82e130be728b4618e5 0 1609990494000 5 connected
549e6d070cba073488cb6d82e130be728b4618e5 172.38.0.11:6379@16379 master - 0 1609990494000 1 connected 0-5460
904bb967518976a005741c2bc0b653f721d635ee 172.38.0.14:6379@16379 slave 96709c4566cbede13a4c258287c4072f0c988543 0 1609990495191 4 connected
96709c4566cbede13a4c258287c4072f0c988543 172.38.0.13:6379@16379 myself,master - 0 1609990493000 3 connected 10923-16383
7acda5adad75068f1e3ee3d9660415b7200e8fc2 172.38.0.16:6379@16379 slave ff7bae21120ab3f05d0153d7929f1c09eb26b9fd 0 1609990495091 6 connected
ff7bae21120ab3f05d0153d7929f1c09eb26b9fd 172.38.0.12:6379@16379 master - 0 1609990494190 2 connected 5461-10922
# 验证成功
[root@VM_0_17_centos conf]# docker stop c355b387c1e1 #停掉其中一个容器节点,验证高可用
c355b387c1e1
[root@VM_0_17_centos conf]# docker exec -it facf9d559439 /bin/sh
/data # redis-cli -c
127.0.0.1:6379> cluster nodes # 其中给一个节点停掉之后,node-4 slave自动转master
549e6d070cba073488cb6d82e130be728b4618e5 172.38.0.11:6379@16379 master - 0 1609990637048 1 connected 0-5460
96709c4566cbede13a4c258287c4072f0c988543 172.38.0.13:6379@16379 master,fail - 1609990604492 1609990603587 3 connected
a24f7707237aaf0e08695a73c0625f8580e92a05 172.38.0.15:6379@16379 slave 549e6d070cba073488cb6d82e130be728b4618e5 0 1609990636047 5 connected
904bb967518976a005741c2bc0b653f721d635ee 172.38.0.14:6379@16379 master - 0 1609990637048 7 connected 10923-16383
7acda5adad75068f1e3ee3d9660415b7200e8fc2 172.38.0.16:6379@16379 myself,slave ff7bae21120ab3f05d0153d7929f1c09eb26b9fd 0 1609990635000 6 connected
ff7bae21120ab3f05d0153d7929f1c09eb26b9fd 172.38.0.12:6379@16379 master - 0 1609990636000 2 connected 5461-10922
127.0.0.1:6379> get a
-> Redirected to slot [15495] located at 172.38.0.14:6379
"aaaa"
复制代码
案例-打包
#Dockerfile 编写
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8099"]
EXPOSE 8099
ENTRYPOINT ["java","-jar","/app.jar"]
[root@localhost idea]# docker build -t admin . # 生成镜像
[root@localhost idea]# Docker images #查看镜像
[root@localhost idea]# Docker run -d -P --name myapp admin #启动容器
复制代码
个人阿里云
评论