Skip to content

Kubernetes Networking

Desarrollo del tema

La presente guía explora el uso de los componentes de Networking de Kubernetes (Service/Ingress) y su correcta configuracion para usar con TLS.

Laboratorio: Service

Descripción

El laboratorio aborda la creacion y configuracion de componente Service y su uso dentro de la red del cluster.

Objetivos

  • Crear un Deployment a partir de un archivo YAML.

  • Crear y asignar un Service al Deployment a partir de un archivo YAML.

Antes de comenzar

  • Contar con el acceso al ambiente de laboratorio

Conexión hacia cluster

  1. Ingrese al cluster asignado con las credenciales proporcionadas.

  2. Configure la variable KUBECONFIG.

    export KUBECONFIG=~/devcluster/kube_config_cluster.yml
    
  3. Verifique el acceso mediante comandos.

    kubectl get namespaces
    

Inicio de laboratorio

  1. Cree una carpeta llamada k8s-networking y ubíquese en ella

    mkdir k8s-networking ; cd k8s-networking
    

  2. Cree un archivo llamado deployment.yaml con el siguiente contenido

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: basic-api
      namespace: userx
      labels:
        app: basic-api
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: basic-api
      template:
        metadata:
          labels:
            app: basic-api
        spec:
          containers:
            - name: basic-api
              image: quay.io/rlam/api-demo:1.0-producer
              ports:
                - containerPort: 8080
    

  3. Cree un archivo llamado service.yaml con el siguiente contenido

    1
    2
    3
    4
    5
    6
    apiVersion: v1
    kind: Service
    metadata:
      name: basic-api-service
      namespace: userx
    spec:
    

  4. Agregue un bloque en spec llamado selector con un key-value app: basic-api

    1
    2
    3
    4
    5
    6
    7
    8
    apiVersion: v1
    kind: Service
    metadata:
      name: basic-api-service
      namespace: userx
    spec:
      selector:
        app: basic-api
    

  5. Agregue un bloque en spec llamado ports con una lista de la siguiente forma

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    apiVersion: v1
    kind: Service
    metadata:
      name: basic-api-service
      namespace: userx
    spec:
      selector:
        app: basic-api
      ports:
        - name: http
          protocol: TCP
          port: 8080
          targetPort: 8080
    

  6. Levante los recursos

    kubectl apply -f deployment.yaml
    kubectl apply -f service.yaml
    

  7. Revise los Services en el namespace

    kubectl get services
    

  8. Cree un archivo llamado consumer-deployment.yaml con el siguiente contenido

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: api-consumer
      namespace: userx
      labels:
        app: api-consumer
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: api-consumer
      template:
        metadata:
          labels:
            app: api-consumer
        spec:
          containers:
            - name: api-consumer
              image: quay.io/rlam/api-demo:1.0-consumer
              ports:
                - containerPort: 8080
    

  9. Agergue un bloque en spec.template.spec.containers[0] llamado env con la siguiente lista

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: api-consumer
      namespace: userx
      labels:
        app: api-consumer
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: api-consumer
      template:
        metadata:
          labels:
            app: api-consumer
        spec:
          containers:
            - name: api-consumer
              image: quay.io/rlam/api-demo:1.0-consumer
              ports:
                - containerPort: 8080
              env:
                - name: API_URL
                  value: "http://basic-api-service:8080/api/v1"
    

  10. Levante el Deployment ejecutando

    kubectl apply -f consumer-deployment.yaml
    

  11. Revise los pods en el namespace

    kubectl get pods -l app=api-consumer
    

  12. Revise los logs del Deployment del consumer

    # Cambie nombre-pod por el nombre del Pod
    kubectl logs nombre-pod
    

  13. Ingrese al Pod del consumer y ejecute un request a su api

    kubectl exec -it nombre-pod -- curl localhost:8080/api/v2/acquisitions/consume
    

  14. Edite el archivo service.yaml en la lista spec.ports de la siguiente forma

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    apiVersion: v1
    kind: Service
    metadata:
      name: basic-api-service
      namespace: userx
    spec:
      selector:
        app: basic-api
      ports:
        - name: http
          protocol: TCP
          port: 8084
          targetPort: 8080
    

  15. Sincronize los cambios

    kubectl apply -f service.yaml
    

  16. Revise el Service

    kubectl describe service basic-api-service
    

  17. Genere un Pod nuevo reescalando el deployment

    kubectl scale deploy/api-consumer --replicas=0
    kubectl scale deploy/api-consumer --replicas=1
    

  18. Ingrese al Pod del consumer y ejecute un request a su api (debe fallar)

    kubectl exec -it nombre-pod -- curl localhost:8080/api/v2/acquisitions/consume
    

  19. Cambie el valor del puerto de la variable API_URL en consumer-deployment.yaml por 8084

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: api-consumer
      namespace: userx
      labels:
        app: api-consumer
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: api-consumer
      template:
        metadata:
          labels:
            app: api-consumer
        spec:
          containers:
            - name: api-consumer
              image: quay.io/rlam/api-demo:1.0-consumer
              ports:
                - containerPort: 8080
              env:
                - name: API_URL
                  value: "http://basic-api-service:8084/api/v1"
    

  20. Sincronize los cambios

    kubectl apply -f consumer-deployment.yaml
    

  21. Revise los pods

    kubectl get pods -l app=api-consumer -w
    ^Ctrl+C
    

  22. Revise los logs

    # Cambie nombre-pod por el nombre del Pod
    kubectl logs nombre-pod
    

  23. Ingrese al Pod del consumer y ejecute un request a su api

    kubectl exec -it nombre-pod -- curl localhost:8080/api/v2/acquisitions/consume
    

  24. Edite el service regresando al puerto 8080

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    apiVersion: v1
    kind: Service
    metadata:
      name: basic-api-service
      namespace: userx
    spec:
      selector:
        app: basic-api
      ports:
        - name: http
          protocol: TCP
          port: 8080
          targetPort: 8080
    

  25. Edite el consumer-deployment regresando la variable al puerto 8080

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: api-consumer
      namespace: userx
      labels:
        app: api-consumer
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: api-consumer
      template:
        metadata:
          labels:
            app: api-consumer
        spec:
          containers:
            - name: api-consumer
              image: quay.io/rlam/api-demo:1.0-consumer
              ports:
                - containerPort: 8080
              env:
                - name: API_URL
                  value: "http://basic-api-service:8080/api/v1"
    

  26. Sincronize los cambios

    kubectl apply -f service.yaml
    kubectl apply -f consumer-deployment.yaml
    

