天天看點

docker網絡

h

一、 Docker 中的網絡功能介紹

預設情況下,容器可以建立到外部網絡的連接配接,但是外部網絡無法連接配接到容器。

Docker 允許通過外部通路容器或容器互聯的方式來提供網絡服務

外部通路容器:

容器中可以運作一些網絡應用,要讓外部也可以通路這些應用,可以通過  -P  或  -p  參數來指定端口映射。

建構鏡像模闆

1) 建立一個sshd_dockerfile工作目錄

<code>[root@localhost ~]</code><code># mkdir sshd_dockerfile</code>

<code>[root@localhost ~]</code><code># cd sshd_dockerfile/</code>

<code>[root@localhost sshd_dockerfile]</code><code># touch dockerfile run.sh</code>

<code>[root@localhost sshd_dockerfile]</code><code># ls</code>

<code>dockerfile  run.sh</code>

編輯run.sh檔案

<code>[root@localhost sshd_dockerfile]</code><code># cat run.sh </code>

<code>#!/bin/bash</code>

<code>/usr/sbin/sshd</code>

<code>/usr/sbin/httpd</code> <code>-DFOREGROUND</code>

在主機上生成ssh秘鑰對,并建立authorized_keys檔案

<code>[root@localhost sshd_dockerfile]</code><code># ssh-keygen -t rsa</code>

<code>Generating public</code><code>/private</code> <code>rsa key pair.</code>

<code>Enter </code><code>file</code> <code>in</code> <code>which</code> <code>to save the key (</code><code>/root/</code><code>.</code><code>ssh</code><code>/id_rsa</code><code>): </code>

<code>Created directory </code><code>'/root/.ssh'</code><code>.</code>

<code>Enter passphrase (empty </code><code>for</code> <code>no passphrase): </code>

<code>Enter same passphrase again: </code>

<code>[root@localhost sshd_dockerfile]</code><code># cat ~/.ssh/id_rsa.pub &gt; /root/sshd_dockerfile/authorized_keys</code>

<code>[root@localhost sshd_dockerfile]</code><code># cat dockerfile </code>

<code>FROM docker.wang.com</code><code>/centos</code><code>:centos7</code>

<code>MAINTAINER from [email protected]</code>

<code>RUN yum -y </code><code>install</code> <code>openssh-server </code><code>sudo</code> <code>httpd</code>

<code>RUN </code><code>useradd</code> <code>admin</code>

<code>RUN </code><code>echo</code> <code>"admin:admin"</code> <code>| chpasswd</code>

<code>RUN </code><code>echo</code> <code>"admin ALL=(ALL) ALL"</code> <code>&gt;&gt; </code><code>/etc/sudoers</code>

<code>RUN </code><code>ssh</code><code>-keygen -t dsa -f </code><code>/etc/ssh/ssh_host_dsa_key</code>

<code>RUN </code><code>ssh</code><code>-keygen -t rsa -f </code><code>/etc/ssh/ssh_host_rsa_key</code>

<code>RUN </code><code>mkdir</code> <code>-p </code><code>/var/run/sshd</code>

<code>RUN </code><code>mkdir</code> <code>-p </code><code>/home/admin/</code><code>.</code><code>ssh</code>

<code>RUN </code><code>sed</code> <code>-ri </code><code>'s/session    required     pam_loginuid.so/#session    required     pam_loginuid.so/g'</code> <code>/etc/pam</code><code>.d</code><code>/sshd</code>

<code>ADD authorized_keys </code><code>/home/admin/</code><code>.</code><code>ssh</code><code>/authorized_keys</code>

<code>RUN </code><code>sed</code> <code>-ri </code><code>'s/#ServerName www.example.com:80/ServerName www.benet.com/g'</code> <code>/etc/httpd/conf/httpd</code><code>.conf</code>

<code>ADD run.sh </code><code>/run</code><code>.sh</code>

<code>RUN </code><code>chmod</code> <code>755 </code><code>/run</code><code>.sh</code>

<code>EXPOSE 22 80 443</code>

<code>CMD [</code><code>"/bin/bash"</code><code>,</code><code>"/run.sh"</code><code>]</code>

二載入centos包

<code>[root@localhost src]</code><code># docker load &lt; centos7.tar</code>

<code>0fe55794a0f7: Loading layer [==================================================&gt;]</code>

1)在sshd_dockerfile目錄下,使用docker  build指令來建立鏡像,注意:在最後還有一個”.”,表示使用目前目錄中的dockerfile

<code>[root@localhost sshd_dockerfile]</code><code># docker build -t centos:http .</code>

<code>Sending build context to Docker daemon 4.608 kB</code>

<code>Step 1 : FROM docker.wang.com</code><code>/centos</code><code>:centos7</code>

