網路安全 - Amazon EKS

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

網路安全

網路安全有幾個面向。第一種涉及規則的套用,這些規則會限制服務之間的網路流量流程。第二個涉及傳輸中流量的加密。在 EKS 上實作這些安全措施的機制會有所不同,但通常包括下列項目:

流量控制

  • 網路政策

  • 安全群組

網路加密

  • Service Mesh

  • 容器網路界面 (CNIs)

  • 輸入控制器和負載平衡器

  • Nitro 執行個體

  • 使用 cert-manager 的 ACM Private CA

網路政策

在 Kubernetes 叢集中,預設允許所有 Pod 對 Pod 通訊。雖然這種靈活性可能有助於促進實驗,但它不被視為安全。Kubernetes 網路政策為您提供一種機制,以限制 Pod 之間的網路流量 (通常稱為東部/西部流量),以及 Pod 與外部服務之間的網路流量。Kubernetes 網路政策在 OSI 模型的第 3 層和第 4 層運作。網路政策使用 Pod、命名空間選擇器和標籤來識別來源和目的地 Pod,但也可以包含 IP 地址、連接埠號碼、通訊協定或這些項目的組合。網路政策可以套用至 Pod 的傳入或傳出連線,通常稱為傳入和傳出規則。

透過 Amazon VPC CNI 外掛程式的原生網路政策支援,您可以實作網路政策來保護 kubernetes 叢集中的網路流量。這與上游 Kubernetes 網路政策 API 整合,以確保相容性和遵守 Kubernetes 標準。您可以使用上游 API 支援的不同識別符來定義政策。根據預設,所有輸入和輸出流量都會允許到 Pod。指定具有 policyType Ingress 的網路政策時,只有來自 Pod 節點的允許連線,以及輸入規則允許的連線。輸出規則也適用。如果定義了多個規則,則在做出決策時,會考慮所有規則的聯集。因此,評估順序不會影響政策結果。

重要

當您第一次佈建 EKS 叢集時,預設不會啟用 VPC CNI 網路政策功能。確保您已部署支援的 VPC CNI 附加元件版本,並在 vpc-cni 附加元件true上將ENABLE_NETWORK_POLICY旗標設定為 以啟用此功能。如需詳細說明,請參閱 Amazon EKS 使用者指南

建議

網路政策入門 - 遵循最低權限原則

建立預設拒絕政策

如同 RBAC 政策,建議使用網路政策遵循最低權限存取原則。首先建立拒絕所有限制命名空間中所有傳入和傳出流量的政策。

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny namespace: default spec: podSelector: {} policyTypes: - Ingress - Egress

預設拒絕

預設拒絕
注意

上圖是由網路政策檢視器從 Tufin 建立。

建立規則以允許 DNS 查詢

設定預設拒絕所有規則後,您就可以開始分層其他規則,例如允許 Pod 查詢 CoreDNS 以進行名稱解析的規則。

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns-access namespace: default spec: podSelector: matchLabels: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53

allow-dns-access

allow-dns-access

遞增新增規則,以選擇性地允許命名空間/Pod 之間的流量流動

了解應用程式需求,並視需要建立精細的輸入和輸出規則。以下範例示範如何將連接埠 80 上的輸入流量app-one從 限制為 client-one。這有助於將攻擊面降至最低,並降低未經授權的存取風險。

apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ingress-app-one namespace: default spec: podSelector: matchLabels: k8s-app: app-one policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: k8s-app: client-one ports: - protocol: TCP port: 80

allow-ingress-app-one

allow-ingress-app-one

