Kubernetes Basics

Fundamentos de Kubernetes

Fundamentos de Kubernetes

¡Apoya a HackTricks y obtén beneficios!

El autor original de esta página es Jorge (lee su publicación original aquí)

Arquitectura y fundamentos

¿Qué hace Kubernetes?

  • Permite ejecutar contenedores en un motor de contenedores.

  • La programación permite que los contenedores sean más eficientes en su misión.

  • Mantiene los contenedores vivos.

  • Permite la comunicación entre contenedores.

  • Permite técnicas de implementación.

  • Maneja volúmenes de información.

Arquitectura

  • Nodo: sistema operativo con pod o pods.

    • Pod: Envoltorio alrededor de un contenedor o varios contenedores. Un pod solo debe contener una aplicación (por lo que generalmente, un pod ejecuta solo 1 contenedor). El pod es la forma en que Kubernetes abstrae la tecnología de contenedores que se ejecuta.

      • Servicio: Cada pod tiene 1 dirección IP interna del rango interno del nodo. Sin embargo, también se puede exponer a través de un servicio. El servicio también tiene una dirección IP y su objetivo es mantener la comunicación entre los pods, por lo que si uno muere, el nuevo reemplazo (con una IP interna diferente) será accesible expuesto en la misma IP del servicio. Se puede configurar como interno o externo. El servicio también actúa como un balanceador de carga cuando 2 pods están conectados al mismo servicio. Cuando se crea un servicio, se pueden encontrar los puntos finales de cada servicio ejecutando kubectl get endpoints

  • Kubelet: Agente primario del nodo. El componente que establece la comunicación entre el nodo y kubectl, y solo puede ejecutar pods (a través del servidor API). El kubelet no administra contenedores que no fueron creados por Kubernetes.

  • Kube-proxy: es el servicio encargado de las comunicaciones (servicios) entre el servidor API y el nodo. La base es un IPtables para nodos. Los usuarios más experimentados podrían instalar otros kube-proxies de otros proveedores.

  • Contenedor Sidecar: Los contenedores Sidecar son los contenedores que deben ejecutarse junto con el contenedor principal en el pod. Este patrón de sidecar extiende y mejora la funcionalidad de los contenedores actuales sin cambiarlos. Hoy en día, sabemos que usamos la tecnología de contenedores para envolver todas las dependencias para que la aplicación se ejecute en cualquier lugar. Un contenedor hace solo una cosa y hace esa cosa muy bien.

  • Proceso maestro:

    • Servidor API: Es la forma en que los usuarios y los pods se comunican con el proceso maestro. Solo se deben permitir solicitudes autenticadas.

    • Programador: La programación se refiere a asegurarse de que los pods se correspondan con los nodos para que Kubelet pueda ejecutarlos. Tiene suficiente inteligencia para decidir qué nodo tiene más recursos disponibles y asignar el nuevo pod a él. Tenga en cuenta que el programador no inicia nuevos pods, simplemente se comunica con el proceso Kubelet que se ejecuta dentro del nodo, que lanzará el nuevo pod.

    • Administrador de controladores de Kube: Verifica los recursos como conjuntos de réplicas o implementaciones para verificar si, por ejemplo, se están ejecutando el número correcto de pods o nodos. En caso de que falte un pod, se comunicará con el programador para iniciar uno nuevo. Controla la replicación, los tokens y los servicios de cuenta para la API.

    • etcd: Almacenamiento de datos, persistente, consistente y distribuido. Es la base de datos de Kubernetes y el almacenamiento de clave-valor donde mantiene el estado completo de los clústeres (cada cambio se registra aquí). Componentes como el programador o el administrador de controladores dependen de esta fecha para saber qué cambios han ocurrido (recursos disponibles de los nodos, número de pods en ejecución...)

  • Administrador de controladores en la nube: Es el controlador específico para el control de flujos y aplicaciones, es decir: si tiene clústeres en AWS o OpenStack.

Tenga en cuenta que, como puede haber varios nodos (ejecutando varios pods), también puede haber varios procesos maestros cuyo acceso al servidor API se equilibra y su etcd se sincroniza.

Volúmenes:

