docker系列(五):網路通訊

奧辰發表於2019-06-30

1 引言

之前的幾篇docker系列部落格說的都是單個容器或者映象的操作。但容器,作為一種簡化的作業系統,又怎能不與機器或者容器相互協同工作呢,這就需要用到容器的網路功能。docker中提供了多種不同的方式實現網路通訊。

本篇就分別說說這幾種通訊方式。

2 埠公開

啟動容器時,如果不給容器設定任何的網路通訊,那麼,容器將作為一個與外界隔絕的獨立機器。如果要讓外界訪問,其中一種方法就是向外界公開埠。埠公開使用--expose引數。

$ docker run -itd --expose 80 ubuntu
781851262fb5e407e6396a8a5094b7ba751dc68f23732a4856e10039b57e39bb

為測試埠是否公開,我們要在80埠上啟動一個apache服務:

chb@chb-VirtualBox:~$ docker attach 7818512
root@781851262fb5:/# apt-get update
root@781851262fb5:/# apt-get install apache2

啟動Apache2:

root@781851262fb5:/# /etc/init.d/apache2 start
* Starting Apache httpd web server apache2 *

檢視一下容器的ip地址:

root@781851262fb5:/# apt-get install net-tools
root@781851262fb5:/# 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 22321 bytes 49869522 (49.8 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 19457 bytes 1063327 (1.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

可以看到,容器ip地址為:172.17.0.2

回到宿主機中,使用curl命令訪問容器的apache伺服器:

$ curl 172.17.0.2:80
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Modified from the Debian original for Ubuntu
Last updated: 2016-11-16
See: https://launchpad.net/bugs/1288690
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Apache2 Ubuntu Default Page: It works</title>
<style type="text/css" media="screen">
* {
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
……

可以正常訪問,在宿主機瀏覽器中也是可以訪問的:

證明埠是公開的。

 3 埠對映

埠對映在介紹容器的那一片博文中也提到過,即在使用docker run命令啟動容器時,通過-p或-P引數來指定埠對映。其中-p(小寫)可手動指定需要對映的埠,需要注意,宿主機一個埠只能繫結一個容器。而-P(大寫)則是讓docker自動隨機對映一個49000~49900埠到容器內部開放的網路埠。

在展開介紹兩者之前那,我們先下載一個nginx映象,我們本篇博文都通過它來展開:

$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
fc7181108d40: Pull complete
c4277fc40ec2: Pull complete
780053e98559: Pull complete
Digest: sha256:bdbf36b7f1f77ffe7bd2a32e59235dff6ecf131e3b6b5b96061c652f30685f3a
Status: Downloaded newer image for nginx:latest

3.1 指定埠對映:-p(小寫)

上面說過,-p(小寫)可以指定一個宿主機的埠繫結到容器指定的埠,它支援以下幾種格式:

(1)HostPort:ContainerPort

使用HostPort:ContainerPort格式將本地的5000埠對映到容器的80埠,返回了HTML網頁:

$ docker run -itd -p 5000:80 nginx
f56c5f10f6d08d4805d32cf9f9ae89bb5ad5bc1fa42d4d88e801548dbdaa0d5c

此時,使用curl命令訪問本機5000埠:

$ curl 127.0.0.1:5000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
 
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
 
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

同時,在瀏覽器通過宿主機ip+5000埠可進行訪問,如下所示,成功訪問容器內執行的nginx,說明真實訪問的是容器的80埠。

多次使用-p引數可以繫結多個埠:

$ docker run -itd -p 5001:5001 -p 5002:5002 nginx:latest
5b1060ff644fda68f83c653615cb04c6fb4835a65f1becad45fe7d97a5d6d06c

通過docker ps命令進行檢視:

(2)IP:HostPort:ContainerPort

可以使用IP:HostPort:ContainerPort格式進行指定地址指定埠進行對映:

$ docker run -itd -p 10.0.2.15:8081:8081 nginx
5053c836089a65cd3b6456e5e1d72e780b5e86ca1d5c04e685ec7593496501b1

通過docker ps命令進行檢視:

(3)IP::ContainerPort

使用IP::ContainerPort格式可以將容器的指定埠對映到宿主機到任意隨機埠:

$ docker run -itd -p 10.0.2.15::8088 nginx:latest
3dc8530e21f0f83d79b4825ffc8708b29f57e27d9deea67e2ed4b984fe2e0d40

通過docker ps命令進行檢視:

3.2 隨機埠對映:-P(大寫)

當使用-P(大寫)引數時,docker會隨機對映一個宿主機埠到內部容器開放的網路埠:

$ docker run -d -P nginx:latest
274fea3b9da2e3f967b18e18d294167ea42f64bfcb5ac99f3a9697d11bec48a9

通過docker ps命令進行檢視:

因為-P(大寫)引數對映到的是容器內部的開放網路埠,所以,在宿主機通過通瀏覽器進行訪問:

4 容器互聯

容器互聯機制是一種讓多個容器之間進行快速互動的一種互動方式,這種方式會在在容器之間建立連線,這種連線對連線中的容器時可見的,避免了暴露埠到外部網路。容器互聯是通過容器的名稱來進行的,所以,需要進行建立容器互聯的容器,最好制定一個容器名(當然,不指定的haul使用系統分配的名稱也可以,不過自定義的名稱好記一些)。使用docker run命令啟動容器時,通過--link引數建立容器互聯,--link命令格式:

--link 容器名1[:容器名2]

其中,容器名1是指需要與正在使用docker run命令建立的容器互聯的容器,容器名2是容器名1的別名,別名可以省略。

還是以nginx為例進行說明:

我們先使用nginx作為伺服器:

$ docker run -d --name nginx_server nginx
3f3e58e016b164f9cb0a17f37997e389ac4f9e0c4ef5004f1f7f155832b22b04

然後在啟動一個ubuntu容器與剛啟動的nginx_server進行互聯:

$ docker run -it --link nginx_server:nginx_server ubuntu
root@4b10ea40eac2:/#

新啟動的ubuntu容器裡面沒有curl命令,為了更好測試,我們安裝一下curl:

root@4b10ea40eac2:/# sudo apt-get update
root@4b10ea40eac2:/# apt install curl

最後,使用curl命令訪問與nginx_client容器互聯的nginx_server容器:

root@4b10ea40eac2:/# curl nginx_server
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
 
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
 
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

成功返回了HTML網頁,證明互聯成功。

多個容器可以同時互聯到同一個容器中,例如在上面的例子中,多個容器可以同時互聯到nginx_server中,互聯的方法是一樣的。

5 總結

本文介紹了幾種docker的容器網路訪問方式,毫無疑問,訪問容器時極其重要且不可避免的操作,如何合理規劃容器間的訪問方式,對資料安全、整個系統的架構有著至關重要的影響.

 
 

相關文章