3.3. 使用服务提供的证书 secret 保护服务流量
3.3.1. 了解服务用证书
服务用证书旨在为需要加密的复杂中间件应用程序提供支持。这些证书是作为 TLS web 服务器证书发布的。
					service-ca 控制器使用 x509.SHA256WithRSA 签名算法来生成服务证书。
				
					生成的证书和密钥采用 PEM 格式,分别存储在所创建 secret 的 tls.crt 和 tls.key 中。证书和密钥在接近到期时自动替换。
				
用于发布服务证书的服务 CA 证书在 26 个月内有效,并在有效期少于 13 个月时进行自动轮转。轮转后,以前的服务 CA 配置仍会被信任直到其过期为止。这将为所有受影响的服务建立一个宽限期,以在过期前刷新其密钥内容。如果没有在这个宽限期内对集群进行升级(升级会重启服务并刷新其密钥),您可能需要手动重启服务以避免在上一个服务 CA 过期后出现故障。
您可以使用以下命令来手动重启集群中的所有 pod。此命令会导致服务中断,因为它将删除每个命名空间中运行的所有 pod。这些 Pod 会在删除后自动重启。
for I in $(oc get ns -o jsonpath='{range .items[*]} {.metadata.name}{"\n"} {end}'); \
      do oc delete pods --all -n $I; \
      sleep 1; \
      done
$ for I in $(oc get ns -o jsonpath='{range .items[*]} {.metadata.name}{"\n"} {end}'); \
      do oc delete pods --all -n $I; \
      sleep 1; \
      done3.3.2. 添加服务证书
要保证与服务的通信的安全,请在与服务相同的命名空间中将签名的服务证书和密钥对生成 secret。
					生成的证书仅对内部服务 DNS 名称 <service.name>.<service.namespace>.svc 有效,并且只适用于内部通信。如果您的服务是一个无头服务(未设置 clusterIP 值),则生成的证书还包含通配符主题,格式为 *.<service.name>.<service.namespace>.svc。
				
因为生成的证书包含无头服务的通配符主题,因此如果您的客户端必须区分不同的 pod,则不得使用服务 CA。在这种情况下:
- 使用其他 CA 生成各个 TLS 证书。
- 对于定向到单个 pod 且不得被其他 pod 模拟的连接,不接受服务 CA 作为可信 CA。这些连接必须配置为信任用于生成单个 TLS 证书的 CA。
先决条件
- 必须定义了服务。
流程
- 使用 - service.beta.openshift.io/serving-cert-secret-name注解该服务:- oc annotate service <service_name> \ service.beta.openshift.io/serving-cert-secret-name=<secret_name>- $ oc annotate service <service_name> \- 1 - service.beta.openshift.io/serving-cert-secret-name=<secret_name>- 2 - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 例如,使用以下命令来注解服务 - test1:- oc annotate service test1 service.beta.openshift.io/serving-cert-secret-name=test1 - $ oc annotate service test1 service.beta.openshift.io/serving-cert-secret-name=test1- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 检查服务以确认是否存在注解: - oc describe service <service_name> - $ oc describe service <service_name>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 输出示例 - ... Annotations: service.beta.openshift.io/serving-cert-secret-name: <service_name> service.beta.openshift.io/serving-cert-signed-by: openshift-service-serving-signer@1556850837 ...- ... Annotations: service.beta.openshift.io/serving-cert-secret-name: <service_name> service.beta.openshift.io/serving-cert-signed-by: openshift-service-serving-signer@1556850837 ...- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 
							在集群为服务生成 secret 后,Podspec 可以挂载它,pod 将在可用后运行。
3.3.3. 将服务 CA 捆绑包添加到配置映射中
					pod 可以通过挂载具有 service.beta.openshift.io/inject-cabundle=true 注解的 ConfigMap 对象来访问服务证书颁发机构(CA)证书。在注解配置映射后,集群会自动将服务 CA 证书注入配置映射上的 service-ca.crt 键。访问此 CA 证书可让 TLS 客户端使用 service serving 证书验证服务的连接。
				
						将此注解添加到配置映射后,OpenShift Service CA Operator 会删除配置映射中的所有数据。考虑使用单独的配置映射来包含 service-ca.crt,而不是使用存储 pod 配置的同一配置映射。
					
流程
- 输入以下命令,使用 - service.beta.openshift.io/inject-cabundle=true注解来注解配置映射:- oc annotate configmap <config_map_name> \ service.beta.openshift.io/inject-cabundle=true- $ oc annotate configmap <config_map_name> \- 1 - service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 1
- 将<config_map_name>替换为配置映射的名称。
 注意- 在卷挂载中明确引用 - service-ca.crt键可防止 pod 启动,直到配置映射使用 CA 捆绑包注入为止。您可以通过在卷的 serving 证书配置中将- 可选参数设置为- true来覆盖此行为。
