En esta página se explica cómo configurar varios certificados SSL para recursos Ingress en clústeres de Google Kubernetes Engine (GKE).
Información general
Si quieres aceptar solicitudes HTTPS de tus clientes, el balanceador de carga de aplicaciones debe tener un certificado para poder demostrar su identidad a tus clientes. El balanceador de carga también debe tener una clave privada para completar el handshake de HTTPS.
Cuando el balanceador de carga acepta una solicitud HTTPS de un cliente, el tráfico entre el cliente y el balanceador de carga se cifra mediante TLS. Sin embargo, el balanceador de carga finaliza el cifrado TLS y reenvía la solicitud sin cifrar a la aplicación. Cuando configuras un balanceador de carga de aplicaciones a través de Ingress, puedes configurar el balanceador de carga para que presente hasta 15 certificados TLS al cliente.
El balanceador de carga usa la indicación del nombre de servidor (SNI) para determinar qué certificado debe presentar al cliente en función del nombre de dominio del handshake de TLS. Si el cliente no usa SNI o si usa un nombre de dominio que no coincide con el nombre común (CN) de uno de los certificados, el balanceador de carga usará el primer certificado que aparezca en el recurso Ingress.
En el siguiente diagrama se muestra el balanceador de carga que envía tráfico a diferentes backends en función del nombre de dominio utilizado en la solicitud:
Puedes proporcionar a un balanceador de carga de aplicaciones certificados SSL mediante los siguientes métodos:
Certificados SSL gestionados por Google Consulta la página de certificados gestionados para obtener información sobre cómo usarlos.
Trusted Cloud by S3NS Certificado SSL que gestionas tú. El certificado SSL usa un certificado precompartido que subes a tu Trusted Cloud by S3NS proyecto.
Secretos de Kubernetes. El secreto contiene un certificado y una clave que creas tú mismo. Añade el nombre del secreto al campo
tls
del archivo de manifiesto de Ingress.
Puedes usar más de un método en el mismo Ingress. Esto permite realizar migraciones sin tiempo de inactividad entre métodos.
Perspectiva general
A continuación, se muestra un resumen de los pasos que se describen en este documento:
Crea un despliegue.
Crea un servicio.
Crea dos archivos de certificado y dos archivos de clave, o dos objetos
ManagedCertificate
. Debes configurar estos certificados en el mismo proyecto y en el mismo espacio de nombres en el que se haya implementado el balanceador de carga.Crea un Ingress que use secretos o certificados precompartidos. Cuando creas el Ingress, GKE crea y configura un balanceador de carga de aplicaciones.
Prueba el balanceador de carga de aplicación.
Antes de empezar
Antes de empezar, asegúrate de que has realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si quieres usar Google Cloud CLI para esta tarea, instálala y, a continuación, inicialízala. Si ya has instalado la gcloud CLI, obtén la versión más reciente ejecutando
gcloud components update
.
- Debes tener dos nombres de dominio. Los nombres de dominio no pueden tener más de 63 caracteres.
- Asegúrate de que tienes un clúster Autopilot o Standard. Para crear un clúster, consulta Crear un clúster de Autopilot.
Limitaciones
Los certificados gestionados por Google solo se admiten con Ingress de GKE mediante el balanceador de carga de aplicaciones externo. Los certificados gestionados por Google no admiten controladores Ingress de terceros.
En el caso de los balanceadores de carga de aplicaciones internos, debes inhabilitar HTTP en el manifiesto de Ingress. No es necesario para el balanceador de carga externo.
No debes cambiar ni actualizar manualmente la configuración del balanceador de carga de aplicaciones. Esto significa que no debe editar ninguno de los componentes del balanceador de carga, incluidos los proxies de destino, los mapas de URLs y los servicios de backend. GKE sobrescribe los cambios que hagas.
Crear un despliegue
Guarda el siguiente archivo de manifiesto 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 manifiesto describe un Deployment con tres pods. Cada pod tiene dos contenedores. Un contenedor ejecuta
hello-app:1.0
y escucha en el puerto TCP 50001. El otro contenedor ejecutahello-app:2.0
y escucha en el puerto TCP 50002.Aplica el manifiesto a tu clúster:
kubectl apply -f my-mc-deployment.yaml
Crea un servicio
Guarda el siguiente archivo de manifiesto 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 manifiesto describe un servicio con los siguientes campos:
selector
: especifica que cualquier pod que tenga la etiquetaapp: products
y la etiquetadepartment: sales
es miembro de este servicio.ports
: especifica que, cuando un cliente envía una solicitud al servicio enmy-first-port
, GKE reenvía la solicitud a uno de los Pods miembros en el puerto 50001. Cuando un cliente envía una solicitud al servicio enmy-second-port
, GKE reenvía la solicitud a uno de los pods miembros en el puerto 50002.
Aplica el manifiesto a tu clúster:
kubectl apply -f my-mc-service.yaml
Crear certificados y claves
Para hacer los ejercicios de esta página, necesitas dos certificados, cada uno con una clave correspondiente. Cada certificado debe tener un nombre común (CN) que sea igual a un nombre de dominio de tu propiedad.
Puedes crear esos certificados manualmente o usar certificados gestionados por Google.
Si ya tiene dos archivos de certificado con los valores adecuados para Nombre común, puede pasar a la siguiente sección.
Certificados gestionados por el usuario
Crea tu primera clave:
openssl genrsa -out test-ingress-1.key 2048
Crea tu primera solicitud de firma de certificado:
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=FIRST_DOMAIN"
Sustituye
FIRST_DOMAIN
por un nombre de dominio que te pertenezca, comoexample.com
.Crea tu primer certificado:
openssl x509 -req -days 365 -in test-ingress-1.csr -signkey test-ingress-1.key \ -out test-ingress-1.crt
Crea tu segunda clave:
openssl genrsa -out test-ingress-2.key 2048
Crea tu segunda solicitud de firma de certificado:
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=SECOND_DOMAIN"
Sustituye
SECOND_DOMAIN
por otro nombre de dominio que te pertenezca, comoexamplepetstore.com
.Crea tu segundo certificado:
openssl x509 -req -days 365 -in test-ingress-2.csr -signkey test-ingress-2.key \ -out test-ingress-2.crt
Para obtener más información sobre los certificados y las claves, consulta el artículo Información general sobre los certificados SSL.
Ahora tienes dos archivos de certificado y dos archivos de clave.
En las tareas restantes se usan los siguientes marcadores de posición para hacer referencia a tus dominios, certificados y claves:
FIRST_CERT_FILE
: la ruta a tu primer archivo de certificado.FIRST_KEY_FILE
: la ruta al archivo de clave que va con tu primer certificado.FIRST_DOMAIN
: un nombre de dominio que sea de tu propiedad.FIRST_SECRET_NAME
: el nombre del secreto que contiene tu primer certificado y tu primera clave.SECOND_CERT_FILE
: la ruta a tu segundo archivo de certificado.SECOND_KEY_FILE
: la ruta al archivo de clave que corresponde a tu segundo certificado.SECOND_DOMAIN
: un segundo nombre de dominio que sea de tu propiedad.SECOND_SECRET_NAME
: el nombre del secreto que contiene tu segundo certificado y clave.
Certificados gestionados por Google
Para crear certificados gestionados por Google, debes añadir objetos ManagedCertificate
al espacio de nombres de tu Ingress. Puedes usar la siguiente plantilla para definir los certificados de tus dominios:
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
Haz los cambios siguientes:
FIRST_CERT_NAME
: el nombre de tu primer objetoManagedCertificate
.FIRST_DOMAIN
: el primer dominio que tengas.SECOND_CERT_NAME
: el nombre del segundo objetoManagedCertificate
.SECOND_DOMAIN
: el segundo dominio de tu propiedad.
Los nombres de los objetos ManagedCertificate
son diferentes de los nombres de los certificados que crean. Solo necesitas saber los nombres de los objetos ManagedCertificate
para usarlos en tu Ingress.
Especificar certificados para tu Ingress
El siguiente paso es crear un objeto Ingress. En el manifiesto de Ingress, puede usar uno de los siguientes métodos para proporcionar certificados al balanceador de carga:
- Secretos
- Certificados precompartidos
- Certificados gestionados por Google
Secretos
Crea un secreto que contenga tu primer certificado y clave:
kubectl create secret tls FIRST_SECRET_NAME \ --cert=FIRST_CERT_FILE \ --key=FIRST_KEY_FILE
Crea un secreto que contenga tu segundo certificado y tu clave:
kubectl create secret tls SECOND_SECRET_NAME \ --cert=SECOND_CERT_FILE \ --key=SECOND_KEY_FILE
Crear un Ingress
Guarda el siguiente archivo de manifiesto 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
Sustituye
FIRST_DOMAIN
ySECOND_DOMAIN
por nombres de dominio que te pertenezcan, comoexample.com
yexamplepetstore.com
.Aplica el manifiesto a tu clúster:
kubectl apply -f my-mc-ingress.yaml
Describe tu Ingress:
kubectl describe ingress my-mc-ingress
El resultado debería ser similar al siguiente:
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
El resultado muestra que hay dos secretos asociados al Ingress. El resultado también muestra la dirección IP externa del balanceador de carga. Si la dirección IP externa no está definida, espera unos minutos y vuelve a probar el comando.
Certificados precompartidos
Crea un certificado:
gcloud compute ssl-certificates create FIRST_CERT_NAME \ --certificate=FIRST_CERT_FILE \ --private-key=FIRST_KEY_FILE
Haz los cambios siguientes:
FIRST_CERT_NAME
: el nombre de tu primer certificado.FIRST_CERT_FILE
: tu primer archivo de certificado.FIRST_KEY_FILE
: tu primer archivo de claves.
Crea un segundo certificado:
gcloud compute ssl-certificates create SECOND_CERT_NAME \ --certificate=SECOND_CERT_FILE \ --private-key=SECOND_KEY_FILE
Haz los cambios siguientes:
SECOND_CERT_NAME
: el nombre de tu segundo certificado.SECOND_CERT_FILE
: tu segundo archivo de certificado.SECOND_KEY_FILE
: tu segundo archivo de claves.
Consulta los recursos de tu certificado:
gcloud compute ssl-certificates list
El resultado debería ser similar al siguiente:
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
Crear un Ingress
Guarda el siguiente archivo de manifiesto 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
Sustituye
FIRST_DOMAIN
ySECOND_DOMAIN
por los nombres de tus dominios.Este manifiesto describe un Ingress que enumera los recursos de certificados precompartidos en una anotación.
Aplica el manifiesto a tu clúster:
kubectl apply -f my-psc-ingress.yaml
Describe tu Ingress:
kubectl describe ingress my-psc-ingress
El resultado debería ser similar al siguiente:
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
El resultado muestra que el Ingress está asociado a certificados precompartidos llamados
FIRST_CERT_NAME
ySECOND_CERT_NAME
. La salida también muestra la dirección IP externa del balanceador de carga. Si la dirección IP externa no está definida, espera unos minutos y vuelve a probar el comando.
Certificados gestionados por Google
Crear un Ingress
Guarda el siguiente archivo de manifiesto 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
Sustituye
FIRST_DOMAIN
ySECOND_DOMAIN
por los nombres de tus dominios.Este manifiesto describe un Ingress que enumera los recursos de certificados precompartidos en una anotación.
Aplica el manifiesto a tu clúster:
kubectl apply -f my-gmc-ingress.yaml
Describe tu Ingress:
kubectl describe ingress my-gmc-ingress
El resultado debería ser similar al siguiente:
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
La salida muestra que el Ingress está asociado a certificados gestionados llamados
FIRST_CERT_NAME
ySECOND_CERT_NAME
. GKE rellena automáticamente las anotacionesingress.gcp.kubernetes.io/pre-shared-cert
yingress.kubernetes.io/ssl-cert
con los certificados gestionados por Google que has creado con los objetosManagedCertificate
. La salida también muestra la dirección IP externa del balanceador de carga. Si no se ha definido la dirección IP externa, espera unos minutos y vuelve a probar el comando.
Probar el balanceador de carga
Espera unos cinco minutos a que GKE termine de configurar el balanceador de carga.
Si has usado certificados gestionados por Google, puede que la configuración tarde bastante más en completarse, ya que el sistema tiene que aprovisionar los certificados y verificar la configuración de DNS de los dominios en cuestión.
Para probar el balanceador de carga, debes tener dos nombres de dominio y ambos deben resolver la dirección IP externa del balanceador de carga de aplicaciones externo.
Envía una solicitud al balanceador de carga mediante tu primer nombre de dominio:
curl -v https://FIRST_DOMAIN
Es posible que tengas que usar la opción
curl -k
para realizar una transferencia SSL no segura, de forma quecurl
acepte certificados autofirmados.El resultado debería ser similar al siguiente:
... * 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 ...
En este resultado se muestra que tu primer certificado se ha usado en el handshake TLS.
Envía una solicitud al balanceador de carga mediante tu segundo nombre de dominio:
curl -v https://SECOND_DOMAIN
El resultado debería ser similar al siguiente:
... * 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
Esta salida muestra que tu segundo certificado se ha usado en el handshake de TLS.
El campo hosts de un objeto Ingress
Un objeto IngressSpec tiene un campo tls
que es una matriz de objetos IngressTLS. Cada objeto IngressTLS
tiene un campo hosts
y un campo SecretName
.
En GKE, el campo hosts
no se utiliza. GKE lee el nombre común (CN) del certificado en el secreto. Si el nombre común coincide con el nombre de dominio de una solicitud de cliente, el balanceador de carga presenta el certificado correspondiente al cliente.
¿Qué certificado se presenta?
El balanceador de carga elige un certificado según estas reglas:
Si tanto los secretos como los certificados precompartidos se incluyen en el Ingress, los certificados precompartidos tienen prioridad sobre los secretos. Es decir, los secretos se siguen incluyendo, pero los certificados precompartidos se presentan primero.
Si ningún certificado tiene un nombre común (CN) que coincida con el nombre de dominio de la solicitud del cliente, el balanceador de carga presenta el certificado principal.
En el caso de los secretos que aparecen en el bloque
tls
, el certificado principal es el primer secreto de la lista.En el caso de los certificados precompartidos que se indican en la anotación
ingress.gcp.kubernetes.io/pre-shared-cert
, el orden en el que se enumeran los certificados determina el certificado principal. El certificado principal, que se presenta cuando ningún otro certificado coincide con la solicitud del cliente, es el primer certificado que aparece en la anotación.Cuando usas certificados gestionados por Google, todos los certificados que se indican en la anotación
networking.gke.io/managed-certificates
se ordenan automáticamente por nombre en orden alfabético. El certificado principal es el que aparece en primer lugar en esta lista alfabética. Para definir un certificado específico como principal, debes asignar nombres a tus objetosManagedCertificate
de forma que se controle el orden de clasificación. Por ejemplo, para quemy-default-cert
sea el principal en lugar deanother-cert
, puedes llamarlos0-my-default-cert
y1-another-cert
.
Prácticas recomendadas para la rotación de certificados
Si quieres rotar el contenido de tu secreto o certificado precompartido, te recomendamos que sigas estas prácticas:
- Crea un secreto o un certificado precompartido con otro nombre que contenga los nuevos datos del certificado. Adjunta este recurso (junto con el que ya tienes) a tu Ingress siguiendo las instrucciones que se han proporcionado anteriormente. Cuando estés conforme con los cambios, puedes quitar el certificado antiguo del Ingress.
- Si no te importa interrumpir el tráfico, puedes quitar el recurso antiguo del Ingress, aprovisionar un recurso nuevo con el mismo nombre, pero con contenido diferente, y, a continuación, volver a adjuntarlo al Ingress.
Para no tener que gestionar la rotación de certificados, consulta el artículo Usar certificados SSL gestionados por Google.
Solución de problemas
Si se especifican secretos no válidos o que no existen, se produce un error de evento de Kubernetes. Para consultar los eventos de Kubernetes de un Ingress, sigue estos pasos:
kubectl describe ingress
El resultado debería ser similar al siguiente:
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'
Siguientes pasos
Consulta la información general sobre la red de GKE.
Consulta cómo configurar nombres de dominio con direcciones IP estáticas.
Consulta cómo usar certificados SSL gestionados por Google.
Si tienes una aplicación que se ejecuta en varios clústeres de GKE en diferentes regiones, configura un Ingress multiclúster para dirigir el tráfico a un clúster de la región más cercana al usuario.