Descripción general
El balanceador de cargas HTTP(S) finaliza las conexiones SSL y TLS del cliente y, luego, balancea las solicitudes en tus Pods. Cuando configuras un balanceador de cargas HTTP(S) a través de [Ingress], puedes configurarlo para que presente hasta diez certificados TLS al cliente.
El balanceador de cargas usa la indicación de nombre del servidor (SNI, por sus siglas en inglés) para determinar qué certificado presentar al cliente, según el nombre de dominio en el protocolo de enlace TLS. Si el cliente no usa SNI o usa un nombre de dominio que no coincide con el nombre común (CN) en uno de los certificados, el balanceador de cargas usa el primer certificado que se encuentra en el Ingress. En el siguiente diagrama, se muestra un balanceador de cargas que envía tráfico a backends diferentes, según el nombre de dominio usado en la solicitud:
Puedes especificar certificados para un Ingress mediante uno de los siguientes métodos:
Secretos de Kubernetes
Certificados ya compartidos que subiste con anterioridad a tu proyecto de Google Cloud Platform
No puedes usar ambos métodos al mismo tiempo. Debes usar el mismo método para especificar todos los certificados.
Versión mínima de GKE
Debes tener una versión de GKE 1.10.2 o posterior para usar certificados ya compartidos o especificar varios certificados en un Ingress.
Panorama general
A continuación, hay una descripción general de los pasos en este tema:
Crea una implementación
Crea un servicio
Crea dos archivos de certificado y dos archivos de claves.
Crea un Ingress que use Secretos o certificados ya compartidos. Como resultado de la creación de un Ingress, GKE crea y configura un balanceador de cargas HTTP(S).
Prueba el balanceador de cargas HTTP(S).
Antes de comenzar
Sigue estos pasos a fin de prepararte para esta tarea:
- Asegúrate de que habilitaste la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Asegúrate de que instalaste el SDK de Cloud.
- Establece tu ID del proyecto predeterminado:
gcloud config set project [PROJECT_ID]
- Si trabajas con clústeres zonales, establece tu zona de procesamiento predeterminada:
gcloud config set compute/zone [COMPUTE_ZONE]
- Si trabajas con clústeres regionales, establece tu región de procesamiento predeterminada:
gcloud config set compute/region [COMPUTE_REGION]
- Actualiza
gcloud
a la versión más reciente:gcloud components update
Crea una implementación
A continuación, se muestra un manifiesto para una implementación:
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: "gcr.io/google-samples/hello-app:2.0"
env:
- name: "PORT"
value: "50001"
- name: hello-again
image: "gcr.io/google-samples/node-hello:1.0"
env:
- name: "PORT"
value: "50002"
La implementación tiene tres Pods y cada Pod tiene dos contenedores. Un contenedor ejecuta hello-app
y escucha en el puerto TCP 50001. El otro contenedor ejecuta node-hello
y escucha en el puerto TCP 50002.
Copia el manifiesto a un archivo llamado my-mc-deployment.yaml
y crea la implementación:
kubectl apply -f my-mc-deployment.yaml
Crea un servicio
A continuación, se detalla un manifiesto para un servicio.
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
El campo selector
en el manifiesto de servicio indica que cualquier Pod que tenga las etiquetas app: products
y department: sales
es miembro de este servicio. Por lo tanto, los Pods de la implementación que creaste en el paso anterior son miembros del servicio.
El campo ports
del manifiesto de servicio es un arreglo de objetos de ServicePort. Cuando un cliente envía una solicitud al servicio en my-first-port
, la solicitud se reenvía a uno de los Pods miembros en el puerto 50001. Cuando un cliente envía una solicitud al servicio en my-second-port
, la solicitud se reenvía a uno de los Pods miembros en el puerto 50002.
Copia el manifiesto a un archivo llamado my-mc-service.yaml
y crea el servicio:
kubectl apply -f my-mc-service.yaml
Crea certificados y claves
Para hacer los ejercicios en esta página, necesitas dos certificados, cada uno con una clave correspondiente. Cada certificado debe tener un nombre común (CN, por sus siglas en inglés) que sea igual a un nombre de dominio de tu propiedad. Si ya tienes dos archivos de certificado con los valores adecuados para el nombre común, puedes pasar a la siguiente sección.
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_NAME]"
en la que [FIRST_DOMAIN_NAME]
es un nombre de dominio de tu propiedad o un nombre de dominio falso.
Por ejemplo, supongamos que deseas que el balanceador de cargas entregue las solicitudes de your-store.example. Tu solicitud de firma de certificado se vería de la siguiente manera:
openssl req -new -key test-ingress-1.key -out test-ingress-1.csr \ -subj "/CN=your-store.example"
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_NAME]"
en la que [SECOND_DOMAIN]
es otro nombre de dominio de tu propiedad o un nombre de dominio falso.
Por ejemplo, supongamos que deseas que el balanceador de cargas entregue las solicitudes de your-experimental-store.example. Tu solicitud de firma de certificado se vería de la siguiente manera:
openssl req -new -key test-ingress-2.key -out test-ingress-2.csr \ -subj "/CN=your-experimental-store.example"
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 la creación de tus certificados y claves, consulta Obtén una clave privada y un certificado firmado.
Ahora tienes dos archivos de certificado y dos archivos de claves. En los pasos restantes en esta tarea, se usan estos marcadores de posición para referirse a tus dominios, archivos de certificado y archivos de claves:
[FIRST_CERT_FILE]
es la ruta a tu primer archivo de certificado.[FIRST_KEY_FILE]
es la ruta al archivo de claves que acompaña a tu primer certificado.[SECOND_CERT_FILE]
es la ruta a tu segundo archivo de certificado.[SECOND_KEY_FILE]
es la ruta al archivo de claves que acompaña a tu segundo certificado.[FIRST_DOMAIN]
es un nombre de dominio de tu propiedad o un nombre de dominio falso.[SECOND_DOMAIN]
es un segundo nombre de dominio de tu propiedad o un segundo nombre de dominio falso.
Especifica certificados para tu Ingress
El paso siguiente es crear un objeto Ingress. En tu manifiesto de Ingress, puedes usar uno de los dos métodos a fin de proporcionar certificados para el balanceador de cargas:
- Secretos
- Certificados ya compartidos
Puedes elegir uno de los dos métodos si seleccionas la pestaña SECRETS
o la pestaña PRE-SHARED CERTS
:
Secretos
Crea Secretos
Crea un Secreto que contenga tu primer certificado y tu primera clave:
kubectl create secret tls my-first-secret \ --cert [FIRST_CERT_FILE] --key [FIRST_KEY_FILE]
Crea un Secreto que contenga tu segundo certificado y tu segunda clave:
kubectl create secret tls my-second-secret \ --cert [SECOND_CERT_FILE] --key [SECOND_KEY_FILE]
Crea un Ingress
A continuación, se detalla un manifiesto para un Ingress.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-mc-ingress
spec:
tls:
- secretName: my-first-secret
- secretName: my-second-secret
rules:
- host: [FIRST_DOMAIN]
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-first-port
- host: [SECOND_DOMAIN]
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-second-port
Copia el manifiesto a un archivo llamado my-mc-ingress.yaml
. Reemplaza [FIRST_DOMAIN]
y [SECOND_DOMAIN]
con nombres de dominio de tu propiedad o nombres de dominio falsos.
Crea el Ingress:
kubectl apply -f my-mc-ingress.yaml
Cuando creas un Ingress, el controlador de entrada de GKE crea un balanceador de cargas HTTP(S). Espera un minuto para que GKE asigne una dirección IP externa al balanceador de cargas.
Describe tu Ingress:
kubectl describe ingress my-mc-ingress
El resultado muestra que dos Secretos están asociados con el Ingress. El resultado también muestra la dirección IP externa del balanceador de cargas.
Name: my-mc-ingress
Address: 203.0.113.1
...
TLS:
my-first-secret terminates
my-second-secret terminates
Rules:
Host Path Backends
---- ---- --------
your-store.example
my-mc-service:my-first-port (<none>)
your-experimental-store.example
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
Certificados ya compartidos
Usa certificados ya compartidos
Crea un recurso de certificado en tu proyecto de Google Cloud Platform:
gcloud compute ssl-certificates create test-ingress-1 \ --certificate [FIRST_CERT_FILE] --private-key [FIRST_KEY_FILE]
donde:
[FIRST_CERT_FILE]
es tu primer archivo de certificado.[FIRST_KEY_FILE]
es tu primer archivo de claves.
Crea un segundo recurso de certificado en tu proyecto de Google Cloud Platform:
gcloud compute ssl-certificates create test-ingress-2 \ --certificate [SECOND_CERT_FILE] --private-key [SECOND_KEY_FILE]
donde:
[SECOND_CERT_FILE]
es tu segundo archivo de certificado.[SECOND_KEY_FILE]
es tu segundo archivo de claves.
Observa tus recursos de certificado:
gcloud compute ssl-certificates list
El resultado muestra que tienes recursos de certificado llamados test-ingres-1
y test-ingress-2
:
NAME CREATION_TIMESTAMP test-ingress-1 2018-11-03T12:08:47.751-07:00 test-ingress-2 2018-11-03T12:09:25.359-07:00
A continuación, se presenta un manifiesto para un Ingress que enumera recursos de certificados ya compartidos en una anotación:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-psc-ingress
annotations:
ingress.gcp.kubernetes.io/pre-shared-cert: "test-ingress-1,test-ingress-2"
spec:
rules:
- host: [FIRST_DOMAIN]
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-first-port
- host: [SECOND_DOMAIN]
http:
paths:
- backend:
serviceName: my-mc-service
servicePort: my-second-port
Copia el manifiesto a un archivo llamado my-psc-ingress.yaml
. Reemplaza [FIRST_DOMAIN]
y [SECOND_DOMAIN]
con tus nombres de dominio o nombres de dominio falsos.
Crea el Ingress:
kubectl apply -f my-psc-ingress.yaml
Espera un minuto para que GKE asigne una dirección IP externa al balanceador de cargas.
Describe tu Ingress:
kubectl describe ingress my-psc-ingress
El resultado muestra que el Ingress está asociado con certificados ya compartidos llamados test-ingress-1
y test-ingress-2
. El resultado también muestra la dirección IP externa del balanceador de cargas:
Name: my-psc-ingress
Address: 203.0.113.2
...
Rules:
Host Path Backends
---- ---- --------
your-store.example
my-mc-service:my-first-port (<none>)
your-experimental-store.example
my-mc-service:my-second-port (<none>)
Annotations:
...
ingress.gcp.kubernetes.io/pre-shared-cert: test-ingress-1,test-ingress-2
...
ingress.kubernetes.io/ssl-cert: test-ingress-1,test-ingress-2
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
Prueba el balanceador de cargas
Espera unos cinco minutos para que GKE termine de configurar el balanceador de cargas.
Para realizar este paso, debes tener dos nombres de dominio y ambos nombres deben resolver la dirección IP externa del balanceador de cargas HTTP(S).
Envía una solicitud al balanceador de cargas mediante tu primer nombre de dominio:
curl -kv https://[FIRST_DOMAIN]
El resultado muestra que tu primer certificado se usó en el protocolo de enlace TLS. Si tu primer dominio es your-store.example, el resultado es similar a lo siguiente:
... * Trying 203.0.113.1... ... * Connected to your-store.example (203.0.113.1) port 443 (#0) ... * TLSv1.2 (IN), TLS handshake, Certificate (11): ... * Server certificate: * subject: CN=your-store.example ... > Host: your-store.example ... < Hello, world! Version: 2.0.0 ...
Envía una solicitud al balanceador de cargas mediante tu segundo nombre de dominio:
curl -kv https://[SECOND_DOMAIN]
El resultado muestra que tu segundo certificado se usó en el protocolo de enlace TLS. Si tu segundo dominio es your-experimental-store.example, el resultado es similar a lo siguiente:
... * Trying 203.0.113.1... ... * Connected to your-experimental-store.example (203.0.113.1) port 443 (#0) ... * Server certificate: * subject: CN=your-experimental-store.example ... > Host: your-experimental-store.example ... Hello Kubernetes!
El campo hosts de un objeto Ingress
Un IngressSpec tiene un campo tls
que es un arreglo de objetos de IngressTLS. Cada objeto IngressTLS
tiene un campo hosts
y un campo SecretName
.
En GKE, el campo hosts
no se usa. GKE lee el nombre común (CN) del certificado en el Secreto. Si el nombre común coincide con el nombre de dominio en una solicitud del cliente, entonces el balanceador de cargas presenta al cliente el certificado coincidente.
¿Qué certificado se presenta?
El balanceador de cargas elige un certificado de acuerdo con las siguientes reglas:
Si los Secretos y los certificados ya compartidos se enumeran en el Ingress, el balanceador de cargas ignora los Secretos y usa la lista de certificados ya compartidos.
Si ningún certificado tiene un nombre común (CN) que coincida con el nombre de dominio en la solicitud del cliente, el balanceador de cargas presenta el certificado principal.
Para los Secretos enumerados en el bloque de
tls
, el certificado principal es el primer Secreto en la lista.Para los certificados ya compartidos que se enumeran en la anotación, el certificado principal es el primer certificado en la lista.
Solución de problemas
Especificar los Secretos no válidos o que no existen genera un error de evento de Kubernetes. Puedes verificar los eventos de Kubernetes para un Ingress de la siguiente manera:
kubectl describe ingress
El resultado es similar al siguiente ejemplo:
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'
Pasos siguientes
Obtén más información sobre el Objeto Ingress de Kubernetes para configurar un balanceador de cargas HTTP(S).
Sigue el instructivo sobre cómo configurar el balanceo de cargas HTTP(S) con Ingress.
Obtén más información sobre cómo configurar una dirección IP estática y un nombre de dominio.
Si tienes una aplicación que se ejecuta en varios clústeres de GKE en regiones diferentes, configura Ingress de varios clústeres para enrutar el tráfico a un clúster en la región más cercana al usuario.