设置使用 Envoy 和负载均衡 API 的服务安全(旧版)
按照本指南中的说明,使用负载均衡 API 为通过 Cloud Service Mesh 和 Envoy 代理部署的服务配置身份验证和授权。如果您使用的是服务路由 API,请阅读设置使用 Envoy 的服务安全。
如需全面了解,请参阅使用负载均衡 API 的 Cloud Service Mesh 服务安全。
本文档适用于使用负载均衡 API 的配置。这是旧版文档。
使用要求
在使用 Envoy 为 Cloud Service Mesh 配置服务安全之前,请确保您的设置符合以下前提条件:
使用适用于 xDS v3 API 的 Envoy 1.20.0 或更高版本。
您能够满足部署 Cloud Service Mesh 的所有要求。如需全面了解这些要求,请参阅准备使用 Envoy 设置 Cloud Service Mesh。
您有足够的权限创建或更新 Cloud Service Mesh 和 Google Cloud 服务网格资源以使用服务安全,如准备使用 Envoy 设置 Cloud Service Mesh 中所述。
准备设置
以下部分介绍了在设置 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
命令启用通过 Certificate Authority Service 设置 Cloud Service Mesh 安全所需的所有 API。
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 角色
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
角色。此角色包含创建、更新、删除、列出和使用所需资源(即在其他资源中引用)的所有必要权限。如果您是项目的所有者编辑者,则会自动拥有此角色。
请注意,在后端服务和目标 HTTPS 代理资源中引用这些资源时,系统不会强制执行 networksecurity.googleapis.com.clientTlsPolicies.use
和 networksecurity.googleapis.com.serverTlsPolicies.use
。
如果这些权限在以后强制执行,并且您使用的是 compute.NetworkAdmin
角色,则在强制执行此检查时不会注意到任何问题。
如果您使用的是自定义角色,并且此检查将强制执行,那么您必须确保添加相应的 .use
权限。否则,将来,您可能会发现自定义角色没有必要的权限,分别引用后端服务或目标 HTTPS 代理中的 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 注入器后,请按照以下说明为您的部署设置测试服务。
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 Google Cloud 资源
按照使用 Cloud Load Balancing 组件配置 Cloud Service Mesh 中的步骤操作。确保验证来自示例客户端的流量被路由到示例服务。
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>
设置入站流量网关安全性
本部分假定您已完成服务到服务的安全部分,包括使用 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
创建将所有请求路由到
td-gke-service
后端服务的新网址映射。入站网关会处理传入请求,并将其发送到属于td-gke-service
后端服务的 pod。gcloud compute url-maps create td-gke-ig-url-map \ --default-service=td-gke-service
在
td-gke-https-proxy.yaml
文件中创建新的目标 HTTPS 代理,并附加之前创建的网址映射和服务器 TLS 政策。这会将 Envoy 代理入站网关配置为终止传入的 TLS 流量。kind: compute#targetHttpsProxy name: td-gke-https-proxy proxyBind: true urlMap: https://www.googleapis.com/compute/beta/projects/PROJECT_ID/global/urlMaps/td-gke-ig-url-map serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
导入政策:
gcloud compute target-https-proxies import td-gke-https-proxy \ --global --source=td-gke-https-proxy.yaml
创建新的转发规则并附加目标 HTTPS 代理。这会将 Envoy 代理配置为监听端口 8080 并应用
td-gke-https-proxy
中定义的路由和安全政策。gcloud compute forwarding-rules create td-gke-gateway-forwarding-rule --global \ --load-balancing-scheme=INTERNAL_SELF_MANAGED --address=0.0.0.0 \ --target-https-proxy=td-gke-https-proxy --ports 8080 \ --network default
(可选)更新后端上的授权政策,以允许满足以下所有条件的请求:
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
为入站网关设置授权政策
您在此处设置的授权政策使入站网关允许满足以下所有条件的请求进入网格:
- 主机:
mesh-gateway
- 端口:
8080
- 路径:
*
- HTTP 方法 GET
在文件
authz-gateway-policy.yaml
中创建授权政策:action: ALLOW name: authz-gateway-policy rules: - destinations: - hosts: - mesh-gateway ports: - 8080 methods: - GET
导入文件中的值:
gcloud network-security authorization-policies import authz-gateway-policy \ --source=authz-gateway-policy.yaml --location=global
修改
td-gke-https-proxy.yaml
文件,将以下内容添加到该文件:authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-gateway-policy
再次导入文件 td-gke-https-proxy.yaml:
gcloud compute target-https-proxies import td-gke-https-proxy \ --global --source=td-gke-https-proxy.yaml
验证部署
运行以下命令验证部署。
# On your localhost. 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: 35.196.50.2 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 user-agent: curl/7.72.0 x-forwarded-proto: https content-length: 0 x-envoy-internal: true x-request-id: 98bec135-6df8-4082-8edc-b2c23609295a accept: */* x-forwarded-for: 10.142.0.7
运行以下反向测试命令:
# Negative test. Expect failure because only POST method is allowed by \ # authz-gateway-policy 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"
您将看到类似如下所示的输出:
wget: server returned error: HTTP/1.1 403 Forbidden
删除部署
您可以选择运行这些命令,删除使用本指南创建的部署。
如需删除集群,请运行以下命令:
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
如需删除您创建的资源,请运行以下命令:
gcloud compute forwarding-rules delete td-gke-forwarding-rule --global --quiet gcloud compute forwarding-rules delete td-gke-gateway-forwarding-rule --global \ --quiet gcloud compute target-http-proxies delete td-gke-proxy --quiet gcloud compute target-https-proxies delete td-gke-https-proxy --quiet gcloud compute url-maps delete td-gke-url-map --quiet gcloud compute url-maps delete td-gke-ig-url-map --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
限制
只有 GKE 支持 Cloud Service Mesh 服务安全。您无法使用 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 网格证书支持单个信任网域中的工作负载之间的通信。