監控網路政策強制執行

  • 使用網路政策編輯器

    • 網路政策編輯器有助於視覺化、安全分數、從網路流量日誌自動產生

    • 以互動方式建置網路政策

  • 稽核日誌

    • 定期檢閱 EKS 叢集的稽核日誌

    • 稽核日誌提供有關叢集上執行的動作的豐富資訊,包括網路政策的變更

    • 使用此資訊來追蹤網路政策隨著時間的變更,並偵測任何未經授權或非預期的變更

  • 自動化測試

    • 建立模擬生產環境的測試環境,並定期部署嘗試違反網路政策的工作負載,以實作自動化測試。

  • 監控指標

    • 設定您的可觀測性代理程式,從 VPC CNI 節點代理程式抓取 prometheus 指標,允許 監控代理程式運作狀態和 sdk 錯誤。

  • 定期稽核網路政策

    • 定期稽核您的網路政策,以確保它們符合您目前的應用程式需求。隨著應用程式的演進,稽核讓您有機會移除備援輸入、輸出規則,並確保您的應用程式沒有過多的許可。

  • 使用開放政策代理程式 (OPA) 確保網路政策存在

    • 使用如下所示的 OPA 政策,以確保網路政策在加入應用程式 Pod 之前始終存在。k8s-app: sample-app 如果對應的網路政策不存在,此政策會拒絕使用標籤加入 k8s Pod。

package kubernetes.admission
import data.kubernetes.networkpolicies

deny[msg] {
    input.request.kind.kind == "Pod"
    pod_label_value := {v["k8s-app"] | v := input.request.object.metadata.labels}
    contains_label(pod_label_value, "sample-app")
    np_label_value := {v["k8s-app"] | v := networkpolicies[_].spec.podSelector.matchLabels}
    not contains_label(np_label_value, "sample-app")
    msg:= sprintf("The Pod %v could not be created because it is missing an associated Network Policy.", [input.request.object.metadata.name])
}
contains_label(arr, val) {
    arr[_] == val
}

故障診斷

監控 vpc-network-policy-controller、 node-agent 日誌

啟用 EKS 控制平面控制器管理員日誌來診斷網路政策功能。您可以將控制平面日誌串流至 CloudWatch 日誌群組,並使用 CloudWatch Log Insights 來執行進階查詢。從日誌中,您可以檢視哪些 Pod 端點物件解析為網路政策、政策的調校狀態,以及政策是否如預期般運作時的偵錯。

此外,Amazon VPC CNI 可讓您啟用從 EKS 工作者節點收集政策強制執行日誌並將其匯出至 Amazon Cloudwatch。啟用後,您可以利用 CloudWatch Container Insights 提供與網路政策相關的用量洞察。

Amazon VPC CNI 也提供 SDK,提供與節點上 eBPF 程式互動的界面。軟體開發套件會在部署到節點時aws-node安裝。您可以在節點的 /opt/cni/bin目錄下找到安裝的 SDK 二進位檔。在啟動時,軟體開發套件支援基本功能,例如檢查 eBPF 程式和映射。

sudo /opt/cni/bin/aws-eks-na-cli ebpf progs

日誌網路流量中繼資料

AWS VPC Flow Logs 會擷取流經 VPC 之流量的中繼資料,例如來源和目的地 IP 地址、連接埠,以及接受/捨棄的封包。此資訊可以進行分析,以尋找 VPC 內資源之間的可疑或異常活動,包括 Pod。不過,由於 Pod 的 IP 地址在取代時經常變更,因此流程日誌本身可能不夠。Calico Enterprise 使用 Pod 標籤和其他中繼資料擴展流程日誌,讓您更輕鬆地解密 Pod 之間的流量流程。

安全群組

EKS 使用 AWS VPC 安全群組 (SGs) 來控制 Kubernetes 控制平面與叢集工作者節點之間的流量。安全群組也用於控制工作者節點與其他 VPC 資源之間的流量,以及外部 IP 地址。當您佈建 EKS 叢集 (使用 Kubernetes 1.14-eks.3 版或更新版本) 時,系統會自動為您建立叢集安全群組。此安全群組允許 EKS 控制平面與受管節點群組節點之間進行不中斷的通訊。為了簡化,建議您將叢集 SG 新增至所有節點群組,包括未受管節點群組。