<code> </code><code>---&gt; 50dae1ee8677</code>

<code>Step 2 : MAINTAINER from [email protected]</code>

<code> </code><code>---&gt; Using cache</code>

<code> </code><code>---&gt; 62fedfca03bd</code>

當使用–P(大寫)标記時,Docker 會随機映射一個随機的端口到内部容器開放的網絡端口。

注:-P使用時需要指定--expose選項或dockerfile中用expose指令容器要暴露的端口,指定需要對外提供服務的端口

使用  docker ps  可以看到,本地主機的32770被映射到了容器的22端口,本地主機的32769被映射到了容器的80端口,本地主機的32768被映射到了容器的443 端口。

<code>[root@localhost sshd_dockerfile]</code><code># docker run -d -P centos:http</code>

<code>131e12661bc10f0bc441784d64e65038ac0263d6beff1d55bf2cd28d4082c948</code>

<code>[root@localhost sshd_dockerfile]</code><code># docker ps</code>

<code>CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS                                                                  NAMES</code>

<code>131e12661bc1        centos:http         </code><code>"/bin/bash /run.sh"</code>   <code>22 seconds ago      Up 21 seconds       0.0.0.0:32770-&gt;22</code><code>/tcp</code><code>, 0.0.0.0:32769-&gt;80</code><code>/tcp</code><code>, 0.0.0.0:32768-&gt;443</code><code>/tcp</code>   <code>trusting_rosalind</code>

此時通路本機的 32770端口即可通路容器内 ssh 應用

<code>[root@localhost sshd_dockerfile]</code><code># ssh [email protected] -p 32770</code>

<code>The authenticity of host </code><code>'[192.168.100.46]:32770 ([192.168.100.46]:32770)'</code> <code>can't be established.</code>

<code>Are you sure you want to </code><code>continue</code> <code>connecting (</code><code>yes</code><code>/no</code><code>)? </code><code>yes</code>

注:192.168.1.102是宿主主機位址。

檢視容器運作的httpd程序

<code>[admin@131e12661bc1 ~]$ pgrep httpd</code>

<code>7</code>

<code>8</code>

<code>9</code>

<code>10</code>

<code>11</code>

<code>12</code>

此時通路本機的 32769端口即可通路容器内 web 應用

-p(小寫)則可以指定要映射的端口,并且,在一個指定端口上隻可以綁定一個容器。支援的格式有ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort

注意:

容器有自己的内部網絡和 ip 位址(使用  docker inspect  可以擷取所有的變量。)

-p 标記可以多次使用來綁定多個端口

<code>[root@localhost sshd_dockerfile]</code><code># docker run -d -p 10111:22 -p 801:80 centos:http</code>

<code>e0c4edcb03ed524d6d9ebfeac62178761910719e3eac7f6e7058cf0e655e8636</code>

<code>e0c4edcb03ed        centos:http         </code><code>"/bin/bash /run.sh"</code>   <code>16 seconds ago      Up 15 seconds       443</code><code>/tcp</code><code>, 0.0.0.0:10111-&gt;22</code><code>/tcp</code><code>, 0.0.0.0:801-&gt;80</code><code>/tcp</code>                    <code>grave_albattani</code>

<code>131e12661bc1        centos:http         </code><code>"/bin/bash /run.sh"</code>   <code>5 minutes ago       Up 5 minutes        0.0.0.0:32770-&gt;22</code><code>/tcp</code><code>, 0.0.0.0:32769-&gt;80</code><code>/tcp</code><code>, 0.0.0.0:32768-&gt;443</code><code>/tcp</code>   <code>trusting_rosalind</code>

測試通路:

1) ssh測試:

使用xshell工具: 賬号密碼為 admin

<a href="https://s1.51cto.com/wyfs02/M01/00/5C/wKiom1ma212iJDDPAABVXHdrYXU463.png-wh_500x0-wm_3-wmp_4-s_3251043453.png" target="_blank"></a>

測試web通路

<a href="https://s2.51cto.com/wyfs02/M01/00/5C/wKiom1ma223jHAckAAGAUEtWubY962.png-wh_500x0-wm_3-wmp_4-s_3354350372.png" target="_blank"></a>

映射到指定位址的指定端口

可以使用 ip:hostPort:containerPort 格式,指定映射使用一個特定位址,比如主控端網卡配置的一個位址192.168.100.46

<code>root@localhost sshd_dockerfile]</code><code># docker run -dit -p 192.168.100.46:10112:22 -p 192.168.100.46:800:80 centos:http</code>

<code>fd41ea4d576f9a337df993b1e39db40274a16289eda134646abd385138216b0f</code>

1. 映射到指定位址的任意端口

