docker 获取宿主机ip_Docker基础修炼6——网络初探及单机容器间通信
如果覺(jué)得文章有幫助,歡迎點(diǎn)擊頭像關(guān)注我獲取更多原創(chuàng)文章,同時(shí)也歡迎轉(zhuǎn)發(fā)。
同時(shí)也可以在我的歷史文章中找到Linux操作系統(tǒng)相關(guān)的服務(wù)器運(yùn)維管理入門(mén)系列文章,歡迎交流。
前文演示docker容器內(nèi)部數(shù)據(jù)共享與持久化,本文繼續(xù)討論docker網(wǎng)絡(luò)以及容器之間的通信。
通過(guò)前面幾篇文章的學(xué)習(xí),大家對(duì)docker已經(jīng)有了初步的認(rèn)識(shí),已經(jīng)能夠?qū)蝹€(gè)容器進(jìn)行管理操作。但在實(shí)際工作中,往往需要多個(gè)服務(wù)容器之間共同協(xié)作,這就要求多個(gè)容器之間能夠相互訪問(wèn)到對(duì)方的服務(wù)。比如我們部署個(gè)人博客網(wǎng)站,往往將數(shù)據(jù)庫(kù)服務(wù)和web服務(wù)放在不同的容器中,web服務(wù)需要訪問(wèn)數(shù)據(jù)庫(kù),因此就要求web容器能否訪問(wèn)數(shù)據(jù)庫(kù)容器。如何實(shí)現(xiàn)這個(gè)功能,正是本文將要探討的。
本文先簡(jiǎn)要描述docker網(wǎng)絡(luò)相關(guān)基礎(chǔ)知識(shí),然后再基于bridge網(wǎng)絡(luò)模式,演示如何將容器端口映射到宿主機(jī)供外部訪問(wèn)、如何通過(guò)互聯(lián)機(jī)制實(shí)現(xiàn)容器之間相互通信。
一、docker網(wǎng)絡(luò)初探
正如前文“Docker基礎(chǔ)修煉3--Docker容器介紹及常用命令”中演示,通過(guò)httpd鏡像run一個(gè)容器的同時(shí)指定端口映射,就可以通過(guò)宿主機(jī)ip和端口訪問(wèn)到web容器。這是怎么實(shí)現(xiàn)的呢,底層原理是什么?要理解這個(gè)現(xiàn)象就要理解docker相關(guān)的網(wǎng)絡(luò)知識(shí)。
1.1 網(wǎng)絡(luò)實(shí)現(xiàn)原理
docker使用Linux橋接在宿主機(jī)虛擬一個(gè)docker容器網(wǎng)橋(名稱為docker0),每當(dāng)啟動(dòng)一個(gè)容器時(shí)會(huì)根據(jù)docker網(wǎng)橋的網(wǎng)段分配一個(gè)IP地址給容器(稱為容器IP),同時(shí)把docker網(wǎng)橋作為每個(gè)容器的默認(rèn)網(wǎng)關(guān)。因?yàn)樵谕凰拗鳈C(jī)內(nèi)的容器都接入同一個(gè)網(wǎng)橋,這樣容器之間就能夠通過(guò)容器IP直接通信。
為了更好的理解上邊這句話,來(lái)看如下案例
1.1.1 案例1:查看docker容器網(wǎng)橋信息
我們可以通過(guò)ifconfig命令查看docker0容器網(wǎng)橋信息
[root@docker ~]# ifconfigdocker0: flags=4099 mtu 1500 ? ? ? inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 ? ? ? ether 02:42:ca:9b:e4:a9 txqueuelen 0 (Ethernet) ? ? ? RX packets 0 bytes 0 (0.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?eno16777736: flags=4163 mtu 1500 ? ? ? inet 192.168.78.101 netmask 255.255.255.0 broadcast 192.168.78.255 ? ? ? inet6 fe80::20c:29ff:fea8:5807 prefixlen 64 scopeid 0x20 ? ? ? ether 00:0c:29:a8:58:07 txqueuelen 1000 (Ethernet) ? ? ? RX packets 155 bytes 16984 (16.5 KiB) ? ? ? RX errors 0 dropped 0 overruns 0 frame 0 ? ? ? TX packets 180 bytes 22972 (22.4 KiB) ? ? ? TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0...省略部分內(nèi)容可以看到docker0即為容器網(wǎng)橋,是宿主機(jī)虛擬出來(lái)的,并不是真實(shí)存在的網(wǎng)絡(luò)設(shè)備。另外一個(gè)eno16777736(每臺(tái)電腦可能名稱不一樣)則為網(wǎng)卡信息,可以通過(guò)它配置宿主機(jī)的IP信息。
1.1.2 案例2:新建兩個(gè)容器觀察容器IP以及互通性
通過(guò)案例1可以看到docker0的ip為:172.17.0.1。本例以官方提供的centos鏡像為例,創(chuàng)建容器mycentos1、mycentos2,觀察這兩個(gè)容器IP與docker0的IP之間的關(guān)系
先創(chuàng)建mycentos1
[root@docker ~]# docker run -it --name mycentos1 centos[root@6db829977fc4 /]# ifconfigbash: ifconfig: command not found[root@6db829977fc4 /]# yum install net-tools...省略部分內(nèi)容,中途需要按兩次y進(jìn)行確認(rèn)[root@6db829977fc4 /]# ifconfigeth0: flags=4163 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 2562 bytes 12723956 (12.1 MiB) ? ? ? RX errors 0 dropped 0 overruns 0 frame 0 ? ? ? TX packets 2168 bytes 121391 (118.5 KiB) ? ? ? TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0...省略部分內(nèi)容[root@6db829977fc4 /]# netstat -rnKernel IP routing tableDestination ? ? Gateway ? ? ? ? Genmask ? ? ? ? Flags ? MSS Window irtt Iface0.0.0.0 ? ? ? ? 172.17.0.1 ? ? 0.0.0.0 ? ? ? ? UG ? ? ? 0 0 ? ? ? ? 0 eth0172.17.0.0 ? ? 0.0.0.0 ? ? ? ? 255.255.0.0 ? ? U ? ? ? ? 0 0 ? ? ? ? 0 eth0[root@6db829977fc4 /]#基于官方鏡像centos創(chuàng)建容器mycentos1后,進(jìn)入容器發(fā)現(xiàn)ifconfig命令提示不存在,原因是此官方進(jìn)行默認(rèn)沒(méi)有安裝網(wǎng)絡(luò)工具包,因此通過(guò)yum install net-tools命令安裝網(wǎng)絡(luò)工具,安裝完成后再次通過(guò)ifconfig命令即可看到該容器的ip為:172.17.0.2 ,然后再通過(guò)netstat -rn查看該容器的網(wǎng)關(guān)為:172.17.0.1。
這就證實(shí)了前面說(shuō)的:每當(dāng)啟動(dòng)一個(gè)容器時(shí)會(huì)根據(jù)docker網(wǎng)橋的網(wǎng)段分配一個(gè)IP地址給容器,同時(shí)把docker網(wǎng)橋作為每個(gè)容器的默認(rèn)網(wǎng)關(guān)。
接下來(lái)繼續(xù)創(chuàng)建容器mycentos2,驗(yàn)證兩容器之間IP的連通性。
克隆一個(gè)連接會(huì)話,然后按如下步驟執(zhí)行
[root@docker ~]# docker run -it --name mycentos2 centos[root@400c375d202d /]# yum install net-tools...與上面相同,因此省略輸出過(guò)程[root@400c375d202d /]# ifconfigeth0: flags=4163 mtu 1500 ? ? ? inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255 ? ? ? ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet) ? ? ? RX packets 1957 bytes 12693925 (12.1 MiB) ? ? ? RX errors 0 dropped 0 overruns 0 frame 0 ? ? ? TX packets 1584 bytes 89868 (87.7 KiB) ? ? ? TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0...省略部分輸出[root@400c375d202d /]# netstat -rnKernel IP routing tableDestination ? ? Gateway ? ? ? ? Genmask ? ? ? ? Flags ? MSS Window irtt Iface0.0.0.0 ? ? ? ? 172.17.0.1 ? ? 0.0.0.0 ? ? ? ? UG ? ? ? 0 0 ? ? ? ? 0 eth0172.17.0.0 ? ? 0.0.0.0 ? ? ? ? 255.255.0.0 ? ? U ? ? ? ? 0 0 ? ? ? ? 0 eth0[root@400c375d202d /]#同理可以看到mycentos2容器的ip地址為:172.17.0.3,網(wǎng)關(guān)為:172.17.0.1
在mycentos2中通過(guò)ip去pingmycentos1的ip,觀察連通性
[root@400c375d202d /]# ping -c 1 172.17.0.3 PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.069 ms?--- 172.17.0.3 ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.069/0.069/0.069/0.000 ms[root@400c375d202d /]# exitexit[root@docker ~]#可以看到在mycentos2中可以直接通過(guò)ping通mycentos1的ip,反過(guò)來(lái)亦然。這充分證明了:因?yàn)樵谕凰拗鳈C(jī)內(nèi)的容器都接入同一個(gè)網(wǎng)橋,這樣容器之間就能夠通過(guò)容器IP直接通信。
1.2 常見(jiàn)網(wǎng)絡(luò)模式
1.2.1 docker網(wǎng)絡(luò)相關(guān)命令
先簡(jiǎn)單介紹下幾個(gè)docker網(wǎng)絡(luò)相關(guān)的命令
docker network ls:查看網(wǎng)絡(luò)
docker network create:創(chuàng)建網(wǎng)絡(luò)
docker network inspect:查看網(wǎng)絡(luò)細(xì)節(jié)
docker port:查看宿主機(jī)與容器間的端口映射
1.2.2 docker網(wǎng)絡(luò)模式
我們先來(lái)看看docker安裝后默認(rèn)的網(wǎng)絡(luò)
[root@docker ~]# docker network lsNETWORK ID ? ? ? ? NAME ? ? ? ? ? ? ? DRIVER ? ? ? ? ? ? SCOPEd0f8ab5a4b42 ? ? ? bridge ? ? ? ? ? ? bridge ? ? ? ? ? ? local28991c6c5348 ? ? ? host ? ? ? ? ? ? ? host ? ? ? ? ? ? ? local969fd1293425 ? ? ? none ? ? ? ? ? ? ? null ? ? ? ? ? ? ? local[root@docker ~]#通過(guò)docker network ls命令查看宿主機(jī)網(wǎng)絡(luò)情況,可以看到安裝docker后,自動(dòng)安裝了三個(gè)網(wǎng)絡(luò),啟動(dòng)類型分別為:bridge、host、null。
實(shí)際上docker有如下幾種類型的網(wǎng)絡(luò)驅(qū)動(dòng):bridge、none、container、host、overlay等
模式配置說(shuō)明bridge-net=bridge默認(rèn)使用該模式none–net=none容器有獨(dú)立的Network namespace,但并沒(méi)有對(duì)其進(jìn)行任何網(wǎng)絡(luò)設(shè)置,如分配veth pair 和網(wǎng)橋連接,配置IP等。container-net=container:NAME_or_ID容器和另外一個(gè)容器共享Network namespace。 kubernetes中的pod就是多個(gè)容器共享一個(gè)Network namespace。host–net=host容器和宿主機(jī)共享Network namespace。overlay–net=overlay多主機(jī)之間通信
(1)bridge模式
bridge模式是docker的默認(rèn)網(wǎng)絡(luò)模式,不寫(xiě)--net參數(shù),就是bridge模式。
bridge模式示意圖如下:
bridge網(wǎng)絡(luò)模式
從docker0子網(wǎng)中分配一個(gè)IP給容器使用,并設(shè)置docker0的IP地址為容器的默認(rèn)網(wǎng)關(guān)。在主機(jī)上創(chuàng)建一對(duì)虛擬網(wǎng)卡veth pair設(shè)備,Docker將veth pair設(shè)備的一端放在新創(chuàng)建的容器中,并命名為eth0(容器的網(wǎng)卡),另一端放在主機(jī)中,以vethxxx這樣類似的名字命名,并將這個(gè)網(wǎng)絡(luò)設(shè)備加入到docker0網(wǎng)橋中。可以通過(guò)brctl show命令查看。
當(dāng)使用命令docker run -p創(chuàng)建容器時(shí),docker實(shí)際是在iptables做了DNAT規(guī)則,實(shí)現(xiàn)端口轉(zhuǎn)發(fā)功能。可以使用iptables -t nat -vnL命令查看。
(2)none模式
使用none模式,Docker容器擁有自己的Network Namespace,但是,并不為Docker容器進(jìn)行任何網(wǎng)絡(luò)配置。也就是說(shuō),這個(gè)Docker容器沒(méi)有網(wǎng)卡、IP、路由等信息。需要我們自己為Docker容器添加網(wǎng)卡、配置IP等。
none模式示意圖如下:
none網(wǎng)絡(luò)模式
這種網(wǎng)絡(luò)模式下容器只有l(wèi)o回環(huán)網(wǎng)絡(luò),沒(méi)有其他網(wǎng)卡。none模式可以在容器創(chuàng)建時(shí)通過(guò)--network=none來(lái)指定。這種類型的網(wǎng)絡(luò)沒(méi)有辦法聯(lián)網(wǎng),封閉的網(wǎng)絡(luò)能很好的保證容器的安全性。
(3)container模式
這個(gè)模式指定新創(chuàng)建的容器和已經(jīng)存在的一個(gè)容器共享一個(gè) Network Namespace,而不是和宿主機(jī)共享。新創(chuàng)建的容器不會(huì)創(chuàng)建自己的網(wǎng)卡,配置自己的 IP,而是和一個(gè)指定的容器共享 IP、端口范圍等。同樣,兩個(gè)容器除了網(wǎng)絡(luò)方面,其他的如文件系統(tǒng)、進(jìn)程列表等還是隔離的。兩個(gè)容器的進(jìn)程可以通過(guò) lo 網(wǎng)卡設(shè)備通信。
container模式示意圖如下:
container網(wǎng)絡(luò)模式
(4)host模式
如果啟動(dòng)容器的時(shí)候使用host模式,那么這個(gè)容器將不會(huì)獲得一個(gè)獨(dú)立的Network Namespace,而是和宿主機(jī)共用一個(gè)Network Namespace。容器將不會(huì)虛擬出自己的網(wǎng)卡,配置自己的IP等,而是使用宿主機(jī)的IP和端口。但是,容器的其他方面,如文件系統(tǒng)、進(jìn)程列表等還是和宿主機(jī)隔離的。
host模式如下圖所示:
host網(wǎng)絡(luò)模式
使用host模式的容器可以直接使用宿主機(jī)的IP地址與外界通信,容器內(nèi)部的服務(wù)端口也可以使用宿主機(jī)的端口,不需要進(jìn)行NAT,host最大的優(yōu)勢(shì)就是網(wǎng)絡(luò)性能比較好,但是docker host上已經(jīng)使用的端口就不能再用了,網(wǎng)絡(luò)的隔離性不好。
(5)overlay模式
overlay網(wǎng)絡(luò)用于連接不同機(jī)器上的docker容器,允許不同機(jī)器上的容器相互通信,同時(shí)支持對(duì)消息進(jìn)行加密,當(dāng)我們初始化一個(gè)swarm或是加入到一個(gè)swarm中時(shí),在docker主機(jī)上會(huì)出現(xiàn)兩種網(wǎng)絡(luò):
a、稱為ingress的overlay網(wǎng)絡(luò),用于傳遞集群服務(wù)的控制或是數(shù)據(jù)消息,若在創(chuàng)建swarm服務(wù)時(shí)沒(méi)有指定連接用戶自定義的overlay網(wǎng)絡(luò),將會(huì)加入到默認(rèn)的ingress網(wǎng)絡(luò)
b、名為docker_gwbridge橋接網(wǎng)絡(luò)會(huì)連接swarm中所有獨(dú)立的docker系統(tǒng)進(jìn)程
overlay網(wǎng)絡(luò)模式
關(guān)于overlay網(wǎng)絡(luò)的更多細(xì)節(jié)將在后續(xù)講解,此處提到的swarm是一個(gè)新的概念,docker swarm是官方提供的集群管理工具,它將若干臺(tái)docker主機(jī)抽象為一個(gè)整體以便于統(tǒng)一進(jìn)行管理。
總結(jié):
在一臺(tái)主機(jī)上的多個(gè)獨(dú)立的容器,用bridge模式
需要將容器的網(wǎng)絡(luò)環(huán)境和主機(jī)的網(wǎng)絡(luò)環(huán)境綁定時(shí),用host模式
需要多個(gè)主機(jī)上的多個(gè)容器相互通信,用overlay網(wǎng)絡(luò)
二、docker端口映射
Docker網(wǎng)橋是宿主機(jī)虛擬出來(lái)的,并不是真實(shí)存在的網(wǎng)絡(luò)設(shè)備,外部網(wǎng)絡(luò)是無(wú)法尋址到的,這也意味著外部網(wǎng)絡(luò)無(wú)法通過(guò)直接Container-IP訪問(wèn)到容器。如果容器希望外部訪問(wèn)能夠訪問(wèn)到,可以通過(guò)映射容器端口到宿主主機(jī)(端口映射),即docker run創(chuàng)建容器時(shí)候通過(guò) -p 或 -P 參數(shù)來(lái)啟用,訪問(wèn)容器的時(shí)候就通過(guò)[宿主機(jī)IP]:[容器端口]訪問(wèn)容器。
正如前面所述,容器有自己的內(nèi)部網(wǎng)絡(luò)和 ip 地址,使用docker inspec可以詳細(xì)查看。
前文已經(jīng)通過(guò)ngnix進(jìn)行了演示,本例再以training/webapp鏡像為例進(jìn)行演示-p和-P的用法。
training/webapp鏡像是一個(gè)運(yùn)行python的環(huán)境,里邊包含了簡(jiǎn)單的基于python的web程序,運(yùn)行后即可訪問(wèn),類似于前文的ngnix演示效果,內(nèi)部運(yùn)行端口為5000。如果你沒(méi)有python基礎(chǔ),完全不用關(guān)心鏡像內(nèi)部的細(xì)節(jié),本文重點(diǎn)是演示容器端口映射的幾種方法。
首先下載鏡像
[root@docker ~]# docker pull training/webappUsing default tag: latestlatest: Pulling from training/webapp...輸出內(nèi)容省略2.1 使用P參數(shù)隨機(jī)映射端口
當(dāng)容器中運(yùn)行一些網(wǎng)絡(luò)應(yīng)用, 要讓外部訪問(wèn)這些應(yīng)用時(shí), 可以通過(guò)-P或-p參數(shù)來(lái)指 定端口映射。 當(dāng)使用P(大寫(xiě)的)標(biāo)記時(shí), Docker 會(huì)隨機(jī)映射一個(gè) 49000~49900 的端口到內(nèi)部容器開(kāi)放的網(wǎng)絡(luò)端口。
[root@docker ~]# docker run -d -P training/webapp python app.py3f6e17415056c27d3186dad236371be9be9bbdd121babfbf3aed6c8b2c86d01f[root@docker ~]# docker psCONTAINER ID ? ? ? IMAGE ? ? ? ? ? ? ? COMMAND ? ? ? ? ? ? CREATED ? ? ? ? ? ? STATUS ? ? ? ? ? ? PORTS ? ? ? ? ? ? ? ? ? ? NAMES3f6e17415056 ? ? ? training/webapp ? ? "python app.py" ? ? 14 seconds ago ? ? Up 12 seconds ? ? ? 0.0.0.0:32768->5000/tcp ? nifty_wing[root@docker ~]#可以看到隨機(jī)映射到宿主機(jī)的端口為32786,因此外部可以通過(guò)宿主機(jī)ip:32786的形式進(jìn)行訪問(wèn)。
另外需要注意,如果沒(méi)有通過(guò)--name顯式指定容器名稱,則會(huì)自動(dòng)隨機(jī)生成一個(gè)容器名,如此處的容器名nifty_wing。
此處的IP地址為我演示是宿主機(jī)的ip地址,因此需要改為自己對(duì)應(yīng)的ip即可。
此外,我們還可以通過(guò)docker logs命令查看python應(yīng)用的輸出信息,其中3f6e17415056為容器的ID,也可以通過(guò)容器名稱訪問(wèn)。
[root@docker ~]# docker logs -f 3f6e17415056 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)192.168.78.1 - - [07/Apr/2020 23:38:03] "GET / HTTP/1.1" 200 -192.168.78.1 - - [07/Apr/2020 23:38:03] "GET /favicon.ico HTTP/1.1" 404 -?當(dāng)使用p(小寫(xiě))參數(shù)時(shí),則可以指定要映射的端口,并且在一個(gè)指定端口上只可以綁定一個(gè)容器。支持格式為:IP:HostPort:ContainerPort 或 IP:: ContainerPort 或 HostPort:ContainerPort,也就是說(shuō)除了容器端口必須指定外,宿主機(jī)IP、宿主機(jī)端口可以不同時(shí)指定。
2.2 映射所有接口地址
使用HostPort:ContainerPort格式將本地的5000端口映射到容器的5000端口, 可以執(zhí)行如下命令:
[root@docker ~]# docker run -d -p 5000:5000 --name test2 training/webapp python app.py511a5a103216391f5075a3e8c3b841bb104806dbd177fce7db1318a887df9f46[root@docker ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES511a5a103216 training/webapp "python app.py" 2 minutes ago Up 2 minutes 0.0.0.0:5000->5000/tcp test2[root@docker ~]#此時(shí)在通過(guò)宿主機(jī)ip:5000的形式在瀏覽器再次訪問(wèn),將看到2.1中同樣的效果,這樣就把容器內(nèi)的5000端口映射到了宿主機(jī)的5000端口上。
可以通過(guò)docker port命令查看端口映射
[root@docker ~]# docker port test2 50000.0.0.0:5000[root@docker ~]#可以看到容器內(nèi)5000端口映射到了宿主機(jī)的0.0.0.0:5000。其中0.0.0.0表示任意地址。
由于此處未指定宿主機(jī)ip地址,因此當(dāng)有多塊網(wǎng)卡或多IP的時(shí)候,都可以通過(guò)這種形式訪問(wèn)到。
2.3 映射到指定地址的指定端口
可以使用IP:HostPart:ContainerPort格式指定映射使用一個(gè)特定地址,比如 localhost地址127.0.0.1:
[root@docker ~]# docker run -d -p 127.0.0.1:5001:5000 --name test3 training/webapp python app.py4b689b1be9faed3d8b50beac57ce4b5a95899ef38c6ed7bdbcde11a7d2dddebd[root@docker ~]# docker port test3 5000127.0.0.1:5001[root@docker ~]#此時(shí)由于指定的宿主機(jī)固定地址為127.0.0.1,物理主機(jī)上將無(wú)法直接通過(guò)這個(gè)地址或宿主機(jī)IP訪問(wèn)
此外,還可以采用IP::ContainerPort的形式,不指定宿主機(jī)端口,本地主機(jī)會(huì)自動(dòng)分配一個(gè)端口。這種方式就不演示了。
三、容器互聯(lián)互通
本文只討論bridge網(wǎng)絡(luò)模式下容器之間的相互通信,以后將要講解的swarm模式下,也是可以通過(guò)服務(wù)名稱進(jìn)行相互通信的。
容器的互聯(lián)(linking)是一種讓多個(gè)容器中的應(yīng)用進(jìn)行快速交互的方式。它會(huì)在源和接收容器之間創(chuàng)建連接關(guān)系,接收容器可以通過(guò)容器名快速訪問(wèn)到源容器,而不用指定具體的IP地址。
查看容器名稱除了可以用docker ps進(jìn)行查看外,還可以用docker inspect命令。前面文章中學(xué)習(xí)過(guò)docker inspect命令,它是用于查看容器內(nèi)部詳細(xì)信息的,我們可以通過(guò)-f參數(shù)來(lái)照看指定內(nèi)容。
[root@docker ~]# docker inspect -f "{{.Name}}" test2 /test2另外,在執(zhí)行docker run的時(shí)候如果添加--rm標(biāo)記,則容器在終止后會(huì)立刻刪除。- -rm 和-d參數(shù)不能同時(shí)使用。
截至目前為止,我們創(chuàng)建的容器都是采用默認(rèn)的bridge驅(qū)動(dòng)類型的名稱為bridge的網(wǎng)絡(luò),因?yàn)槿绻趧?chuàng)建容器時(shí)沒(méi)有顯示通過(guò)--net指定網(wǎng)絡(luò),則默認(rèn)采用bridge網(wǎng)絡(luò)。
這里有個(gè)大坑,都是dridge驅(qū)動(dòng)類型的網(wǎng)絡(luò),默認(rèn)的bridge和自定義的bridge兩者有些區(qū)別,3.1和3.2就是用來(lái)演示他們的不同
3.1 bridge默認(rèn)網(wǎng)絡(luò)下容器間互通
默認(rèn)的bridge網(wǎng)絡(luò)下,使用--link參數(shù)可以讓容器之間安全地進(jìn)行交互。
在操作之前,我們采用如下命令刪除之前創(chuàng)建的所有容器
[root@docker ~]# docker rm -f $(docker ps -aq)本例我們通過(guò)training/postgres和training/webapp這2個(gè)鏡像進(jìn)行演示。其中postgres為數(shù)據(jù)庫(kù),webapp鏡像為基于python的web。
先下載對(duì)應(yīng)的鏡像
[root@docker ~]# docker pull training/postgres3.1.1 創(chuàng)建db容器
[root@docker ~]# docker run -d --name db training/postgres370dd884b187bfc4f91af955270d1695f737d20883fbb9e11601afbc1a98274a[root@docker ~]#3.1.2 創(chuàng)建web容器
[root@docker ~]# docker run -d -P --name web --link db:db training/webapp python app.py429c3b111d76948812be1a495ff5eebf4fe8340c540c7633a0fe2e212c35cc74[root@docker ~]#此時(shí),db容器和web容器建立互聯(lián)關(guān)系。 --link參數(shù)的格式為--link name: alias, 其中name是要鏈接的容器的名稱 , alias是別名。
3.1.3 連通性測(cè)試
通過(guò)docker ps命令查看,相互進(jìn)入容器ping對(duì)方容器名稱
[root@docker ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES429c3b111d76 training/webapp "python app.py" 22 seconds ago Up 20 seconds 0.0.0.0:32769->5000/tcp web370dd884b187 training/postgres "su postgres -c '/us…" About a minute ago Up About a minute 5432/tcp db[root@docker ~]# docker exec -it web /bin/bash root@429c3b111d76:/opt/webapp# ping -c 1 dbPING db (172.17.0.2) 56(84) bytes of data.64 bytes from db (172.17.0.2): icmp_seq=1 ttl=64 time=0.183 ms--- db ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.183/0.183/0.183/0.000 msroot@429c3b111d76:/opt/webapp# exitexit[root@docker ~]# docker exec -it db /bin/bashroot@370dd884b187:/# ping webping: unknown host webroot@370dd884b187:/# exitexit[root@docker ~]#可以看到在web容器內(nèi)可以ping通db,但是db內(nèi)卻ping不通web,因此說(shuō)明--link是單向的。
這相當(dāng)于在兩個(gè)互聯(lián)的容器之間創(chuàng)建了一個(gè)虛機(jī)通道, 而且不用映射它們的端口到宿主主機(jī)上。 在啟動(dòng) db 容器的時(shí)候并沒(méi)有使用 -p 和 -P 標(biāo)記, 從而避免了暴露數(shù)據(jù)庫(kù)服務(wù) 端口到外部網(wǎng)絡(luò)上。
從這個(gè)單向性也可以看出,在目前這種默認(rèn)的bridge網(wǎng)絡(luò)下,如果在創(chuàng)建web容器時(shí)不通過(guò)--link指定連接,則在web內(nèi)是無(wú)法連接到db的,可以自己動(dòng)手驗(yàn)證一下。
3.1.4 link內(nèi)部原理
docker通過(guò)兩種方式為容器公開(kāi)連接信息:環(huán)境變量和/etc/hosts文件。
當(dāng)我們創(chuàng)建容器時(shí),指定--link,實(shí)際上docker內(nèi)部會(huì)自動(dòng)做一些事情,才使得容器之間能夠互聯(lián)。
進(jìn)入web容器觀察環(huán)境變量
[root@docker ~]# docker exec -it web /bin/bash root@1424259bc79d:/opt/webapp# envHOSTNAME=1424259bc79dDB_NAME=/web/dbTERM=xtermDB_PORT_5432_TCP_ADDR=172.17.0.2DB_PORT=tcp://172.17.0.2:5432DB_PORT_5432_TCP=tcp://172.17.0.2:5432...省略部分內(nèi)容其中 DB—開(kāi)頭的環(huán)境變量是供 web 容器連接 db 容器使用, 前綴采用大寫(xiě)的連接別名。
除了環(huán)境變量, Docker 還添加 host信息到父容器的 /etc/hosts 的文件。 下面是父容器web的 hosts 文件
root@1424259bc79d:/opt/webapp# cat /etc/hosts...省略部分無(wú)關(guān)內(nèi)容172.17.0.2 db d31f1617c99f172.17.0.3 1424259bc79droot@1424259bc79d:/opt/webapp# exitexit[root@docker ~]#這里有 2 個(gè) hosts 信息, 第一個(gè)是 web 容器, web 容器用自己的 id 作為默認(rèn)主機(jī)名, 第二個(gè)是 db 容器的 IP 和主機(jī)名。
這個(gè)過(guò)程都是自動(dòng)的,無(wú)需人工干預(yù)。這樣就實(shí)現(xiàn)了容器間的互聯(lián)。
3.2 bridge自定義網(wǎng)絡(luò)下容器間互通
上一節(jié)演示了創(chuàng)建容器是不指定網(wǎng)絡(luò),采用默認(rèn)的bridge的網(wǎng)絡(luò),需要指定--link才能實(shí)現(xiàn)容器間通信。而如果是自定義的bridge網(wǎng)絡(luò),則無(wú)需指定直接就可以通信。
避免干擾,先刪除所有容器
[root@docker ~]# docker rm -f $(docker ps -qa)1424259bc79dd31f1617c99f[root@docker ~]#3.2.1 創(chuàng)建自定義bridge網(wǎng)絡(luò)
[root@docker ~]# docker network lsNETWORK ID NAME DRIVER SCOPEda812afe6179 bridge bridge local28991c6c5348 host host local969fd1293425 none null local[root@docker ~]# docker network create -d bridge --attachable mybridge12d1d3bc9619d8e5f00785a2ac29eb4a5a1cef06610015e1689eddef79ae47b1[root@docker ~]# docker network lsNETWORK ID NAME DRIVER SCOPEda812afe6179 bridge bridge local28991c6c5348 host host local12d1d3bc9619 mybridge bridge local969fd1293425 none null local[root@docker ~]#創(chuàng)建網(wǎng)絡(luò)采用docker network create 命令,-d參數(shù)指定網(wǎng)絡(luò)驅(qū)動(dòng)類型,--attacheable指定網(wǎng)絡(luò)是否可以附加。
3.2.2 創(chuàng)建容器是指定自定義網(wǎng)絡(luò)
[root@docker ~]# docker run -d --name db --network mybridge training/postgres 9b0fad4485c4fdb08346b1154da4932c4dbf40b20f2af049733bc31edc261638[root@docker ~]# docker run -d -P --name web --network mybridge training/webapp python app.py2aa7fcd3400eafb833aa2473eed4d7ecce532e4f571af380fa3df3c459ad73fc[root@docker ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES2aa7fcd3400e training/webapp "python app.py" 10 seconds ago Up 8 seconds 0.0.0.0:32772->5000/tcp web9b0fad4485c4 training/postgres "su postgres -c '/us…" 44 seconds ago Up 42 seconds 5432/tcp db3.2.3 測(cè)試容器連通性
[root@docker ~]# docker exec -it db /bin/bashroot@9b0fad4485c4:/# ping -c 1 webPING web (172.18.0.3) 56(84) bytes of data.64 bytes from web.mybridge (172.18.0.3): icmp_seq=1 ttl=64 time=0.101 ms--- web ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.101/0.101/0.101/0.000 msroot@9b0fad4485c4:/# exitexit[root@docker ~]# docker exec -it web /bin/bashroot@2aa7fcd3400e:/opt/webapp# ping -c 1 dbPING db (172.18.0.2) 56(84) bytes of data.64 bytes from db.mybridge (172.18.0.2): icmp_seq=1 ttl=64 time=0.094 ms--- db ping statistics ---1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.094/0.094/0.094/0.000 msroot@2aa7fcd3400e:/opt/webapp# exitexit[root@docker ~]#可以看到不用--link也可以正常訪問(wèn),并且是相互能通的。說(shuō)明自定義bridge網(wǎng)絡(luò),無(wú)須指定--link參數(shù)(如果你指定了也不會(huì)報(bào)錯(cuò))直接就可以訪問(wèn)了。
3.3 bridge自定義網(wǎng)絡(luò)和默認(rèn)網(wǎng)絡(luò)區(qū)別
上邊兩個(gè)案例演示了基于bridge網(wǎng)絡(luò)驅(qū)動(dòng)的默認(rèn)網(wǎng)絡(luò)和自定義網(wǎng)絡(luò)之間的區(qū)別,在此做一個(gè)總結(jié)。
按照一般的思維,docker默認(rèn)提供的bridge網(wǎng)絡(luò)與用戶自定義的bridge網(wǎng)絡(luò)之間,在功能上應(yīng)該沒(méi)有什么區(qū)別,但實(shí)際情況與此相反,兩者之間存在著一些不同,假設(shè)有兩個(gè)容器連接在同一個(gè)bridge網(wǎng)絡(luò)之上,在網(wǎng)絡(luò)是默認(rèn)的與用戶自定義的情況下的一些不同點(diǎn):
bridge驅(qū)動(dòng)類型默認(rèn)網(wǎng)絡(luò)和自定義網(wǎng)絡(luò)的區(qū)別
本文詳細(xì)演示了docker網(wǎng)絡(luò)中bridge網(wǎng)絡(luò)驅(qū)動(dòng)模式下默認(rèn)網(wǎng)絡(luò)和自定義網(wǎng)絡(luò)的區(qū)別,關(guān)于overlay網(wǎng)絡(luò)模式將在以后進(jìn)行介紹。
總結(jié)
以上是生活随笔為你收集整理的docker 获取宿主机ip_Docker基础修炼6——网络初探及单机容器间通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: skywalking原理_微服务链路追踪
- 下一篇: gnss单频软件接收机应用与编程_GNS