docker基礎篇(一)補
1.docker的網絡模式
安裝Docker時,它會自動創建三個網絡,bridge(創建容器默認連接到此網絡,也就是在不使用--network參數時)、 none 、host。還有以後一種自定義模式,自定義模式有三種:bridge、overlay、macvlan。
docker network ls
我們可以在docker run的時候使用--net= none/ host/ bridge來設置容器具體使用哪種模式。
(1)默認網絡通信模式bridge網橋
默認情況下docker運行容器時,宿主機會創建一個bridge網橋,是一個名叫docker 0的虛擬網橋 ,默認docker 0 IP為172.17.0.1,網橋再給容器分配虛擬子網IP,並且以網橋IP作為網關。在不指定網絡的情況下,容器之間的通信都是通過bridge網橋進行通信。然後網橋在與宿主機鏡像進行IP轉換,端口映射等通信。
(2) host宿主機模式
如果容器指定網絡模式為host,容器不會有自己的network namespace,而是和宿主機共用一個network網絡及IP,容器不會有虛擬出自己的網卡、IP等,當然除了網絡通信這一塊和宿主機綁定了,其余的容器內容還是和宿主機安全隔離了。這種在做容器遷移時,很不方便,不推薦使用。
(3) none模式
容器指定網絡模式-net為none時,docker容器不再擁有自己的network namespace,但是所有網絡配置都得自行配置,如IP、網卡等,這種方式很麻煩。(關閉了容器的網絡功能)
這裏補充兩個docker服務運行時參數
-b BRIDGE or--bridge=BRIDGE ——指定容器掛載的網橋;
--fixed-cidr=10.200.55.64/26 #定制容器的IP地址範圍
2.單機間的容器通信
單機間的通信,就是同一宿主機中的不同容器之間的通信,容器之間可通過 IP,Docker DNS Server 和joined 容器三種方式通信。
(1)IP通信
兩個容器要能通信,必須要有屬於同一個網絡的網卡。滿足這個條件後,容器就可以通過 IP 交互了。這也是默認的方式,我們在使用--net= bridge,docker虛擬出來的一個docker0網橋,會給每一個容器在docker0網橋的網段中分配一個IP,這樣同主機中的容器的IP是同一網段的自然可以通過IP相互訪問。
演示:
[[email protected] ~]# ifconfig
這裏看到我的這臺機器中的docker0的網橋的地址為172.17.0.1,這臺機器中啟動的所有的docker的容器的IP都是這個網段的。
[[email protected] ~]# docker ps #查看正在運行的docker容器
我這裏有兩個一個是registry一個是MySQL。
[[email protected] ~]# docker inspect 28b2c91d4be4|grep -i ipaddress #查看容器的IP
[[email protected] ~]# docker inspect 5708c1dcbdd7|grep -i ipaddress #查看容器的IP
可以發現這兩個容器的IP地址果然都是172.17.0.1網段的。
(2)docker DNS server
通過 IP 訪問容器雖然滿足了通信的需求,但還是不夠靈活。因為我們在部署服務之前可能不能確定IP。比如:現在部署一個Nginx web服務,但是每次容器啟動分配的IP地址都會改變,我們無法通過固定的IIP地址去訪問web服務,這樣每次訪問時都要查看IP,非常麻煩,對於這個問題,可以通過 docker 自帶的 DNS 服務解決。
從 Docker 1.10 版本開始,docker daemon 實現了一個內嵌的 DNS server,使容器可以直接通過"容器名"通信。方法很簡單,只要在啟動時用 --name 為容器命名就可以了。
演示:
#下面在同主機啟動兩個Ubuntu系統並指定--name:
[[email protected] ~]#docker run -it --network=brideg2 --name box1 ubuntu:net /bin/bash
[[email protected] ~]#docker run -it --name --network= brideg2 box2 ubuntu:net /bin/bash
我們發現使用--name,的容器名稱可以ping通其他容器。
註意:使用 docker DNS 有個限制:只能在 user-defined 網絡中使用。也就是說,默認的 bridge 網絡是無法使用 DNS 的。
(3) joined 容器
joined 容器是另一種實現容器間通信的方式。它可以使兩個或多個容器共享一個網絡棧,共享網卡和配置信息,joined 容器之間可以通過 127.0.0.1 直接通信。
演示:
#啟動一個http服務
[[email protected] ~]# docker run -dit --name my-apache-app -p 8099:80 -v "/http":/usr/local/apache2/htdocs/ httpd
#創建一個Ubuntu容器容器並通過 --network=container: my-apache-app指定 jointed 容器為 my-apache-app
[[email protected] ~]# docker run -it --network=container:my-apache-app ubuntu:net /bin/bash
#使用命令去訪問my-apache-app容器中的web頁面
[email protected]:/# curl 127.0.0.1
此時我們發現訪問成功!原因是:我們分別查看著兩個容器的IP:
Ubuntu:
http:
我們發現兩個容器的網卡 mac 地址與 IP 完全一樣,它們共享了相同的網絡棧。所以Ubuntu容器可以使用127.0.0.1直接訪問http容器的web服務。
(4) 補充
docker run 命令的參數介紹:
-h 運行容器時指定主機名,這樣我們可以使用主機名去與容器通信。
--link=容器名 別名 ,這樣使用--link連接的容器間就可以使用主機名進行通信。
-p host_port:container_port 端口映射,容器的服務端口映射到宿主機。
-P container_port 端口映射,映射到宿主機的任意空閑端口。
容器的訪問控制
容器訪問外部網絡:兩種方法:
- sysctl -w net.ipv4.ip_forward=1 (設置宿主機的開啟數據轉發)
- 啟動Docker服務的時候設定--ip-forward=true,docker會自動打開宿主機系統的轉發服務
外部訪問容器:這裏很簡單,通過docker run -h hostname -p 端口映射,來實現外部訪問容器。
3.跨主機間的容器通信
(1)Docker網橋實現跨主機容器連接
在同一宿主機下docker容器之間是可以相同連通的。這是因為默認的docker容器在同一宿主機下,所有容器分配的IP處於同一個地址段的,相互之間可以ping通;當我們使用ifconfig命令查看IP時會發現,其中有一個docker0的網橋,docker容器通過docker0 網橋實現同一主機間中,容器的IP地址分配和訪問,這就保證了所有的容器在同一地址段。
雖然這些IP地址在同一宿主機中是處於同一網段並且相互之間可以通信,但是如果在不同宿主機之間,如果網橋的網段不同,容器之間還是不可能實現跨住進的通信,那麽我們可以將每個主機下的容器的網段都處於同一網段,這樣,就可以實現跨主機的訪問啦,這也是Docker容器默認跨主機之間的連接方法的第一種:網橋實現。
上圖就是網橋方式實現跨主機的連接,但是缺點也很明顯,宿主機和容器的IP處於同一網段,如果在局域網下,IP地址是有限的,那麽一個容器占據一個IP地址,IP地址很快就會被用光,這就是個不友好的現象,所以這種方式僅僅只用來學習測試使用。
實戰操作:
實驗環境:
主機名 | IP | Gateway | Netmask | |
---|---|---|---|---|
Host1 | 192.168.130.130 | 192.168.130.2 | 255.255.255.0 | |
Host2 | 192.168.130.131 | 192.168.130.2 | 255.255.255.0 |
① 下載網橋管理工具
yum install -y bridge-utils
② 分別在docker主機上建立網橋
Host1: $ sudo brctl addbr br0
Host2: $ sudo brctl addbr br0
③ 為網橋分配一個同網段IP
Host1: $ sudo ifconfig br0 192.168.130.10 netmask 255.255.255.0
Host2: $ sudo ifconfig br0 192.168.130.20 netmask 255.255.255.0
④ 橋接本地網卡
Host1: $ brctl addif br0 eth0
Host2: $ brctl addif br0 eth0
⑤ 修改docker配置文件
$ Host1 vim /etc/default/docker
$ Host2 vim /etc/default/docker
改成:Host1: DOCKER_OPTS=” -b=br0 –fixed-cidr=‘192.168.130.64/26“
Host2: DOCKER_OPTS=” -b=br1 –fixed-cidr=‘192.168.130.128/26“
這裏的:
-b :用來指定容器連接的網橋的名字。
--fixed-cidr :用來限定容器分配的IP地址的範圍。
⑥重啟docker
$ Host1 systemctl daemon-reload
$ Host1 systemctl restart docker
$ Host2 systemctl daemon-reload
$ Host2 systemctl restart docker
⑦ 測試
這裏在host1和host2中各啟動一個容器,然後相互ping對方容器IP,如果可以ping桶表示配置成功。
(2)Open vSwitch 實現跨主機容器通信
Open vSwitch是一個高質量、多層虛擬交換機。使用Apache2.0許可協議,旨在通過編程擴展,使龐大的網絡自動化(配置、管理、維護),同時還支持標準的管理接口和協議。
實戰操作:
實驗環境:
主機名 | IP | Gateway | Netmask | |
---|---|---|---|---|
Host1 | 192.168.130.130 | 192.168.130.2 | 255.255.255.0 | |
Host2 | 192.168.130.131 | 192.168.130.2 | 255.255.255.0 |
虛擬機網段:
主機名 | 網段 |
---|---|
Host1 | 192.168.1.1 |
Host2 | 192.168.2.1 |
操作步驟:
- 在虛擬機中建立ovs網橋
- 添加gre連接
- 配置docker容器虛擬網橋接
- 為虛擬網橋添加ovs接口
-
添加不同Docker容器網段路由
① 安裝Open vSwitch並啟動[[email protected] Host1~]#yum install -y openvswitch.x86_64
[[email protected] Host1~]#systemctl start openvswitch
② 安裝網橋
[[email protected] Host1~]# yum install -y bridge-utils
③ 建立ovs網橋並添加GRE接口
[[email protected] Host1~]# ovs-vsctl add-br obr0
[[email protected] Host1~]# ovs-vsctl add-port obr0 gre0
④ 設置遠程的網橋連接
[[email protected] Host1~]#ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.130.131
#查看osv網橋配置
[[email protected] Host1~]#ovs-vsctl show
⑤ 設置docker的虛擬網橋
[[email protected] Host1~]#brctl addbr br0
[[email protected] Host1~]#ifconfig br0 192.168.1.1 netmask 255.255.255.0
[[email protected] Host1~]#brctl addif br0 obr0
[[email protected] Host1~]#brctl show
⑥ 設置路由規則
[[email protected] Host1~]#ip route add 192.168.2.0/24 via 192.168.130.131 dev ens33
同理host2也需要按照上述方式配置。最後兩個容器之間就可以通信。
(3)Weave實現跨主機容器通信
Weave是由weaveworks公司開發的解決Docker跨主機網絡的解決方案,它能夠創建一個虛擬網絡,用於連接部署在多臺主機上的Docker容器,這樣容器就像被接入了同一個網絡交換機,那些使用網絡的應用程序不必去配置端口映射和鏈接等信息。
外部設備能夠訪問Weave網絡上的應用程序容器所提供的服務,同時已有的內部系統也能夠暴露到應用程序容器上。Weave能夠穿透防火墻並運行在部分連接的網絡上,另外,Weave的通信支持加密,所以用戶可以從一個不受信任的網絡連接到主機。
原理:
Weave會在主機上創建一個網橋,每一個容器通過 veth pair 連接到該網橋上,同時網橋上有個 Weave router 的容器與之連接,該router會通過連接在網橋上的接口來抓取網絡包(該接口工作在Promiscuous模式)。
在每一個部署Docker的主機(可能是物理機也可能是虛擬機)上都部署有一個W(即Weave router),它本身也可以一個容器的形式部署。Weave run的時候就可以給每個veth的容器端分配一個ip和相應的掩碼。veth的網橋這端就是Weave router容器,並在Weave launch的時候分配好ip和掩碼。
Weave網絡是由這些weave routers組成的對等端點(peer)構成,每個對等的一端都有自己的名字,其中包括一個可讀性好的名字用於表示狀態和日誌的輸出,一個唯一標識符用於運行中相互區別,即使重啟Docker主機名字也保持不變,這些名字默認是mac地址。
每個部署了Weave router的主機都需要將TCP和UDP的6783端口的防火墻設置打開,保證Weave router之間控制面流量和數據面流量的通過。控制面由weave routers之間建立的TCP連接構成,通過它進行握手和拓撲關系信息的交換通信。 這個通信可以被配置為加密通信。而數據面由Weave routers之間建立的UDP連接構成,這些連接大部分都會加密。這些連接都是全雙工的,並且可以穿越防火墻。
實戰操作:
實驗環境:
主機名 | IP | Gateway | Netmask | |
---|---|---|---|---|
Host1 | 192.168.130.130 | 192.168.130.2 | 255.255.255.0 | |
Host2 | 192.168.130.131 | 192.168.130.2 | 255.255.255.0 |
① 下載復制weave二進制執行文件
[[email protected] Host1~]#git clone https://github.com/weaveworks/weave
[[email protected] Host1~]#cp -p /root/weave/weave /usr/bin/
[[email protected] Host1~]#cd /usr/bin/
#查看weave版本
[[email protected] Host1~]#weave version
② 啟動weave服務
[[email protected] Host1~]# weave launch --no-detect-tls #註意第一次啟動會在docker中拉取相應的鏡像
③ 運行一個容器
[[email protected] Host1~]#docker run -it ubuntu:net /bin/bash
然後Ctrl+p+q退出容器,並且讓容器後臺運行
④ 進入容器
[[email protected] Host1~]#weave attach 192.168.2.1/24 c45932ef7da4
註意:這裏的192.168.2.1/24 是默認的給當前容器分配的一個weaveIP
之後再host2宿主機中也執行以上的命令,並且在“weave attach 192.168.2.1/24 容器ID” 這裏分配一相同網段的不同IP。
此時通過這個ethwe中的IP,去相同ping對方容器,這裏就可以相同訪問:
docker基礎篇(一)補