Crea un Service y un Ingress

En esta página, se muestra cómo crear un objeto Ingress de Kubernetes en un clúster de usuario de clústeres de Anthos alojados en VMware (GKE On-Prem). Un objeto Ingress debe estar asociado con uno o más objetos Service, cada uno de los cuales está asociado con un conjunto de Pods.

Establece una conexión SSH a la estación de trabajo de administrador

Para establecer una conexión SSH a tu estación de trabajo de administrador, ejecuta lo siguiente:

ssh -i ~/.ssh/vsphere_workstation ubuntu@[IP_ADDRESS]

En el ejemplo anterior, [IP_ADDRESS] es la dirección IP de tu estación de trabajo de administrador.

Realiza todos los pasos restantes de este instructivo en la estación de trabajo de administrador.

Crea un Deployment

A continuación, se muestra el 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"

A los fines de este ejercicio, estos son los puntos importantes que debes comprender sobre el manifiesto de Deployment:

  • Cada Pod que pertenece al Deployment tiene la etiqueta greeting: hello.

  • Cada Pod tiene dos contenedores.

  • En los campos env, se especifica que los contenedores hello-app escuchan en el puerto TCP 50000, y los contenedores node-hello escuchan en el puerto TCP 8080. En el caso de hello-app, puedes ver el efecto de la variable de entorno PORT si observas el código fuente.

Copia el manifiesto en un archivo llamado hello-deployment.yaml y crea el Deployment:

kubectl apply --kubeconfig [USER_CLUSTER_KUBECONFIG] -f hello-deployment.yaml

En el ejemplo anterior, [USER_CLUSTER_KUBECONFIG] es el archivo kubeconfig para el clúster de usuario.

Expón el Deployment con un Service

A fin de proporcionar una forma estable para que los clientes envíen solicitudes a los Pods de tu Deployment, crea un Service.

Este es un manifiesto para un Service que expone tu Deployment a los clientes dentro y fuera del clúster:

apiVersion: v1
kind: Service
metadata:
  name: hello-service
spec:
  type: NodePort
  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 Service:

kubectl apply --kubeconfig [USER_CLUSTER_KUBECONFIG] -f hello-service.yaml

Observa el Service:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] get service hello-service --output yaml

El resultado muestra los valores nodePort que se asignaron al Service:

apiVersion: v1
kind: Service
metadata:
  ...
  name: hello-service
  namespace: default
  ...
spec:
  clusterIP: 10.105.252.237
  externalTrafficPolicy: Cluster
  ports:
  - name: world-port
    nodePort: 31807
    port: 60000
    protocol: TCP
    targetPort: 50000
  - name: kubernetes-port
    nodePort: 30734
    port: 60001
    protocol: TCP
    targetPort: 8080
  selector:
    greeting: hello
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer:
    ingress:
    - {}

En el resultado anterior, el campo ports es un arreglo de objetos ServicePort: uno llamado world-port y otro kubernetes-port.

Estas son las formas en que un cliente puede llamar al Service mediante world-port:

  • Un cliente que se ejecuta en uno de los nodos del clúster puede enviar una solicitud a clusterIP en port. En este ejemplo, 10.105.252.237:60000. La solicitud se reenvía a un Pod miembro en targetPort. En este ejemplo, [POD_IP_ADDRESS]:50000.

  • Un cliente puede enviar una solicitud a la dirección IP de cualquier nodo de clúster en nodePort. En este ejemplo, [NODE_IP_ADDRESS]:31807. La solicitud se reenvía a un Pod miembro en targetPort. En este ejemplo, [POD_IP_ADDRESS]:50000.

Estas son las formas en que un cliente puede llamar al Service mediante kubernetes-port:

  • Un cliente que se ejecuta en uno de los nodos del clúster puede enviar una solicitud a clusterIP en port. En este ejemplo, 10.105.252.237:60001. La solicitud se reenvía a un Pod miembro en targetPort. En este ejemplo, [POD_IP_ADDRESS]:8080.

  • Un cliente puede enviar una solicitud a la dirección IP de cualquier nodo de clúster en nodePort. En este ejemplo, [NODE_IP_ADDRESS]:30734. La solicitud se reenvía a un Pod miembro en targetPort. En este ejemplo, [POD_IP_ADDRESS]:8080.

Crea un Ingress

A continuación, se muestra el 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

Como parte de la creación de tu clúster de usuario, especificaste una dirección IP virtual (VIP) para Ingress mediante un valor para usercluster.vips.ingressvip en tu archivo de configuración de clúster de usuario.

Cuando un cliente envía una solicitud a tu VIP de entrada del clúster de usuario, la solicitud se enruta al balanceador de cargas de BIG-IP de F5. El balanceador de cargas reenvía la solicitud a un Service de entrada que se ejecuta en el clúster de usuario. El Service de entrada está configurado para reenviar la solicitud a diferentes backends según la ruta en la URL de la solicitud.

Es importante comprender que hay dos objetos Service diferentes relacionados con los pasos de este tema:

  • El Service llamado hello-service. Este es un Service que creaste para exponer los Pods de tu Deployment hello-deployment.

  • El Service de entrada que se ejecuta en el espacio de nombres gke-system de tu clúster de usuario. Este es parte de la infraestructura del clúster.

La ruta /greet-the-world

En el manifiesto de Ingress, puedes ver una regla que indica que la ruta /greet-the-world está asociada con serviceName: hello-service y servicePort: 60000. Recuerda que 60000 es el valor de port en el campo world-port del Service hello-service.

- name: world-port
    nodePort: 31807
    port: 60000
    protocol: TCP
    targetPort: 50000

El Service de entrada elige un nodo de clúster y reenvía la solicitud al nodo en nodePort. En este ejemplo, [NODE_IP_ADDRESS]:31807. Las reglas de iptables en el nodo reenvían la solicitud a un Pod miembro en el puerto 50000. El contenedor que escucha en el puerto 50000 muestra un mensaje Hello World!.

La ruta /greet-kubernetes

En el manifiesto de Ingress, puedes ver una regla que indica que la ruta /greet-kubernetes está asociada con serviceName: hello-service y servicePort: 60001. Recuerda que 60001 es el valor de port en el campo kubernetes-port del Service hello-service.

- name: kubernetes-port
    nodePort: 30734
    port: 60001
    protocol: TCP
    targetPort: 8080

El Service de entrada elige un nodo de clúster y reenvía la solicitud al nodo en nodePort. En este ejemplo, [NODE_IP_ADDRESS]:30734. Las reglas de iptables en el nodo reenvían la solicitud a un Pod miembro en el puerto 8080. El contenedor que escucha en el puerto 8080 muestra un mensaje Hello Kubernetes!.

Prueba el Ingress:

Prueba el Ingress con la ruta /greet-the-world:

curl [USER_CLUSTER_INGRESS_VIP]/greet-the-world

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!

Realice una limpieza

Borra el Ingress:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete ingress my-ingress

Borra el Service:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete service hello-service

Borra el Deployment:

kubectl --kubeconfig [USER_CLUSTER_KUBECONFIG] delete deployment hello-deployment