Tutoriales

Fundamentos de la pila de red de Kubernetes: cómo se comunican los contenedores dentro de un pod

Muchos administradores de sistemas ven las redes como uno de los elementos más complejos en un entorno de Kubernetes. Esto es especialmente cierto cuando se aloja su propio clúster de Kubernetes en lugar de pagar por él.

Adaptarse al paradigma de los microservicios, donde los servicios dependen en gran medida de la red para la comunicación, requiere fundamentos de red extensos. Si bien las habilidades de redes muy básicas son parte de la caja de herramientas de cada administrador de sistemas, los administradores de sistemas rara vez tienen una comprensión profunda de las redes. Esto hace que sea más difícil razonar sobre las complejas topologías de red que a menudo acompañan a los entornos de Kubernetes.

En esta serie de artículos, lo guiaré a través de las diferentes capas de la pila de redes de Kubernetes y veré cómo se comunican los contenedores, los pods y los nodos. Estos artículos se centrarán en profundizar en estos conceptos mediante el uso de herramientas como la captura de paquetes para comprender realmente el tráfico que pasa por la red.

Si bien operar un clúster de Kubernetes normal rara vez requiere un conocimiento profundo, este conocimiento puede ayudarlo a mantener y solucionar problemas de cargas de trabajo que se ejecutan en Kubernetes.

Conceptos básicos de redes de pods

La unidad de trabajo básica en un clúster de Kubernetes es el Pod, que proporciona un punto de partida ideal para comprender las redes de Kubernetes. Un pod consta de uno o más contenedores que comparten un espacio de nombres específico.

Puede parecer extraño tener varios contenedores en un pod, pero este enfoque es bastante común.por ejemplo, un Inicializar el contenedor Puede ejecutarse antes de que el contenedor de la aplicación comience a realizar la configuración de la carga de trabajo. Esta configuración puede incluir la obtención de secretos del almacén de secretos o la realización de otra configuración de tiempo de ejecución que no se puede integrar fácilmente en la imagen del contenedor. Este enfoque también es común en las mallas de servicios, donde los contenedores sidecar se ejecutan junto con los contenedores de aplicaciones para proporcionar capacidades de red avanzadas.

LEER  Cómo guardar un archivo en Vim / Vi sin permiso de root con sudo
Publicaciones relacionadas

[ Learn how to manage your Linux environment for success. ]

Desde una perspectiva de red, cada contenedor en un pod comparte el mismo espacio de nombres de red. Esto permite que cada contenedor acceda a los mismos recursos de red, como la dirección IP del pod. Los contenedores en el mismo pod también pueden comunicarse entre sí a través de localhost.

(Anthony Critley, CC BY-SA 4.0)

Para comprender mejor cómo funciona esto en la práctica, iniciaré algunos pods y examinaré sus pilas de red.

Vaina multicontenedor

Este artículo usa minikube para construir rápidamente un clúster para pruebas. Si no ha usado minikube antes, es fácil de instalar. Un clúster de un solo nodo con la configuración predeterminada es suficiente para este laboratorio:

$ minikube start
😄  minikube v1.25.2 on Ubuntu 20.04
✨  Automatically selected the kvm2 driver. Other choices: virtualbox, ssh
👍  Starting control plane node minikube in cluster minikube
🔥  Creating kvm2 VM (CPUs=2, Memory=3900MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.23.3 on Docker 20.10.12 ...
    ▪ kubelet.housekeeping-interval=5m
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: default-storageclass, storage-provisioner
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

[ Cheat sheet: Get a list of Linux utilities and commands for managing servers and networks. ]

Para comprender cómo se comunican los contenedores en un pod, necesita un pod con varios contenedores. Este artículo usa un pod simple con dos contenedores: Nginx y BusyBox. El contenedor Nginx sirve la página web predeterminada y el contenedor BusyBox duerme indefinidamente:

$ cat nginx_busybox.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-busybox
spec:
  containers:
  - command:
    - sleep
    - infinity
    image: busybox
    name: busybox
  - image: nginx
    name: nginx
    
$ kubectl apply -f nginx_busybox.yaml 
pod/nginx-busybox created

$ kubectl get pods
NAME            READY   STATUS    RESTARTS   AGE
nginx-busybox   2/2     Running   0          17s

Una vez que el pod se ejecuta correctamente, puede conectarse a él e iniciar un shell para mirar alrededor. Primero, confirme que BusyBox puede comunicarse con Nginx a través de localhost:

$ kubectl exec -it -c busybox nginx-busybox -- /bin/sh

/ # wget localhost -O - 2>/dev/null



Welcome to nginx!



Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

Thank you for using nginx.

Se puede acceder a Nginx a través de localhost y sirve una página predeterminada.una examinacion netstat La salida confirma que algo está escuchando en el puerto 80. Sin embargo, el contenedor BusyBox no puede ver el ID del proceso en ejecución:

/ # netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -
tcp        0      0 :::80                   :::*                    LISTEN      -

El ID del proceso no está visible porque el contenedor BusyBox se ejecuta en un espacio de nombres de proceso diferente al del contenedor Nginx.Sin embargo, puede iniciar un shell en el contenedor de Nginx y ver el ID del proceso (después de la instalación). netstat en un recipiente):