在 Kubernetes 1.14 版和 EKS eks.3 版之前,已針對 EKS 控制平面和節點群組設定個別的安全群組。您可以在 https://https://docs.aws.amazon.com/eks/latest/userguide/sec-group-reqs.html 找到控制平面和節點群組安全群組的最低和建議規則。控制平面安全群組的最低規則允許連接埠 443 從工作者節點 SG 傳入。此規則允許 kubelet 與 Kubernetes API 伺服器通訊。它還包括傳出流量到工作者節點 SG 的連接埠 10250;10250 是 kubelet 接聽的連接埠。同樣地,最小節點群組規則允許連接埠 10250 從控制平面 SG 傳入,以及 443 傳出至控制平面 SG。最後,有一個規則允許節點群組內的節點之間進行不中斷的通訊。

如果您需要控制叢集內執行的服務與叢集外執行的服務之間的通訊,例如 RDS 資料庫,請考慮 Pod 的安全群組。透過 Pod 的安全群組,您可以將現有的安全群組指派給 Pod 集合。

警告

如果您參考在建立 Pod 之前不存在的安全群組,則不會排程 Pod。

您可以透過建立SecurityGroupPolicy物件並指定 PodSelector或 來控制指派給安全群組的 PodServiceAccountSelector。將選取器設定為 {}會將 中參考SGs 指派給命名空間中的所有 SecurityGroupPolicy Pod 或命名空間中的所有服務帳戶。在實作 Pod 的安全群組之前,請確定您已熟悉所有考量事項。

重要

如果您將 SGs用於 Pod,則必須建立允許連接埠 53 傳出至叢集安全群組的 SGs。同樣地,您必須更新叢集安全群組,以接受來自 Pod 安全群組的連接埠 53 傳入流量。

重要

對 Pod 使用安全群組時,安全群組的限制仍然適用,因此請謹慎使用。

重要

您必須為針對 Pod 設定的所有探查,從叢集安全群組 (kubelet) 建立傳入流量的規則。

重要

Pod 的安全群組依賴於稱為 ENI 中繼的功能,該功能已建立以增加 EC2 執行個體的 ENI 密度。當 Pod 指派給 SG 時,VPC 控制器會將來自節點群組的分支 ENI 與 Pod 建立關聯。如果在排程 Pod 時節點群組中沒有足夠的分支 ENIs,則 Pod 將保持待定狀態。執行個體可支援的分支 ENIs 數量會因執行個體類型/系列而異。如需更多詳細資訊,請參閱 https://docs.aws.amazon.com/eks/latest/userguide/security-groups-for-pods.html#supported-instance-types://。

雖然 Pod 的安全群組提供 AWS 原生的方式來控制叢集內外的網路流量,而不會產生政策協助程式的額外負荷,但還有其他選項可用。例如,Cilium 政策引擎可讓您在網路政策中參考 DNS 名稱。Calico Enterprise 包含將網路政策映射至 AWS 安全群組的選項。如果您已實作類似 Istio 的服務網格,您可以使用輸出閘道,將網路輸出限制為特定、完全合格的網域或 IP 地址。如需此選項的詳細資訊,請閱讀 Istio 中輸出流量控制的三個部分系列。

何時使用 Pod 的網路政策與安全群組?

何時使用 Kubernetes 網路政策

  • 控制 pod-to-pod流量

    • 適用於控制叢集內 Pod 之間的網路流量 (東西流量)

  • 在 IP 地址或連接埠層級控制流量 (OSI layer 3 或 4)

何時針對 Pod 使用 AWS 安全群組 (SGP)

  • 利用現有的 AWS 組態

    • 如果您已經有一組複雜的 EC2 安全群組來管理對 AWS 服務的存取,而且您正在將應用程式從 EC2 執行個體遷移至 EKS,則 SGPs 可能是很好的選擇,可讓您重複使用安全群組資源並將其套用至您的 Pod。

  • 控制對 AWS 服務的存取

    • 您在 EKS 叢集內執行的應用程式想要與其他 AWS 服務 (RDS 資料庫) 通訊,使用 SGPs做為有效的機制來控制從 Pod 到 AWS 服務的流量。

  • Pod 和節點流量的隔離

    • 如果您想要將 Pod 流量與其他節點流量完全分開,請在 POD_SECURITY_GROUP_ENFORCING_MODE=strict 模式中使用 SGP。