Laboratorio: Ingress

Descripción

El laboratorio aborda la creacion y configuracion del componente Ingress y su uso dentro de la red del cluster.

Objetivos

  • Crear y asignar un Ingress a un Service a partir de un archivo YAML
  • Configurar acceso seguro por TLS

Antes de comenzar

  • Contar con el acceso al ambiente de laboratorio
  • Haber completado el primer laboratorio de Networking (Service)

Inicio de laboratorio

  1. Cree un archivo nuevo llamado ingress.yaml con el siguiente contenido

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: basic-api-ingress
      namespace: userx
    spec:
      rules:
      - host: "basic-api.example.com" # Cambiar .example.com por un host valido
        http:
          paths:
          - path: /api/v1
            pathType: Prefix
            backend:
              service:
                name: basic-api-service
                port:
                  number: 8080
    

  2. Asegurese que los pods de basic-api todavia esten arriba

    kubectl get pods -l app=basic-api
    

  3. Levante el Ingress

    kubectl apply -f ingress.yaml
    

  4. Revise los Ingresses en el namespace

    kubectl get ingress
    

  5. Revise los eventos del namespace

    kubectl get events
    

  6. Ingrese a la URL del Ingress o haga un request mediante cURL

    curl http://basic-api.example.com/api/v1/acquisitions # Cambiar basic-api.example.com por el host real
    

  7. Edite el archivo service.yaml agregando otro recurso de Service

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    apiVersion: v1
    kind: Service
    metadata:
      name: basic-api-service
      namespace: userx
    spec:
      selector:
        app: basic-api
      ports:
        - name: http
          protocol: TCP
          port: 8080
          targetPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: api-consumer-service
      namespace: userx
    spec:
      selector:
        app: api-consumer
      ports:
        - name: http
          protocol: TCP
          port: 8080
          targetPort: 8080
    

  8. Sincronize los cambios

    kubectl apply -f service.yaml
    

  9. Observe un nuevo Service en el namespace

    kubectl get services
    

  10. Edite el archivo ingress.yaml agregando un path en spec.rules[0] para el service basic-api-v2-service

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: basic-api-ingress
      namespace: userx
    spec:
      rules:
      - host: "basic-api.example.com" # Cambiar .example.com por un host valido
        http:
          paths:
          - path: /api/v1
            pathType: Prefix
            backend:
              service:
                name: basic-api-service
                port:
                  number: 8080
          - path: /api/v2
            pathType: Prefix
            backend:
              service:
                name: api-consumer-service
                port:
                  number: 8080
    

  11. Sincronize los cambios

    kubectl apply -f ingress.yaml
    

  12. Realize el request desde el navegador o mediante cURL hacia http://basic-api.example.com/api/v1/acquisitions y http://basic-api.example.com/api/v2/acquisitions/consume

    # Cambiar .example.com por un host valido
    curl -i http://basic-api.example.com/api/v1/acquisitions
    curl -i http://basic-api.example.com/api/v2/acquisitions/consume
    

