引言
這一篇文章,理論和實踐各佔一半,有需要的可以先安裝配置好兩臺虛擬機和Docker。
覺得寫的可以不妨點個贊吧,收藏比贊高N倍,枯了😂~
文章導讀
- Docker的C/S架構
- Docker容器的網絡連接
- Docker容器的數據管理
一、Docker的C/S模式
Docker的C/S架構中,最重要的就是Docker Client和Docker Daemon。
1.1 Docker的C/S模式
Docker守護進程會在Docker啓動後,在宿主機後臺運行,負責處理docker的各種命令功能。用戶並不是直接和守護進程交互,而是和Docker客戶端交互。意思是我們輸入的命令,通過命令行接口(/bin/bash這樣二進制的程序),再傳遞給守護進程,守護進程再將命令執行後返回結果給客戶端,顯示於命令行接口。
docker客戶端除了以命令的方式和守護進程通信,還可通過Remote API。
客戶端與守護進程的連接方式
從整體上來看,用戶通過命令行接口或應用程序(程序是對Remote API的封裝)來對Docker Client進行訪問,而這個客戶端是以Socket的方式來對守護進程訪問的。
Docker是以Socket的方式連接,有三種模式:
- unix://var/run/docker.sock(默認)
- tcp://host:port
- fd://socketfd
1.2 Docker守護進程的配置和操作
使用service命令管理
- service docker start
- service docker stop
- service docker restart
Docker的啓動選項
docker -d [OPTIONS]
- 運行相關
-D,--debug:是否開啓debug
-e, 運行時使用的驅動模式
-g ,指定docker寫入文件的地址
--icc :指定容器之間是否可以互相連接
-l,--log-level:設置日誌界別
-p,pidfile默認爲"/var/run/docker.pid" - 服務器連接相關
-G,指定用戶組,默認是"docker"
-H,按照上一節所講的Socket連接模式來寫
--tls=false 安全性相關選項
... ... - RemoteAPI相關
--api-enable-cors 是否使用RemoteAPI - 存儲相關
-s:storage driver,設置驅動
--selinux-enable:是否開啓selinux
... ... - Registry相關
--registry-mirror:配置鏡像連接 - 網絡設置相關(下一章會講)
-ip
-ip-forward:決定是否會轉發流量
--iptables :允許容器與iptables設置的ip之間的訪問
... ...
具體配置可以參考官網: 詳細配置說明
除了通過設置啓動時的參數,也可以通過配置docker啓動時的配置文件,/etc/default/docker設置詳細的配置項。
二、Docker容器的網絡連接
Docker的網絡連接部分主要包括:
- Docker容器的網絡基礎
- Docker容器的互聯
- Docker容器與外部網絡的連接
- Docker容器的跨主機訪問
2.1 Docker容器的網絡基礎
Docker守護進程啓動後,在宿主機中查看網卡信息,會發現多了一個網卡(Docker0)。Docker0其實就是一個Linux虛擬網橋。
提到這裏,先回顧一下什麼是網橋?
網橋工作於數據鏈路層,通過網絡設備的物理地址(MAC地址)對網絡進行劃分,在不同網絡之間傳遞數據。
Linux虛擬網橋的特點是可以設置IP地址,相當於擁有一個隱藏的虛擬網卡。
docker0來說,他的IP地址爲172.17.0.1,屬於B類IP。子網掩碼爲255.255.0.0。可以計算出總共可劃分65534個地址。
docker0的工作過程
Docker對網絡連接的管理,是在容器啓動時就初始化兩端。一端是容器中的網絡設備,另一端在守護進程的主機中(docker0的Host端)開放veth開頭的接口,用於網橋與容器網卡的網絡通信。
簡單感受下網橋是怎麼工作的:
- 首先安裝網橋管理程序
yum install bridge-utils
- 查看網橋設備
brctl show
3. 創建一個容器
- docker run -it --name container1 centos:centos7 /bin/bash
- ctrl+P;ctrl+Q(讓容器後臺運行)
此時可以看到,網橋有了對應的網絡。
我們也可以自定義docker0的ip網段,使用ifconfig指令:ifconfig docker0 192.168.200.1 netmask 255.255.255.0
自定義虛擬網橋
- 添加虛擬網橋
brctl addbr newbridge
ifconfig newbridge 192.168.100.1 netmask 255.255.255.0
- 更改docker守護進程的啓動配置
vim /etc/default/docker
添加DOCKER_OPS="-b=newbridge"
2.2 Docker容器的互聯
Docker容器的互聯可分爲:
- 允許所有容器互聯
- 拒絕容器間互聯
- 允許特定容器間的連接
前提
FROM centos:centos7
RUN yum install -y ping
RUN yum install -y nginx
RUN yum install -y curl
EXPOSE 80
CMD /bin/bash
構建鏡像 docker build -t image1 .
2.2.1 允許容器間的互聯
容器之間默認是可以互聯的,具體可由docker守護進程的啓動選項:--icc=true|false指定。
- 構建容器
docker run -it --name container1 image1
- 啓動服務
nginx
- 讓容器後臺運行後,再啓動一個容器
docker run -it --name container2 image1
- 進入各自容器,互相ping一下,發現是可行的
配置容器間的動態連接
docker容器重啓後,IP會發生變化,如果服務與服務之間將IP寫死調用,勢必會調用失敗,此時就需要link參數: docker run --link=[CONTAINER]:[ALIAS] [IMAGE] [COMMAND]
給某個想要連接的容器取別名,這樣在容器重啓時,對應的host文件中的映射也會變化。
2.2.2 拒絕容器間的互聯
首先要修改守護進程的啓動選項,就要修改docker默認的配置文件。
- vim /etc/default/docker
- 在DOCKER_OPS中添加--icc=false
執行service dockers restart後,創建的所有容器都不能互聯,如果需要指定容器互聯就需要下一節的操作。
2.2.3 允許特定容器間的連接
- Docekr守護進程的啓動選項:
--icc=false
--iptables=true - 重啓一下docker,創建容器時用--link指定
service docker restart
docker run -it --name container3 --link=container1:c1 image1
- 測試是否能連通
curl c1
2.3 Docker容器與外部網絡連接
ip-forward是linux系統中的變量,決定是否會轉發流量。 對應了Linux的這個系統變量:sysctl net.ipv4.conf.all.forwarding
docekr守護進程配置的ip-forword默認爲true。iptables是與Linux內核集成的包過濾防火牆系統,幾乎所有的Linux發行版本都包括iptables的功能。
阻止特定ip對特定容器的訪問
指令格式:
iptables -I DOCKER -s 源地址 -d 目標地址 -p TCP --dport 目的端口 -j 執行操作
注:執行操作包括DROP,ACCEPT等等。
可以通過iptables -L -n
來查看系統中的一些包過濾規則。
通過一個例子感受下:
阻止192.168.29.100訪問容器ip爲192.168.29.111的80端口iptables -l DOCKER -s 192.168.29.100 -d 192.168.29.111 -p TCP --dport 80 -j DROP
如果是允許的化,也同理,講DROP改爲ACCEPT。
2.4 Docker容器的跨主機訪問
目前蒐集的至少有3中方式可以實現:
- 使用網橋實現跨主機容器連接。
- 使用Open vSwitch實現跨主機容器連接。
- 使用weave實現跨主機容器連接。
這裏由於配置簡單,就講解第一種,使用網橋的方式。
主要思路:
如果將連接容器的網橋橋接到docker宿主機提供的網卡上,並將網橋分配的ip地址與docker宿主機的ip地址設置到同一網段,就能夠實現容器與容器之間跨主機的通信。簡單來說就是在一個宿主機中,大家都用一個網橋。
操作步驟
- 需要兩臺虛擬機
IP地址:Host1(192.168.29.3),Host2(192.168.29.4) - 修改兩臺虛擬機中網橋的連接
vim /etc/network/interfaces
配置如下:
auto bridge
#分配網橋的方式
iface bridge inet static
address 192.168.29.3
netmask 255.255.255.0
#默認網關
gateway 192.168.29.1
#將本地的物理網卡連接到新建的網橋上
bridge_ports eth0
在另一臺虛擬機中也進行類似操作。
3. 修改docker默認的網絡配置
IP的劃分將改成192.168.29.65~192.168.29.126和192.168.29.129~192.168.29.190
Host1中:vim /etc/default/docker
DOCKER_OPTS=" -b=bridge --fixed-cidr='192.168.29.64/26' "
Host2中:DOCKER_OPTS=" -b=bridge --fixed-cidr='192.168.29.128/26' "
4. 啓動一個容器,執行ping另一臺宿主機的ip或者另一臺宿主機中的容器,發現能夠連通則配置成功。
三、Docker容器的數據管理
有時候,我們需要容器與宿主機磁盤中的數據共享,對此,Docker提供的解決方案是數據卷技術。以容器掛載數據卷的方式來實現數據的互通。
本小節主要分爲:
- Docekr容器的數據卷
- Docker的數據卷容器
- Docker數據卷的備份和還原
3.1 Docker容器的數據卷
什麼是數據卷?
數據卷是經過特殊設計的目錄,可以繞過聯合文件系統(UFS),爲一個或多個容器提供訪問。對數據卷應該有如下的感覺:
數據卷設計的目的在於持久化,它完全獨立於容器的生存週期,因此,Docker不會在容器刪除時,刪除其掛載的數據卷,也不會存在類似的垃圾收集機制,對容器的數據捲進行處理。
數據卷的特點
- 數據卷在容器啓動時初始化,如果容器使用的鏡像在掛載點包含了數據,這些數據會拷貝到新初始化的數據卷中。
- 數據卷可以在容器之間共享和重用。
- 可以對數據卷裏的內容直接進行修改。
- 數據卷的變化不會影響鏡像的更新。
- 卷會一直存在,即使掛載數據卷的容器已經被刪除。
爲容器添加數據卷
docker run -v ~/container_data:/data -it centos:centos7 /bin/bash
爲數據卷添加訪問權限
docker run -v 宿主機目錄:容器目錄:ro IMAGE COMMAND -d
注:"ro"的意思是read only。
使用Dockerfile構建數據卷
VOLUME["/data"]
這裏是不需要寫明映射關係的,因爲通過這個鏡像創建的不同容器的數據卷是不一樣的。具體映射關係可以通過docker inspect CONTAINER
查看。
3.2 Docker的數據卷容器
數據卷提供了容器與宿主機的共享數據,如果容器與容器之間要共享,該怎麼辦呢?這就需要掛載包含數據卷的容器來實現。
什麼是數據卷容器?
命名的容器掛載數據卷,其他容器通過掛載這個容器實現數據共享,掛載數據卷的容器叫數據卷容器。
文字看着又繞又枯燥,一張圖梳理一下:
圖中可以看出:
- 數據卷容器掛載了一個本地目錄。
- 其他容器通過連接這個數據卷容器實現數據的共享。
掛載數據卷容器的方法 docekr run --volumes-from [CONTAINER]
注:CONTAINER是掛載數據卷的容器。
下面通過一個例子來實現container1與container2的數據共享。
前提
image2.dockerfile如下:
FROM centos:centos7
VOLUME["/datavolume"]
CMD /bin/bash
構建鏡像後的步驟
下面步驟中container1是數據卷容器,container2和container3要實現數據共享。
- 啓動container1
docker run -it --name container1 image2
- 在container1中創建文件
touch /datavolume/c1
exit
- 啓動container2,並掛載到container1
docker run -it --name container2 --volumes-from container1 IMAGE /bin/bash
- 在container2中創建文件
touceh /datavolume/c2
exit
- 同理啓動container3
docker run -it --name container3 --volumes-from container1 IMAGE /bin/bash
exit
docker inspect --format="{{.Volumes}}" container2
docker inspect --format="{{.Volumes}}" container3
最後,我們可以驚奇地發現兩個掛載了數據卷容器的容器返回結果一樣。
此時將container1容器刪除,會發現,container2和container3還是共享了一個數據卷容器,因此可以得出這樣的結論:數據卷容器僅僅承載配置信息的傳遞。
3.3 Docker數據卷的備份和還原
數據備份方法
docker run --volumes-from CONTAINER -v 期望備份存放的路徑(宿主機路徑):映射到備份命令容器中的目錄:權限(一般爲wr,即讀寫權限) IMAGE tar cvf 壓縮至某個路徑下的某個文件名(宿主機路徑) 數據卷在容器中的路徑
文字描述比較繞,通過例子展示一下:
docker run --volumes-from container1 -v ~/backup:/backup --name container2 IMAGE tar cvf /backup/c1.tar /datavolume1
具體過程:
備份過程其實就是對數據容器掛載的數據卷中的數據的轉移,相當於執行備份命令的容器既掛載了數據容器的數據卷,又掛載了備份數據存放的數據卷。
同樣地,數據還原方法就是對備份的解壓縮:docker run --volumes-from container1 -v ~/backup:/backup IMAGE tar xvf /backup/backup.tar /datavolume1
總結
Docker的學習暫時告一段落,在這個過程中,最終要的還是在虛擬機中多多實踐。真實運行中可能會碰到許多問題,解決問題的過程中經驗才能一步一步的積累~
感覺寫得還可不妨點個贊哈~