- 查看配置映射,以确保注入了服务 CA 捆绑包: - oc get configmap <config_map_name> -o yaml - $ oc get configmap <config_map_name> -o yaml- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - CA 捆绑包在 YAML 输出中作为 - service-ca.crt键的值显示:- apiVersion: v1 data: service-ca.crt: | -----BEGIN CERTIFICATE----- ...- apiVersion: v1 data: service-ca.crt: | -----BEGIN CERTIFICATE----- ...- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 通过配置 - Deployment对象,将配置映射作为卷挂载到 pod 中存在的每个容器中。- 为挂载的配置映射定义卷的 Deployment 对象示例 - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
3.3.4. 将服务 CA 捆绑包添加到 API 服务
					您可以使用 service.beta.openshift.io/inject-cabundle=true 注解 APIService 对象,使其 spec.caBundle 字段由服务 CA 捆绑包填充。这可让 Kubernetes API 服务器验证用于保护目标端点的安全的服务 CA 证书。
				
流程
- 使用 - service.beta.openshift.io/inject-cabundle=true注解 API 服务:- oc annotate apiservice <api_service_name> \ service.beta.openshift.io/inject-cabundle=true- $ oc annotate apiservice <api_service_name> \- 1 - service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 1
- 将<api_service_name>替换为要注解的 API 服务的名称。
 - 例如,使用以下命令来注解 API 服务 - test1:- oc annotate apiservice test1 service.beta.openshift.io/inject-cabundle=true - $ oc annotate apiservice test1 service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 查看 API 服务,以确保注入了服务 CA 捆绑包: - oc get apiservice <api_service_name> -o yaml - $ oc get apiservice <api_service_name> -o yaml- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - CA 捆绑包在 YAML 输出中的 - spec.caBundle字段中显示:- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
3.3.5. 将服务 CA 捆绑包添加到自定义资源定义中
					您可以使用 service.beta.openshift.io/inject-cabundle=true 注解 CustomResourceDefinition(CRD)对象,使其 spec.conversion.webhook.clientConfig.caBundle 字段 由服务 CA 捆绑包填充。这可让 Kubernetes API 服务器验证用于保护目标端点的安全的服务 CA 证书。
				
只有在 CRD 被配置为使用 webhook 进行转换,才会将服务 CA 捆绑包注入 CRD。只有在 CRD 的 webhook 需要使用服务 CA 证书时,注入服务 CA 捆绑包才有意义。
流程
- 使用 - service.beta.openshift.io/inject-cabundle=true注解 CRD:- oc annotate crd <crd_name> \ service.beta.openshift.io/inject-cabundle=true- $ oc annotate crd <crd_name> \- 1 - service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 1
- 将<crd_name>替换为要注解的 CRD 的名称。
 - 例如,使用以下命令来注解 CRD - test1:- oc annotate crd test1 service.beta.openshift.io/inject-cabundle=true - $ oc annotate crd test1 service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 查看 CRD,以确保注入了服务 CA 捆绑包: - oc get crd <crd_name> -o yaml - $ oc get crd <crd_name> -o yaml- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - CA 捆绑包在 YAML 输出中的 - spec.conversion.webhook.clientConfig.caBundle字段中显示:- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
3.3.6. 将服务 CA 捆绑包添加到变异的 webhook 配置中
					您可以使用 service.beta.openshift.io/inject-cabundle=true 注解 MutatingWebhookConfiguration 对象,使每个 webhook 的 clientConfig.caBundle 字段由服务 CA 捆绑包填充。这可让 Kubernetes API 服务器验证用于保护目标端点的安全的服务 CA 证书。
				
不要为 admission webhook 配置设置此注解,不同的 webhook 需要指定不同的 CA 捆绑包。如果您这样做了,则会为所有 webhook 注入这个服务 CA 捆绑包。
流程
- 使用 - service.beta.openshift.io/inject-cabundle=true注解变异 Webhook 配置:- oc annotate mutatingwebhookconfigurations <mutating_webhook_name> \ service.beta.openshift.io/inject-cabundle=true- $ oc annotate mutatingwebhookconfigurations <mutating_webhook_name> \- 1 - service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 1
- 将<mutating_webhook_name>替换为要注解的变异 Webhook 配置的名称。
 - 例如,使用以下命令来注解变异 Webhook 配置 - test1:- oc annotate mutatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true - $ oc annotate mutatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 查看变异 Webhook 配置,以确保注入了服务 CA 捆绑包: - oc get mutatingwebhookconfigurations <mutating_webhook_name> -o yaml - $ oc get mutatingwebhookconfigurations <mutating_webhook_name> -o yaml- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - CA 捆包在 YAML 输出中所有 webhook 的 - clientConfig.caBundle字段中显示:- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
