O Google Distributed Cloud (GDC) com isolamento físico oferece um balanceador de carga gerenciado integrado de camada 4 (L4), mas muitos aplicativos corporativos exigem recursos avançados de camada 7 (L7), como roteamento com base em host, gerenciamento centralizado de TLS e divisão de tráfego complexa. Historicamente, isso é feito usando a API Entrada, que agora é considerada um recurso congelado na comunidade do Kubernetes.
Esta arquitetura de referência fornece uma solução autogerenciada de balanceamento de carga da camada 7. Ao implantar o conhecido controlador de código aberto HAProxy em um cluster padrão do GDC, os clientes podem rotear o tráfego L7 para ambientes híbridos sem problemas. Essa arquitetura usa o encerramento de TLS (HTTPRoute) para rotear o tráfego com base na indicação de nome do servidor (SNI, na sigla em inglês) para pods em contêineres integrados e aplicativos hospedados em máquinas virtuais externas.
Arquitetura

Os principais componentes da solução incluem:
- Cliente: uma entidade que inicia solicitações HTTPS para interagir com os aplicativos.
- Cluster padrão do GDC: o GDC oferece uma maneira integrada de criar clusters Vanilla do Kubernetes. Nesta solução, o cluster vai hospedar o LB L7 e os controladores, além das cargas de trabalho e do serviço sem cabeçalho para VMs externas.
- Balanceador de carga L4 do GDC: o balanceador de carga L4 integrado que serve como ponto de entrada, distribuindo o tráfego TCP/443 diretamente para os pods do Kubernetes que executam os controladores.
- Controladores de entrada: operadores HAProxy em execução no cluster padrão.
Eles monitoram os recursos
Ingresse atualizam dinamicamente os proxies subjacentes. O controlador de entrada do HAProxy será usado na implementação a seguir. - Entrada: recursos padronizados do Kubernetes que definem a porta de detecção física (443) e as regras de roteamento de host baseadas em SNI com encerramento de TLS.
- Carga de trabalho conteinerizada (pods): uma implantação padrão do Kubernetes exposta
internamente com um
Serviceregular do Kubernetes. - Carga de trabalho baseada em VM (externa): uma carga de trabalho hospedada em uma VM externa na
rede do projeto, exposta ao proxy usando um
Servicedo Kubernetes sem comando e um endpoint personalizado que contém o IP direto da VM. - Registro do Harbor: um Container Registry particular usado para armazenar e disponibilizar as imagens de proxy e de aplicativo no ambiente com isolamento físico.
No cluster padrão, você cria três namespaces:
O namespace
load-balancerhospeda o controlador de entrada do HAProxy e a carga de trabalho do balanceador de carga do HAProxy:
O namespace
hello-apphospeda oDeployment, umServicee umIngresspara a carga de trabalho do contêiner de demonstração:
O namespace
vm-apphospeda um serviço headless que expõe o IP externo da VM, umEndpointSliceque aponta para o IP externo e umIngress:
Antes de começar
Antes de implantar essa solução, verifique se você tem os seguintes pré-requisitos:
- Software necessário: helm, docker, kubectl
Login da CLI e configuração local: faça o download da CLI gdcloud no console do GDC e configure seu ambiente localmente:
export USER_NAME="USER_NAME" export PROJECT_ID="PROJECT_ID" export ZONE="ZONE" export ORG_NAME="ORG_NAME" export GDC_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 errorConfiguração do projeto: crie um projeto no ambiente do GDC com isolamento físico para armazenar os recursos:
gdcloud projects create $PROJECT_IDPapéis do IAM: conceda ao usuário os papéis de administrador de cluster e administrador de cluster padrão para gerenciar recursos do Kubernetes e o papel de administrador de instância do Harbor para enviar imagens:
# 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
criar um cluster padrão
Nesta seção, você vai aprender a configurar um cluster padrão do Kubernetes no ambiente do GDC com isolamento físico. Um cluster padrão oferece uma base flexível e robusta para implantar várias cargas de trabalho, incluindo o controlador de entrada do HAProxy e seus aplicativos personalizados. As etapas a seguir garantem que o cluster esteja configurado corretamente e acessível para implantações subsequentes.
Identifique os tipos de imagem de máquina virtual disponíveis executando:
gdcloud compute machine-types listSelecione um tipo de máquina apropriado para os nós de trabalho do cluster. Para este tutorial, recomendamos um tipo de máquina com pelo menos 4 vCPUs.
export MACHINE_TYPE="MACHINE_TYPE"Acesse o kubeconfig do servidor da API de gerenciamento e defina um alias:
export CLUSTER_NAME="CLUSTER_NAME" KUBECONFIG=kubeconfig-admin.yaml gdcloud clusters \ get-credentials ${ORG_NAME}-admin alias km="kubectl --kubeconfig kubeconfig-admin.yaml"Crie um cluster padrão com dois nós de trabalho:
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 EOFPara mais detalhes sobre as opções disponíveis, consulte a documentação.
A criação de um cluster padrão pode levar até 60 minutos. Para verificar o status, use o seguinte comando:
km get clusters/${CLUSTER_NAME} \ -n ${PROJECT_ID} \ --watchDepois que o cluster estiver pronto, a saída vai mostrar um estado de Running, como este:
NAME STATE K8S VERSION my-cluster Running 1.30.12-gke.300Quando o cluster estiver pronto, recupere as credenciais dele:
KUBECONFIG=kubeconfig-${CLUSTER_NAME}.yaml gdcloud clusters \ get-credentials ${CLUSTER_NAME} \ --standard \ --project ${PROJECT_ID} \ --zone ${ZONE}Crie um alias para manter os comandos
kubectlmais concisos no restante deste guia. Esse alias será usado para interagir com o cluster padrão:alias kk="kubectl --kubeconfig kubeconfig-${CLUSTER_NAME}.yaml"Crie namespaces para o controlador, o app de demonstração conteinerizado "hello-app" e o app de demonstração baseado em VM:
kk create namespace load-balancer kk create namespace hello-app kk create namespace vm-app
Criar e integrar o Harbor Registry
O Harbor é um registro de imagens de contêiner com suporte integrado no GDC com isolamento físico. Nesta seção, mostramos as etapas para integrar um registro do Harbor ao cluster padrão, incluindo a configuração de credenciais e secrets para permitir a extração e o envio seguros de imagens.
- Crie uma instância do Harbor no seu projeto.
- Crie um projeto do Harbor na sua instância do Harbor.
Defina as variáveis de ambiente:
export HARBOR_INSTANCE_NAME="HARBOR_INSTANCE_NAME" export HARBOR_INSTANCE_URL="HARBOR_INSTANCE_URL" export HARBOR_PROJECT="HARBOR_PROJECT" export IMAGE_PULL_SECRET_NAME="harbor-secret"Faça login na instância do Harbor usando uma conta de robô:
docker --config=./docker login ${HARBOR_INSTANCE_URL}Crie os secrets no cluster padrão:
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
Implantar app de demonstração em contêineres
Nesta seção, detalhamos a implantação de um aplicativo conteinerizado de demonstração
(hello-app) no cluster do Kubernetes com isolamento físico
do GDC. Você vai criar os recursos necessários de implantação e serviço do Kubernetes
para executar o hello-app e expô-lo internamente no cluster,
preparando-o para acesso usando o balanceador de carga L7.
Faça upload de uma imagem de amostra para o app de demonstração em contêiner no 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.0Implante o seguinte manifesto no cluster padrão:
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
Em seguida, verifique se a implantação e o serviço estão lá.
kk get svc,deploy -n hello-app
Implantar o app de demonstração em uma VM
Nesta seção, detalhamos a implantação de um aplicativo de demonstração em uma máquina virtual (VM) fora do cluster do Kubernetes. Ao configurar um servidor HTTP em uma VM, você vai simular um aplicativo externo que o balanceador de carga pode expor, demonstrando a capacidade de gerenciar o tráfego para recursos dentro e fora do cluster.
Primeiro, crie uma VM para o app de demonstração:
- Abra o console do GDC no navegador da Web.
- Selecione o mesmo projeto em que você criou o cluster padrão do Kubernetes.
- Abra o menu e clique em Máquinas virtuais.
- Clique em Criar instância.
- Dê à VM o nome
vm-workload. Uma imagem de 2 vCPUs é suficiente para o exemplo. - Para a imagem do disco de inicialização, selecione uma distribuição do Ubuntu 22.04, que vem com o Python pré-instalado.
- Clique em Criar.
- Aguarde alguns minutos até que a VM esteja pronta.
- Estabeleça uma conexão SSH com a VM:
- No console do GDC, clique na VM.
- Clique em Conectar com SSH.
Depois de se conectar ao console SSH, execute o seguinte:
mkdir ~/simple-server
cd ~/simple-server
echo 'Welcome to my VM!' > index.html
python3 -m http.server --bind 0.0.0.0 8080 &
Para rotear o tráfego para uma VM, crie um serviço headless (sem seletores). Ele
será mapeado manualmente para o endereço IP interno da VM usando um recurso
EndpointSlice.
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
Para saber o endereço IP da VM vm-workload, execute o seguinte comando:
gdcloud compute instances list --project ${PROJECT_ID} \
| grep workload-vm | awk '{print $3}'
A saída será o endereço IP da VM que será necessário para configurar o recurso EndpointSlice.
Crie o recurso EndpointSlice que vai se conectar ao serviço sem seletor
da VM-app e use o endereço IP da VM para onde o tráfego precisa
ser roteado.
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
Criar certificados autoassinados
Nesta seção, você vai aprender a criar certificados TLS e secrets do Kubernetes para proteger a comunicação dos aplicativos baseados em contêineres e em VMs. Este guia usa certificados autoassinados por conveniência, mas em ambientes de produção, é necessário usar certificados de nível de produção, conforme descrito em Opcional: usar certificados prontos para produção. Escolha nomes de domínio de amostra arbitrários para esses apps. Ao estabelecer conexões seguras, você garante a integridade de dados e a confidencialidade para os clientes que acessam seu aplicativo pelo controlador de entrada do HAProxy.
Para o app conteinerizado, criamos um certificado autoassinado e o salvamos como um secret no namespace do balanceador de carga. Isso será usado para o TLS ao solicitar k8s-app.example.com
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
Para o app da VM, um certificado autoassinado semelhante é emitido e salvo. Ele será usado para o TLS ao solicitar vm-app.example.com
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
Implantar o HAProxy
Instalar o controlador de entrada do HAProxy e o LB L4
export HAPROXY_VERSION=3.1.14
# pull the HAProxy Ingress Controller image and push it to Harbor
docker pull haproxytech/kubernetes-ingress:${HAPROXY_VERSION} \
--platform linux/amd64
docker tag haproxytech/kubernetes-ingress:${HAPROXY_VERSION} \
${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/haproxy-ingress:${HAPROXY_VERSION}
docker --config=./docker push \
${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/haproxy-ingress:${HAPROXY_VERSION}
# Get Helm repo
helm repo add haproxytech https://haproxytech.github.io/helm-charts
helm repo update
# Install the Ingress Controller with helm
helm upgrade --install haproxy-kubernetes-ingress \
haproxytech/kubernetes-ingress \
--kubeconfig kubeconfig-${CLUSTER_NAME}.yaml \
--namespace load-balancer \
--set controller.image.repository=${HARBOR_INSTANCE_URL}/${HARBOR_PROJECT}/haproxy-ingress \
--set controller.image.tag=${HAPROXY_VERSION} \
--set controller.existingImagePullSecret=${IMAGE_PULL_SECRET_NAME} \
--set controller.service.type=LoadBalancer \
--set-json \
controller.service.annotations='{"networking.gke.io/load-balancer-type": "internal"}'
O controlador de entrada do HAProxy recebe um endereço IP virtual exclusivo para acesso do cliente usando um
serviço do tipo LoadBalancer. Esse serviço configura um balanceador de carga de camada 4 totalmente gerenciado. Para simplificar este guia, um balanceador de carga interno é criado
definindo a anotação load-balancer-type como internal. A omissão dessa anotação resultaria em um balanceador de carga externo. A implantação do Kubernetes
extrai imagens do Harbor com segurança usando o secret fornecido
(${IMAGE_PULL_SECRET_NAME}), que contém as credenciais da conta de robô
do Harbor.
Validar a instalação do controlador de entrada do HAProxy
Verifique se os pods do controlador de entrada do HAProxy estão em execução e prontos:
kk get pods -n load-balancer
A saída será semelhante a esta:
NAME READY STATUS RESTARTS AGE
haproxy-kubernetes-ingress-78dc9c8676-f8fcb 1/1 Running 0 35s
haproxy-kubernetes-ingress-78dc9c8676-lfnr2 1/1 Running 0 65s
haproxy-kubernetes-ingress-crdjob-3-tgj2h 0/1 Completed 0 65s
Verifique se o serviço do controlador de entrada do HAProxy foi criado e configurado:
kk get services -n load-balancer
A saída será assim:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
haproxy-kubernetes-ingress LoadBalancer 10.252.27.46 10.252.4.17 80:32023/TCP,443:31103/TCP,443:31103/UDP,1024:30146/TCP,6060:30718/TCP 10m
Definir recursos de Entrada para os apps de demonstração
Crie o recurso de entrada que vai conectar o HAProxy ao serviço do app conteinerizado.
cat << EOF > hello-app-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-app-ingress
namespace: hello-app
annotations:
haproxy.org/ssl-redirect: "true"
haproxy.org/ssl-redirect-port: "443"
haproxy.org/ssl-redirect-code: "308"
spec:
ingressClassName: haproxy
tls:
- hosts:
- "k8s-app.example.com"
secretName: tls-containerized
rules:
- host: "k8s-app.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-app
port:
number: 80
EOF
kk apply -f hello-app-ingress.yaml
Crie o recurso de Entrada que vai se conectar ao Serviço sem seletor da VM-app e use o IP da VM para onde o tráfego precisa ser roteado.
cat << EOF > vm-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: vm-app-ingress
namespace: vm-app
annotations:
haproxy.org/ssl-redirect: "true"
haproxy.org/ssl-redirect-port: "443"
haproxy.org/ssl-redirect-code: "308"
spec:
ingressClassName: haproxy
tls:
- hosts:
- "vm-app.example.com"
secretName: tls-vm
rules:
- host: "vm-app.example.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vm-app-svc
port:
number: 443
EOF
kk apply -f vm-ingress.yaml
Recuperar o endereço IP do balanceador de carga
Execute o comando para receber o endereço IP do balanceador de carga.
kk get services/haproxy-kubernetes-ingress \
-n load-balancer \
-o jsonpath='{.status.loadBalancer.ingress[0].ip}'
Isso será necessário ao verificar o acesso aos apps. Ele será indicado como LOAD_BALANCER_IP.
Criar uma VM cliente
Siga as etapas para criar uma VM de cliente:
- Abra o console do GDC no navegador da Web.
- Abra o menu e clique em Máquinas virtuais.
- Clique em Criar instância.
- Crie uma VM chamada
client, selecione um tipo de máquina pequeno e escolha Rocky Linux ou Ubuntu, que vêm com ocurlpré-instalado. - Clique em Criar.
- Aguarde alguns minutos até que a VM esteja pronta.
- Depois que a VM estiver pronta, estabeleça uma conexão SSH com ela:
- No console do GDC, clique na VM.
- Clique em Conectar com SSH.
Verificar o acesso verificado e o roteamento
Para testar o roteamento, execute comandos curl na VM do cliente. É possível
se conectar aos dois aplicativos usando os nomes de host definidos com o endereço IP do balanceador de
carga.
Ao transmitir a flag --resolve no curl, é possível forçar os nomes de domínio a
serem resolvidos para o IP do balanceador de carga L4 do GDC com isolamento físico.
Observe que transmitimos a flag -k para confiar nos certificados autoassinados.
Teste o app conteinerizado do Kubernetes:
curl -k --resolve k8s-app.example.com:443:$LOAD_BALANCER_IP https://k8s-app.example.com -v
Teste o app da VM externa:
curl -k --resolve vm-app.example.com:443:$LOAD_BALANCER_IP https://vm-app.example.com -v
Se configurado corretamente, o controlador de entrada vai atuar perfeitamente como terminador de TLS e transmitir o tráfego para o destino.
Opcional: usar certificados prontos para produção
Nesta seção, mostramos como usar o CA Service do GDC com isolamento físico para criar uma autoridade certificadora (CA) raiz particular, emitir certificados assinados para suas cargas de trabalho e atualizar com segurança o cluster padrão e as VMs de cliente do GDC com isolamento físico.
Nesta seção, descrevemos como usar o CA Service do GDC com isolamento físico para criar uma autoridade certificadora raiz particular e emitir certificados válidos para seus aplicativos. Ao instalar essa CA raiz na VM do cliente, é possível verificar se
o término de TLS funciona perfeitamente com certificados confiáveis, sem precisar
ignorar avisos de SSL (por exemplo, usando curl -k).
Conceder as permissões necessárias e receber credenciais
Para gerenciar o CA Service e emitir certificados, o usuário precisa ter os papéis do IAM apropriados no projeto.
Conceda os papéis
certificate-authority-service-adminecertificate-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-requesterReceba as credenciais do servidor da API Management:
gdcloud clusters get-credentials ${ORG_NAME}-admin
Criar a CA raiz
Você vai criar uma autoridade certificadora no servidor da API de gerenciamento no namespace do projeto.
Aplique o recurso
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'
Emitir e implantar certificados
Depois que a CA estiver pronta, você vai solicitar certificados para o app conteinerizado e o app baseado em VM. Essas solicitações acontecem no servidor de API de gerenciamento, e as chaves resultantes precisam ser movidas para o cluster padrão.
Crie solicitações para os dois domínios:
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
Aguarde alguns instantes até que os certificados sejam emitidos. É possível verificar se eles estão prontos quando a condição "Ready" é "True":
km get certificaterequests -n ${PROJECT_ID}
Atualizar o cluster padrão
Se você seguiu as seções anteriores deste guia, tem secrets autoassinados no cluster padrão. Exclua-as antes de criar as novas versões assinadas:
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
Agora, extraia os certificados assinados do servidor da API Management e crie os novos secrets no cluster padrão.
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
Os novos secrets serão obtidos automaticamente e atualizados pelos balanceadores de carga.
Configurar a confiança do cliente
Para verificar a configuração, informe à VM cliente que ela deve confiar na nova CA raiz.
Extraia o certificado de CA raiz para um arquivo:
km get secret -n ${PROJECT_ID} my-root-ca-secret \
-o jsonpath='{.data.tls\.crt}' \
| base64 -d > my-root-ca.crt
Transfira o certificado para a VM do cliente. É possível copiar o conteúdo de my-root-ca.crt e colá-lo em um arquivo na VM do cliente.
Na VM do cliente, atualize o repositório de confiança.
Se a VM client for 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
Se a VM client for Rocky Linux:
sudo cp my-root-ca.crt /etc/pki/ca-trust/source/anchors/
sudo update-ca-trust
Verifique o acesso
Agora é possível acessar os aplicativos usando curl sem a flag -k. A
conexão será totalmente confiável.
Teste o app conteinerizado do k8s:
curl -v --resolve k8s-app.example.com:443:LOAD_BALANDER_IP https://k8s-app.example.com
Teste o app da VM:
curl -v --resolve vm.example.com:443:LOAD_BALANDER_IP https://vm-app.example.com
Se for bem-sucedido, você verá a saída do aplicativo imediatamente, sem avisos de certificado SSL.