写点什么

Docker 系列 (3)-- 容器连接和 Dockerfile,kafka 的原理

用户头像
极客good
关注
发布于: 刚刚


[root@a ~]# docker ps


CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES


4ceb424eff78 training/webapp "python app.py" 15 seconds ago Up 15 seconds 127.0.0.1:5001->5000/tcp interesting_rhodes


ed817fe4fbd6 training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:5000->5000/tcp wizardly_lewin


52e8351ab9bc training/webapp "python app.py" 7 minutes ago Up 7 minutes 0.0.0.0:32768->5000/tcp stoic_chatterjee


3.如果要绑定 UDP 扩展,可以在端口后面加上/ udp




[root@a ~]# docker ps


CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES


0156a6e359be training/webapp "python app.py" 10 seconds ago Up 10 seconds 5000/tcp, 127.0.0.1:5000->5000/udp dreamy_shaw


4ceb424eff78 training/webapp "python app.py" 13 minutes ago Up 13 minutes 127.0.0.1:5001->5000/tcp interesting_rhodes


ed817fe4fbd6 training/webapp "python app.py" 14 minutes ago Up 14 minutes 0.0.0.0:5000->5000/tcp wizardly_lewin


52e8351ab9bc training/webapp "python app.py" 20 minutes ago Up 20 minutes 0.0.0.0:32768->5000/tcp stoic_chatterjee


4.docker port 命令可以让我们快捷地查看端口的绑定情况。




[root@a ~]# docker port interesting_rhodes 5000


127.0.0.1:5001


5.Docker 容器互联




进入映射并非唯一把 docker 连接到另一个容器的方法。


docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。


docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。


容器命名


当我们创建一个容器的时候,docker 会自动对它进行命名。另外,我们也可以使用--name 标识来命名容器,例如:


[root@a ~]# docker run -d -P --name caq training/webapp python app.py


5ccfa6094c72beca0f1bc28b460efd48d096721788648b6056d61b7b51d62c7d


[root@a ~]# docker ps -l


CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES


5ccfa6094c72 training/webapp "python app.py" 10 seconds ago Up 9 seconds 0.0.0.0:32769->5000/tcp caq


新建网络


下面先创建一个新的 Docker 网络。


[root@a ~]# docker network create -d bridge test-net


d517093f0f3460bfa34a88544ad4f264b591b1849a0a4cd07332540a1fb89f4d


[root@a ~]# docker network ls


NETWORK ID NAME DRIVER SCOPE


0923e7b2d104 bridge bridge local


7c3d205b3fbf host host local


f74c9f9eb6ad none null local


d517093f0f34 test-net bridge local


-d:参数指定 Docker 网络类型,有网桥,覆盖。


连接容器


运行一个容器并连接到新建的 test-net 网络:


[root@a ~]# docker run -itd --name test1 --network test-net ubuntu /bin/bash


[root@a ~]# docker run -itd --name test2 --network test-net ubuntu /bin/bash


root@1267f1a3c916:/# ping test2


PING test2 (172.18.0.2) 56(84) bytes of data.


64 bytes from test2.test-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.365 ms


64 bytes from test2.test-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.133 ms


^C


--- test2 ping statistics ---


2 packets transmitted, 2 received, 0% packet loss, time 1002ms


rtt min/avg/max/mdev = 0.133/0.249/0.365/0.116 ms


[root@a ~]# docker exec -it test1 /bin/bash


root@1267f1a3c916:/# ping test2


PING test2 (172.18.0.2) 56(84) bytes of data.


64 bytes from test2.test-net (172.18.0.2): icmp_seq=1 ttl=64 time=0.291 ms


64 bytes from test2.test-net (172.18.0.2): icmp_seq=2 ttl=64 time=0.131 ms


64 bytes from test2.test-net (172.18.0.2): icmp_seq=3 ttl=64 time=0.209 ms


64 bytes from test2.test-net (172.18.0.2): icmp_seq=4 ttl=64 time=0.143 ms


^C


--- test2 ping statistics ---


4 packets transmitted, 4 received, 0% packet loss, time 3002ms


rtt min/avg/max/mdev = 0.131/0.193/0.291/0.065 ms


[root@a ~]# docker exec -it test2 /bin/bash


root@007730f40eae:/# ping test1


PING test1 (172.18.0.3) 56(84) bytes of data.


64 bytes from 1267f1a3c916 (172.18.0.3): icmp_seq=1 ttl=64 time=0.062 ms


64 bytes from 1267f1a3c916 (172.18.0.3): icmp_seq=2 ttl=64 time=0.092 ms


64 bytes from 1267f1a3c916 (172.18.0.3): icmp_seq=3 ttl=64 time=0.081 ms


64 bytes from 1267f1a3c916 (172.18.0.3): icmp_seq=4 ttl=64 time=0.096 ms


64 bytes from 1267f1a3c916 (172.18.0.3): icmp_seq=5 ttl=64 time=0.100 ms


^C


--- test1


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


ping statistics ---


5 packets transmitted, 5 received, 0% packet loss, time 4001ms


rtt min/avg/max/mdev = 0.062/0.086/0.100/0.014 ms


6.配置 DNS




我们可以在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:


{


"dns" : ["dns" : [


"114.114.114.114","114.114.114.114",


"8.8.8.8""8.8.8.8"


]]


}}


7.手动指定容器的配置




如果只想在指定的容器设置 DNS,则可以使用以下命令:


[root@a ~]# docker run -it --rm -h ubuntu:15.10 --dns=114.114.114.114 --dns-search=test.com ubuntu:15.10


root@ubuntu:15:/# cat /etc/hostname


ubuntu:15.10


