Google Distributed Cloud (GDC) air-gapped 提供内置的托管式第 4 层 (L4) 负载平衡器,但许多企业应用需要高级第 7 层 (L7) 功能,例如基于主机的路由、集中式 TLS 管理和复杂的流量拆分。过去,这是使用 Ingress API 完成的,但 Kubernetes 社区现在认为该 API 已冻结功能。
此参考架构提供了一种自行管理的第 7 层负载均衡解决方案。通过在 GDC Standard 集群上部署热门的 NGINX Gateway Fabric 开源控制器,客户可以无缝地将 L7 流量路由到混合环境。此架构使用 TLS 终止 (HTTPRoute) 根据服务器名称指示 (SNI) 将流量路由到内置容器化 pod 和托管在外部虚拟机上的应用。
架构

该解决方案的关键组件包括:
- 客户端 :向应用发起 HTTPS 请求以进行交互的实体。
- GDC Standard 集群 :GDC 提供了一种内置方式来创建 Kubernetes Vanilla 集群。在此解决方案中,集群将托管 L7 LB 及其控制器,以及外部虚拟机的无头服务和工作负载
- GDC L4 负载平衡器 :内置 L4 负载平衡器充当入口点,将 TCP/443 流量直接分发给运行网关控制器的 Kubernetes Pod。
- 网关控制器 :在 Standard 集群中运行的 NGINX 运算符。
它们会监控网关 API 资源(如
Gateway和HTTPRoute),并动态更新底层代理。Nginx Gateway Fabric 将用于 解决方案。 - 网关(使用 HTTPRoute) :标准化 Kubernetes 资源,用于定义物理监听端口 (443) 和基于 SNI 的主机路由规则(使用 TLS 终止)。
- 容器化工作负载 (Pod) :使用常规 Kubernetes
Service在内部公开的标准 Kubernetes Deployment。 - 基于虚拟机的工作负载(外部) :托管在项目网络中的外部虚拟机上的工作负载,通过无头 Kubernetes
Service和包含虚拟机直接 IP 的自定义端点向代理公开。 - Harbor Registry :一个私有容器仓库,用于在 air-gapped 环境中存储和提供代理和应用映像。
在 Standard 集群中,您将创建四个命名空间:
用于托管 Nginx Gateway Fabric 资源的
nginx-gateway命名空间:
用于托管
Gateway资源的load-balancer命名空间:
vm-app命名空间托管外部虚拟机 IPvm-app、无头服务、指向外部 IP 的EndpointSlice以及Gateway的HTTPRoute:
hello-app命名空间托管演示容器工作负载的Deployment、Service、HTTPRoute和Gateway:
准备工作
在部署此解决方案之前,请确保您已满足以下前提条件:
- 所需软件 :helm、docker、kubectl
CLI 登录和本地设置 :从 GDC 控制台下载 gdcloud CLI,并在本地设置环境。
export USER_NAME="USER_NAME" export PROJECT_ID="PROJECT_ID" export ZONE="ZONE" export ORG_NAME="ORG_NAME" export GDCH_URL="GDC_URL" gdcloud components install gdcloud-k8s-auth-plugin gdcloud config set core/organization_console_url \ https://console.$ORG_NAME.$ZONE.$GDC_URL gdcloud config set core/zone $ZONE gdcloud config set core/project ${PROJECT_ID} gdcloud auth login # use --login-config-cert option in case of TLS error项目设置 :在 GDC 网闸隔离配置环境中创建一个 项目,以保存资源。
gdcloud projects create $PROJECT_IDIAM 角色 :向用户授予集群管理员 和 Standard 集群管理员 角色以管理 Kubernetes 资源,并授予 Harbor 实例管理员 角色以推送映像。
# Grant standard cluster and cluster admin roles gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=cluster-admin gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=standard-cluster-admin # Grant Harbor instance admin role gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member="user:${USER_NAME}" \ --role=harbor-instance-admin
创建 Standard 集群
本部分将引导您完成在 GDC 网闸隔离配置环境中设置 Standard Kubernetes 集群的过程。Standard 集群为部署各种工作负载(包括 Nginx 网关控制器)和自定义应用提供了灵活且稳健的基础。 以下步骤将确保您的集群已正确配置,并且可供后续部署使用。
运行以下命令,确定可用的虚拟机映像类型:
gdcloud compute machine-types list为集群工作器节点选择合适的机器类型。对于本教程,建议使用 至少具有 4 个 vCPU 的机器类型。
export MACHINE_TYPE="MACHINE_TYPE"获取管理 API 服务器 kubeconfig 并设置别名:
export CLUSTER_NAME="CLUSTER_NAME" KUBECONFIG=kubeconfig-admin.yaml gdcloud clusters \ get-credentials ${ORG_NAME}-admin alias km="kubectl --kubeconfig kubeconfig-admin.yaml"创建具有 2 个工作器节点的 Standard 集群:
km create -f - <<EOF apiVersion: cluster.gdc.goog/v1 kind: Cluster metadata: name: ${CLUSTER_NAME} namespace: ${PROJECT_ID} spec: nodePools: - machineTypeName: ${MACHINE_TYPE} nodeCount: 2 name: ${CLUSTER_NAME}-node-pool EOF如需详细了解可用选项,请参阅 文档。
Standard 集群创建过程最多可能需要 60 分钟才能完成。如需检查状态,请使用以下命令:
km get clusters/${CLUSTER_NAME} \ -n ${PROJECT_ID} \ --watch集群准备就绪后,输出应显示“正在运行”状态,如下所示:
NAME STATE K8S VERSION my-cluster Running 1.30.12-gke.300集群准备就绪后,检索其凭据:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \ get-credentials ${CLUSTER_NAME} \ --standard \ --project ${PROJECT_ID} \ --zone ${ZONE}创建一个别名,以便在本指南的其余部分中使
kubectl命令更简洁。此别名将用于与 Standard 集群进行交互:alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"为控制器、“hello-app”演示容器化应用和基于虚拟机的演示版应用创建命名空间:
kk create namespace load-balancer kk create namespace hello-app kk create namespace vm-app
创建和集成 Harbor Registry
Harbor 是一个容器映像仓库,在 GDC air-gapped 中内置了支持。本部分将引导您完成将 Harbor Registry 与 Standard 集集群成的步骤,包括配置凭据和 Secret 以安全地拉取和推送映像。
- 在项目中创建 Harbor 实例 。
- 在 Harbor 实例中创建 Harbor 项目 。
设置环境变量:
export HARBOR_INSTANCE_NAME="HARBOR_INSTANCE_NAME" export HARBOR_INSTANCE_URL="HARBOR_INSTANCE_URL" export HARBOR_PROJECT="HARBOR_INSTANCE_PROJECT" export IMAGE_PULL_SECRET_NAME="harbor-secret"使用 机器人 账号 登录 Harbor 实例:
docker --config=./docker login ${HARBOR_INSTANCE_URL}在 Standard 集群中创建 Secret:
kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker/config.json \ -n load-balancer kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker/config.json \ -n hello-app
部署演示容器化应用
本部分详细介绍了在 GDC 网闸隔离配置 Kubernetes 集群中部署演示容器化应用 (hello-app) 的过程。您将创建必要的 Kubernetes Deployment 和 Service 资源来运行 hello-app
并在集群内部公开它,以便使用 L7 负载均衡器进行访问。
将演示容器化应用的示例映像上传到 Harbor:
docker pull gcr.io/google-samples/hello-app:1.0 \ --platform linux/amd64 docker tag gcr.io/google-samples/hello-app:1.0 \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0 docker --config=./docker push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0在 Standard 集群中部署以下清单:
cat << EOF > hello-app.yaml apiVersion: apps/v1 kind: Deployment metadata: name: hello-app namespace: hello-app spec: replicas: 2 selector: matchLabels: app: hello-app template: metadata: labels: app: hello-app spec: containers: - name: hello-server image: ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/hello-app:1.0 ports: - containerPort: 8080 imagePullSecrets: - name: ${IMAGE_PULL_SECRET_NAME} --- apiVersion: v1 kind: Service metadata: name: hello-app namespace: hello-app spec: type: ClusterIP selector: app: hello-app ports: - protocol: TCP port: 80 targetPort: 8080 EOF kk apply -f hello-app.yaml
然后验证部署和服务是否存在:
kk get svc,deploy -n hello-app
在虚拟机中部署演示版应用
本部分详细介绍了在 Kubernetes 集群外部的虚拟机 (VM) 中部署演示应用的过程。通过在虚拟机上设置 HTTP 服务器,您将模拟负载均衡器可以公开的外部应用,展示其管理集群内部和外部资源流量的能力。
首先,为演示版应用创建一个虚拟机
- 在 Web 浏览器中打开 GDC 控制台。
- 选择与创建 Standard Kubernetes 集群时相同的项目。
- 打开菜单,然后点击虚拟机 。
- 点击创建实例 。
- 将虚拟机命名为
vm-workload。对于此示例,2 个 vCPU 映像就足够了。 - 对于启动磁盘映像,请选择 Ubuntu 22.04 发行版,该发行版预安装了 Python。
- 点击创建 。
- 等待几分钟,直到虚拟机准备就绪。
- 与虚拟机建立 SSH 连接:
- 在 GDC 控制台中,点击虚拟机。
- 点击 Connect with SSH 。
连接到 SSH 控制台后,运行以下命令:
mkdir ~/simple-server
cd ~/simple-server
echo 'Welcome to my VM!' > index.html
python3 -m http.server --bind 0.0.0.0 8080 &
如需将流量路由到虚拟机,请创建一个无头 Service(不带选择器)。这将使用 EndpointSlice 资源手动映射到虚拟机的内部 IP 地址。
kk apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: vm-app-svc
namespace: vm-app
spec:
ports:
- protocol: TCP
port: 443
targetPort: 443
EOF
运行以下命令,获取 vm-workload 虚拟机的 IP 地址
gdcloud compute instances list --project ${PROJECT_ID} \
| grep workload-vm | awk '{print $3}'
输出将是设置 EndpointSlice 资源所需的虚拟机的 IP 地址。
创建将连接到无选择器的虚拟机应用 Service 的资源 EndpointSlice,并寻址应将流量路由到的虚拟机的 IP。
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: vm-app-endpoints
namespace: vm-app
labels:
kubernetes.io/service-name: vm-app-svc
addressType: IPv4
ports:
- port: 8080
endpoints:
- addresses:
- "VM_IP"
conditions:
ready: true
创建自签名证书
本部分将引导您完成为应用生成自签名 TLS 证书的过程。为方便起见,本指南使用自签名证书,但在生产环境中,您必须使用可用于生产用途的证书,如可选:使用可用于生产用途的证书中所述。这些证书对于在 Nginx 网关上启用 HTTPS 终止至关重要,可确保客户端与负载均衡器之间针对容器化工作负载和基于虚拟机的工作负载进行加密通信。
为容器化应用创建证书:
openssl req -x509 -newkey rsa:2048 -nodes \ -keyout tls-containerized.key \ -out tls-containerized.crt \ -subj "/CN=k8s-app.example.com" \ -days 365 kk create secret tls tls-containerized \ --namespace load-balancer \ --key tls-containerized.key \ --cert tls-containerized.crt kk create secret tls tls-containerized \ --namespace hello-app \ --key tls-containerized.key \ --cert tls-containerized.crt为虚拟机应用创建证书:
openssl req -x509 -newkey rsa:2048 -nodes \ -keyout tls-vm.key \ -out tls-vm.crt \ -subj "/CN=vm-app.example.com" \ -days 365 kk create secret tls tls-vm \ --namespace load-balancer \ --key tls-vm.key \ --cert tls-vm.crt kk create secret tls tls-vm \ --namespace vm-app \ --key tls-vm.key \ --cert tls-vm.crt
部署 NGINX
本部分概述了部署 Nginx 网关控制器的步骤,包括安装 Gateway API 自定义资源定义 (CRD)、使用 Helm 设置 Nginx Gateway Fabric,以及在 Standard 集群中验证安装。这为高级第 7 层路由准备了基础架构。
安装 Gateway API CRD
Gateway API 需要在部署控制器之前在集群中安装自定义资源定义 (CRD)。我们将使用 Gateway API 项目中的官方实验性自定义资源定义 (CRD)(本指南使用 1.2.0 版)。
安装实验性 CRD:
kk apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml运行
kk get crd gateways.gateway.networking.k8s.io,验证 CRD 是否已成功安装。
安装 NGINX Gateway Fabric
使用 Helm 部署 NGINX Gateway Fabric 控制器。此控制器将监控 Gateway API 资源并配置 NGINX 以处理流量。
设置 NGINX 映像标记:
helm template nfg oci://ghcr.io/nginx/charts/nginx-gateway-fabric | grep "image:" # get the tag of the nginx-gateway-fabric (in following case 2.4.2) export NGINX_TAG="2.4.2"拉取 NGINX Gateway Fabric 和 NGINX 映像,然后将其推送到 Harbor 仓库:
docker pull ghcr.io/nginx/nginx-gateway-fabric:${NGINX_TAG} docker tag ghcr.io/nginx/nginx-gateway-fabric:${NGINX_TAG} \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx-gateway-fabric:${NGINX_TAG} docker --config=./docker push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx-gateway-fabric:${NGINX_TAG} docker pull nginx:1.27.3 docker tag nginx:1.27.3 \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.27.3 docker --config=./docker push \ ${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.27.3创建
nginx-gateway命名空间并添加 Harbor 映像拉取 Secret:kk create namespace nginx-gateway kk create secret docker-registry ${IMAGE_PULL_SECRET_NAME} \ --from-file=.dockerconfigjson=./docker/config.json \ -n nginx-gateway使用 Helm 部署 NGINX Gateway Fabric,指向 Harbor 仓库中的映像:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml helm upgrade --install ngf \ oci://ghcr.io/nginx/charts/nginx-gateway-fabric \ --create-namespace -n nginx-gateway \ --set nginxGateway.image.tag="${NGINX_TAG}" \ --set nginxGateway.image.repository="${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx-gateway-fabric" \ --set nginx.image.repository="${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/nginx" \ --set nginxGateway.serviceAccount.imagePullSecret="${IMAGE_PULL_SECRET_NAME}" \ --set nginx.imagePullSecret="${IMAGE_PULL_SECRET_NAME}"Kubernetes 部署使用提供的 Secret (
${IMAGE_PULL_SECRET_NAME}) 安全地从 Harbor 拉取映像,该 Secret 包含 Harbor 机器人账号的凭据。验证
GatewayClass资源是否被接受:kk get gatewayclass您应该会看到
nginx列出,且ACCEPTED = True。
创建网关实例
定义监听端口 443 的逻辑负载均衡器实例。我们将为其配置 Terminate 模式,这意味着网关将执行 TLS
终止并解密流量,然后再将其传递。
创建并应用 gateway.yaml:
cat << EOF > gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
namespace: load-balancer
spec:
gatewayClassName: nginx
listeners:
- name: https-k8s-workload
hostname: "k8s-app.example.com"
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: tls-containerized
- name: https-vm-workload
hostname: "vm-app.example.com"
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: All
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: tls-vm
EOF
kk apply -f gateway.yaml
通过检查 PROGRAMMED 是否为 True,验证网关是否已成功部署:
kk get gateway my-gateway --n load-balancer
验证是否已将托管式 GDC L4 负载均衡器作为 Service 与网关一起部署
kk get services -n load-balancer
检查 Nginx 服务是否已创建和配置,输出应如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-gateway-nginx LoadBalancer 10.252.19.148 10.200.32.43 443:30649/TCP 45h
定义 L7 路由逻辑 (HTTPRoute)
将 HTTPRoute 绑定到网关,以定义应如何根据请求的主机名 (SNI) 分配流量。
创建并应用 routing.yaml:
cat << EOF > routing.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: k8s-http-route
namespace: hello-app
spec:
parentRefs:
- name: my-gateway
namespace: load-balancer
hostnames:
- "k8s-app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: hello-app
namespace: hello-app
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: vm-http-route
namespace: vm-app
spec:
parentRefs:
- name: my-gateway
namespace: load-balancer
hostnames:
- "vm-app.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: vm-app-svc
namespace: vm-app
port: 443
EOF
kk apply -f routing.yaml
检索负载均衡器 IP
运行命令以获取 Nginx 负载平衡器的 IP
kk get services/my-gateway-nginx \
-n load-balancer \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}'
在验证对应用的访问权限时,需要此 IP。此 IP 将称为 LOAD_BALANCER_IP。
创建客户端虚拟机
按照步骤创建客户端虚拟机
- 在 Web 浏览器中打开 GDC 控制台。
- 打开菜单,然后点击虚拟机 。
- 点击创建实例 。
- 创建一个名为
client的虚拟机,选择一个小型机器类型,然后选择 Rocky Linux 或 Ubuntu,它们都预安装了curl。 - 点击创建 。
- 等待几分钟,直到虚拟机准备就绪。
- 虚拟机准备就绪后,与虚拟机建立 SSH 连接:
- 在 GDC 控制台中,点击虚拟机。
- 点击 Connect with SSH 。
验证访问权限和路由
如需测试路由,请从客户端虚拟机执行 curl 命令。您可以使用负载平衡器的 IP 地址,通过其定义的主机名连接到这两个应用。
通过在 curl 中传递 --resolve 标志,您可以强制域名解析为 GDC 网闸隔离配置 L4 负载平衡器的 IP 地址。请注意,我们传递 -k 标志以信任自签名证书。
测试 Kubernetes 容器化应用:
curl -k --resolve k8s-app.example.com:443:$LOAD_BALANCER_IP https://k8s-app.example.com -v
测试外部虚拟机应用:
curl -k --resolve vm-app.example.com:443:$LOAD_BALANCER_IP https://vm-app.example.com -v
如果配置正确,网关控制器将无缝充当 TLS 终止器,并将流量直通到目标。
可选:使用可用于生产用途的证书
本部分介绍了如何利用 GDC 网闸隔离配置 CA Service 创建私有根证书授权机构 (CA)、为工作负载颁发签名证书,以及安全地更新 GDC 网闸隔离配置 Standard 集群和客户端虚拟机。
本部分概述了如何使用 GDC 网闸隔离配置 CA
Service 创建
私有根证书授权机构 (CA) 并为您的
应用颁发有效证书。通过在客户端虚拟机上安装此根 CA,您可以验证 TLS 终结是否与受信任的证书无缝协作,而无需绕过 SSL 警告(例如,使用 curl -k)。
授予必要权限并获取凭据
如需管理 CA Service 和颁发证书,您的用户需要在项目中具有适当的 IAM 角色。
授予
certificate-authority-service-admin和certificate-requester角色:gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member=user:${USER_NAME} \ --role=certificate-authority-service-admin gdcloud projects add-iam-policy-binding ${PROJECT_ID} \ --member=user:${USER_NAME} \ --role=certificate-requester获取管理 API 服务器的凭据:
gdcloud clusters get-credentials ${ORG_NAME}-admin
创建根 CA
您将在项目命名空间内的管理 API 服务器中创建证书授权机构。
应用
CertificateAuthority资源:km apply -f - <<EOF apiVersion: pki.security.gdc.goog/v1 kind: CertificateAuthority metadata: name: my-root-ca namespace: ${PROJECT_ID} spec: caProfile: commonName: "My Root CA" duration: 87600h # 10 years keyAlgorithm: RSA_2048 maxChainLength: 1 caType: ROOT keyLocation: HSM rotationPolicy: cronTime: 0 0 1 1 * EOFkm -n ${PROJECT_ID} get \ certificateauthority.pki.security.gdc.goog/my-root-ca -ojson \ | jq -r ' .status.conditions[] | select( .type as $id | "Ready" | index($id)) .status'
颁发和部署证书
CA 准备就绪后,您将为容器化应用和基于虚拟机的应用请求证书。这些请求发生在管理 API 服务器中,生成的密钥必须移至 Standard 集群。
为这两个网域创建请求:
km apply -f - <<EOF
apiVersion: pki.security.gdc.goog/v1
kind: CertificateRequest
metadata:
name: tls-containerized-req
namespace: ${PROJECT_ID}
spec:
certificateAuthorityRef:
name: my-root-ca
namespace: ${PROJECT_ID}
certificateConfig:
subjectConfig:
commonName: "k8s-app.example.com"
dnsNames:
- "k8s-app.example.com"
signedCertificateSecret: tls-containerized-signed
---
apiVersion: pki.security.gdc.goog/v1
kind: CertificateRequest
metadata:
name: tls-vm-req
namespace: ${PROJECT_ID}
spec:
certificateAuthorityRef:
name: my-root-ca
namespace: ${PROJECT_ID}
certificateConfig:
subjectConfig:
commonName: "vm-app.example.com"
dnsNames:
- "vm-app.example.com"
signedCertificateSecret: tls-vm-signed
EOF
等待片刻,让系统颁发证书。当“就绪”条件为 True 时,您可以验证证书是否已准备就绪:
km get certificaterequests -n ${PROJECT_ID}
更新 Standard 集群
如果您已按照本指南的前几部分操作,则 Standard 集群中会有自签名 Secret。您必须先删除它们,然后才能创建新的签名版本:
kk delete secret tls-containerized -n load-balancer
kk delete secret tls-vm -n load-balancer
kk delete secret tls-containerized -n hello-app
kk delete secret tls-vm -n vm-app
现在,从管理 API 服务器提取签名证书,并在 Standard 集群中创建新的 Secret。
km get secret -n ${PROJECT_ID} tls-containerized-signed \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d > tls-containerized.crt
km get secret -n ${PROJECT_ID} tls-containerized-signed \
-o jsonpath='{.data.tls\.key}' \
| base64 -d > tls-containerized.key
kk create secret tls tls-containerized \
--namespace load-balancer \
--key tls-containerized.key \
--cert tls-containerized.crt
kk create secret tls tls-containerized \
--namespace hello-app \
--key tls-containerized.key \
--cert tls-containerized.crt
km get secret -n ${PROJECT_ID} tls-vm-signed \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d > tls-vm.crt
km get secret -n ${PROJECT_ID} tls-vm-signed \
-o jsonpath='{.data.tls\.key}' \
| base64 -d > tls-vm.key
kk create secret tls tls-vm \
--namespace load-balancer \
--key tls-vm.key \
--cert tls-vm.crt
kk create secret tls tls-vm \
--namespace vm-app \
--key tls-vm.key \
--cert tls-vm.crt
负载平衡器将自动获取并刷新新的 Secret。
配置客户端信任
如需验证设置,您需要告知客户端虚拟机信任新的根 CA。
将根 CA 证书提取到文件中:
km get secret -n ${PROJECT_ID} my-root-ca-secret \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d > my-root-ca.crt
将证书传输到客户端虚拟机。(您可以复制 my-root-ca.crt 的内容,然后将其粘贴到客户端虚拟机上的文件中)。
在客户端虚拟机上,更新受信任证书存储区。
如果 client 虚拟机是 Ubuntu:
sudo cp my-root-ca.crt /usr/local/share/ca-certificates/
sudo chmod 644 /usr/local/share/ca-certificates/my-root-ca.crt
sudo update-ca-certificates
如果 client 虚拟机是 Rocky Linux:
sudo cp my-root-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
验证访问权限
现在,您可以使用 curl 访问应用,而无需使用 -k 标志。连接将完全受信任。
测试 Kubernetes 容器化应用:
curl -v --resolve k8s-app.example.com:443:LOAD_BALANDER_IP https://k8s-app.example.com
测试虚拟机应用:
curl -v --resolve vm.example.com:443:LOAD_BALANDER_IP https://vm-app.example.com
如果成功,您将立即看到应用输出,而不会收到任何 SSL 证书警告。