使用 Pod 安全群組和網路政策的最佳實務

  • 分層安全性

    • 針對分層安全方法使用 SGP 和 kubernetes 網路政策的組合

    • 使用 SGPs 限制網路層級存取不屬於叢集的 AWS 服務,而 kubernetes 網路政策可以限制叢集內 Pod 之間的網路流量

  • 最低權限原則

    • 僅允許 Pod 或命名空間之間的必要流量

  • 分割您的應用程式

    • 盡可能依網路政策分割應用程式,以便在應用程式遭到入侵時減少爆量半徑

  • 保持政策簡單明瞭

    • Kubernetes 網路政策可以相當精細且複雜,最好盡可能保持簡單,以降低組態錯誤的風險並減輕管理開銷

  • 減少攻擊面

    • 透過限制應用程式的暴露,將攻擊面降至最低

重要

Pod 的安全群組提供兩種強制執行模式: strictstandard。在 EKS 叢集中使用網路政策和 Pod 功能的安全群組時,您必須使用 standard 模式。

在網路安全方面,分層方法通常是最有效的解決方案。搭配使用 kubernetes 網路政策和 SGP 可為在 EKS 中執行的應用程式提供強大的defense-in-depth策略。

Service Mesh 政策強制執行或 Kubernetes 網路政策

service mesh 是您可以新增至應用程式的專用基礎設施層。它可讓您透明地新增可觀測性、流量管理和安全性等功能,而無需將其新增至您自己的程式碼。

服務網格會在 OSI 模型的第 7 層 (應用程式) 強制執行政策,而 kubernetes 網路政策會在第 3 層 (網路) 和第 4 層 (傳輸) 操作。這個空間有許多方案,例如 AWS AppMesh、Istio、Linkerd 等,

何時使用服務網格執行政策

  • 現有投資服務網格

  • 需要更進階的功能,例如流量管理、可觀測性和安全性

    • 流量控制、負載平衡、電路中斷、速率限制、逾時等。

    • 服務執行方式的詳細洞見 (延遲、錯誤率、每秒請求數、請求量等)

    • 您想要針對 mTLS 等安全功能實作和利用服務網格

針對更簡單的使用案例選擇 Kubernetes 網路政策

  • 限制哪些 Pod 可以互相通訊

  • 網路政策所需的資源少於服務網格,因此非常適合較簡單的使用案例,或是執行和管理服務網格的額外負荷可能不合理的小型叢集

注意

網路政策和服務網格也可以一起使用。使用網路政策在 Pod 之間提供基準層級的安全性和隔離,然後使用服務網格來新增其他功能,例如流量管理、可觀測性和安全性。

ThirdParty網路政策引擎

當您有進階政策需求,例如全球網路政策、支援以 DNS 主機名稱為基礎的規則、第 7 層規則、以 ServiceAccount 為基礎的規則,以及明確拒絕/記錄動作等時,請考慮第三方網路政策引擎。Calico 是來自 Tigera 的開放原始碼政策引擎,可與 EKS 搭配使用。除了實作完整的 Kubernetes 網路政策功能,Calico 還支援具有更豐富功能的網路政策,包括支援第 7 層規則,例如 HTTP,當 與 Istio 整合時。Calico 政策的範圍可以是命名空間、Pod、服務帳戶或全域。當政策範圍限定於服務帳戶時,它會將一組輸入/輸出規則與該服務帳戶建立關聯。有了適當的 RBAC 規則,您可以防止團隊覆寫這些規則,讓 IT 安全專業人員安全地委派命名空間的管理。Cilium 的維護者 Isovalent 也擴展了網路政策,以包含對第 7 層規則的部分支援,例如 HTTP。Cilium 也支援 DNS 主機名稱,可用於限制 Kubernetes Services/Pod 與 VPC 內外執行的資源之間的流量。相反地,Calico Enterprise 包含的功能可讓您將 Kubernetes 網路政策映射至 AWS 安全群組,以及 DNS 主機名稱。

您可以在 https://github.com/ahmetb/kubernetes-network-policy-recipes:// 找到常見的 Kubernetes 網路政策清單。如需 Calico 的類似規則集,請參閱 https://https://docs.projectcalico.org/security/calico-network-policy

遷移至 Amazon VPC CNI 網路政策引擎

為了保持一致性並避免意外的 Pod 通訊行為,建議您在叢集中僅部署一個網路政策引擎。如果您想要從 3P 遷移至 VPC CNI 網路政策引擎,建議您先將現有的 3P NetworkPolicy CRDs轉換為 Kubernetes NetworkPolicy 資源,再啟用 VPC CNI 網路政策支援。此外,在生產環境中套用遷移的政策之前,請先在不同的測試叢集中進行測試。這可讓您識別和解決 Pod 通訊行為中的任何潛在問題或不一致。

遷移工具

為了協助您進行遷移程序,我們開發了一個名為 K8s Network Policy Migrator 的工具,可將您現有的 Calico/Cilium 網路政策 CRDs 轉換為 Kubernetes 原生網路政策。轉換後,您可以在執行 VPC CNI 網路政策控制器的新叢集上直接測試轉換的網路政策。此工具旨在協助您簡化遷移程序,並確保順利轉換。

重要

遷移工具只會轉換與原生 kubernetes 網路政策 api 相容的 3P 政策。如果您使用 3P 外掛程式提供的進階網路政策功能,遷移工具會略過並報告它們。

請注意,AWS VPC CNI 網路政策工程團隊目前不支援遷移工具,該工具會盡力提供給客戶。我們鼓勵您利用此工具來促進遷移程序。如果您在使用工具時遇到任何問題或錯誤,請建立 GitHub 問題。您的意見回饋對我們來說非常寶貴,有助於持續改進我們的服務。

其他資源

傳輸中加密

需要符合 PCI、HIPAA 或其他法規的應用程式,可能需要在傳輸期間加密資料。現在 TLS 是加密線路上流量的事實選擇。TLS 如同前一代 SSL,使用密碼編譯通訊協定透過網路提供安全的通訊。TLS 使用對稱加密,其中加密資料的金鑰是根據工作階段開始時交涉的共用秘密產生。以下是您可以在 Kubernetes 環境中加密資料的幾種方式。

Nitro 執行個體

根據預設,下列 Nitro 執行個體類型之間交換的流量會自動加密,例如 C5n, G4, I3en, M5dn, M5n, P3dn, R5dn和 R5n。有傳輸閘道或負載平衡器等中繼躍點時,不會加密流量。如需傳輸中加密的更多詳細資訊,以及預設支援網路加密的執行個體類型完整清單,請參閱傳輸中加密。

容器網路界面 (CNIs)

您可以將 WeaveNet 設定為使用 NaCl 加密來自動加密所有流量,並使用 IPsec ESP 來加密快速資料路徑流量。

Service Mesh

傳輸中加密也可以使用服務網格實作,例如 App Mesh、Linkerd v2 和 Istio。AppMesh 支援 mTLS 搭配 X.509 憑證或 Envoy 的 Secret Discovery Service (SDS)。Linkerd 和 Istio 都支援 mTLS。

aws-app-mesh-examples GitHub 儲存庫提供逐步解說,以搭配您的 Envoy 容器使用 X.509 憑證和 SPIRE 做為 SDS 供應商來設定 mTLS:

App Mesh 也支援使用 AWS Certificate Manager (ACM) 發行的私有憑證或存放在虛擬節點本機檔案系統的憑證進行 TLS 加密

aws-app-mesh-examples GitHub 儲存庫提供逐步解說,以使用 ACM 發行的憑證和 Envoy 容器隨附的憑證來設定 TLS:

輸入控制器和負載平衡器

輸入控制器可讓您以智慧方式將從叢集外部發出的 HTTP/S 流量路由至叢集內執行的服務。通常,這些傳入會由第 4 層負載平衡器前置,例如 Classic Load Balancer 或 Network Load Balancer (NLB)。加密的流量可以在網路中的不同位置終止,例如負載平衡器、傳入資源或 Pod。終止 SSL 連線的方式和位置最終將由組織的網路安全政策決定。例如,如果您的政策需要end-to-end加密,您必須解密 Pod 的流量。這會對 Pod 造成額外的負擔,因為它必須花費週期來建立初始交握。整體 SSL/TLS 處理非常耗用 CPU。因此,如果您有彈性,請嘗試在輸入或負載平衡器執行 SSL 卸載。

搭配 AWS Elastic Load Balancer 使用加密

AWS Application Load Balancer (ALB) 和 Network Load Balancer (NLB) 都支援傳輸加密 (SSL 和 TLS)。ALB 的alb.ingress.kubernetes.io/certificate-arn註釋可讓您指定要新增至 ALB 的憑證。如果您省略註釋,控制器會嘗試透過使用主機欄位比對可用的 AWS Certificate Manager (ACM) 憑證,將憑證新增至需要它的接聽程式。從 EKS 1.15 版開始,您可以搭配 NLB 使用service.beta.kubernetes.io/aws-load-balancer-ssl-cert註釋,如以下範例所示。

apiVersion: v1 kind: Service metadata: name: demo-app namespace: default labels: app: demo-app annotations: service.beta.kubernetes.io/aws-load-balancer-type: "nlb" service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "<certificate ARN>" service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" spec: type: LoadBalancer ports: - port: 443 targetPort: 80 protocol: TCP selector: app: demo-app //--- kind: Deployment apiVersion: apps/v1 metadata: name: nginx namespace: default labels: app: demo-app spec: replicas: 1 selector: matchLabels: app: demo-app template: metadata: labels: app: demo-app spec: containers: - name: nginx image: nginx ports: - containerPort: 443 protocol: TCP - containerPort: 80 protocol: TCP

以下是 SSL/TLS 終止的其他範例。

重要

有些輸入,例如 AWS LB 控制器,使用註釋實作 SSL/TLS,而不是作為輸入規格的一部分。

使用 cert-manager 的 ACM Private CA

您可以啟用 TLS 和 mTLS,使用 ACM Private Certificate Authority (CA) 和 cert-manager,這是常用的 Kubernetes 附加元件,在輸入、Pod 以及 Pod 之間保護您的 EKS 應用程式工作負載,以分發、續約和撤銷憑證。ACM Private CA 是一種高可用性、安全、受管的 CA,無需管理您自己的 CA 的預付和維護成本。如果您使用預設的 Kubernetes 憑證授權單位,則有機會透過 ACM Private CA 來改善安全性並符合合規要求。ACM Private CA 會保護 FIPS 140-2 第 3 級硬體安全模組中的私有金鑰 (非常安全),而預設的 CA 會存放以記憶體編碼的金鑰 (較不安全)。集中式 CA 也可讓您在 Kubernetes 環境內外,更妥善控制並改善私有憑證的可稽核性。

工作負載之間相互 TLS 的短期 CA 模式

在 EKS 中使用 ACM Private CA for mTLS 時,建議您使用短期 CA 模式的短期有效憑證。雖然可以在一般用途 CA 模式下發行短期憑證,但對於需要頻繁發行新憑證的使用案例,使用短期 CA 模式可提高成本效益 (比一般模式便宜約 75%)。此外,您應該嘗試將私有憑證的有效期間與 EKS 叢集中的 Pod 生命週期保持一致。在此處進一步了解 ACM Private CA 及其優點

ACM 設定說明

首先,遵循 ACM Private CA 技術文件中提供的程序建立私有 CA。一旦您擁有私有 CA,請使用一般安裝指示來安裝 cert-manager。安裝 cert-manager 之後,請依照 GitHub 中的設定說明安裝 Private CA Kubernetes cert-manager 外掛程式。外掛程式可讓 cert-manager 從 ACM Private CA 請求私有憑證。

現在您已擁有私有 CA 和已安裝 cert-manager 和外掛程式的 EKS 叢集,是時候設定許可並建立發行者了。更新 EKS 節點角色的 IAM 許可,以允許存取 ACM Private CA。將 取代<CA_ARN>為私有 CA 的值:

{ "Version": "2012-10-17", "Statement": [ { "Sid": "awspcaissuer", "Action": [ "acm-pca:DescribeCertificateAuthority", "acm-pca:GetCertificate", "acm-pca:IssueCertificate" ], "Effect": "Allow", "Resource": "<CA_ARN>" } ] }

也可以使用 IAM 帳戶或 IRSA 的服務角色。如需完整範例,請參閱以下的其他資源一節。

在 Amazon EKS 中建立發行者,方法是使用下列文字建立名為 cluster-issuer.yaml 的自訂資源定義檔案,以私有 CA 取代 <CA_ARN><Region>資訊。

apiVersion: awspca.cert-manager.io/v1beta1 kind: AWSPCAClusterIssuer metadata: name: demo-test-root-ca spec: arn: <CA_ARN> region: <Region>

部署您建立的發行者。

kubectl apply -f cluster-issuer.yaml

EKS 叢集已設定為向 Private CA 請求憑證。您現在可以使用 cert-manager Certificate的資源,透過將issuerRef欄位的值變更為您在上面建立的私有 CA 發行者來發行憑證。如需如何指定和請求憑證資源的詳細資訊,請參閱 cert-manager 的憑證資源指南請參閱此處的範例

具有 Istio 和 cert-manager 的 ACM Private CA

如果您在 EKS 叢集中執行 Istio,您可以停用 Istio 控制平面 (特別是 istiod) 做為根憑證授權單位 (CA),並將 ACM Private CA 設定為工作負載之間 mTLS 的根 CA。如果您要使用此方法,請考慮在 ACM Private CA 中使用短期 CA 模式。如需詳細資訊,請參閱上一節和此部落格文章

憑證簽署如何在 Istio 中運作 (預設)

Kubernetes 中的工作負載是使用服務帳戶來識別。如果您未指定服務帳戶,Kubernetes 會自動為您的工作負載指派一個。此外,服務帳戶會自動掛載相關聯的字符。服務帳戶會使用此權杖,讓工作負載對 Kubernetes API 進行身分驗證。服務帳戶可能足以做為 Kubernetes 的身分,但 Istio 擁有自己的身分管理系統和 CA。當工作負載以其呼叫附屬代理啟動時,它需要從 Istio 指派的身分,以便將其視為可信,並允許與網格中的其他 服務通訊。

若要從 Istio 取得此身分, istio-agent會將稱為憑證簽署請求 (或 CSR) 的請求傳送至 Istio 控制平面。此 CSR 包含服務帳戶字符,以便在處理之前驗證工作負載的身分。此驗證程序由 處理istiod,其同時做為註冊授權單位 (或 RA) 和 CA。RA 做為gatekeeper,確保只有已驗證的 CSR 才能將其傳遞給 CA。驗證 CSR 後,該 CSR 會轉送至 CA,然後向服務帳戶發行包含 SPIFFE 身分的憑證。此憑證稱為 SPIFFE 驗證身分文件 (或 SVID)。SVID 會指派給請求的服務,以用於識別和加密通訊服務之間的傳輸中流量。

Istio 憑證簽署請求的預設流程:

Istio 憑證簽署請求的預設流程

憑證簽署如何搭配 ACM Private CA 在 Istio 中運作

您可以使用稱為 Istio 憑證簽署請求代理程式 (istio-csr) 的 cert-manager 附加元件,將 Istio 與 ACM Private CA 整合。此代理程式允許使用憑證管理員發行者保護 Istio 工作負載和控制平面元件,在此情況下為 ACM Private CA。istio-csr 代理程式會在驗證傳入 CSRs 的預設組態中公開 istiod 提供的相同服務。除了驗證之後,它會將請求轉換為 cert manager 支援的資源 (即與外部 CA 發行者整合)。

每當有來自工作負載的 CSR 時,就會將其轉送至 istio-csr,以向 ACM Private CA 請求憑證。AWS Private CA 發行者外掛程式會啟用 istio-csr 與 ACM Private CA 之間的通訊。 https://github.com/cert-manager/aws-privateca-issuerCert Manager 使用此外掛程式向 ACM Private CA 請求 TLS 憑證。發行者外掛程式將與 ACM Private CA 服務通訊,以請求工作負載的已簽署憑證。憑證簽署完成後,會傳回給 istio-csr,其將讀取已簽署的請求,並將其傳回給啟動 CSR 的工作負載。

使用 istio-csr 的 Istio 憑證簽署請求流程

image::istio-csr-with-acm-private-ca.png【使用 istio-csr 簽署 Istio 憑證請求的流量】

具有私有 CA 的 Istio 設定指示

  1. 從遵循本節中的相同設定說明開始,完成下列操作:

  2. 建立私有 CA

  3. 安裝 cert-manager

  4. 安裝發行者外掛程式

  5. 設定許可並建立發行者。發行者代表 CA,用於簽署istiod和網格工作負載憑證。它會與 ACM Private CA 通訊。

  6. 建立 istio-system 命名空間。這是將部署 istiod certificate和其他 Istio 資源的位置。

  7. 安裝使用 AWS Private CA 發行者外掛程式設定的 Istio CSR。您可以保留工作負載的憑證簽署請求,以確認它們獲得核准和簽署 (preserveCertificateRequests=true)。

    helm install -n cert-manager cert-manager-istio-csr jetstack/cert-manager-istio-csr \ --set "app.certmanager.issuer.group=awspca.cert-manager.io" \ --set "app.certmanager.issuer.kind=AWSPCAClusterIssuer" \ --set "app.certmanager.issuer.name=<the-name-of-the-issuer-you-created>" \ --set "app.certmanager.preserveCertificateRequests=true" \ --set "app.server.maxCertificateDuration=48h" \ --set "app.tls.certificateDuration=24h" \ --set "app.tls.istiodCertificateDuration=24h" \ --set "app.tls.rootCAFile=/var/run/secrets/istio-csr/ca.pem" \ --set "volumeMounts[0].name=root-ca" \ --set "volumeMounts[0].mountPath=/var/run/secrets/istio-csr" \ --set "volumes[0].name=root-ca" \ --set "volumes[0].secret.secretName=istio-root-ca"
  8. 使用自訂組態安裝 Istio,istiod以 取代cert-manager istio-csr為網格的憑證提供者。您可以使用 Istio Operator 執行此程序。

    apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: istio namespace: istio-system spec: profile: "demo" hub: gcr.io/istio-release values: global: # Change certificate provider to cert-manager istio agent for istio agent caAddress: cert-manager-istio-csr.cert-manager.svc:443 components: pilot: k8s: env: # Disable istiod CA Sever functionality - name: ENABLE_CA_SERVER value: "false" overlays: - apiVersion: apps/v1 kind: Deployment name: istiod patches: # Mount istiod serving and webhook certificate from Secret mount - path: spec.template.spec.containers.[name:discovery].args[7] value: "--tlsCertFile=/etc/cert-manager/tls/tls.crt" - path: spec.template.spec.containers.[name:discovery].args[8] value: "--tlsKeyFile=/etc/cert-manager/tls/tls.key" - path: spec.template.spec.containers.[name:discovery].args[9] value: "--caCertFile=/etc/cert-manager/ca/root-cert.pem" - path: spec.template.spec.containers.[name:discovery].volumeMounts[6] value: name: cert-manager mountPath: "/etc/cert-manager/tls" readOnly: true - path: spec.template.spec.containers.[name:discovery].volumeMounts[7] value: name: ca-root-cert mountPath: "/etc/cert-manager/ca" readOnly: true - path: spec.template.spec.volumes[6] value: name: cert-manager secret: secretName: istiod-tls - path: spec.template.spec.volumes[7] value: name: ca-root-cert configMap: defaultMode: 420 name: istio-ca-root-cert
  9. 部署您建立的上述自訂資源。

    istioctl operator init kubectl apply -f istio-custom-config.yaml
  10. 現在,您可以將工作負載部署到 EKS 叢集中的網格,並強制執行 mTLS

Istio 憑證簽署請求

image::istio-csr-requests.png【Istio 憑證簽署請求】

工具和資源