root@ubuntu:15:/# 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.2 ubuntu:15.10 ubuntu:15


root@ubuntu:15:/# cat /etc/resolv.conf


search test.com


nameserver 114.114.114.114


8.参数说明:




  • -h HOSTNAME 或者 --hostname=HOSTNAME: 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts。

  • –dns=IP_ADDRESS: 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名。

  • –dns-search=DOMAIN: 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com。




二、Dockerfile


===========================================================================


什么是 Dockerfile?




Dockerfile 是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。


Docker 执行 Dockerfile 的大致流程:


1、docker 从基础镜像运行一个容器


2、执行一条指令并对容器做出修改


3、执行类似 docker commit 的操作提交一个新的镜像层


4、docker 再基于刚提交的镜像运行一个新容器


5、执行 dockerfile 中的下一条指令直到所有指令都执行完成


使用 Dockerfile 定制镜像



定制一个 nginx 镜像

(构建好的镜像内会有一个


/usr/share/nginx/html/index.html 文件)


[root@a ~]# mkdir Dockerfile


[root@a ~]# cd Dockerfile/


[root@a Dockerfile]# vi Dockerfile


[root@a Dockerfile]# cat Dockerfile


FROM nginx


run echo "aaaa" > /usr/share/nginx/html/index.html

FROM 和 RUN 指令的作用

FROM:定制的镜像都是基于 FROM 的镜像,这里的 nginx 就是定制需要的基础镜像。后续的操作都是基于 nginx。


RUN:用于执行后面跟着的命令行命令。有以下俩种格式:


shell 格式:


RUN <命令行命令>


#<命令行命令> 等同于,在终端操作的 shell 命令。


exec 格式:


RUN ["可执行文件", "参数 1", "参数 2"]


#例如:


#RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline


注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:


FROM centos


RUN yum install wget


RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"


RUN tar -xvf redis.tar.gz


以上执行会创建 3 层镜像。可简化为以下格式:


FROM centos


RUN yum install wget \


&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \


&& tar -xvf redis.tar.gz


如上,以 && 符号连接命令,这样执行后,只会创建 1 层镜像。

开始构建镜像

在 Dockerfile 文件的存放目录下,执行构建动作。


以下示例,通过目录下的 Dockerfile 构建一个 nginx:test(镜像名称:镜像标签)。


注:最后的 . 代表本次执行的上下文路径


[root@a Dockerfile]# docker build -t nginx:v1 .

上下文路径

上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。


解析:由于 docker 的运行模式是 C/S。我们本机是 C,docker 引擎是 S。实际的构建过程是在 docker 引擎下完成的,所以这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。


如果未说明最后一个参数,那么默认上下文路径就是 Dockerfile 所在的位置。


注意:上下文路径下不要放无用的文件,因为会一起打包发送给 docker 引擎,如果文件过多会造成过程缓慢


保留关键字




FROM


基础镜像,当前镜像是基于那个镜像的


MAINTAINER


镜像维护者的姓名和邮件地址


RUN


容器构建时需要运行的命令


EXPOSE


当前容器对外暴露的端口


WORKDIR


工作目录,一个落脚点


ENY


用来构建镜像过程中设置环境变量


ADD


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


COPY


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




CMD


类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:


CMD 在 docker run 时运行。


RUN 是在 docker build。


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


注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。


格式:


CMD <shell 命令>


CMD ["<可执行文件或命令>","<param1>","<param2>",...]


CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数


推荐使用第二种格式,执行过程比较明确。第一种格式实际上在运行的过程中也会自动转换成第二种格式运行,并且默认可执行文件是 sh。


ENTRYPOINT


类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。


但是, 如果运行 docker run 时使用了 --entrypoint 选项,此选项的参数可当作要运行的程序覆盖 ENTRYPOINT 指令指定的程序。


优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。


注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。


格式:


ENTRYPOINT ["<executeable>","<param1>","<param2>",...]


可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参,以下示例会提到。




ONBUILD


当构建一个被继承的 Dockerfile 时运行命令,父镜像在被子镜像继承后父镜像的 onbuild 被触发


三、实例


===================================================================


实例 1




更改进入容器后的根目录


启动容器时自动安装 vim 工具和 net-tools


开放 80 端口


启动新的的 shell 进程


输出环境变量


输出 successful


流程:


1、从 docker hub 上拉取 centos 镜像(我是在阿里云拉的)


[root@docker1 dockerfile]# docker pull centos


2、编写 dockerfile


[root@docker1 dockerfile]# vim Dockerfile


FROM centos


ENV MYPATH /usr/local


WORKDIR $MYPATH


RUN yum install -y vim


RUN yum install -y net-tools


EXPOSE 80


CMD echo $MYPATH


CMD echo sucess----------------------------ok


CMD /bin/bash


3、建立容器


[root@docker1 dockerfile]# docker build -f /dockerfile/Dockerfile -t mycentos:1.3 .


4、启动容器


[root@docker1 dockerfile]# docker run -it mycentos:1.3


[root@ec8778c010e4 local]# pwd


/usr/local


[root@ec8778c010e4 local]# vim test.txt


[root@ec8778c010e4 local]# ifconfig


eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500


inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255


ether 02:42:ac:11:00:02 txqueuelen 0 (Ethernet)


RX packets 8 bytes 656 (656.0 B)


RX errors 0 dropped 0 overruns 0 frame 0


TX packets 0 bytes 0 (0.0 B)


TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0


lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536


inet 127.0.0.1 netmask 255.0.0.0


loop txqueuelen 1000 (Local Loopback)


RX packets 0 bytes 0 (0.0 B)


RX errors 0 dropped 0 overruns 0 frame 0

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
Docker系列(3)--容器连接和Dockerfile,kafka的原理