<code>[root@localhost sshd_dockerfile]</code><code># docker run -d -p 192.168.100.46::80 --name webserver centos:http</code>

<code>c15abaf81039fb58f3104e7a8d6f854f640cc2ea8ed67615a8388866abf0c649</code>

1 udp端口

<code>[root@localhost sshd_dockerfile]</code><code># docker run -d -p 192.168.100.46:5000:5000/udp --name db4 centos:http</code>

<code>fadedde03f89a235e6cf7dd5412dba7a6870844625d498290126c05e68961335</code>

1. 端口端口映射配置

<code>[root@localhost sshd_dockerfile]</code><code># docker port webserver</code>

<code>80</code><code>/tcp</code> <code>-&gt; 192.168.100.46:32771</code>

Docker NAT iptables實作

預設情況下,容器可以主動通路到外部網絡的連接配接,但是外部網絡無法通路到容器

容器通路外部實作

容器所有到外部網絡的連接配接,源位址都會被 NAT 成本地系統的 IP 位址(即docker0位址)。這是使用 iptables 的源位址僞裝操作實作的

檢視主機的 NAT 規則

<code>[root@localhost sshd_dockerfile]</code><code># iptables -t nat -vnL</code>

<code>Chain PREROUTING (policy ACCEPT 3 packets, 234 bytes)</code>

<code> </code><code>pkts bytes target     prot opt </code><code>in</code>     <code>out     </code><code>source</code>               <code>destination         </code>

<code>  </code><code>242 19323 PREROUTING_direct  all  --  *      *       0.0.0.0</code><code>/0</code>            <code>0.0.0.0</code><code>/0</code>

外部通路容器實作

容器允許外部通路,可以在 docker run 時候通過 -p 或 -P 參數來啟用,不管用那種辦法,其實也是在本地的 iptable 的nat 表中添加相應的規則

使用 -P 時:

<code>f2f3ca6d96693b2223d4011e770c3d2b8359219f13e5e617f2263a6bc4298f18</code>

docker0  網橋

Docker服務預設會建立一個 docker0 網橋(其上有一個 docker0 内部接口),它在核心層連通了其他的實體或虛拟網卡,這就将所有容器和本地主機都放到同一個實體網絡。

<code>[root@localhost ~]</code><code># brctl show</code>

<code>bridge name    bridge </code><code>id</code>      <code>STP enabled    interfaces</code>

<code>docker0     8000.02429a3b4e3e   no      veth3855536</code>

注意(brctl可以使用yum install bridge-utils)

容器

<code>[root@localhost ~]</code><code># docker exec -it e0c4edcb03ed /bin/bash</code>

<code>[root@e0c4edcb03ed /]</code><code># </code>

<code>[root@e0c4edcb03ed /]</code><code># sudo yum -y install iproute</code>

進入運作的容器使用exec;之後安裝iproute包。

<code>[root@e0c4edcb03ed /]</code><code># ip r</code>

<code>default via 172.17.0.1 dev eth0 </code>

<code>172.17.0.0</code><code>/16</code> <code>dev eth0  proto kernel  scope link  src 172.17.0.3</code>

會看到容器的ip/預設網關。

Docker 網絡配置

Docker 四種網絡模式

docker run 建立 Docker 容器時,可以用 --net 選項指定容器的網絡模式,Docker 有以下 4 種網絡模式:

· host 模式,使用 --net=host 指定。

· container 模式,使用 --net=container:NAMEorID 指定。

· none 模式,使用 --net=none 指定。

· bridge 模式,使用 --net=bridge 指定,預設設定。

如果啟動容器的時候使用 host 模式,那麼這個容器将不會獲得一個獨立的 Network Namespace,而是和主控端共用一個Network Namespace。容器将不會虛拟出自己的網卡,配置自己的 IP 等,而是使用主控端的 IP 和端口。

檢視httpd程序

<code>[root@localhost ~]</code><code># pgrep httpd</code>

啟動容器 host模式

<code>root@localhost sshd_dockerfile]</code><code># docker run -dit --net=host centos:http</code>

<code>b4f57f10bbc3da6aeefaf435613f7832d152d60cd971613e7d8da30b3b5b2c29</code>

放行80端口

<code>[root@localhost sshd_dockerfile]</code><code># firewall-cmd --add-port=80/tcp</code>

<code>success</code>

這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace,而不是和主控端共享。新建立的容器不會建立自己的網卡,配置自己的 IP,而是和一個指定的容器共享 IP、端口範圍等。同樣,兩個容器除了網絡方面,其他的如檔案系統、程序清單等還是隔離的。兩個容器的程序可以通過 lo 網卡裝置通信。

運作一個容器:檢視容器的IP

