Docker学习笔记整理(二)

1、DockerFile

用于制作自己的镜像。

1.1、DockerFile相关命令

FROM:定制的镜像都是基于 FROM 的镜像。

RUN:用于执行后面跟着的命令行命令, docker build时执行。

COPY:复制指令,从上下文目录中复制文件或者目录到容器里指定路径。

ADD:ADD 指令和 COPY 的使用格类似(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:

ADD 的优点:在执行 <源文件> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <目标路径>。
ADD 的缺点:在不解压的前提下,无法复制 tar 压缩文件。会令镜像构建缓存失效,从而可能会令镜像构建变得比较缓慢。具体是否使用,可以根据是否需要自动解压来决定。

CMD:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。

如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。
CMD 在docker run 时运行。
RUN 是在 docker build。

ENTRYPOINT: 类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。

优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。

ENV:设置环境变量。K-V键值方式,在后续的使用过程中可以使用$K的当时使用

VOLUME:定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。

EXPOSE:暴漏端口。

WORKDIR:设置工作目录

MAINTIANER:设置镜像的作者信息 姓名<邮箱>

2、构建自己的centos

[root@node1 mycentos]# cat Dockerfile 
FROM centos
MAINTAINER liu<247202624@qq.com>
WORKDIR /etc
RUN yum -y install vim
EXPOSE 80
CMD /bin/bash
#构建镜像
[root@node1 mycentos]# docker build -f Dockerfile -t mycentos:1.0 .
#启动镜像
[root@node1 mycentos]# docker run -it mycentos:1.0

3、Docker网络

3.1、docker0

在docker中所有的容器之间的网络是相互隔离的,如果需要将容器将网络联通,应该怎么办?
docker提供了一个docker0的虚拟网络来实现容器间的网络联通

3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:d7:0e:71:0b brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:d7ff:fe0e:710b/64 scope link 
       valid_lft forever preferred_lft forever

172.17.0.1/16:表示docker0这个虚拟网络可以管理的网络是从172.17.0.2一直到172.17.255.254的网络,也就是可以管理255*255-2个容器,如果172.17.0.1/32,则表示可管理172.17.0.2到172.17.0.254的网络。

也就是说每当你启动一个容器时,docker就会自动根据docker0的网络自动分配一个虚拟的ip,一般情况下是递增的。
当容器A要和容器B进行通信时,直接访问容器B的虚拟ip就可以了,因为容器A和容器B同属于同一个docker0的网段内。

举例:进入容器B 去ping容器A(172.17.0.2),就可以ping通

root@4c4404728d65:/usr/local/tomcat# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.086 ms
64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.087 ms
64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.087 ms
64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.067 ms
64 bytes from 172.17.0.2: icmp_seq=6 ttl=64 time=0.056 ms
64 bytes from 172.17.0.2: icmp_seq=7 ttl=64 time=0.049 ms
64 bytes from 172.17.0.2: icmp_seq=8 ttl=64 time=0.044 ms
64 bytes from 172.17.0.2: icmp_seq=9 ttl=64 time=0.047 ms
64 bytes from 172.17.0.2: icmp_seq=10 ttl=64 time=0.044 ms
64 bytes from 172.17.0.2: icmp_seq=11 ttl=64 time=0.040 ms
64 bytes from 172.17.0.2: icmp_seq=12 ttl=64 time=0.040 ms
^C
--- 172.17.0.2 ping statistics ---
12 packets transmitted, 12 received, 0% packet loss, time 29ms
rtt min/avg/max/mdev = 0.040/0.057/0.087/0.020 ms

具体访问原理如下图
启动容器A,并进入容器内部如何 ip addr 查看网络发现出现了成对的网络配置
在这里插入图片描述
退出容器A,查看宿主机的网络,也同样出现了成对的网络配置,恰好数字是相反的。
容器B也会出现同样的成对网络配置
在这里插入图片描述
其实,当容器A去ping容器B的地址时,先通过这个成对的网络配置到达docker0 由docker0去寻找容器B的成对网络配置,然后将请求转发到容器B,这样就完成了通信。

问题!!!
容器每次重启都会随机分配一个ip,显然这种网络联通模式是不便捷的。所以就需要一种比较便捷的通信。这就是link

3.2 、link

link就是在启动的时候通过绑定容器名称,实现网络的通信,类似于域名访问

举例:启动三个名字分别为tomcat01,tomcat02,tomcat03的容器,在启动tomcat03的时候绑定tomcat01的容器名,不绑定tomcat02,进行测试。

[root@node1 ~]# docker run -d -P --link tomcat01 --name tomcat03 tomcat:8.5
4e722dcf11d4efe6e2e2369e38374a14fce8658335af578f137f3434f17f4eff
[root@node1 ~]# docker ps
CONTAINER ID   IMAGE        COMMAND             CREATED         STATUS         PORTS                                         NAMES
4e722dcf11d4   tomcat:8.5   "catalina.sh run"   5 seconds ago   Up 5 seconds   0.0.0.0:49156->8080/tcp, :::49156->8080/tcp   tomcat03
9ef584ffca4f   tomcat:8.5   "catalina.sh run"   4 minutes ago   Up 4 minutes   0.0.0.0:49155->8080/tcp, :::49155->8080/tcp   tomcat02
4c4404728d65   tomcat:8.5   "catalina.sh run"   5 minutes ago   Up 4 minutes   0.0.0.0:49154->8080/tcp, :::49154->8080/tcp   tomcat01
[root@node1 ~]# docker exec -it tomcat03 ping tomcat01
PING tomcat01 (172.17.0.2) 56(84) bytes of data.
64 bytes from tomcat01 (172.17.0.2): icmp_seq=1 ttl=64 time=0.150 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=2 ttl=64 time=0.124 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=3 ttl=64 time=0.121 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=4 ttl=64 time=0.123 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=5 ttl=64 time=0.096 ms
64 bytes from tomcat01 (172.17.0.2): icmp_seq=6 ttl=64 time=0.121 ms
^C
--- tomcat01 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 11ms
rtt min/avg/max/mdev = 0.096/0.122/0.150/0.019 ms
[root@node1 ~]# docker exec -it tomcat03 ping tomcat02
ping: tomcat02: Name or service not known

结果显示,tomcat03绑定tomcat01之后可以通过容器名字直接ping通,但是没有绑定tomcat02,所以无法ping通。

原理:
进入tomcat03容器内查看host文件发现,tomcat03的host文件中配置了tomcat01域名访问,所以才可以ping通。
在这里插入图片描述

问题!!!
虽然–link可以解决容器重启之后的网络通信,但是在每次run的时候都需要去配置–link,很麻烦,而且如果搭建一个集群的时候,集群的网络和其他的应用的网络都同处于一个网络下面,没有办法进行网络隔离,很难保证网络的健康。
所以,我们需自定义一个类似于docker0的网络来解决这个问题。

3.3自定义网络

查看docker网络

[root@node1 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ef70fb31e63c   bridge    bridge    local   #docker0 的网络 桥接模式
5a90a9073842   host      host      local   #主机模式,使用宿主机的ip通信
55323c86fa97   none      null      local   #无模式

新建mynet的网络,模式为桥接

[root@node1 ~]# docker network create -d bridge --gateway 192.168.0.1 --subnet 192.168.0.0/16 mynet
e9abdffe2cd9c26c0fa211de1de437c295822f46faf17a4aab910327f4815ef2
[root@node1 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ef70fb31e63c   bridge    bridge    local
5a90a9073842   host      host      local
e9abdffe2cd9   mynet     bridge    local
55323c86fa97   none      null      local

查看宿主机的网络发现,生成了一个虚拟的网络,ip是从192.168.0.1开始的。
在这里插入图片描述
通过这个网络来启动容器测试网络联通,在不需要link的情况下是否可以直接通过容器名通信呢?

启动tomcat01和tomcat02

[root@node1 ~]# docker run -d -P --name  tomcat01 --network mynet tomcat:8.5
6761b9bbbcce34c2ba63eda4dacb9881eb707a3570af0e0279c51abdde61677b
[root@node1 ~]# docker run -d -P --name  tomcat02 --network mynet tomcat:8.5
a9b3f2c705537a1f979cdd2dc6b575e047c34af458485ecf31d7dcbe308d65a2

测试结果如下:可以通过容器名通信。
在这里插入图片描述
所以自定义docker网络弥补docker0需要link 的确定,也同样可以满足不同的组件集群可以部署在不同的网络环境当中,保证了网络的健康。

问题!!!
如果容器A在docker0中,容器B在自定义网络中,那么这个两个容器如何通信呢?

解决方法:
将容器A加入到容器B所处的网络中即可,测试通过,访问成功,操作如下:

[root@node1 ~]# docker network connect mynet tomcat03
[root@node1 ~]# docker exec -it tomcat03 ping tomcat01
PING tomcat01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.046 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.124 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.056 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=4 ttl=64 time=0.123 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=5 ttl=64 time=0.054 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=6 ttl=64 time=0.111 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=7 ttl=64 time=0.121 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=8 ttl=64 time=0.125 ms
64 bytes from tomcat01.mynet (192.168.0.2): icmp_seq=9 ttl=64 time=0.122 ms
^C
--- tomcat01 ping statistics ---
9 packets transmitted, 9 received, 0% packet loss, time 46ms
rtt min/avg/max/mdev = 0.046/0.098/0.125/0.032 ms
[root@node1 ~]# docker exec -it tomcat03 ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.120 ms
64 bytes from 192.168.0.2: icmp_seq=3 ttl=64 time=0.120 ms
64 bytes from 192.168.0.2: icmp_seq=4 ttl=64 time=0.119 ms
^C
--- 192.168.0.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 8ms
rtt min/avg/max/mdev = 0.072/0.107/0.120/0.024 ms

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值