Cuando un pod crea datos que no deben perderse cuando el pod desaparece, deben almacenarse en un volumen físico. Kubernetes permite adjuntar un volumen a un pod para persistir los datos. El volumen puede estar en la máquina local o en un almacenamiento remoto. Si está ejecutando pods en diferentes nodos físicos, debe usar un almacenamiento remoto para que todos los pods puedan acceder a él.

Otras configuraciones:

  • ConfigMap: Puede configurar URL para acceder a servicios. El pod obtendrá datos de aquí para saber cómo comunicarse con el resto de los servicios (pods). ¡Tenga en cuenta que este no es el lugar recomendado para guardar credenciales!

  • Secret: Este es el lugar para almacenar datos secretos como contraseñas, claves de API... codificadas en B64. El pod podrá acceder a estos datos para usar las credenciales requeridas.

  • Implementaciones: Aquí es donde se indican los componentes que se ejecutarán por Kubernetes. Un usuario generalmente no trabajará directamente con pods, los pods se abstraen en ReplicaSets (número de pods idénticos replicados), que se ejecutan a través de implementaciones. Tenga en cuenta que las implementaciones son para aplicaciones sin estado. La configuración mínima para una implementación es el nombre y la imagen a ejecutar.

  • StatefulSet: Este componente está destinado específicamente a aplicaciones como bases de datos que necesitan acceder al mismo almacenamiento.

  • Ingress: Esta es la configuración que se utiliza para exponer la aplicación públicamente con una URL. Tenga en cuenta que esto también se puede hacer utilizando servicios externos, pero esta es la forma correcta de exponer la aplicación.

    • Si implementa un Ingress, deberá crear Controladores de Ingress. El controlador de Ingress es un pod que será el punto final que recibirá las solicitudes y verificará y las equilibrará a los servicios. el controlador de ingreso enviará la solicitud en función de las reglas de ingreso configuradas. Tenga en cuenta que las reglas de ingreso pueden apuntar a diferentes rutas o incluso subdominios a diferentes servicios internos de Kubernetes.

      • Una práctica de seguridad mejor sería usar un balanceador de carga en la nube o un servidor proxy como punto de entrada para no tener ninguna parte del clúster de Kubernetes expuesta.

      • Cuando se recibe una solicitud que no coincide con ninguna regla de ingreso, el controlador de ingreso la dirigirá al "backend predeterminado". Puede describir el controlador de ingreso para obtener la dirección de este parámetro.

      • minikube addons enable ingress

Infraestructura PKI - Autoridad de Certificación CA:

  • CA es la raíz de confianza para todos los certificados dentro del clúster.

  • Permite que los componentes se validen entre sí.

  • Todos los certificados del clúster están firmados por la CA.

  • ETCd tiene su propio certificado.

  • tipos:

    • certificado de apiserver.

    • certificado de kubelet.

    • certificado de programador.

Acciones básicas

Minikube

Minikube se puede utilizar para realizar algunas pruebas rápidas en kubernetes sin necesidad de implementar todo un entorno de kubernetes. Ejecutará los procesos de master y node en una sola máquina. Minikube utilizará virtualbox para ejecutar el nodo. Vea aquí cómo instalarlo.

$ minikube start
😄  minikube v1.19.0 en Ubuntu 20.04
✨  Se seleccionó automáticamente el controlador virtualbox. Otras opciones: none, ssh
💿  Descargando la imagen de arranque de la VM ...
    > minikube-v1.19.0.iso.sha256: 65 B / 65 B [-------------] 100.00% ? p/s 0s
    > minikube-v1.19.0.iso: 244.49 MiB / 244.49 MiB  100.00% 1.78 MiB p/s 2m17.
👍  Iniciando el nodo del plano de control minikube en el clúster minikube
💾  Descargando Kubernetes v1.20.2 preload ...
    > preloaded-images-k8s-v10-v1...: 491.71 MiB / 491.71 MiB  100.00% 2.59 MiB
🔥  Creando la VM de virtualbox (CPUs=2, Memoria=3900MB, Disco=20000MB) ...
🐳  Preparando Kubernetes v1.20.2 en Docker 20.10.4 ...
    ▪ Generando certificados y claves ...
    ▪ Iniciando el plano de control ...
    ▪ Configurando las reglas de RBAC ...