<code>root@localhost sshd_dockerfile]</code><code># docker run -it docker.wang.com/centos:centos7</code>

<code>[root@17cd70302107 /]</code><code>#</code>

将容器切換到背景運作:ctrl+p  ctrl+q

在運作一個容器使用container模式:檢視新容器的位址

docker run -it --ent=container:d86194948685(上個容器id) 鏡像名

檢視ip,發現與上個容器ip一緻。

1. none模式(容器擁有自己的Network namespace)

需自己為容器添加網卡、配置ip等。

2. bridge模式(docker0網卡、橋接到容器的網卡。)

所有的veth*的接口都會橋接到docker0(虛拟共享網)

<a href="https://s3.51cto.com/wyfs02/M00/9F/0C/wKioL1ma3KzDCjyTAAEev0Y3vAQ029.png-wh_500x0-wm_3-wmp_4-s_2761375797.png" target="_blank"></a>

檢視橋接網絡的詳細資訊

<code>[root@localhost sshd_dockerfile]</code><code># docker network inspect</code>

<a href="https://s3.51cto.com/wyfs02/M00/00/5C/wKiom1ma3PeyhwLJAAAijPSr6hs687.png-wh_500x0-wm_3-wmp_4-s_389056282.png" target="_blank"></a>

除了預設的  docker0  網橋,使用者也可以指定網橋來連接配接各個容器。在啟動 Docker 服務的時候,使用  -b BRIDGE  或 --bridge=BRIDGE  來指定使用的網橋。

Docker 允許你管理 docker0 橋接或者通過-b選項自定義橋接網卡,需要安裝bridge-utils軟體包。

基本步驟如下:

1.確定 docker 的程序是停止的

2.建立自定義網橋

3.給網橋配置設定特定的 ip

4.以 -b 的方式指定網橋

如果服務已經運作,那需要先停止服務,并删除舊的網橋

<code>[root@localhost sshd_dockerfile]</code><code># systemctl stop docker</code>

<code>[root@localhost sshd_dockerfile]</code><code># ip link set dev docker0 down</code>

<code>[root@localhost sshd_dockerfile]</code><code># brctl delbr docker0</code>

<code>[root@localhost sshd_dockerfile]</code><code># brctl show</code>

<code>virbr0      8000.000000000000   </code><code>yes</code>    

1. 建立網橋,配置設定ip。

<code>[root@localhost sshd_dockerfile]</code><code># brctl addbr bridge0</code>

<code>[root@localhost sshd_dockerfile]</code><code># ip addr add 192.168.1.1/24 dev bridge0</code>

<code>[root@localhost sshd_dockerfile]</code><code># ip link set dev bridge0 up</code>

檢視确認網橋成功與否

<code>bridge0     8000.000000000000   no     </code>

<a href="https://s4.51cto.com/wyfs02/M01/9F/0C/wKioL1ma3Tbg0zIgAAAhCqBcK9o424.png-wh_500x0-wm_3-wmp_4-s_2831328041.png" target="_blank"></a>

1. 修改/etc/sysconfig/docker檔案。

<a href="https://s4.51cto.com/wyfs02/M02/00/5C/wKiom1ma3U_iCb1mAAAgvMotc_w176.png-wh_500x0-wm_3-wmp_4-s_3790175569.png" target="_blank"></a>

1. 啟動服務。

<code>[root@localhost sshd_dockerfile]</code><code># systemctl start docker</code>

1. 建立容器。

<a href="https://s2.51cto.com/wyfs02/M02/9F/0C/wKioL1ma3WXwpFlyAAAjWhkDW3g646.png-wh_500x0-wm_3-wmp_4-s_2108289559.png" target="_blank"></a>

1. 進入容器檢視。

<code>[root@localhost sshd_dockerfile]</code><code># docker attach 1481b536c081462aade6e8c7b590142057e6fb29a649011a983672044ea8b609</code>

<code>[root@1481b536c081 /]</code><code># yum -y install iproute</code>

<code>[root@localhost sshd_dockerfile]</code><code># 'rpm' -qf `which ifconfig`</code>

<code>net-tools-2.0-0.17.20131004git.el7.x86_64</code>

查詢下ifconfig指令所需軟體包

<code>[root@1481b536c081 /]</code><code># yum -y install net-tools</code>

<a href="https://s4.51cto.com/wyfs02/M01/00/5C/wKiom1ma3aqAYuZNAAAnctBPTJU892.png-wh_500x0-wm_3-wmp_4-s_2616858819.png" target="_blank"></a>

     本文轉自柴鑫旺 51CTO部落格,原文連結:http://blog.51cto.com/chaixinwang/1958172,如需轉載請自行聯系原作者