Esta página mostra como configurar vários certificados SSL para recursos de entrada em clusters do Google Kubernetes Engine (GKE).
Vista geral
Se quiser aceitar pedidos HTTPS dos seus clientes, o Application Load Balancer tem de ter um certificado para poder provar a sua identidade aos seus clientes. O balanceador de carga também tem de ter uma chave privada para concluir o handshake HTTPS.
Quando o balanceador de carga aceita um pedido HTTPS de um cliente, o tráfego entre o cliente e o balanceador de carga é encriptado através do protocolo TLS. No entanto, o balanceador de carga termina a encriptação TLS e encaminha o pedido sem encriptação para a aplicação. Quando configura um balanceador de carga de aplicações através do Ingress, pode configurar o balanceador de carga para apresentar até 15 certificados TLS ao cliente.
O balanceador de carga usa a Indicação do nome do servidor (SNI) para determinar que certificado apresentar ao cliente, com base no nome do domínio na negociação TLS. Se o cliente não usar SNI ou se usar um nome de domínio que não corresponda ao nome comum (CN) num dos certificados, o balanceador de carga usa o primeiro certificado indicado no Ingress.
O diagrama seguinte mostra o balanceador de carga a enviar tráfego para diferentes back-ends, consoante o nome do domínio usado no pedido:
Pode fornecer um Application Load Balancer com certificados SSL através dos seguintes métodos:
Certificados SSL geridos pela Google. Consulte a página de certificados geridos para ver informações sobre como os usar.
Trusted Cloud by S3NS Certificado SSL gerido por si. O certificado SSL usa um certificado pré-partilhado que carrega para o seu Trusted Cloud by S3NS projeto.
Kubernetes Secrets. O segredo contém um certificado e uma chave que cria. Adicione o nome do segredo ao campo
tls
do manifesto do Ingress.
Pode usar mais do que um método no mesmo Ingress. Isto permite migrações sem tempo de inatividade entre métodos.
O panorama geral
Segue-se uma vista geral dos passos descritos neste documento:
Crie uma implementação.
Crie um serviço.
Crie dois ficheiros de certificado e dois ficheiros de chave ou dois objetos
ManagedCertificate
. Tem de configurar estes certificados no mesmo projeto e no mesmo espaço de nomes onde o equilibrador de carga está implementado.Crie um Ingress que use segredos ou certificados partilhados previamente. Quando cria o Ingress, o GKE cria e configura um Application Load Balancer.
Teste o balanceador de carga de aplicações.
Antes de começar
Antes de começar, certifique-se de que realizou as seguintes tarefas:
- Ative a API Google Kubernetes Engine. Ative a API Google Kubernetes Engine
- Se quiser usar a CLI gcloud para esta tarefa,
instale-a e, em seguida,
inicialize-a. Se instalou anteriormente a CLI gcloud, execute
gcloud components update
para obter a versão mais recente.
- Tem de ser proprietário de dois nomes de domínio. Os nomes de domínio não podem ter mais de 63 carateres.
- Certifique-se de que tem um cluster do Autopilot ou Standard existente. Para criar um novo cluster, consulte o artigo Crie um cluster do Autopilot.
Limitações
Os certificados geridos pela Google só são suportados com o GKE Ingress através do Application Load Balancer externo. Os certificados geridos pela Google não suportam controladores Ingress de terceiros.
Para balanceadores de carga de aplicações internos, tem de desativar o HTTP no manifesto de entrada. Isto não é necessário para o balanceador de carga externo.
Não deve alterar nem atualizar manualmente a configuração do Application Load Balancer. Isto significa que não pode editar nenhum dos componentes do equilibrador de carga, incluindo proxies de destino, mapas de URLs e serviços de back-end. Quaisquer alterações que fizer são substituídas pelo GKE.
Crie uma implementação
Guarde o seguinte manifesto como
my-mc-deployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: my-mc-deployment spec: selector: matchLabels: app: products department: sales replicas: 3 template: metadata: labels: app: products department: sales spec: containers: - name: hello image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0" env: - name: "PORT" value: "50001" - name: hello-again image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0" env: - name: "PORT" value: "50002"
Este manifesto descreve uma implementação com três pods. Cada pod tem dois contentores. Um contentor executa o
hello-app:1.0
e ouve na porta TCP 50001. O outro contentor executa ohello-app:2.0
e ouve na porta TCP 50002.Aplique o manifesto ao cluster:
kubectl apply -f my-mc-deployment.yaml
Crie um serviço
Guarde o seguinte manifesto como
my-mc-service.yaml
:apiVersion: v1 kind: Service metadata: name: my-mc-service spec: type: NodePort selector: app: products department: sales ports: - name: my-first-port protocol: TCP port: 60001 targetPort: 50001 - name: my-second-port protocol: TCP port: 60002 targetPort: 50002
Este manifesto descreve um serviço com os seguintes campos:
selector
: especifica que qualquer Pod que tenha a etiquetaapp: products
e a etiquetadepartment: sales
é membro deste serviço.ports
: especifica que, quando um cliente envia um pedido ao serviço emmy-first-port
, o GKE encaminha o pedido para um dos pods membros na porta 50001. Quando um cliente envia um pedido para o Serviço emmy-second-port
, o GKE encaminha o pedido para um dos pods membros na porta 50002.
Aplique o manifesto ao cluster:
kubectl apply -f my-mc-service.yaml
Crie certificados e chaves
Para fazer os exercícios nesta página, precisa de dois certificados, cada um com uma chave correspondente. Cada certificado tem de ter um nome comum (CN) igual a um nome de domínio que lhe pertence.
Pode criar esses certificados manualmente ou usar certificados geridos pela Google.
Se já tiver dois ficheiros de certificado com os valores adequados para o nome comum, pode avançar para a secção seguinte.
Certificados geridos pelo utilizador
Crie a sua primeira chave:
openssl genrsa -out test-ingress-1.key 2048
Crie o seu primeiro pedido de assinatura de certificado:
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=FIRST_DOMAIN"
Substitua
FIRST_DOMAIN
por um nome de domínio que lhe pertença, comoexample.com
.Crie o seu primeiro certificado:
openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \ -out test-ingress-1.crt
Crie a sua segunda chave:
openssl genrsa -out test-ingress-2.key 2048
Crie o segundo pedido de assinatura de certificado:
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=SECOND_DOMAIN"
Substitua-o por outro nome de domínio que lhe pertença, como
examplepetstore.com
.SECOND_DOMAIN
Crie o seu segundo certificado:
openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \ -out test-ingress-2.crt
Para mais informações acerca de certificados e chaves, consulte a vista geral dos certificados SSL.
Agora, tem dois ficheiros de certificado e dois ficheiros de chave.
As restantes tarefas usam os seguintes marcadores de posição para fazer referência aos seus domínios, certificados e chaves:
FIRST_CERT_FILE
: o caminho para o ficheiro do seu primeiro certificado.FIRST_KEY_FILE
: o caminho para o ficheiro de chave que acompanha o seu primeiro certificado.FIRST_DOMAIN
: um nome de domínio do qual é proprietário.FIRST_SECRET_NAME
: o nome do segredo que contém o seu primeiro certificado e chave.SECOND_CERT_FILE
: o caminho para o seu segundo ficheiro de certificado.SECOND_KEY_FILE
: o caminho para o ficheiro de chave que corresponde ao seu segundo certificado.SECOND_DOMAIN
: um segundo nome de domínio que lhe pertence.SECOND_SECRET_NAME
: o nome do segredo que contém o seu segundo certificado e chave.
Certificados geridos pela Google
Para criar certificados geridos pela Google, tem de adicionar ManagedCertificate
objetos ao espaço de nomes do seu Ingress. Pode usar o seguinte modelo para definir certificados para os seus domínios:
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: FIRST_CERT_NAME
spec:
domains:
- FIRST_DOMAIN
---
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
name: SECOND_CERT_NAME
spec:
domains:
- SECOND_DOMAIN
Substitua o seguinte:
FIRST_CERT_NAME
: o nome do seu primeiro objetoManagedCertificate
.FIRST_DOMAIN
: o primeiro domínio que detém.SECOND_CERT_NAME
: o nome do segundo objetoManagedCertificate
.SECOND_DOMAIN
: o segundo domínio que detém.
Os nomes dos objetos ManagedCertificate
são diferentes dos nomes dos certificados reais que criam. Só precisa de saber os nomes dos objetos ManagedCertificate
para os usar no seu Ingress.
Especifique certificados para o seu Ingress
O passo seguinte é criar um objeto Ingress. No manifesto do Ingress, pode usar um dos seguintes métodos para fornecer certificados para o equilibrador de carga:
- Secrets
- Certificados pré-partilhados
- Certificados geridos pela Google
Secrets
Crie um Secret que contenha o seu primeiro certificado e chave:
kubectl create secret tls FIRST_SECRET_NAME \ --cert=FIRST_CERT_FILE \ --key=FIRST_KEY_FILE
Crie um Secret que contenha o seu segundo certificado e chave:
kubectl create secret tls SECOND_SECRET_NAME \ --cert=SECOND_CERT_FILE \ --key=SECOND_KEY_FILE
Crie um Ingress
Guarde o seguinte manifesto como
my-mc-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-mc-ingress spec: tls: - secretName: FIRST_SECRET_NAME - secretName: SECOND_SECRET_NAME rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002
Substitua
FIRST_DOMAIN
eSECOND_DOMAIN
por nomes de domínio que lhe pertencem, por exemplo,example.com
eexamplepetstore.com
.Aplique o manifesto ao cluster:
kubectl apply -f my-mc-ingress.yaml
Descreva a sua entrada no Ingress:
kubectl describe ingress my-mc-ingress
O resultado é semelhante ao seguinte:
Name: my-mc-ingress Address: 203.0.113.1 ... TLS: FIRST_SECRET_NAME terminates SECOND_SECRET_NAME terminates Rules: Host Path Backends ---- ---- -------- FIRST_DOMAIN my-mc-service:my-first-port (<none>) SECOND_DOMAIN my-mc-service:my-second-port (<none>) Annotations: ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 3m loadbalancer-controller default/my-mc-ingress Normal CREATE 2m loadbalancer-controller ip: 203.0.113.1
O resultado mostra que existem dois segredos associados ao Ingress. O resultado também mostra o endereço IP externo do balanceador de carga. Se o endereço IP externo não estiver definido, aguarde alguns minutos e experimente o comando novamente.
Certificados pré-partilhados
Crie um certificado:
gcloud compute ssl-certificates create FIRST_CERT_NAME \ --certificate=FIRST_CERT_FILE \ --private-key=FIRST_KEY_FILE
Substitua o seguinte:
FIRST_CERT_NAME
: o nome do seu primeiro certificado.FIRST_CERT_FILE
: o seu primeiro ficheiro de certificado.FIRST_KEY_FILE
: o seu primeiro ficheiro de chave.
Crie um segundo certificado:
gcloud compute ssl-certificates create SECOND_CERT_NAME \ --certificate=SECOND_CERT_FILE \ --private-key=SECOND_KEY_FILE
Substitua o seguinte:
SECOND_CERT_NAME
: o nome do seu segundo certificado.SECOND_CERT_FILE
: o segundo ficheiro de certificado.SECOND_KEY_FILE
: o seu segundo ficheiro de chave.
Veja os recursos do certificado:
gcloud compute ssl-certificates list
O resultado é semelhante ao seguinte:
NAME CREATION_TIMESTAMP FIRST_CERT_NAME 2018-11-03T12:08:47.751-07:00 SECOND_CERT_NAME 2018-11-03T12:09:25.359-07:00
Crie um Ingress
Guarde o seguinte manifesto como
my-psc-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-psc-ingress annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002
Substitua
FIRST_DOMAIN
eSECOND_DOMAIN
pelos seus nomes de domínios.Este manifesto descreve um Ingress que lista recursos de certificados pré-partilhados numa anotação.
Aplique o manifesto ao cluster:
kubectl apply -f my-psc-ingress.yaml
Descreva a sua entrada no Ingress:
kubectl describe ingress my-psc-ingress
O resultado é semelhante ao seguinte:
Name: my-psc-ingress Address: 203.0.113.2 ... Rules: Host Path Backends ---- ---- -------- FIRST_DOMAIN my-mc-service:my-first-port (<none>) SECOND_DOMAIN my-mc-service:my-second-port (<none>) Annotations: ... ingress.gcp.kubernetes.io/pre-shared-cert: FIRST_CERT_NAME,SECOND_CERT_NAME ... ingress.kubernetes.io/ssl-cert: FIRST_CERT_NAME,SECOND_CERT_NAME Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m loadbalancer-controller default/my-psc-ingress Normal CREATE 1m loadbalancer-controller ip: 203.0.113.2
O resultado mostra que o Ingress está associado a certificados partilhados previamente com os nomes
FIRST_CERT_NAME
eSECOND_CERT_NAME
. O resultado também mostra o endereço IP externo do balanceador de carga. Se o endereço IP externo não estiver definido, aguarde alguns minutos e experimente o comando novamente.
Certificados geridos pela Google
Crie um Ingress
Guarde o seguinte manifesto como
my-gmc-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-gmc-ingress annotations: networking.gke.io/managed-certificates: "FIRST_CERT_NAME,SECOND_CERT_NAME" spec: rules: - host: FIRST_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60001 - host: SECOND_DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: my-mc-service port: number: 60002
Substitua
FIRST_DOMAIN
eSECOND_DOMAIN
pelos seus nomes de domínios.Este manifesto descreve um Ingress que lista recursos de certificados pré-partilhados numa anotação.
Aplique o manifesto ao cluster:
kubectl apply -f my-gmc-ingress.yaml
Descreva a sua entrada no Ingress:
kubectl describe ingress my-gmc-ingress
O resultado é semelhante ao seguinte:
Name: my-gmc-ingress Address: 203.0.113.2 ... Rules: Host Path Backends ---- ---- -------- FIRST_DOMAIN my-mc-service:my-first-port (<none>) SECOND_DOMAIN my-mc-service:my-second-port (<none>) Annotations: ... ingress.gcp.kubernetes.io/pre-shared-cert: mcrt-a6e41ce4-2b39-4334-84ce-867ff543c424,mcrt-bbff4116-f014-4800-a43a-4095bffeb4f4 ... ingress.kubernetes.io/ssl-cert: mcrt-a6e41ce4-2b39-4334-84ce-867ff543c424,mcrt-bbff4116-f014-4800-a43a-4095bffeb4f4 networking.gke.io/managed-certificates: FIRST_CERT_NAME,SECOND_CERT_NAME Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m loadbalancer-controller default/my-gmc-ingress Normal CREATE 1m loadbalancer-controller ip: 203.0.113.2
O resultado mostra que o Ingress está associado a certificados geridos com os nomes
FIRST_CERT_NAME
eSECOND_CERT_NAME
. O GKE preenche automaticamente as anotaçõesingress.gcp.kubernetes.io/pre-shared-cert
eingress.kubernetes.io/ssl-cert
com os certificados geridos pela Google que criou através dos objetosManagedCertificate
. O resultado também mostra o endereço IP externo do equilibrador de carga. Se o endereço IP externo não estiver definido, aguarde alguns minutos e experimente o comando novamente.
Teste o balanceador de carga
Aguarde cerca de cinco minutos para que o GKE termine a configuração do balanceador de carga.
Se usou certificados geridos pela Google, a conclusão da configuração pode demorar consideravelmente mais tempo, uma vez que o sistema tem de aprovisionar os certificados e validar a configuração de DNS para os domínios indicados.
Para testar o equilibrador de carga, tem de ter dois nomes de domínio e ambos os nomes de domínio têm de resolver o endereço IP externo do equilibrador de carga de aplicações externo.
Envie um pedido ao balanceador de carga através do seu primeiro nome de domínio:
curl -v https://FIRST_DOMAIN
Pode ter de usar a opção
curl -k
para fazer uma transferência SSL não segura, para que ocurl
aceite certificados autoassinados.O resultado é semelhante ao seguinte:
... * Trying 203.0.113.1... ... * Connected to FIRST_DOMAIN (203.0.113.1) port 443 (#0) ... * TLSv1.2 (IN), TLS handshake, Certificate (11): ... * Server certificate: * subject: CN=FIRST_DOMAIN ... > Host: FIRST_DOMAIN.com ... Hello, world! Version: 1.0.0 ...
Este resultado mostra que o seu primeiro certificado foi usado no handshake TLS.
Envie um pedido ao balanceador de carga através do segundo nome de domínio:
curl -v https://SECOND_DOMAIN
O resultado é semelhante ao seguinte:
... * Trying 203.0.113.1... ... * Connected to SECOND_DOMAIN (203.0.113.1) port 443 (#0) ... * Server certificate: * subject: CN=SECOND_DOMAIN ... > Host: SECOND_DOMAIN ... Hello, world! Version: 2.0.0
Este resultado mostra que o seu segundo certificado foi usado na negociação de TLS.
O campo hosts de um objeto Ingress
Um
IngressSpec
tem um campo tls
que é uma matriz de objetos
IngressTLS. Cada objeto IngressTLS
tem um campo hosts
e um campo SecretName
.
No GKE, o campo hosts
não é usado. O GKE lê o nome comum (CN) do certificado no segredo. Se o nome comum corresponder ao nome de domínio num pedido do cliente, o equilibrador de carga apresenta o certificado correspondente ao cliente.
Que certificado é apresentado?
O balanceador de carga escolhe um certificado de acordo com estas regras:
Se os segredos e os certificados pré-partilhados estiverem listados no Ingress, os certificados pré-partilhados têm prioridade sobre os segredos. Por outras palavras, os segredos continuam a ser incluídos, mas os certificados pré-partilhados são apresentados primeiro.
Se nenhum certificado tiver um nome comum (CN) que corresponda ao nome do domínio no pedido do cliente, o equilibrador de carga apresenta o certificado principal.
Para os segredos listados no bloco
tls
, o certificado principal encontra-se no primeiro segredo da lista.Para os certificados partilhados previamente indicados na anotação
ingress.gcp.kubernetes.io/pre-shared-cert
, a ordem pela qual indica os certificados determina o certificado principal. O certificado principal, que é apresentado quando nenhum outro certificado corresponde ao pedido do cliente, é o primeiro certificado apresentado na anotação.Quando usa certificados geridos pela Google, todos os certificados listados na anotação
networking.gke.io/managed-certificates
são automaticamente ordenados alfabeticamente por nome. O certificado principal é o que aparece primeiro nesta lista alfabética. Para definir um certificado específico como o principal, tem de atribuir nomes aos objetosManagedCertificate
em conformidade para controlar a ordem de ordenação. Por exemplo, para tornarmy-default-cert
o principal em relação aanother-cert
, pode atribuir-lhes os nomes0-my-default-cert
e1-another-cert
.
Práticas recomendadas para a rotação de certificados
Se quiser rodar o conteúdo do seu segredo ou certificado pré-partilhado, seguem-se algumas práticas recomendadas:
- Crie um novo Secret ou um certificado pré-partilhado com um nome diferente que contenha os novos dados do certificado. Anexe este recurso (juntamente com o existente) ao seu Ingress através das instruções fornecidas anteriormente. Quando estiver satisfeito com as alterações, pode remover o certificado antigo do Ingress.
- Se não se importar de interromper o tráfego, pode remover o recurso antigo do Ingress, aprovisionar um novo recurso com o mesmo nome, mas conteúdos diferentes e, em seguida, voltar a anexá-lo ao Ingress.
Para evitar gerir a rotação de certificados, consulte o artigo Use certificados SSL geridos pela Google.
Resolução de problemas
A especificação de secrets inválidos ou inexistentes resulta num erro de evento do Kubernetes. Pode verificar os eventos do Kubernetes para um Ingress da seguinte forma:
kubectl describe ingress
O resultado é semelhante ao seguinte:
Name: my-ingress
Namespace: default
Address: 203.0.113.3
Default backend: hello-server:8080 (10.8.0.3:8080)
TLS:
my-faulty-Secret terminates
Rules:
Host Path Backends
---- ---- --------
* * my-service:443 (10.8.0.3:443)
Events:
Error during sync: cannot get certs for Ingress default/my-ingress:
Secret "my-faulty-ingress" has no 'tls.crt'
O que se segue?
Leia a vista geral da rede do GKE.
Saiba como configurar nomes de domínios com endereços IP estáticos.
Saiba como usar certificados SSL geridos pela Google.
Se tiver uma aplicação em execução em vários clusters do GKE em diferentes regiões, configure um Multi Cluster Ingress para encaminhar o tráfego para um cluster na região mais próxima do utilizador.