🔎  Verificando los componentes de Kubernetes...
    ▪ Usando la imagen gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Se habilitaron los complementos: storage-provisioner, default-storageclass
🏄  ¡Listo! kubectl está configurado para usar el clúster "minikube" y el espacio de nombres "default" de forma predeterminada

$ minikube status
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

---- UNA VEZ QUE TENGA UN SERVICIO K8 EN EJECUCIÓN CON UN SERVICIO EXTERNO -----
$ minikube service mongo-express-service
(Esto abrirá su navegador para acceder al puerto expuesto del servicio)

$ minikube delete
🔥  Eliminando "minikube" en virtualbox ...
💀  Se eliminaron todas las huellas del clúster "minikube"

Conceptos básicos de Kubectl

Kubectl es la herramienta de línea de comandos para clústeres de kubernetes. Se comunica con el servidor Api del proceso maestro para realizar acciones en kubernetes o para solicitar datos.

kubectl version #Obtener la versión del cliente y del servidor
kubectl get pod
kubectl get services
kubectl get deployment
kubectl get replicaset
kubectl get secret
kubectl get all
kubectl get ingress
kubectl get endpoints

#kubectl create deployment <deployment-name> --image=<docker image>
kubectl create deployment nginx-deployment --image=nginx
#Acceda a la configuración del despliegue y modifíquela
#kubectl edit deployment <deployment-name>
kubectl edit deployment nginx-deployment
#Obtenga los registros del pod para la depuración (la salida del contenedor docker en ejecución)
#kubectl logs <replicaset-id/pod-id>
kubectl logs nginx-deployment-84cd76b964
#kubectl describe pod <pod-id>
kubectl describe pod mongo-depl-5fd6b7d4b4-kkt9q
#kubectl exec -it <pod-id> -- bash
kubectl exec -it mongo-depl-5fd6b7d4b4-kkt9q -- bash
#kubectl describe service <service-name>
kubectl describe service mongodb-service
#kubectl delete deployment <deployment-name>
kubectl delete deployment mongo-depl
#Implementar desde el archivo de configuración
kubectl apply -f deployment.yml

Panel de control de Minikube

El panel de control le permite ver más fácilmente lo que está ejecutando minikube, puede encontrar la URL para acceder a él en:

minikube dashboard --url


🔌  Habilitando el panel de control ...
    ▪ Usando la imagen kubernetesui/dashboard:v2.3.1
    ▪ Usando la imagen kubernetesui/metrics-scraper:v1.0.7
🤔  Verificando la salud del panel de control ...
🚀  Lanzando el proxy ...
🤔  Verificando la salud del proxy ...
http://127.0.0.1:50034/api/v1/namespaces/kubernetes-dashboard/services/http:kubernetes-dashboard:/proxy/

Ejemplos de archivos de configuración YAML

Cada archivo de configuración tiene 3 partes: metadata, specification (lo que se necesita lanzar), status (estado deseado). Dentro de la especificación del archivo de configuración de implementación, puede encontrar la plantilla definida con una nueva estructura de configuración que define la imagen a ejecutar:

Ejemplo de implementación + servicio declarado en el mismo archivo de configuración (de aquí)

Como un servicio generalmente está relacionado con una implementación, es posible declarar ambos en el mismo archivo de configuración (el servicio declarado en esta configuración solo es accesible internamente):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mongodb-deployment
  labels:
    app: mongodb
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mongodb
  template:
    metadata:
      labels:
        app: mongodb
    spec:
      containers:
      - name: mongodb
        image: mongo
        ports:
        - containerPort: 27017
        env:
        - name: MONGO_INITDB_ROOT_USERNAME
          valueFrom:
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-username
        - name: MONGO_INITDB_ROOT_PASSWORD
          valueFrom: 
            secretKeyRef:
              name: mongodb-secret
              key: mongo-root-password
---
apiVersion: v1
kind: Service
metadata:
  name: mongodb-service
spec:
  selector:
    app: mongodb
  ports:
    - protocol: TCP
      port: 27017
      targetPort: 27017

**E

Crear namespace

kubectl create namespace my-namespace


<div data-gb-custom-block data-tag="hint" data-style='info'>

