如何安全便捷地管理Docker船隊

Docker

Docker是什麼?若是說你的服務器是一條船,你只是一個小船主,你的船上散裝着各類貨物(也就是服務,好比http服務,數據庫服務,緩存服務,消息服務等等),那麼Docker就至關於把你的服務器改裝成了一條集裝箱貨船,把你原先凌亂堆放的貨物放置在一個一個容器裏,互相隔離,有序堆放。咱們來看看Docker的商標,是否是很形象呢?html

Docker_logo_011.0.png

可是你的業務越作越大,很明顯一條船是裝不下了,你須要一支船隊:linux

圖片描述

這時候,如何管理船隊就變成了一個難題,沒有工具的幫忙,你甚至都不知道你有幾條船,每條船上裝的都是些什麼貨物,這些貨物如今的狀態如何。docker

Portainer

Portainer這個工具就是管理你船隊的一個好幫手。而且它自己也是安裝在一條船上,這條船就是你的指揮艇吧(說實話這個圖標有點醜,一點都沒有船隊老大的氣質)。數據庫

圖片描述

怎麼安裝Portainer呢?這個別人早都已經介紹過了,包括官網上也有說明。可是我要介紹一下個人經驗,我安裝Portainer的方式和官網的也不一樣,和別人講的也不一樣:緩存

docker run -d --network=host --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

在這裏咱們沒有暴露9000端口,而是使用了一個特殊的設置:--network=host,就是這一點點小小的不一樣,會對你後面的操做影響巨大。安全

Docker API

光裝上Portainer是沒有用的,它充其量也只能管理它所在的這條船。服務器

它怎麼管理整個船隊呢?首先你得創建Portainer和船隊裏其它船隻之間的聯繫。這個聯繫就是讓被管理的船隻暴露出Docker API接口來。可是若是你查看Docker官方的說明文檔,把整個過程弄得極其複雜無比,又要創建什麼安全證書中心,又要頒發證書,沒有初中以上文化是搞不定的。tcp

Docker原本是有一套簡便的暴露端口的方法的,爲何官網要搞這麼複雜呢?由於原先的方法比較簡單,會直接把整個管理界面所有暴露給公網,有極大的安全風險,因此Docker官網搞了一套複雜的認證流程。工具

咱們的解決思路比較簡單:你不要把端口暴露給公網不就好了嗎?加一個防火牆,只讓咱們容許的地址來訪問就能夠了,何須搞什麼CA認證!spa

回到咱們的被管理的船上,把API端口先暴露出來:

# systemctl edit docker
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

好吧,這只是CentOS 7下的一種做法,還有一種做法是修改/etc/sysconfig/docker文件:

OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375'

具體應該用哪一種做法,要取決於你的docker服務是怎麼設置的:

systemctl show docker | grep EnvironmentFile

你若是有EnvironmentFile設定,那麼你就須要用上面第二種辦法,若是沒有,就用第一種辦法。

iptables

好了,如今端口是暴露出來了,可是全公網任何人都能訪問,安全性怎麼辦?這時候咱們發現一個嚴重的問題:Docker在亂搞咱們的iptables表!

iptables是很重要的防火牆的設置,docker爲了暴露它的服務,它會忽視你設置在iptables表裏的一切規則,強行讓它的規則生效。這還了得?咱們必須禁止Docker這麼胡搞,在上面的options裏再加上一個選項--iptables=false

OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375' --iptables=false

重啓Docker服務後,它終於再也不亂動咱們的iptables表了。實際上爲了安全起見,咱們應該在全部docker服務器上都加上--iptables=false的選項。可是這樣又產生了另一個問題:外部訪問當然是阻止了,但咱們的Docker容器想訪問外部也訪問不了了,好比咱們一開始安裝的Portainer也是運行在容器裏的,不能訪問互聯網,它就沒有辦法管理其它Docker服務器了。爲了解決這個問題,須要咱們在創建Docker容器的時候指定--network=host,這也就是本文一開始安裝Portainer時候那樣設置的緣由。

好,如今各個被管理端的2375端口是開開了,可是除了localhost誰也訪問不了它,怎麼辦?咱們能夠在iptables裏增長一條規則:

-A INPUT -s ###.###.###.### -m state --state NEW -m tcp -p tcp --dport 2375 -j ACCEPT

上面那個###.###.###.###就是你的Portainer指揮艇服務器的IP地址。這樣一來,除了這臺指揮艇服務器能夠訪問被管理船隻的Docker API接口之外,別的任何人都不能訪問。這樣就既達到了咱們管理的目的,又保證了安全,同時還免出去了設置證書的繁瑣。

啓航吧,船隊!

圖片描述

相關文章
相關標籤/搜索