AWS是運(yùn)行容器工作負(fù)載的首選平臺(tái)。有第三方數(shù)據(jù)顯示,云中80%的容器工作負(fù)載,和82%的Kubernetes工作負(fù)載構(gòu)建在AWS云平臺(tái)之上。在AWS上運(yùn)行容器時(shí),我們提供了更多的選擇。首先,您可以選擇編排工具,您可以選擇AWS原生的Amazon ECS或者支持Kubernetes的Amazon EKS。其次,您可以選擇啟動(dòng)類型,就是您是否要管理服務(wù)器。如果您想要進(jìn)行容器的無(wú)服務(wù)器計(jì)算,您可以選擇AWS Fargate模式,如果您想要控制計(jì)算環(huán)境的安裝,配置和管理,您可以選擇Amazon EC2模式。我們提供更多的選擇,也是希望能夠以更靈活的方式幫助您把容器工作負(fù)載更快更好更安全的遷移到云端。
安全性和合規(guī)性是AWS和客戶共同的責(zé)任,基于此,AWS提出了云安全的責(zé)任共擔(dān)模式。這種責(zé)任區(qū)分為云本身的安全和云內(nèi)部的安全。AWS負(fù)責(zé)云本身的安全,包括保護(hù)所有運(yùn)行AWS云服務(wù)的基礎(chǔ)設(shè)施,包括區(qū)域,可用區(qū),邊緣站點(diǎn),計(jì)算存儲(chǔ)網(wǎng)絡(luò),數(shù)據(jù)庫(kù)等等??蛻糌?fù)責(zé)云內(nèi)部的安全??蛻舻呢?zé)任由客戶使用的AWS服務(wù)確定,通常來講,客戶會(huì)負(fù)責(zé)操作系統(tǒng)的安全,網(wǎng)絡(luò)和防火墻的配置,身份和訪問管理,應(yīng)用,平臺(tái)和客戶數(shù)據(jù)的安全。同時(shí),對(duì)于客戶負(fù)責(zé)的云內(nèi)部安全,AWS提供了大量的工具幫助用戶提升安全性。
我們來看一下把上述安全和合規(guī)的責(zé)任共擔(dān)模式應(yīng)用于AWS容器服務(wù)Amazon ECS和Amazon EKS的具體實(shí)踐。
首先,我們看一下身份和訪問管理。談到身份和訪問管理,我們很容易就會(huì)想到AWS IAM服務(wù),它能夠安全的管理對(duì)AWS服務(wù)和資源的訪問。您可以使用IAM創(chuàng)建和管理AWS用戶和組,并使用各種權(quán)限來允許或者拒絕這些用戶和組對(duì)AWS資源的訪問。對(duì)于ECS來說,由于它是AWS原生的容器解決方案。使用IAM就可以完全管理身份和訪問控制。而對(duì)于EKS則需要同時(shí)了解和配置IAM和Kubernetes RBAC,就是基于角色的訪問控制。IAM負(fù)責(zé)將權(quán)限分配到AWS服務(wù),而RBAC負(fù)責(zé)控制資源的權(quán)限。
下面我們看一下Kubernetes的管理工具kubectl的執(zhí)行過程是如何在EKS上進(jìn)行身份認(rèn)證的。比如說啟動(dòng)命令kubectl get pods,在這里我們通過kubectl訪問Kubernetes的API,在其中我們會(huì)傳遞AWS相關(guān)的身份信息,Kubernetes會(huì)向IAM驗(yàn)證身份信息,這里我們會(huì)用到IAM認(rèn)證的一個(gè)插件,aws-iam-authenticator,它是AWS官方用于連接驗(yàn)證身份信息的一個(gè)工具,驗(yàn)證返回之后,Kubernetes API針對(duì)RBAC來授權(quán)AWS身份的資源訪問權(quán)限,最后向kubectl返回執(zhí)行結(jié)果是允許還是拒絕。
對(duì)于Kubernetes來說,RBAC很重要,在這里我們不詳細(xì)展開,大家有需要可以參閱Kubernetes的相關(guān)文檔。這里我們只做一些基本介紹。在RBAC中,一個(gè)角色,role,它包含一組相關(guān)權(quán)限的規(guī)則。在RBAC中,權(quán)限是純粹累加的,并不存在拒絕某操作的規(guī)則。角色可以用Role定義到某個(gè)命名空間上,或者用ClusterRole定義到整個(gè)集群。在RBAC中,可以定義描述資源,比如pod和node;允許對(duì)資源使用動(dòng)詞,比如get,update和delete。同時(shí),RBAC上內(nèi)置了一系列默認(rèn)的ClusterRoles,包括cluster-admin,admin,edit,view,賦予不同的用戶對(duì)不同的資源進(jìn)行不同的操作的權(quán)限。
另外,通過 Amazon EKS 集群上服務(wù)賬戶 (service account)的 IAM 角色,您可以將 IAM 角色與 Kubernetes 服務(wù)賬戶關(guān)聯(lián)。然后,此服務(wù)賬戶就能夠?yàn)槭褂盟娜魏我粋€(gè) Pod 中的容器提供 AWS 權(quán)限。您可以將 IAM 權(quán)限范圍限定到服務(wù)賬戶,并且只有使用該服務(wù)賬戶的 Pod 可以訪問這些權(quán)限。
其次,我們看一下平臺(tái)安全。在這里,我們考慮的是記錄和審核控制平面的安全??刂破矫娴娜罩居涗?,特別是圍繞API動(dòng)作的審核記錄,是平臺(tái)安全的重要部分。對(duì)于ECS來講,由于它是AWS原生的容器服務(wù),所以和其它AWS產(chǎn)品一下,控制平面的日志會(huì)進(jìn)入AWS CloudTrail中,進(jìn)行云資源調(diào)用的記錄。CloudTrail 是一項(xiàng)支持對(duì)AWS 賬戶進(jìn)行監(jiān)管、合規(guī)性檢查、操作審核和風(fēng)險(xiǎn)審核的服務(wù)。借助 CloudTrail,您可以記錄日志、持續(xù)監(jiān)控并保留與整個(gè) AWS 基礎(chǔ)設(shè)施中的操作相關(guān)的賬戶活動(dòng)。對(duì)于Kubernetes來講,它的控制平面包括審計(jì)跟蹤,但這些日志在默認(rèn)情況下不會(huì)公開。EKS有一個(gè)功能可以啟用這些日志,我們建議啟用并且將它們發(fā)送到Amazon CloudWatch進(jìn)行進(jìn)一步的處理并發(fā)現(xiàn)洞察。
第三,我們看一下網(wǎng)絡(luò)和防火墻的配置,這也是容器安全實(shí)踐中最重要的部分。對(duì)于ECS來講,由于它是AWS的原生服務(wù),您只需要了解和配置Amazon VPC和AWS安全組即可。而對(duì)于EKS,除了管理VPC和安全組之外,還需要安裝和配置Kubernetes的網(wǎng)絡(luò)插件和網(wǎng)絡(luò)策略等。
我們先來看一下ECS的網(wǎng)絡(luò)配置。當(dāng)我們將ECS與VPC結(jié)合使用的時(shí)候,每個(gè)任務(wù)都會(huì)有自己專用的彈性網(wǎng)絡(luò)接口 (ENI)。由于每個(gè)任務(wù)和每個(gè)ENI是一一對(duì)應(yīng)的,而每個(gè)ENI和安全組也是一一對(duì)應(yīng)的,因此每個(gè)任務(wù)進(jìn)出的任何通信都會(huì)通過安全組來進(jìn)行,從而簡(jiǎn)單便捷的實(shí)現(xiàn)網(wǎng)絡(luò)的安全性。
對(duì)于EKS來講,在創(chuàng)建新的Kubernetes集群的時(shí)候,EKS會(huì)為與集群通信的托管Kubernetes API服務(wù)器創(chuàng)建一個(gè)終端節(jié)點(diǎn)。默認(rèn)情況下,這個(gè)API終端節(jié)點(diǎn)對(duì)于Internet是公有的,對(duì)API終端節(jié)點(diǎn)的訪問,我們使用AWS IAM和Kubernetes RBAC的組合加以保護(hù)。但是我們建議您啟動(dòng)Kubernetes API終端節(jié)點(diǎn)的私有訪問,以使得工作節(jié)點(diǎn)和API終端節(jié)點(diǎn)之間的所有通信都在VPC之內(nèi)。您可以限制從Internet訪問API終端節(jié)點(diǎn)的IP地址,或者完全禁用對(duì)API終端節(jié)點(diǎn)的Internet訪問。
Amazon VPC CNI目前是Amazon EKS集群默認(rèn)的網(wǎng)絡(luò)插件。在Amazon VPC CNI中,對(duì)于每個(gè)Kubernetes節(jié)點(diǎn),我們創(chuàng)建多個(gè)ENI并且分配輔助IP地址,對(duì)于每個(gè)Pod,我們選擇空閑的輔助IP地址進(jìn)行分配。這樣通過Amazon VPC CNI,可以使得EKS得到原生的Amazon VPC網(wǎng)絡(luò)支持,使得Pod和Pod直接互聯(lián)互通,包括單一主機(jī)內(nèi)的Pod通信,不同主機(jī)內(nèi)的Pod通信,甚至是Pod和其他AWS服務(wù),Pod和On-Premise,Pod和Internet的通信,并提供了更快的網(wǎng)絡(luò)延遲。Amazon VPC CNI是一個(gè)開源項(xiàng)目,在GitHub上進(jìn)行維護(hù)。
對(duì)于Kubernetes來講,網(wǎng)絡(luò)策略是一種關(guān)于 Pod 間及Pod與其他網(wǎng)絡(luò)間所允許的通信規(guī)則的規(guī)范。如果在EKS上進(jìn)行網(wǎng)絡(luò)策略管理,首先需要將網(wǎng)絡(luò)策略提供程序添加到EKS中。Calico是EKS官方文檔中介紹的一種主流的方式。
一種既可以分配EC2實(shí)例級(jí)IAM角色,又可以完全信任基于安全組的方式,是為不同的Pod使用不同的工作節(jié)點(diǎn)集群,甚至是完全獨(dú)立的集群。EKS有NodeGroup的概念,它是一個(gè)獨(dú)立的自動(dòng)伸縮的工作節(jié)點(diǎn)組,可以對(duì)其進(jìn)行標(biāo)記,這樣您就可以限制哪些Pod/服務(wù)可以在其上運(yùn)行。
另外,服務(wù)網(wǎng)格也是可以對(duì)網(wǎng)絡(luò)進(jìn)行配置和管理的一種方法。您可以使用服務(wù)網(wǎng)格來對(duì)所有服務(wù)進(jìn)行加密和身份驗(yàn)證,而不是強(qiáng)加AWS安全組或Kubernetes網(wǎng)絡(luò)策略之類的網(wǎng)絡(luò)級(jí)限制,從而在保持安全的同時(shí)允許更扁平的底層未分級(jí)網(wǎng)絡(luò)。服務(wù)網(wǎng)格通常是通過一組輕量級(jí)的網(wǎng)絡(luò)代理,與應(yīng)用代碼部署在一起來實(shí)現(xiàn)的。網(wǎng)絡(luò)代理包含在每一個(gè)微服務(wù)之中,主要處理微服務(wù)之間的通信,監(jiān)控,以及一些安全相關(guān)的工作。我們可以使用服務(wù)網(wǎng)格增強(qiáng)安全性。以傳輸身份認(rèn)證舉例,傳輸身份驗(yàn)證可以理解為服務(wù)到服務(wù)的身份驗(yàn)證,服務(wù)網(wǎng)格提供雙向TLS功能來實(shí)現(xiàn)。當(dāng)開啟了雙向TLS后,服務(wù)間的流量為加密流量,并且相互根據(jù)證書以及密鑰進(jìn)行訪問從而保障服務(wù)間的通信安全。
AWS App Mesh是AWS推出服務(wù)網(wǎng)格,App Mesh 能夠與 AWS 服務(wù)集成以進(jìn)行監(jiān)控和跟蹤,還可以與很多常用的第三方工具結(jié)合使用。App Mesh 可以與在 AWS 上運(yùn)行的各種容器,包括ECS,EKS,F(xiàn)argate,以及自建Kubernetes集群結(jié)合使用。另外,Istio也已經(jīng)支持在EKS上很好的部署。
第四,我們看一下操作系統(tǒng)的安全。在容器的EC2模式中,客戶的安全責(zé)任更多一些。比如要選擇的實(shí)例類型和數(shù)量,CPU與RAM的比率是多少,擴(kuò)展能力和可用性是多少;還有選擇哪個(gè)操作系統(tǒng),何時(shí)進(jìn)行操作系統(tǒng)加固,何時(shí)給OS,Docker,ECS代理或kubelet打補(bǔ)丁等等,這些都是客戶的責(zé)任。在Fargate的模式下,對(duì)于安全責(zé)任,AWS做得更多,客戶做得更少。AWS負(fù)責(zé)擴(kuò)展、修補(bǔ)、保護(hù)和管理服務(wù)器,為OS,Docker, ECS代理等進(jìn)行打補(bǔ)丁的操作。Fargate需要運(yùn)行在VPC網(wǎng)絡(luò)中,在Fargate中也沒有容器的特權(quán)模式,各個(gè) ECS 任務(wù)或 EKS Pod 各自在其自己的專用內(nèi)核運(yùn)行時(shí)環(huán)境中運(yùn)行,并且不與其他任務(wù)和 Pod 共享 CPU、內(nèi)存、存儲(chǔ)或網(wǎng)絡(luò)資源。這樣可以確保針對(duì)每個(gè)任務(wù)或 Pod 進(jìn)行工作負(fù)載隔離并提高安全性。
對(duì)于EKS來講,Kubernetes的更新也是一個(gè)很重要的話題。通常,Kubernetes每個(gè)季度都有一個(gè)新的主要版本,同時(shí)也會(huì)定期發(fā)布新的次要版本,有時(shí)Kubernetes更新與安全性相關(guān)。EKS具有用于觸發(fā)控制平面更新的API,在觸發(fā)之后您需要更新工作節(jié)點(diǎn),例如,Kubernetes以及Docker和OS。通常工作節(jié)點(diǎn)在一個(gè)自動(dòng)擴(kuò)展組中,因此我們需要重新構(gòu)建或者更新AMI。AWS為工作節(jié)點(diǎn)提供定期自動(dòng)更新的的AMI和手動(dòng)更新的腳本。
第五,我們看一下容器中客戶數(shù)據(jù)的安全。AWS同時(shí)具有Parameter Store和Secrets Manager來存儲(chǔ)您的機(jī)密。它們已集成到ECS中,但對(duì)于EKS,需要通過CLI或SDK在Kubernetes的Pod中調(diào)用它們。Kubernetes的內(nèi)置Secrets功能將機(jī)密存儲(chǔ)在其控制平面中,并通過環(huán)境變量或文件系統(tǒng)中的文件將其放入正在運(yùn)行的Pod中,但是不能在Kubernetes集群之外使用它們。
我們?cè)谧罱l(fā)布了一個(gè)新的功能。您可以使用 AWS Key Management Service (KMS) 生成的密鑰,對(duì)EKS中存儲(chǔ)的 Kubernetes Secrets進(jìn)行信封加密;或者,您也可以將其他地方生成的密鑰導(dǎo)入KMS,并在EKS集群中使用。實(shí)施信封加密被視為存儲(chǔ)敏感數(shù)據(jù)的一種最佳安全實(shí)踐。我們使用開源的AWS Encryption Provider在EKS中為您提供KMS機(jī)密的信封加密。這個(gè)項(xiàng)目得到了Kubernetes社區(qū)和Kubernetes興趣小組的支持。
最后,我們看一下容器鏡像的安全。容器鏡像安全的最佳實(shí)踐包括:不在容器鏡像內(nèi)部存儲(chǔ)機(jī)密;讓一個(gè)容器對(duì)應(yīng)一個(gè)服務(wù),在任務(wù)/Pod內(nèi)使用Sidecar代理;最小化容器體積,只包括運(yùn)行時(shí)需要的內(nèi)容等等。同時(shí),我們要使用已知且受信任的基本鏡像,包括使用Docker Hub上的官方鏡像,仔細(xì)閱讀Dockerfiles,掃描鏡像以獲取CVE。我們需要在Dockerfile中指定USER和最小權(quán)限,以及為容器鏡像建立獨(dú)特且內(nèi)容豐富的標(biāo)簽,來快速分辨出容器鏡像的版本。容器鏡像的掃描包括注冊(cè)表中的鏡像掃描,構(gòu)建管道中的鏡像,和運(yùn)行時(shí)的容器鏡像掃描。注冊(cè)表中的鏡像掃描由Docker Hub和Amazon ECR提供。另外還有一些第三方的開源或商業(yè)軟件可以對(duì)構(gòu)建管道中的鏡像或者運(yùn)行時(shí)的鏡像進(jìn)行掃描。還有,我們也要保證運(yùn)行時(shí)的容器安全。我們可以通過規(guī)則引擎限制可以在容器中執(zhí)行的操作,例如,“請(qǐng)勿運(yùn)行容器中未包含的內(nèi)容”或 “請(qǐng)勿運(yùn)行不在此白名單中的內(nèi)容”來確保只能在集群中部署/運(yùn)行受信任的鏡像,我們需要隨時(shí)了解整個(gè)環(huán)境的運(yùn)行時(shí)行為,一旦遇到CVE公開,立即檢測(cè)運(yùn)行中的易受攻擊的容器