$ kubectl exec -it -c nginx nginx-busybox -- /bin/bash
root@nginx-busybox:/# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1/nginx: master pro 
tcp6       0      0 :::80                   :::*                    LISTEN      1/nginx: master pro 

Comprobar espacio de nombres

Hasta ahora, este artículo ha analizado varios aspectos de las redes desde una perspectiva de contenedor. Pero, ¿cómo se ve esto en el host? Para comprender la configuración del espacio de nombres desde la perspectiva del host, primero debe obtener la identificación del contenedor de cada contenedor dentro del pod:

$ kubectl get pod -o json nginx-busybox | jq .status.containerStatuses[].containerID
"docker://1d77670aebe59cdcc0f1f538e3e9e7a33b179abd1311c4230bbea69eea65eb02"
"docker://b34908dad17f3a139678520d367aa81786a2b8c74531a2b93b9c221a038b7a1e"

[ Download now: Advanced Linux commands cheat sheet. ]

Cada contenedor se puede verificar usando minikube ssh Conéctese a una instancia de minikube en ejecución. Minikube usa el tiempo de ejecución de Docker de forma predeterminada y puede usar los comandos estándar de Docker para obtener el ID de proceso del contenedor.Estos ID de proceso se pueden pasar a lsns Muestre los diferentes espacios de nombres en los que se ejecuta cada contenedor:

# Connect to minikube over SSH
$ minikube ssh
                         _             _            
            _         _ ( )           ( )           
  ___ ___  (_)  ___  (_)| |/')  _   _ | |_      __  
/' _ ` _ `\| |/' _ `\| || , <  ( ) ( )| '_`\  /'__`\
| ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )(  ___/
(_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)

# Obtain the process ID of each container in the pod
$ docker inspect 1d77670aebe59cdcc0f1f538e3e9e7a33b179abd1311c4230bbea69eea65eb02 | jq .[].State.Pid
4590
$ docker inspect b34908dad17f3a139678520d367aa81786a2b8c74531a2b93b9c221a038b7a1e | jq .[].State.Pid
4685

# Obtain the namespaces for each process
$ sudo lsns -p 4590
        NS TYPE   NPROCS   PID USER  COMMAND
4026531835 cgroup    124     1 root  /sbin/init noembed norestore
4026531837 user      124     1 root  /sbin/init noembed norestore
4026532463 ipc         5  4513 65535 /pause
4026532466 net         5  4513 65535 /pause
4026532573 mnt         1  4590 root  sleep infinity
4026532574 uts         1  4590 root  sleep infinity
4026532575 pid         1  4590 root  sleep infinity
$ sudo lsns -p 4685
        NS TYPE   NPROCS   PID USER  COMMAND
4026531835 cgroup    124     1 root  /sbin/init noembed norestore
4026531837 user      124     1 root  /sbin/init noembed norestore
4026532463 ipc         5  4513 65535 /pause
4026532466 net         5  4513 65535 /pause
4026532576 mnt         3  4685 root  nginx: master process nginx -g daemon off;
4026532577 uts         3  4685 root  nginx: master process nginx -g daemon off;
4026532578 pid         3  4685 root  nginx: master process nginx -g daemon off;

Este resultado muestra la configuración desde la perspectiva del host.Los contenedores comparten un la red Espacios de nombres (4026532466), pero funcionan de manera diferente proceso Espacios de nombres (4026532575 y 4026532578). Esto explica por qué los contenedores dentro de un pod pueden comunicarse entre sí a través de localhost, pero no pueden ver los ID de proceso de los demás.

envolver

Un pod es la unidad de trabajo básica en un clúster de Kubernetes, y comprender el funcionamiento general de su pila de red es fundamental para comprender cómo se comunican las cargas de trabajo de Kubernetes.

Si bien un solo pod puede parecer una estructura muy simple, este artículo ha demostrado que se puede hacer mucho más en un pod en la parte inferior de la pila de redes de Linux. Además, la capacidad de los contenedores en un pod para comunicarse a través de direcciones de host local permite patrones como contenedores sidecar e init.

El próximo artículo de esta serie cubrirá cómo los Pods se comunican entre sí a través de múltiples nodos de Kubernetes.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba