设置使用 Envoy 的服务安全
请按照本指南中的说明配置身份验证和授权 。如需全面了解 Cloud Service Mesh 服务安全,请参阅 Cloud Service Mesh 服务安全。
使用要求
在使用 Envoy 为 Cloud Service Mesh 配置服务安全之前,请确保您的设置符合以下前提条件:
您能够满足部署 Cloud Service Mesh 的所有要求。对于 有关这些要求的完整信息,请参阅 准备使用 Envoy 和无代理工作负载设置服务路由 API。
您有足够的权限创建或更新 Cloud Service Mesh 使用服务安全性的 Google Cloud 服务网格资源,如下所述 准备使用 Envoy 和无代理工作负载设置服务路由 API。
准备设置
以下各部分介绍了您在设置之前需要完成的任务 Cloud Service Mesh 安全服务。这些任务是:
- 更新 Google Cloud CLI
- 设置变量
- 启用 Cloud Service Mesh 与 Certificate Authority Service 搭配使用所需的 API
更新 gcloud
命令行工具
如需更新 Google Cloud CLI,请在本地机器上运行以下命令:
gcloud components update
设置变量
请设置以下变量,以便在执行本文档中的示例时复制和粘贴具有一致值的代码。请使用以下值:
- PROJECT_ID:替换项目的 ID。
- CLUSTER_NAME:替换为您要使用的集群名称,例如
secure-td-cluster
。 - ZONE:替换集群所在的可用区。
- GKE_CLUSTER_URL:替换为
https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME
- WORKLOAD_POOL:替换为
PROJECT_ID.svc.id.goog
- K8S_NAMESPACE:替换为
default
。 - DEMO_CLIENT_KSA:替换为您的客户端 Kubernetes 服务账号的名称。
- DEMO_SERVER_KSA:替换为服务器 Kubernetes 服务账号的名称。
PROJNUM:替换为您的项目的编号(您可以在 Google Cloud 控制台中或使用以下命令确定项目编号):
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
SA_GKE:替换为
service-PROJNUM@container-engine-robot.iam.gserviceaccount.com
CLUSTER_VERSION:替换为可用的最新版本。您可以在快速渠道版本说明中找到此信息。所需的最低版本为 1.21.4-gke.1801。这是要在此示例中使用的 GKE 集群版本。
在此处设置值:
# Substitute your project ID PROJECT_ID=PROJECT_ID # GKE cluster name and zone for this example. CLUSTER_NAME=CLUSTER_NAME ZONE=ZONE # GKE cluster URL derived from the above GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME" # Workload pool to be used with the GKE cluster WORKLOAD_POOL="PROJECT_ID.svc.id.goog" # Kubernetes namespace to run client and server demo. K8S_NAMESPACE=K8S_NAMESPACE DEMO_CLIENT_KSA=DEMO_CLIENT_KSA DEMO_SERVER_KSA=DEMO_SERVER_KSA # Compute other values # Project number for your project PROJNUM=PROJNUM CLUSTER_VERSION=CLUSTER_VERSION SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com
启用 API
使用 gcloud services enable
命令,以启用设置 Cloud Service Mesh 所需的所有 API
使用 Certificate Authority Service 来保障安全。
gcloud services enable \ container.googleapis.com \ cloudresourcemanager.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ networksecurity.googleapis.com \ privateca.googleapis.com \ gkehub.googleapis.com
创建或更新 GKE 集群
Cloud Service Mesh 服务安全取决于 CA Service 与 GKE 的集成。除了设置要求之外,GKE 集群还必须满足以下要求:
- 使用的最低集群版本为 1.21.4-gke.1801。如果您需要更高版本的功能,则可以从快速发布渠道中获取该版本。
- 必须使用网格证书启用和配置 GKE 集群,如创建证书授权机构以颁发证书中所述。
创建一个使用适用于 GKE 的工作负载身份联合的新集群。如果您要更新现有集群,请跳至下一步。您为
--tags
指定的值必须与使用 Cloud Load Balancing 组件配置 Cloud Service Mesh 部分中传递给firewall-rules create
命令的--target-tags
标志的名称匹配。# Create a GKE cluster with GKE managed mesh certificates. gcloud container clusters create CLUSTER_NAME \ --release-channel=rapid \ --scopes=cloud-platform \ --image-type=cos_containerd \ --machine-type=e2-standard-2 \ --zone=ZONE \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-mesh-certificates \ --cluster-version=CLUSTER_VERSION \ --enable-ip-alias \ --tags=allow-health-checks \ --workload-metadata=GKE_METADATA
集群创建可能需要几分钟才能完成。
如果您使用的是现有集群,请启用适用于 GKE 的工作负载身份联合,并 GKE 网格证书。确保使用
--enable-ip-alias
标志创建集群,该标志无法与update
命令一起使用。gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
运行以下命令切换到作为
kubectl
命令的默认集群的新集群:gcloud container clusters get-credentials CLUSTER_NAME \ --zone ZONE
在多集群环境中部署
如果您要在多集群环境中进行部署,请按照本部分中所述的常规步骤操作。以下说明假定客户端 Pod 在一个集群中运行,而服务器 Pod 在另一个集群中运行。
按照上一部分中的说明创建或更新集群。
使用以下命令捕获每个集群的 Pod IP 地址范围:
gcloud compute firewall-rules list \ --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \ --format="value(sourceRanges)"
例如,对于名为
cluster-a
和cluster-b
的集群,该命令会返回如下结果:cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
创建允许集群相互通信的 VPC 防火墙规则。例如,以下命令会创建一条防火墙规则,允许
cluster-a
pod IP 地址与cluster-b
节点通信:gcloud compute firewall-rules create per-cluster-a-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-b-acd14479-node"
以下命令会创建一条防火墙规则,允许
cluster-b
pod IP 地址与cluster-a
节点通信:gcloud compute firewall-rules create per-cluster-b-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-a-9cd18751-node"
向舰队注册集群
向舰队注册您在创建 GKE 集群中创建或更新的集群。通过注册集群,您可以更轻松地跨多个项目配置集群。
请注意,每个步骤最长可能需要十分钟才能完成。
向舰队注册集群:
gcloud container fleet memberships register CLUSTER_NAME \ --gke-cluster=ZONE/CLUSTER_NAME \ --enable-workload-identity --install-connect-agent \ --manifest-output-file=MANIFEST-FILE_NAME
替换如下变量:
- CLUSTER_NAME:您的集群的名称。
- ZONE:您的集群的可用区。
- MANIFEST-FILE_NAME:这些命令生成注册清单的路径。
注册成功后,您会看到如下消息:
Finished registering the cluster CLUSTER_NAME with the fleet.
将生成的清单文件应用于您的集群:
kubectl apply -f MANIFEST-FILE_NAME
应用成功后,您会看到如下消息:
namespace/gke-connect created serviceaccount/connect-agent-sa created podsecuritypolicy.policy/gkeconnect-psp created role.rbac.authorization.k8s.io/gkeconnect-psp:role created rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created role.rbac.authorization.k8s.io/agent-updater created rolebinding.rbac.authorization.k8s.io/agent-updater created role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created role.rbac.authorization.k8s.io/gke-connect-namespace-getter created rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created secret/http-proxy created deployment.apps/gke-connect-agent-20210416-01-00 created service/gke-connect-monitoring created secret/creds-gcp create
从集群获取成员资格资源:
kubectl get memberships membership -o yaml
输出应包含由舰队分配的 Workoad Identity 池,其中 PROJECT_ID 是您的项目 ID:
workload_identity_pool: PROJECT_ID.svc.id.goog
这表示集群已成功注册。
创建证书授权机构以颁发证书
如需向 Pod 颁发证书,请创建 CA 服务池和以下证书授权机构 (CA):
- 根 CA。这是所有已颁发的网格证书的信任根。可以使用现有的根 CA。在
enterprise
层级创建根 CA,用于颁发长期、少量的证书。 - 从属 CA。此 CA 会为工作负载颁发证书。请在部署集群的区域中创建从属 CA。在
devops
层级创建从属 CA,用于颁发短期、大量的证书。
创建从属 CA 是可选操作,但我们强烈建议您创建一个,而不是使用根 CA 颁发 GKE 网格证书。如果您决定使用根 CA 颁发网格证书,请确保允许使用默认的基于配置的颁发模式。
从属 CA 的区域可以不同于集群的区域,但我们强烈建议您在集群所在的区域中创建从属 CA 以优化性能。但是,您可以在不同区域中创建根 CA 和从属 CA,这不会影响性能或可用性。
CA Service 支持以下区域:
区域名称 | 区域说明 |
---|---|
asia-east1 |
台湾 |
asia-east2 |
香港 |
asia-northeast1 |
东京 |
asia-northeast2 |
大阪 |
asia-northeast3 |
首尔 |
asia-south1 |
孟买 |
asia-south2 |
德里 |
asia-southeast1 |
新加坡 |
asia-southeast2 |
雅加达 |
australia-southeast1 |
悉尼 |
australia-southeast2 |
墨尔本 |
europe-central2 |
华沙 |
europe-north1 |
芬兰 |
europe-southwest1 |
马德里 |
europe-west1 |
比利时 |
europe-west2 |
伦敦 |
europe-west3 |
法兰克福 |
europe-west4 |
荷兰 |
europe-west6 |
苏黎世 |
europe-west8 |
米兰 |
europe-west9 |
巴黎 |
europe-west10 |
柏林 |
europe-west12 |
都灵 |
me-central1 |
多哈 |
me-central2 |
达曼 |
me-west1 |
特拉维夫 |
northamerica-northeast1 |
蒙特利尔 |
northamerica-northeast2 |
多伦多 |
southamerica-east1 |
圣保罗 |
southamerica-west1 |
圣地亚哥 |
us-central1 |
爱荷华 |
us-east1 |
南卡罗来纳 |
us-east4 |
北弗吉尼亚 |
us-east5 |
哥伦布 |
us-south1 |
达拉斯 |
us-west1 |
俄勒冈 |
us-west2 |
洛杉矶 |
us-west3 |
盐湖城 |
us-west4 |
拉斯维加斯 |
此外,还可以通过运行以下命令来查看受支持位置的列表:
gcloud privateca locations list
将 IAM
roles/privateca.caManager
授予创建 CA 池和 CA 的个人。请注意,对于 MEMBER,正确格式为user:userid@example.com
。如果该人员是当前用户,您可以使用 shell 命令$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
获取当前用户 ID。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.caManager
将 CA Service 的
role/privateca.admin
角色授予个人 其需要修改 IAM 政策,其中MEMBER
是 具体而言,就是执行这些操作的 授予privateca.auditor
和privateca.certificateManager
个角色:gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
创建根 CA 服务池。
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
创建根 CA。
gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \ --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \ --key-algorithm="ec-p256-sha256" \ --max-chain-length=1 \ --location ROOT_CA_POOL_LOCATION
对于此演示设置,请为变量使用以下值:
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_NAME=pkcs2-ca
- ROOT_CA_POOL_LOCATION=us-east1
- ROOT_CA_ORGANIZATION="TestCorpLLC"
创建从属池和从属 CA。确保允许使用默认的基于配置的颁发模式。
gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --tier devops
gcloud privateca subordinates create SUBORDINATE_CA_NAME \ --pool SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --issuer-pool ROOT_CA_POOL_NAME \ --issuer-location ROOT_CA_POOL_LOCATION \ --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \ --key-algorithm "ec-p256-sha256" \ --use-preset-profile subordinate_mtls_pathlen_0
对于此演示设置,请为变量使用以下值:
- SUBORDINATE_CA_POOL_NAME="td-ca-pool"
- SUBORDINATE_CA_POOL_LOCATION=us-east1
- SUBORDINATE_CA_NAME="td-ca"
- SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_POOL_LOCATION=us-east1
授予根 CA 池 IAM
privateca.auditor
角色,以允许从 GKE 服务账号进行访问:gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --role roles/privateca.auditor \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
授予从属 CA 池 IAM
privateca.certificateManager
角色,以允许从 GKE 服务账号进行访问:gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --role roles/privateca.certificateManager \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
保存以下
WorkloadCertificateConfig
YAML 配置,以告知集群如何颁发网格证书:apiVersion: security.cloud.google.com/v1 kind: WorkloadCertificateConfig metadata: name: default spec: # Required. The CA service that issues your certificates. certificateAuthorityConfig: certificateAuthorityServiceConfig: endpointURI: ISSUING_CA_POOL_URI # Required. The key algorithm to use. Choice of RSA or ECDSA. # # To maximize compatibility with various TLS stacks, your workloads # should use keys of the same family as your root and subordinate CAs. # # To use RSA, specify configuration such as: # keyAlgorithm: # rsa: # modulusSize: 4096 # # Currently, the only supported ECDSA curves are "P256" and "P384", and the only # supported RSA modulus sizes are 2048, 3072 and 4096. keyAlgorithm: rsa: modulusSize: 4096 # Optional. Validity duration of issued certificates, in seconds. # # Defaults to 86400 (1 day) if not specified. validityDurationSeconds: 86400 # Optional. Try to start rotating the certificate once this # percentage of validityDurationSeconds is remaining. # # Defaults to 50 if not specified. rotationWindowPercentage: 50
替换以下内容:
- 运行您的集群的项目的 ID:
PROJECT_ID
- 颁发网格证书的 CA 的完全限定 URI (ISSUING_CA_POOL_URI)。这可以是从属 CA(推荐)也可以是根 CA。格式为:
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- 运行您的集群的项目的 ID:
保存以下
TrustConfig
YAML 配置,以告知集群如何信任颁发的证书:apiVersion: security.cloud.google.com/v1 kind: TrustConfig metadata: name: default spec: # You must include a trustStores entry for the trust domain that # your cluster is enrolled in. trustStores: - trustDomain: PROJECT_ID.svc.id.goog # Trust identities in this trustDomain if they appear in a certificate # that chains up to this root CA. trustAnchors: - certificateAuthorityServiceURI: ROOT_CA_POOL_URI
替换以下内容:
- 运行您的集群的项目的 ID:
PROJECT_ID
- 根 CA 池的完全限定 URI (ROOT_CA_POOL_URI)。格式为:
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- 运行您的集群的项目的 ID:
将配置应用到您的集群:
kubectl apply -f WorkloadCertificateConfig.yaml kubectl apply -f TrustConfig.yaml
配置身份和访问权限管理
如要创建设置所需的资源,您必须具有 compute.NetworkAdmin
角色。此角色包含创建、更新、删除、列出和使用所需资源(即在其他资源中引用)的所有必要权限。如果您是项目的所有者编辑者,则会自动拥有此角色。
请注意,在后端服务中引用这些资源时,系统不会强制执行 networksecurity.googleapis.com.clientTlsPolicies.use
和 networksecurity.googleapis.com.serverTlsPolicies.use
。
如果这些权限在以后强制执行,并且您使用的是 compute.NetworkAdmin
角色,则在强制执行此检查时不会注意到任何问题。
如果您使用的是自定义角色,并且此检查将强制执行,那么您必须确保添加相应的 .use
权限。否则,将来您可能会发现自定义角色没有必要的权限,无法引用后端服务或端点政策中的 clientTlsPolicy
或 serverTlsPolicy
。
以下说明使默认服务账号能够访问 Cloud Service Mesh Security API 并创建 Kubernetes 服务账号。
配置 IAM 以允许默认服务账号访问 Cloud Service Mesh 安全 API。
GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \ --filter='displayName:Compute Engine default service account') gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:${GSA_EMAIL} \ --role roles/trafficdirector.client
设置 Kubernetes 服务账号。以下部分中的客户端和服务器部署使用 Kubernetes 服务器和客户端服务账号的 Knames。
kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
通过在 Kubernetes 服务账号与默认 Compute Engine 服务账号之间创建 IAM 政策绑定,允许前者模拟后者。此绑定允许 Kubernetes 服务账号充当默认 Compute Engine 服务账号。
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL} gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}
为 Kubernetes 服务账号添加注解,以将其与默认的 Compute Engine 服务账号相关联。
kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_SERVER_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL} kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_CLIENT_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL}
设置 Cloud Service Mesh
按照以下说明安装 Sidecar 注入器、设置测试服务并完成其他部署任务。
在集群中安装 Envoy Sidecar 注入器
按照针对启用自动 Envoy 注入的 GKE pod 的 Cloud Service Mesh 设置中以下两个部分中的说明在集群中部署和启用 Envoy Sidecar 注入:
- 安装 Envoy Sidecar 注入器。
确保将网格名称配置为
sidecar_mesh
,并将网络配置为 ""(空字符串)。 - 启用 Sidecar 注入
在设置测试服务之前,请务必按照这两组说明完成操作。
设置测试服务
安装 Envoy Sidecar 注入器后,请按照以下说明为您的部署设置测试服务。
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml kubectl apply -f service_sample.yaml
文件 service_sample.yaml
包含演示服务器应用的 podspec。有一些注释是专门针对 Cloud Service Mesh 安全的。
Cloud Service Mesh 代理元数据
podspec 指定 proxyMetadata
注释:
spec: ... annotations: cloud.google.com/proxyMetadata: '{"app": "payments"}' ...
Pod 初始化后,边车代理会获取此注解, 将其传输到 Cloud Service Mesh。然后,Cloud Service Mesh 便可 信息以发回过滤的配置:
- 请注意,在本指南的后面部分,端点政策会指定端点匹配器。
- 端点匹配器指定仅提供名称为
app
且值为payments
的标签的客户端接收过滤后的配置。
使用由 CA Service 签名的网格证书和密钥
podspec 指定 enableManagedCerts
注释:
spec: ... annotations: ... cloud.google.com/enableManagedCerts: "true" ...
初始化 Pod 后,CA Service 签名证书和 密钥会自动装载在本地边车代理文件系统上。
配置入站流量拦截端口
podspec 指定 includeInboundPorts
注释:
spec: ... annotations: ... cloud.google.com/includeInboundPorts: "8000" ...
这是服务器应用监听连接的端口。时间 Pod 初始化后,边车代理会收到此注解, Cloud Service Mesh然后,Cloud Service Mesh 可以使用此信息发回经过过滤的配置,该配置会拦截到此端口的所有传入流量,并且可以对其应用安全政策。
健康检查端口必须与应用端口不同。否则,相同的安全政策将应用于健康检查端口的传入连接,这可能会导致连接被拒,进而导致服务器错误地被标记为健康状况不佳。
使用 NEG 配置 GKE 服务
GKE 服务必须通过网络端点组 (NEG) 公开,以便您可以将它们配置为 Cloud Service Mesh 后端服务的后端。本设置指南提供的 service_sample.yaml
软件包在以下注释中使用 NEG 名称 service-test-neg
:
... metadata: annotations: cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}' spec: ports: - port: 80 name: service-test protocol: TCP targetPort: 8000
您无需更改 service_sample.yaml
文件。
保存 NEG 的名称
将 NEG 的名称保存在 NEG_NAME
变量中:
NEG_NAME="service-test-neg"
将客户端应用部署到 GKE
运行以下命令,启动将 Envoy 代理作为 Sidecar 的演示客户端,以展示安全功能。
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml kubectl apply -f client_sample.yaml
客户端 podspec 仅包含 enableManagedCerts
注释。装载由 CA Service 实例签名的 GKE 代管式网格证书和密钥所需的卷时,需要此注解。
配置健康检查、防火墙规则和后端服务资源
在本部分中,您将为 Cloud Service Mesh 创建健康检查、防火墙规则和后端服务资源。
创建健康检查。
gcloud compute health-checks create http td-gke-health-check \ --use-serving-port
创建防火墙规则以允许健康检查器 IP 地址范围。
gcloud compute firewall-rules create fw-allow-health-checks \ --action ALLOW \ --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --rules tcp
创建后端服务并将健康检查与后端服务相关联。
gcloud compute backend-services create td-gke-service \ --global \ --health-checks td-gke-health-check \ --load-balancing-scheme INTERNAL_SELF_MANAGED
将之前创建的 NEG 作为后端添加到后端服务。
gcloud compute backend-services add-backend td-gke-service \ --global \ --network-endpoint-group ${NEG_NAME} \ --network-endpoint-group-zone ZONE \ --balancing-mode RATE \ --max-rate-per-endpoint 5
配置 Mesh
和 HTTPRoute
资源
在本部分中,您将创建 Mesh
和 HTTPRoute
资源。
创建
Mesh
资源规范并将其保存在名为mesh.yaml
的文件中。name: sidecar-mesh interceptionPort: 15001
如果您未在
15001
mesh.yaml
文件。使用 mesh.yaml 规范创建
Mesh
资源。gcloud network-services meshes import sidecar-mesh \ --source=mesh.yaml \ --location=global
创建
HTTPRoute
规范并将其保存到名为http_route.yaml
的文件中。您可以使用
PROJECT_ID
或PROJECT_NUMBER
。name: helloworld-http-route hostnames: - service-test meshes: - projects/PROJNUM/locations/global/meshes/sidecar-mesh rules: - action: destinations: - serviceName: "projects/PROJNUM/locations/global/backendServices/td-gke-service"
使用
http_route.yaml
文件中的规范来创建HTTPRoute
资源。gcloud network-services http-routes import helloworld-http-route \ --source=http_route.yaml \ --location=global
Cloud Service Mesh 配置已完成,您现在可以配置 身份验证和授权政策
设置服务到服务的安全性
按照以下部分中的说明设置服务间安全。
在网格中启用 mTLS
要在网格中设置 mTLS,您必须保护到后端服务的出站流量以及到端点的入站流量。
政策引用的格式
请注意引用服务器 TLS、客户端 TLS 和授权政策的以下必需格式:
projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]
例如:
projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
保护到后端服务的出站流量
要保护出站流量,您首先需要创建执行以下操作的客户端 TLS 政策:
- 使用
google_cloud_private_spiffe
作为clientCertificate
的插件,此插件将 Envoy 编程为使用 GKE 代管式网格证书作为客户端身份。 - 使用
google_cloud_private_spiffe
作为serverValidationCa
的插件,此插件将 Envoy 编程为将 GKE 代管式网格证书用于服务器验证。
接下来,将客户端 TLS 政策附加到后端服务。该命令将执行以下操作:
- 将客户端 TLS 政策中的身份验证政策应用于到后端服务端点的出站连接。
- SAN(主题备用名称)指示客户端声明其要连接的服务器的确切身份。
在文件
client-mtls-policy.yaml
中创建客户端 TLS 政策:name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
导入客户端 TLS 政策:
gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=global
将客户端 TLS 政策附加到后端服务。这会对从客户端到此后端服务的所有出站请求强制执行 mTLS 身份验证。
gcloud compute backend-services export td-gke-service \ --global --destination=demo-backend-service.yaml
将以下行添加到
demo-backend-service.yaml
:securitySettings: clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy subjectAltNames: - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"
导入值:
gcloud compute backend-services import td-gke-service \ --global --source=demo-backend-service.yaml
(可选)运行以下命令检查请求是否失败。失败是预期现象,因为客户端要求来自端点的证书,但端点未编程为使用安全政策。
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
您会看到如下输出:
wget: server returned error: HTTP/1.1 503 Service Unavailable
保护到端点的入站流量
要保护入站流量,您首先要创建一个执行以下操作的服务器 TLS 政策:
- 使用
google_cloud_private_spiffe
作为serverCertificate
的插件,此插件将 Envoy 编程为使用 GKE 代管式网格证书作为服务器端身份。 - 使用
google_cloud_private_spiffe
作为clientValidationCa
的插件,此插件将 Envoy 编程为将 GKE 代管式网格证书用于客户端验证。
将服务器 TLS 政策值保存在名为
server-mtls-policy.yaml
的文件中。name: "server-mtls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe mtlsPolicy: clientValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
创建服务器 TLS 政策:
gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=global
创建一个名为
ep_mtls.yaml
且包含端点匹配器的文件,并附加服务器 TLS 政策。endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: payments name: "ep" serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy type: SIDECAR_PROXY
导入端点匹配器。
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
验证设置
运行以下 curl
命令:如果请求成功完成,您会在输出中看到 x-forwarded-client-cert
。只有当连接是 mTLS 连接时,才会输出标头。
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
输出将如下所示:
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: 10.48.0.6 x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
请注意,x-forwarded-client-cert
标头由服务器端 Envoy 插入,包含自己的身份(服务器)和源客户端的身份。我们可以看到客户端和服务器身份,表明这是 mTLS 连接。
使用授权政策配置服务级访问权限
以下说明会创建一项授权政策,该政策允许 DEMO_CLIENT_KSA
账号发送的请求,其中主机名为 service-test
,端口为 8000
,HTTP 方法为 GET
。在创建授权政策之前,请阅读使用授权限制访问权限中的注意事项。
通过创建名为
authz-policy.yaml
的文件创建授权政策。action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test ports: - 8000 methods: - GET
导入政策:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
通过将以下内容附加到文件
ep_mtls.yaml
,将端点政策更新为引用新的授权政策:authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
端点政策现在指定,必须对以下 pod 的入站请求强制执行 mTLS 和授权政策:该 pod 的 Envoy Sidecar 代理提供标签
app:payments
。导入政策:
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
验证设置
运行以下命令来验证设置。
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. # This is a valid request and will be allowed. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
预期输出如下所示:
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: redacted x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
运行以下命令测试授权政策是否正确拒绝无效请求:
# Failure case # Command to execute that tests connectivity to the service service-test. # This is an invalid request and server will reject because the server # authorization policy only allows GET requests. TEST_CMD="wget -q -O - service-test --post-data='' ; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
预期输出如下所示:
<RBAC: access denied HTTP/1.1 403 Forbidden>
在 GKE 上的边车上设置授权政策
本部分介绍如何在 GKE 上的 Cloud Service Mesh 边车上设置不同类型的授权政策。
您必须先安装 GCPAuthzPolicy CustomResourceDefinition (CRD),然后才能创建授权政策:
curl https://github.com/GoogleCloudPlatform/gke-networking-recipes/blob/main/gateway-api/config/mesh/crd/experimental/gcpauthzpolicy.yaml \
| kubectl apply -f -
用于拒绝请求的授权政策
如果您的工作负载应仅进行出站调用(例如 cron 作业),您可以配置授权政策,以拒绝向该工作负载发送任何传入 HTTP 请求。以下示例会拒绝向工作负载 example-app
发送传入 HTTP 请求。
如需创建和应用拒绝授权政策,请执行以下步骤:
通过创建一个名为
deny-all-authz-policy.yaml
的文件来创建自定义政策:cat >deny-all-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - to: operations: - paths: - type: Prefix value: "/" action: DENY EOF
应用政策:
kubectl apply -f deny-all-authz-policy.yaml
用于允许请求的授权政策
您还可以配置一项允许政策,仅允许与
同时拒绝其余的过滤条件以下示例在 example-app
部署上配置了授权政策,以仅允许来自具有身份 spiffee://cluster.local/ns1/pod1
的 Pod 的 mTLS 请求。
如需创建和应用允许授权政策,请执行以下步骤:
通过创建一个名为
allow-authz-policy.yaml
的文件来创建自定义政策:cat >allow-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - from: sources: - principals: - type: Exact value: "spiffee://cluster.local/ns1/pod1" action: ALLOW EOF
应用政策:
kubectl apply -f allow-authz-policy.yaml
设置入站流量网关安全性
本部分假定您已完成服务到服务的安全部分,包括使用 Sidecar 自动注入器设置 GKE 集群、创建证书授权机构和创建端点政策。
在本部分中,您将 Envoy 代理部署为入站网关,该网关终止 TLS 连接并向来自集群内部客户端的请求授权。
要设置入站网关以终止 TLS,请执行以下操作:
- 部署一个可使用集群内部 IP 地址访问的 Kubernetes 服务。
- 该部署包含一个独立的 Envoy 代理,该代理作为 Kubernetes 服务并连接到 Cloud Service Mesh
- 创建终止 TLS 的服务器 TLS 政策。
- 创建向传入请求授权的授权政策。
将入站流量网关服务部署到 GKE
运行以下命令,在 GKE 上部署入站网关服务:
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml kubectl apply -f gateway_sample.yaml
文件 gateway_sample.yaml
是入站网关的规范。以下部分介绍一些可以添加到该规范的内容。
停用 Cloud Service Mesh Sidecar 注入
gateway_sample.yaml
规范将 Envoy 代理部署为唯一容器。在之前的步骤中,Envoy 被作为 Sidecar 注入应用容器。为避免多个 Envoy 处理请求,您可以使用以下语句为此 Kubernetes 服务停用 Sidecar 注入:
sidecar.istio.io/inject: "false"
装载正确的卷
gateway_sample.yaml
规范装载卷 gke-workload-certificates
。此卷也在 Sidecar 部署中使用,但当 Sidecar 注入器看到注释 cloud.google.com/enableManagedCerts: "true"
时,会自动添加该卷。gke-workload-certificates
卷包含您设置的 CA Service 实例签名的 GKE 代管式 SPIFFE 证书和密钥。
设置集群的内部 IP 地址
使用 ClusterInternal
类型的服务配置入站网关。这会为 mesh-gateway
创建一个内部可解析的 DNS 主机名。当客户端向 mesh-gateway:443
发送请求时,Kubernetes 会立即将请求路由到入站网关 Envoy 部署的端口 8080
。
在入站流量网关上启用 TLS
按照以下说明在入站网关上启用 TLS。
使用名为
server-tls-policy.yaml
的文件中的值创建服务器 TLS 政策资源以终止 TLS 连接:description: tls server policy name: server-tls-policy serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe
导入服务器 TLS 政策:
gcloud network-security server-tls-policies import server-tls-policy \ --source=server-tls-policy.yaml --location=global
创建一个新的目标
Gateway
并将其保存在文件td-gke-gateway.yaml
中。这会附加服务器 TLS 政策并将 Envoy 代理入站流量网关配置为终结传入的 TLS 流量。name: td-gke-gateway scope: gateway-proxy ports: - 8080 type: OPEN_MESH serverTLSPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
导入网关:
gcloud network-services gateways import td-gke-gateway \ --source=td-gke-gateway.yaml \ --location=global
创建并保存新的名为
td-gke-route
的HTTPRoute
,它引用网关并将所有请求路由到td-gke-service
。name: td-gke-route hostnames: - mesh-gateway gateways: - projects/PROJECT_NUMBER/locations/global/gateways/td-gke-gateway rules: - action: destinations: - serviceName: "projects/PROJECT_NUMBER/locations/global/backendServices/td-gke-service"
导入
HTTPRoute
:gcloud network-services httproutes import td-gke-route \ --source=td-gke-route.yaml \ --location=global
(可选)更新后端上的授权政策,以允许满足以下所有条件的请求:
DEMO_CLIENT_KSA
发送的请求。(入站网关部署使用DEMO_CLIENT_KSA
服务账号。)- 主机
mesh-gateway
或service-test
的请求 - 端口:
8000
除非您为后端配置了授权政策,否则无需运行这些命令。如果端点上没有授权政策,或者授权政策中不包含主机或来源主账号匹配,则无需此步骤即可允许请求。将这些值添加到
authz-policy.yaml
中。action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test - mesh-gateway ports: - 8000 methods: - GET
导入政策:
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
验证入站流量网关部署
您可以使用名为 debug
的新容器向入站网关发送请求,以验证部署。
在以下规范中,注解 "sidecar.istio.io/inject":"false"
会防止 Cloud Service Mesh Sidecar 注入器自动注入 Sidecar 代理。没有 Sidecar 帮助 debug
容器路由请求。该容器必须连接到入站网关才能路由。
规范包含 --no-check-certificate
标志,此标志会忽略服务器证书验证。debug
容器不具有由 CA Service 签名的有效证书所需的证书授权机构验证证书,入站网关需要使用该证书来终止 TLS。
在生产环境中,我们建议您下载 CA Service 验证证书,并将其装载或安装到您的客户端上。安装验证证书后,移除 wget
命令的 --no-check-certificate
选项。
运行以下命令:
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"
您将看到如下所示的输出:
GET / HTTP/1.1 Host: 10.68.7.132 x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA x-envoy-expected-rq-timeout-ms: 15000 x-envoy-internal: true x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef x-forwarded-for: 10.64.0.53 x-forwarded-proto: https content-length: 0 user-agent: Wget
运行以下反向测试命令:
# Negative test # Expect this to fail because gateway expects TLS. kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"
您将看到类似如下所示的输出:
wget: error getting response: Connection reset by peer
运行以下反向测试命令:
# Negative test. # AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise # the request is denied authorization. kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"
您将看到类似如下所示的输出:
HTTP/1.1 403 Forbidden wget: server returned error: HTTP/1.1 403 Forbidden
删除部署
您可以选择运行这些命令,删除使用本指南创建的部署。
如需删除集群,请运行以下命令:
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
如需删除您创建的资源,请运行以下命令:
gcloud compute backend-services delete td-gke-service --global --quiet cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet gcloud compute firewall-rules delete fw-allow-health-checks --quiet gcloud compute health-checks delete td-gke-health-check --quiet gcloud network-services endpoint-policies delete ep \ --location=global --quiet gcloud network-security authorization-policies delete authz-gateway-policy \ --location=global --quiet gcloud network-security authorization-policies delete authz-policy \ --location=global --quiet gcloud network-security client-tls-policies delete client-mtls-policy \ --location=global --quiet gcloud network-security server-tls-policies delete server-tls-policy \ --location=global --quiet gcloud network-security server-tls-policies delete server-mtls-policy \ --location=global --quiet
限制
Cloud Service Mesh 服务安全性仅支持以下几项: GKE您无法使用 Compute Engine 部署服务安全。
问题排查
本部分介绍如何修复在安全服务设置期间遇到的问题。
连接失败
如果连接失败并显示 upstream connect
错误或 disconnect/reset
before headers
错误,请检查 Envoy 日志,您可能会看到以下某条日志消息:
gRPC config stream closed: 5, Requested entity was not found
gRPC config stream closed: 2, no credential token is found
如果您在 Envoy 日志中看到这些错误,则可能是因为服务账号令牌未正确装载和/或它使用了不同的 audience
。
如需了解详情,请参阅 Envoy 日志中的错误消息指示配置问题。
pod 未创建
如需排查此问题,请参阅排查 GKE pod 的自动部署问题。
Envoy 未向 Cloud Service Mesh 进行身份验证
Envoy (envoy-proxy
) 连接到 Cloud Service Mesh 以提取 xDS 配置时,它使用适用于 GKE 的工作负载身份联合和 Compute Engine 虚拟机默认服务账号(除非更改了引导文件)。如果身份验证失败,则 Envoy 不会进入就绪状态。
无法使用 --workload-identity-certificate-authority flag
创建集群
如果您看到此错误,请确保您运行的是最新版本的 Google Cloud CLI:
gcloud components update
Pod 保持待处理状态
如果 Pod 在设置过程中保持待处理状态,请增加部署规范中 Pod 的 CPU 和内存资源。
无法使用 --enable-mesh-certificates
标志创建集群
确保您运行的是最新版本的 gcloud CLI:
gcloud components update
请注意,--enable-mesh-certificates
标志仅适用于 gcloud beta
。
pod 无法启动
如果证书预配失败,使用 GKE 网格证书的 pod 可能无法启动。在以下情况下可能发生此问题:
WorkloadCertificateConfig
或TrustConfig
配置错误或缺失。- CSR 未被批准。
您可以通过检查 pod 事件来检查证书预配是否失败。
检查 pod 的状态:
kubectl get pod -n POD_NAMESPACE POD_NAME
请替换以下内容:
POD_NAMESPACE
:您的 pod 的命名空间。POD_NAME
:您的 pod 的名称。
检查 pod 的近期事件:
kubectl describe pod -n POD_NAMESPACE POD_NAME
如果证书预配失败,您将看到一个事件具有
Type=Warning
、Reason=FailedMount
、From=kubelet
以及以MountVolume.SetUp failed for volume "gke-workload-certificates"
开头的Message
字段。Message
字段包含问题排查信息。Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedMount 13s (x7 over 46s) kubelet MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)
如果 pod 无法启动的原因是对象配置错误或 CSR 被拒,请参阅以下问题排查步骤。
WorkloadCertificateConfig
或 TrustConfig
配置错误
确保您已正确创建 WorkloadCertificateConfig
和 TrustConfig
对象。您可以使用 kubectl
诊断这两个对象的配置错误。
检索当前状态。
对于
WorkloadCertificateConfig
:kubectl get WorkloadCertificateConfig default -o yaml
对于
TrustConfig
:kubectl get TrustConfig default -o yaml
检查状态输出。有效对象的条件将包含
type: Ready
和status: "True"
。status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: Ready
无效对象则会显示
status: "False"
。reason
和message
字段包含更多问题排查详细信息。
CSR 未被批准
如果 CSR 审批流程中出现问题,您可以在 CSR 的 type: Approved
和 type: Issued
条件中查看错误详细信息。
使用
kubectl
列出相关 CSR:kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'
选择一个
Approved
并且未Issued
,或者未Approved
的 CSR。使用 kubectl 获取所选 CSR 的详细信息:
kubectl get csr CSR_NAME -o yaml
将
CSR_NAME
替换为您选择的 CSR 的名称。
有效 CSR 的条件包含 type: Approved
和 status: "True"
,且 status.certificate
字段中为有效证书:
status:
certificate: <base64-encoded data>
conditions:
- lastTransitionTime: "2021-03-04T21:58:46Z"
lastUpdateTime: "2021-03-04T21:58:46Z"
message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
reason: AutoApproved
status: "True"
type: Approved
message
和 reason
字段中会显示无效 CSR 的问题排查信息。
应用无法使用已颁发的 mTLS 凭据
验证证书未过期:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
检查应用是否支持您使用的密钥类型。
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3
检查发证 CA 是否使用与证书密钥相同的密钥系列。
获取 CA Service(预览版)实例的状态:
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATION
请替换以下内容:
ISSUING_CA_TYPE
:发证 CA 类型,必须为subordinates
或roots
。ISSUING_CA_NAME
:发证 CA 的名称。ISSUING_CA_LOCATION
:发证 CA 的区域。
检查输出中的
keySpec.algorithm
是否与您在WorkloadCertificateConfig
YAML 清单中定义的密钥算法相同。输出如下所示:config: ... subjectConfig: commonName: td-sub-ca subject: organization: TestOrgLLC subjectAltName: {} createTime: '2021-05-04T05:37:58.329293525Z' issuingOptions: includeCaCertUrl: true keySpec: algorithm: RSA_PKCS1_2048_SHA256 ...
证书遭拒
- 验证对等应用使用同一信任软件包来验证证书。
验证证书未过期:
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"
验证客户端代码(如果未使用 gRPC Go Credentials Reloading API)定期刷新文件系统中的凭据。
验证工作负载与 CA 位于同一信任网域。GKE 网格证书支持单个信任网域中的工作负载之间的通信。