En este documento se muestra cómo crear un objeto Ingress de Kubernetes en un clúster de usuario de Google Distributed Cloud. Un Ingress se asocia a uno o varios Services, cada uno de los cuales se asocia a un conjunto de Pods.
Antes de empezar
Obtén una conexión SSH con tu estación de trabajo de administrador:
Crear un despliegue
Aquí tienes un manifiesto de un Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment
spec:
  selector:
    matchLabels:
      greeting: hello
  replicas: 3
  template:
    metadata:
      labels:
        greeting: hello
    spec:
      containers:
      - name: hello-world
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"
      - name: hello-kubernetes
        image: "gcr.io/google-samples/node-hello:1.0"
        env:
        - name: "PORT"
          value: "8080"
En este ejercicio, estos son los puntos importantes que debes conocer sobre el manifiesto de la implementación:
- Cada pod que pertenece a la implementación tiene la etiqueta - greeting: hello.
- Cada pod tiene dos contenedores. 
- Los campos - envespecifican que los contenedores- hello-appescuchan en el puerto TCP 50000 y los contenedores- node-helloescuchan en el puerto TCP 8080. En el caso de- hello-app, puedes ver el efecto de la variable de entorno- PORTconsultando el código fuente de la aplicación Hello.
Copia el manifiesto en un archivo llamado hello-deployment.yaml y crea la implementación:
kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f hello-deployment.yaml
donde USER_CLUSTER_KUBECONFIG es la ruta del archivo kubeconfig de tu clúster de usuario.
Exponer un Deployment con un Service
Para que los clientes puedan enviar solicitudes a los pods de tu Deployment de forma estable, crea un servicio.
A continuación, se muestra un manifiesto de un servicio que expone tu implementación a los clientes de tu clúster:
apiVersion: v1
kind: Service
metadata:
  name: hello-service
spec:
  type: ClusterIP
  selector:
    greeting: hello
  ports:
  - name: world-port
    protocol: TCP
    port: 60000
    targetPort: 50000
  - name: kubernetes-port
    protocol: TCP
    port: 60001
    targetPort: 8080
Copia el manifiesto en un archivo llamado hello-service.yaml y crea el servicio:
kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f hello-service.yaml
Ver el servicio:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service hello-service --output yaml
El resultado muestra el valor de clusterIP que se ha asignado al servicio.
Por ejemplo:
apiVersion: v1
kind: Service
metadata:
  annotations:
    ...
spec:
  clusterIP: 10.96.14.249
  clusterIPs:
  - 10.96.14.249
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: world-port
    port: 60000
    protocol: TCP
    targetPort: 50000
  - name: kubernetes-port
    port: 60001
    protocol: TCP
    targetPort: 8080
  selector:
    greeting: hello
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
En el resultado anterior, el campo ports es un array de objetos de Kubernetes ServicePort: uno llamado world-port y otro llamado kubernetes-port.
Estas son las formas en las que un cliente puede llamar al Servicio:
- Uso de - world-port: un cliente que se ejecuta en uno de los nodos del clúster envía una solicitud a- clusterIPen- port. En este ejemplo, 10.96.14.249:60000. La solicitud se reenvía a un pod miembro el- targetPort. En este ejemplo, POD_IP_ADDRESS:50000.
- Uso de - kubernetes-port: un cliente que se ejecuta en uno de los nodos del clúster envía una solicitud a- clusterIPen- port. En este ejemplo: 10.96.14.249:60001. La solicitud se reenvía a un pod miembro el- targetPort. En este ejemplo, POD_IP_ADDRESS:8080.
Componentes de Ingress
Estos son algunos de los componentes del clúster relacionados con el ingreso:
- La - istio-ingressimplementación. Este es el proxy de entrada. El proxy de entrada reenvía el tráfico a los servicios internos según las reglas especificadas en un objeto Ingress.
- El servicio - istio-ingress. Este servicio expone el- istio-ingressDeployment.
- La - istiodimplementación. Este es el controlador de entrada. El controlador de entrada monitoriza la creación de objetos Ingress y configura el proxy de entrada en consecuencia.
Crear un Ingress
Aquí tienes un manifiesto de un Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /greet-the-world
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60000
      - path: /greet-kubernetes
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60001
Copia el manifiesto en un archivo llamado my-ingress.yaml y crea el Ingress:
kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-ingress.yaml
Cuando creas un clúster de usuarios, especificas un valor para
loadbalancer.ingressVip en el archivo de configuración del clúster. Esta dirección IP está configurada en el balanceador de carga del clúster. Cuando creas un Ingress, se le asigna la misma IP virtual como dirección IP externa.
Cuando un cliente envía una solicitud a la dirección IP virtual de entrada de tu clúster de usuario, la solicitud se enruta a tu balanceador de carga. El balanceador de carga usa el servicio istio-ingress para reenviar la solicitud al proxy de entrada, que se ejecuta en tu clúster de usuario. El proxy de entrada está configurado para reenviar la solicitud a diferentes back-ends en función de la ruta de la URL de la solicitud.
Ruta /greet-the-world
En el manifiesto de Ingress, puedes ver una regla que indica que la ruta /greet-the-world está asociada a serviceName: hello-service y servicePort: 60000. Recuerda que 60000 es el valor de port en la sección world-port
de tu servicio hello-service.
- name: world-port
    port: 60000
    protocol: TCP
    targetPort: 50000