Tenga en cuenta que la mayoría de los recursos de Kubernetes (por ejemplo, pods, servicios, controladores de replicación y otros) están en algunos espacios de nombres. Sin embargo, otros recursos como los recursos de espacio de nombres y los recursos de bajo nivel, como los nodos y los volúmenes persistentes, no están en un espacio de nombres. Para ver qué recursos de Kubernetes están y no están en un espacio de nombres:

```bash
kubectl api-resources --namespaced=true #En un espacio de nombres
kubectl api-resources --namespaced=false #No en un espacio de nombres

Puede guardar el espacio de nombres para todos los comandos kubectl posteriores en ese contexto.

kubectl config set-context --current --namespace=<insert-namespace-name-here>

Helm

Helm es el administrador de paquetes para Kubernetes. Permite empaquetar archivos YAML y distribuirlos en repositorios públicos y privados. Estos paquetes se llaman Helm Charts.

helm search <keyword>

Helm también es un motor de plantillas que permite generar archivos de configuración con variables:

Secretos de Kubernetes

Un Secreto es un objeto que contiene datos sensibles como una contraseña, un token o una clave. De lo contrario, dicha información podría ponerse en una especificación de Pod o en una imagen. Los usuarios pueden crear Secretos y el sistema también crea Secretos. El nombre de un objeto Secret debe ser un nombre de subdominio DNS válido. Lea aquí la documentación oficial.

Los secretos podrían ser cosas como:

  • API, claves SSH.

  • Tokens OAuth.

  • Credenciales, contraseñas (texto plano o b64 + cifrado).

  • Información o comentarios.

  • Código de conexión de base de datos, cadenas… .

Hay diferentes tipos de secretos en Kubernetes

Tipo integradoUso

Opaco

datos definidos por el usuario arbitrarios (predeterminado)

kubernetes.io/service-account-token

token de cuenta de servicio

kubernetes.io/dockercfg

archivo ~/.dockercfg serializado

kubernetes.io/dockerconfigjson

archivo ~/.docker/config.json serializado

kubernetes.io/basic-auth

credenciales para autenticación básica

kubernetes.io/ssh-auth

credenciales para autenticación SSH

kubernetes.io/tls

datos para un cliente o servidor TLS

bootstrap.kubernetes.io/token

datos de token de arranque

El tipo Opaque es el predeterminado, el par clave-valor típico definido por los usuarios.

Cómo funcionan los secretos:

El siguiente archivo de configuración define un secreto llamado mysecret con 2 pares clave-valor username: YWRtaW4= y password: MWYyZDFlMmU2N2Rm. También define un pod llamado secretpod que tendrá el username y la password definidos en mysecret expuestos en las variables de entorno SECRET_USERNAME y SECRET_PASSWOR. También montará el secreto username dentro de mysecret en la ruta /etc/foo/my-group/my-username con permisos 0640.

secretpod.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
---
apiVersion: v1
kind: Pod
metadata:
  name: secretpod
spec:
  containers:
  - name: secretpod
    image: nginx
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  restartPolicy: Never
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username
        mode: 0640
kubectl apply -f <secretpod.yaml>
kubectl get pods #Espere hasta que el pod secretpod esté en ejecución
kubectl exec -it  secretpod -- bash
env | grep SECRET && cat /etc/foo/my-group/my-username && echo

Secretos en etcd

etcd es una tienda de clave-valor consistente y altamente disponible utilizada como almacenamiento de respaldo de Kubernetes para todos los datos del clúster. Accedamos a los secretos almacenados en etcd:

cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep etcd

Verá que los certificados, claves y URL se encuentran en el sistema de archivos. Una vez que lo obtenga, podrá conectarse a etcd.

#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket> --cacert <path to CA.cert> endpoint=[<ip:port>] health

ETCDCTL_API=3 etcdctl --cert /etc/kubernetes/pki/apiserver-etcd-client.crt --key /etc/kubernetes/pki/apiserver-etcd-client.key --cacert /etc/kubernetes/pki/etcd/etcd/ca.cert endpoint=[127.0.0.1:1234] health

Una vez que logre establecer la comunicación, podrá obtener los secretos:

#ETCDCTL_API=3 etcdctl --cert <path to client.crt> --key <path to client.ket>

Última actualización