Docker上的MySQL:MySQL容器的單主機網絡

【編者的話】網絡是Docker相當重要的一部分,本文以MySQL容器爲例,詳細介紹了Docker所支持的各類網絡,值得一讀。html


對於MySQL而言,網絡很重要,這是客戶端應用程序和其餘副本可以成功訪問服務器所依賴的基礎資源。容器化的MySQL服務的行爲由運行「docker run」命令的時候如何生成MySQL鏡像來決定。使用Docker單主機網絡,MySQL容器能夠運行在隔離的環境裏(僅僅能夠被在相同網絡裏的容器訪問),或者運行在開放環境裏(這時MySQL服務徹底暴露給外部),或者MySQL實例只是運行着可是沒有任何網絡。mysql


在以前的兩篇博文裏,我介紹了在容器裏運行MySQL的基礎如何構建自定義的MySQL鏡像。這篇博文裏,將繼續介紹Docker是如何處理單主機網絡的,以及MySQL容器如何利用這個功能。sql

 

3種類型網絡

 

默認來講,Docker安裝時在宿主機上建立了3個網絡:docker

$ docker network ls NETWORK ID          NAME                DRIVER 1a54de857c50        host                host 1421a175401a        bridge              bridge 62bf0f8a1267        none                null

 

每一個網絡的驅動都有本身的特徵,下面將詳細討論。shell

 

Host網絡

host網絡將容器添加到宿主機的網絡堆棧上。你能夠認爲容器所運行的網絡鏈接到了和宿主機相同的網絡接口上。它的特徵以下:bash

  • 容器的網絡接口和宿主機是徹底相同的。
  • 每一個宿主機僅有一個host網絡。沒法建立更多的。
  • 必須在「docker run」命令行裏顯式指定"--net=host",給容器分配該網絡。
  • 容器連接,不支持 「--link mysql-container:mysql」
  • 端口映射,不支持 「-p 3307:3306」


讓咱們使用「--net=host」在宿主網絡上建立一個容器:服務器

$ docker run \ --name=mysql-host \ --net=host \ -e MYSQL_ROOT_PASSWORD=mypassword \ -v /storage/mysql-host/datadir:/var/lib/mysql \ -d mysql


查看容器網絡接口,能夠看到容器內的網絡配置和宿主機是徹底同樣的:網絡

[machine-host]$ docker exec -it mysql-host /bin/bash [container-host]$ ip a 1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo    valid_lft forever preferred_lft forever inet6 ::1/128 scope host    valid_lft forever preferred_lft forever 2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:fa:f6:30 brd ff:ff:ff:ff:ff:ff inet 192.168.55.166/24 brd 192.168.55.255 scope global eth0    valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fefa:f630/64 scope link    valid_lft forever preferred_lft forever 3: docker0:  mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:93:50:ee:c8 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 scope global docker0    valid_lft forever preferred_lft forever inet6 fe80::42:93ff:fe50:eec8/64 scope link


這麼設置時,容器不須要在iptables裏添加任何轉發規則,由於它已經attach到了和宿主同樣的網絡上。因此,不支持使用參數「-p」的端口映射,而且Docker不會管理運行在這種類型網絡上的容器的防火牆規則。架構

查看宿主機的偵聽端口,能夠看到3306端口正在偵聽:dom

[machine-host]$ netstat -tulpn | grep 3306 tcp6       0      0 :::3306                 :::*                    LISTEN      25336/mysqld


在Docker宿主網絡上運行MySQL容器相似於在宿主機上安裝了一個標準的MySQL服務器。這僅僅在你但願將這臺宿主機做爲獨佔的MySQL服務器,同時由Docker管理的時候纔有用。
 

這裏,容器架構以下圖所示:

Docker上的MySQL:MySQL容器的單主機網絡
 

在host網絡上建立的容器可以訪問在默認docker0以及用戶定義的bridge網絡上的容器。

 

Bridge網絡

橋接網絡容許多個網絡獨立通訊,同時保證同一臺物理宿主機上網絡之間的隔離。你能夠認爲這相似於宿主機內的另外一種內部網絡。僅僅那些處在相同網絡裏的容器纔可以互相訪問,而且可以訪問宿主機。若是宿主機可以訪問外界,那麼容器也就能夠。


有兩種類型的bridge網絡:

  1. 默認bridge(docker0)
  2. 用戶定義的bridge

 

默認bridge(docker0)

 

默認的bridge網絡,docker0在Docker安裝的時候會自動建立出來。可使用「ifconfig」或者「ip a」命令來驗證這一點。默認的IP範圍是172.17.0.1/16,能夠在/etc/default/docker (Debian) 或者/etc/sysconfig/docker (RedHat)裏改變該值。如何更改參考Docker文檔


直接開始示例。若是不在「docker run」命令裏顯式指定「-net」參數,Docker會在默認的docker0網絡下建立容器:

$ docker run \ --name=mysql-bridge \ -p 3307:3306 \ -e MYSQL_ROOT_PASSWORD=mypassword \ -v /storage/mysql-bridge/datadir:/var/lib/mysql \ -d mysql


查看容器的網絡接口,能夠看到Docker建立了一個網絡接口,eth0(不包含localhost):

[machine-host]$ docker exec -it mysql-container-bridge /bin/bash [container-host]$ ip a 1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo    valid_lft forever preferred_lft forever inet6 ::1/128 scope host    valid_lft forever preferred_lft forever 4: eth0:  mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff inet 172.17.0.2/16 scope global eth0    valid_lft forever preferred_lft forever inet6 fe80::42:acff:fe11:2/64 scope link    valid_lft forever preferred_lft forever


默認來講,Docker利用iptables來管理轉發到bridge網絡的包。每一個出站的鏈接看上去都是從宿主機本身的IP地址之一發送出去的。以下是上述容器啓動後機器的NAT chain:

[machine-host]$ iptables -L -n -t nat Chain POSTROUTING (policy ACCEPT) target     prot opt source               destination MASQUERADE  all  --  172.17.0.0/16        0.0.0.0/0 MASQUERADE  tcp  --  172.17.0.2           172.17.0.2           tcp dpt:3306 Chain DOCKER (2 references) target     prot opt source               destination DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:3307 to:172.17.0.2:3306


上述規則,基於「docker run」 命令行裏指定的端口映射參數 「-p 3307:3306」,容許3307端口暴露在宿主機上。查看宿主機的netstat輸出,能夠看到MySQL在端口3307上偵聽,屬於docker-proxy進程:

[machine-host]$ netstat -tulpn | grep 3307 tcp6       0      0 :::3307                 :::*                    LISTEN      4150/docker-proxy


這種狀況下,容器搭建以下圖所示:

Docker上的MySQL:MySQL容器的單主機網絡
 

默認的bridge網絡支持端口映射和容器連接的使用,容許docker0網絡上的容器間的通訊。關於如何經過暴露環境變量連接容器,以及如何經過/etc/hosts文件自動配置主機映射,Docker文檔提供了詳盡的信息。

 

用戶定義的bridge

Docker讓用戶能夠建立自定義的bridge網絡,也就是用戶定義的bridge網絡(也能夠建立用戶定義的overlay網絡,可是咱們計劃在下一篇博文裏討論這一點)。它的行爲和docker0網絡同樣,網絡裏的每一個容器可以當即和網絡裏的其餘容器通訊。可是,網絡自己將容器和外部網絡隔離開了。


該網絡方式的最大的好處在於,全部容器都可以解析容器名。考慮以下網絡:

[machine-host]$ docker network create mysql-network

 

而後,在用戶定義網絡裏建立5個MySQL容器:

[machine-host]$ for i in {1..5}; do docker run --name=mysql$i --net=mysql-network -e MYSQL_ROOT_PASSWORD=mypassword -d mysql; done


如今,登陸進其中一個容器(mysql3):

[machine-host]$ docker exec -it mysql3 /bin/bash


咱們隨後能夠ping通該網絡裏的全部容器,而徹底不須要連接它們:

[mysql3-container]$ for i in {1..5}; do ping -c 1 mysql$i ; done PING mysql1 (172.18.0.2): 56 data bytes 64 bytes from 172.18.0.2: icmp_seq=0 ttl=64 time=0.151 ms --- mysql1 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.151/0.151/0.151/0.000 ms PING mysql2 (172.18.0.3): 56 data bytes 64 bytes from 172.18.0.3: icmp_seq=0 ttl=64 time=0.138 ms --- mysql2 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.138/0.138/0.138/0.000 ms PING mysql3 (172.18.0.4): 56 data bytes 64 bytes from 172.18.0.4: icmp_seq=0 ttl=64 time=0.087 ms --- mysql3 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.087/0.087/0.087/0.000 ms PING mysql4 (172.18.0.5): 56 data bytes 64 bytes from 172.18.0.5: icmp_seq=0 ttl=64 time=0.353 ms --- mysql4 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.353/0.353/0.353/0.000 ms PING mysql5 (172.18.0.6): 56 data bytes 64 bytes from 172.18.0.6: icmp_seq=0 ttl=64 time=0.135 ms --- mysql5 ping statistics --- 1 packets transmitted, 1 packets received, 0% packet loss round-trip min/avg/max/stddev = 0.135/0.135/0.135/0.000 ms


若是查看resolver的設置,能夠看到Docker配置爲一個內嵌的DNS服務器:

[mysql3-container]$ cat /etc/resolv.conf search localdomain nameserver 127.0.0.11 options ndots:0


內嵌的DNS服務器在容器鏈接到的網絡上,這裏是mysql-network時,維護容器名稱和其IP地址的映射。該功能輔助網絡裏的節點發現,在使用MySQL集羣技術,好比MySQL複製,Galera Cluster或者MySQL Cluster,構建MySQL容器集羣的時候很是有用。


這裏,容器搭建以下圖所示:

Docker上的MySQL:MySQL容器的單主機網絡
 

默認 vs. 用戶定義Bridge

 

下表展現了這兩種網絡的主要不一樣點:

Docker上的MySQL:MySQL容器的單主機網絡
 

No網絡

 

咱們還能夠經過在「docker run」命令裏指定「--net=none」建立出沒有任何網絡的容器。只能經過交互式shell才能訪問這樣的容器。該節點上不會配置任何額外的網絡接口。
以下命令:

[machine-host]$ docker run --name=mysql0 --net=none -e MYSQL_ROOT_PASSWORD=mypassword -d mysql


經過查看容器的網絡接口,僅僅localhost的接口是可用的:

[machine-host]$ docker exec -it mysql0 /bin/bash [mysql0-container]$ ip a 1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo    valid_lft forever preferred_lft forever inet6 ::1/128 scope host    valid_lft forever preferred_lft forever


在network none裏的容器意味着它沒法加入任何網絡。雖然如此,MySQL容器仍然在運行,用戶能夠從shell裏經過localhost或者socket使用mysql客戶端命令行直接訪問該實例:

[mysql0-container]$ mysql -uroot -pmypassword -h127.0.0.1 -P3306 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor.  Commands end with ; or \g. Your MySQL connection id is 6 Server version: 5.7.13 MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>


在該網絡上運行的實例的用例是驗證MySQL的備份,經過測試恢復流程,準備經過使用,好比Percona Xtrabackup,所建立備份,或者在不一樣版本的MySQL服務器上測試查詢語句。

這裏,容器搭建以下圖所示:

Docker上的MySQL:MySQL容器的單主機網絡
 

本片博文至此完結。

  

來源:http://www.youruncloud.com/docker/1_82.html

相關文章
相關標籤/搜索