TLS

  1. Cree un directorio llamado ssl

    mkdir ssl ; cd ssl
    

  2. Revise que tenga el comando openssl

    openssl
    

  3. Cree la llave y certificado auto firmados

    openssl req -x509 -newkey rsa:4096 -keyout private.key -out cert.crt -sha256 -days 365 -nodes
    

Campos requeridos

Utilice cualquier valor para los valores o inclusive deje vacio si desea a excepcion del campo CN este debe de contener el dominio o IP a resolver

  1. Cree un Secret que contenga la llave y certificados

    kubectl create secret tls widlcard-tls \
    --key private.key --cert cert.crt --dry-run=client -o yaml \
    | kubectl apply -f -
    
    cd ..
    

  2. Edite el archivo ingress.yaml agregando el bloque tls en spec

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: basic-api-ingress
      namespace: userx
    spec:
      tls:
        - hosts:
          - basic-api.example.com
          secretName: wildcard-tls
      rules:
      - host: "basic-api.example.com" # Cambiar .example.com por un host valido
        http:
          paths:
          - path: /api/v1
            pathType: Prefix
            backend:
              service:
                name: basic-api-service
                port:
                  number: 8080
          - path: /api/v2
            pathType: Prefix
            backend:
              service:
                name: api-consumer-service
                port:
                  number: 8080
    

  3. Sincronize los cambios

    kubectl apply -f ingress.yaml
    

  4. Revise la información del Ingress

    kubectl describe ingress basic-api-ingress
    

  5. Acceda a la url desde el navegador o haciendo un request mediante cURL y observe el certificado que se ocupa

Debe aceptar el certificado en la pantalla de advertencia Posteriormente, acceda al icono de candado a un lado de la URL y obtenga el detalle del certificado

# Cambie basci-api.example.com por el dominio real
curl -kvI https://basic-api.example.com/api/v1/acquisitions

curl -ki https://basic-api.example.com/api/v1/acquisitions
  1. Limpie el ambiente
    find /home/student/k8s-networking/ -name '*.yaml' -exec bash -c 'file=$1; kubectl delete -f $1' _ {} \;