3.3.7. 将服务 CA 捆绑包添加到验证 webhook 配置中
					您可以使用 service.beta.openshift.io/inject-cabundle=true 注解 ValidatingWebhookConfiguration 对象,使每个 webhook 的 clientConfig.caBundle 字段 由服务 CA 捆绑包填充。这可让 Kubernetes API 服务器验证用于保护目标端点的安全的服务 CA 证书。
				
不要为 admission webhook 配置设置此注解,不同的 webhook 需要指定不同的 CA 捆绑包。如果您这样做了,则会为所有 webhook 注入这个服务 CA 捆绑包。
流程
- 使用 - service.beta.openshift.io/inject-cabundle=true注解验证 Webhook 配置:- oc annotate validatingwebhookconfigurations <validating_webhook_name> \ service.beta.openshift.io/inject-cabundle=true- $ oc annotate validatingwebhookconfigurations <validating_webhook_name> \- 1 - service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 1
- 将<validating_webhook_name>替换为要注解的验证 webhook 配置的名称。
 - 例如,使用以下命令来注解验证 webhook 配置 - test1:- oc annotate validatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true - $ oc annotate validatingwebhookconfigurations test1 service.beta.openshift.io/inject-cabundle=true- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 查看验证 Webhook 配置,以确保注入了服务 CA 捆绑包: - oc get validatingwebhookconfigurations <validating_webhook_name> -o yaml - $ oc get validatingwebhookconfigurations <validating_webhook_name> -o yaml- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - CA 捆包在 YAML 输出中所有 webhook 的 - clientConfig.caBundle字段中显示:- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
3.3.8. 手动轮转生成的服务证书
您可以通过删除关联的 secret 来轮换服务证书。删除 secret 会导致自动创建新 secret,进而生成新的证书。
先决条件
- 必须为服务生成了包含证书和密钥对的 secret。
流程
- 检查该服务以确定包含证书的 secret。这可以在 - service-cert-secret-name注解中找到,如下所示。- oc describe service <service_name> - $ oc describe service <service_name>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 输出示例 - ... service.beta.openshift.io/serving-cert-secret-name: <secret> ... - ... service.beta.openshift.io/serving-cert-secret-name: <secret> ...- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 删除为服务生成的 secret。此过程将自动重新创建 secret。 - oc delete secret <secret> - $ oc delete secret <secret>- 1 - Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 1
- 将<secret>替换为前一步中的 secret 名称。
 
- 通过获取新 secret 并检查 - AGE来确认已经重新创建了证书。- oc get secret <service_name> - $ oc get secret <service_name>- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow - 输出示例 - NAME TYPE DATA AGE <service.name> kubernetes.io/tls 2 1s - NAME TYPE DATA AGE <service.name> kubernetes.io/tls 2 1s- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
3.3.9. 手动轮转服务 CA 证书
服务 CA 在 26 个月内有效,并在有效期少于 13 个月时进行刷新。
如果需要,您可以按照以下步骤手动刷新服务 CA。
手动轮换的服务 CA 不会保留对上一个服务 CA 的信任。在集群中的 pod 重启完成前,您的服务可能会临时中断。pod 重启可以确保 Pod 使用由新服务 CA 发布的证书服务。
先决条件
- 必须以集群管理员身份登录。
流程
- 使用以下命令,查看当前服务 CA 证书的到期日期。 - oc get secrets/signing-key -n openshift-service-ca \ -o template='{{index .data "tls.crt"}}' \ | base64 --decode \ | openssl x509 -noout -enddate- $ oc get secrets/signing-key -n openshift-service-ca \ -o template='{{index .data "tls.crt"}}' \ | base64 --decode \ | openssl x509 -noout -enddate- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 手动轮转服务 CA。此过程会生成一个新的服务 CA,用来为新服务证书签名。 - oc delete secret/signing-key -n openshift-service-ca - $ oc delete secret/signing-key -n openshift-service-ca- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 
- 要将新证书应用到所有服务,请重启集群中的所有 pod。此命令确保所有服务都使用更新的证书。 - for I in $(oc get ns -o jsonpath='{range .items[*]} {.metadata.name}{"\n"} {end}'); \ do oc delete pods --all -n $I; \ sleep 1; \ done- $ for I in $(oc get ns -o jsonpath='{range .items[*]} {.metadata.name}{"\n"} {end}'); \ do oc delete pods --all -n $I; \ sleep 1; \ done- Copy to Clipboard Copied! - Toggle word wrap Toggle overflow 警告- 此命令会导致服务中断,因为它将遍历并删除每个命名空间中运行的 Pod。这些 Pod 会在删除后自动重启。