El servicio de entrada reenvía la solicitud a clusterIP:50000. A continuación, la solicitud se envía a uno de los pods miembros del servicio hello-service. El contenedor de ese pod, que escucha en el puerto 50000, muestra un mensaje Hello World!.
Ruta /greet-kubernetes
En el manifiesto de Ingress, puedes ver una regla que indica que la ruta /greet-kubernetes está asociada a serviceName: hello-service y servicePort: 60001. Recuerda que 60001 es el valor de port en la sección kubernetes-port de tu servicio hello-service.
- name: kubernetes-port
    port: 60001
    protocol: TCP
    targetPort: 8080
El servicio de entrada reenvía la solicitud a clusterIP: 8080. A continuación, la solicitud se envía a uno de los pods miembros del servicio hello-service. El contenedor de ese pod, que escucha en el puerto 8080, muestra un mensaje Hello Kubernetes!.
Probar el objeto Ingress
Prueba el Ingress con la ruta /greet-the-world:
curl USER_CLUSTER_INGRESS_VIP/greet-the-world
Sustituye USER_CLUSTER_INGRESS_VIP por la dirección IP externa del Ingress.
El resultado muestra un mensaje Hello, world!:
Hello, world! Version: 2.0.0 Hostname: ...
Prueba el Ingress con la ruta /greet-kubernetes:
curl USER_CLUSTER_INGRESS_VIP/greet-kubernetes
El resultado muestra un mensaje Hello, Kubernetes!:
Hello Kubernetes!
Configurar HTTPS para Ingress
Si quieres aceptar solicitudes HTTPS de tus clientes, el proxy de entrada debe tener un certificado para poder demostrar su identidad a tus clientes. Este proxy también debe tener una clave privada para completar el handshake de HTTPS.
En el siguiente ejemplo se usan estas entidades:
- Proxy de Ingress: participa en el handshake de HTTPS y, a continuación, reenvía paquetes a los pods miembros del servicio - hello-service.
- Dominio del servicio - hello-service: altostrat.com en Ejemplo de organización
Sigue estos pasos:
- Crea un certificado raíz y una clave privada. En este ejemplo se usa una autoridad de certificación raíz de - root.ca.example.comen Root CA Example Org.- openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Root CA Example Inc./CN=root.ca.example.com' -keyout root-ca.key -out root-ca.crt 
- Crea una solicitud de firma de certificado: - openssl req -out server.csr -newkey rsa:2048 -nodes -keyout server.key -subj "/CN=altostrat.com/O=Example Org" 
- Crea un certificado de servicio para el proxy de entrada. - openssl x509 -req -days 365 -CA root-ca.crt -CAkey root-ca.key -set_serial 0 -in server.csr -out server.crt - Ahora has creado los siguientes certificados y claves: - root-ca.crt: certificado de la AC raíz
- root-ca.key: clave privada de la CA raíz
- server.crt: Certificado de servicio del proxy de entrada
- server.key: clave privada del proxy de entrada
 
- Crea un secreto de Kubernetes que contenga el certificado y la clave de servicio. - kubectl create secret tls example-server-creds --key=server.key --cert=server.crt --namespace gke-system - El secreto resultante se llama - example-server-creds.
Crear un despliegue y un servicio
Si has creado una implementación y un servicio en la parte HTTP de esta guía, déjalos como están. Si no lo has hecho, créalas ahora siguiendo los pasos descritos para HTTP.
Crear un Ingress
Crear un Ingress para HTTPS es similar a crear un Ingress para HTTP, pero la especificación de Ingress para HTTPS incluye una sección tls
que especifica el host y un Secret. Los hosts de la sección tls deben coincidir explícitamente con los host de la sección rules.
Si tu servicio de backend está en un espacio de nombres independiente, debes crear un servicio de tipo ExternalName en el mismo espacio de nombres que el Ingress para enrutar el tráfico al servicio de backend.
Si has creado un Ingress en la parte HTTP, elimínalo antes de continuar.
Elimina el Ingress:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete ingress my-ingress
Para gestionar el tráfico del servicio que has creado anteriormente, crea un nuevo recurso Ingress que tenga una sección tls. De esta forma, se habilitará HTTPS entre los clientes y el proxy de entrada.
Aquí tienes un manifiesto de un Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress-2
spec:
  tls:
  - hosts:
    - altostrat.com
    secretName: example-server-creds
  rules:
  - host: altostrat.com
    http:
      paths:
      - path: /greet-the-world
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60000
      - path: /greet-kubernetes
        pathType: Exact
        backend:
          service:
            name: hello-service
            port:
              number: 60001
Guarda el manifiesto en un archivo llamado my-ingress-2.yaml y crea el Ingress:
kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-ingress-2.yaml
Confirma la acción haciendo una prueba.
- Prueba la ruta /greet-the-world: - curl -v --resolve altostrat.com:443:USER_CLUSTER_INGRESS_VIP https://altostrat.com/greet-the-world --cacert root-ca.crt - Resultado: - Hello, world! Version: 2.0.0 Hostname: hello-deployment-5ff7f68854-wqzp7 
- Prueba la ruta - /greet-kubernetes:- curl -v --resolve altostrat.com:443:USER_CLUSTER_INGRESS_VIP https://altostrat.com/greet-kubernetes --cacert root-ca.crt - Resultado: - Hello Kubernetes! 
Eliminar los recursos utilizados
Eliminar tu Ingress:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete ingress INGRESS_NAME
Sustituye INGRESS_NAME por el nombre del Ingress, como my-ingress o my-ingress-2.
Eliminar tu Servicio:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service hello-service
Eliminar tu implementación:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment hello-deployment