Kubernetes
- Arquitectura
- Notas
- Distros
- Tools
- Temaplates
- POD identities
- Firewall
- SELinux
- CRI-O
- Kube repo
- kube-controller-manager
- Ubicaciones
- Tags - Roles
- Persistent Volume (PV)
- Backups
- Comandos
- - Unir al cluster
- - Aplicar deployment
- - Editar deployment
- - Mostrar eventos
- - Customizar salida
- - Obtener información
- - Obtener una descripción
- - Inspeccionar pod
- - Ver registros (logs)
- - Adjuntar a container
- - Ejecutar en un contenedor
- - Auditar autenticación
- - Setear auto escalado horizontal
- - Setear escalado manual
- - Aprobar una solicitud de firmar un certificado (CSR: Certificate Signing Request)
- - Marcar nodo como inusable
- - Copiar desde/hacia el POD
- - Debug resource
- - Borrar recursos
- - Ver diferencias entre configuraciones
- - Crear un servicio en un pod existente
- - Actualizar labels en un recurso
- - Exponer puerto sin crear servicios
- - Proxy HTTP para acceder a la API de Kubernetes
- - Remplazar/actualizar POD
- - Rollback
- - Crear POD
- - Ver consumo de recursos
Arquitectura
Notas
- Los 'Service' que van anidados a un deployment usan el valor de 'spec' -> 'selector' -> 'app', que está especificado en el deployment en 'metadata' -> 'lebels' -> 'app'
Distros
-
Bottlerocket
Distro imutable para funcionar como worker que se actualiza automáticamente.
-
K3S
Versión más minimalista de K8S en un solo binario.
Tiene el socket en /run/k3s/containerd/containerd.sock
Tiene todo en el namespace de containerd; k8s.io
sudo ctr -n=k8s.io [comandos] -a /run/k3s/containerd/containerd.sock
sudo crictl --runtime-endpoint unix:///run/k3s/containerd/containerd.sock
-
RKEv2 (Goberment)
Versión de K3S para seguridad.
No trae containerd instalado, si no que lo tiene embebido. Se recomienda instalar containerd para poder administrarlo fuera del propio rkev2.
Tools
-
Creador de Deployment / StatefulSet / DaemonSet
-
Creador de Deployment / Service / Ingress
-
CI/CD
- Jenkins (CI/CD, opensource)
- Terraform (CD, opensource)
- Spinnaker (CD, opensource)
- IO (CD, opensource)
-
Métricas;
- Prometheus
-
Monitoreo general;
- DataDog (pago)
- Sematext Monitoring (pago)
- Cast.ai (pago)
- Jaeger (open source)
-
Monitoreo desde métricas;
- Grafana
-
Monitoreo desde Service mesh (específico de la red en los PODS);
- istio (open source)
-
Análisis de seguridad;
- kube-lint (YAML, opensource)
- kube-bench (deployment, opensource)
- Trivy (runner, opensource)
- Tenable/Terrascan (IAC, opensource)
Temaplates
Deployment template
El modo por defecto para desplegar una aplicación/es.
apiVersion: apps/v1 # Define la versión de la API que se usa para manejar este recurso.
kind: Deployment # Especifica que este manifiesto es un Deployment.
metadata:
name: my-deployment # Nombre del Deployment.
namespace: default # Namespace en el cual se desplegará este Deployment (por defecto es 'default').
labels:
app: my-app # Etiquetas que permiten identificar y organizar recursos.
annotations:
description: "Este Deployment despliega una aplicación con múltiples configuraciones." # Anotaciones adicionales para describir el recurso.
spec:
replicas: 3 # Número de réplicas del pod a desplegar.
selector: # Define cómo se seleccionarán los Pods creados por este Deployment.
matchLabels:
app: my-app # Etiquetas que deben coincidir para que un pod sea considerado parte de este Deployment.
strategy: # Estrategia de actualización de los Pods.
type: RollingUpdate # Define cómo se actualizarán los pods, opciones: RollingUpdate o Recreate.
rollingUpdate: # Parámetros específicos para una actualización progresiva.
maxUnavailable: 1 # Número o porcentaje máximo de pods no disponibles durante la actualización.
maxSurge: 1 # Número o porcentaje máximo de pods adicionales que pueden crearse temporalmente durante la actualización.
template: # Define la plantilla para los pods que serán gestionados por este Deployment.
metadata:
labels:
app: my-app # Las etiquetas que los pods llevarán. Deben coincidir con el selector.
spec:
containers:
- name: my-container # Nombre del contenedor.
image: nginx:1.19 # Imagen del contenedor.
ports:
- containerPort: 80 # Puerto expuesto dentro del contenedor.
resources: # Define los recursos solicitados y límites para este contenedor.
requests:
memory: "64Mi" # Memoria mínima solicitada.
cpu: "250m" # CPU mínima solicitada.
limits:
memory: "128Mi" # Memoria máxima permitida.
cpu: "500m" # CPU máxima permitida.
env: # Variables de entorno para configurar el contenedor.
- name: ENVIRONMENT
value: production
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config # Toma el valor desde un ConfigMap.
key: log-level
envFrom: # Cargar variables de entorno desde ConfigMap o Secret.
- configMapRef:
name: app-config # Nombre del ConfigMap.
- secretRef:
name: app-secrets # Nombre del Secret.
volumeMounts: # Define los volúmenes que se montarán dentro del contenedor.
- name: config-volume
mountPath: /etc/config
- name: logs
mountPath: /var/log/nginx
livenessProbe: # Configuración de liveness para comprobar si el contenedor sigue funcionando.
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 10 # Espera antes de la primera comprobación.
periodSeconds: 10 # Intervalo de tiempo entre las comprobaciones.
timeoutSeconds: 1 # Tiempo límite para cada comprobación.
failureThreshold: 3 # Número de fallos consecutivos antes de considerarse fallido.
readinessProbe: # Configuración para verificar si el contenedor está listo para recibir tráfico.
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
startupProbe: # Verificación de que el contenedor ha arrancado correctamente.
httpGet:
path: /startup
port: 80
initialDelaySeconds: 20
periodSeconds: 10
imagePullPolicy: Always # Política de pull de la imagen: Always, IfNotPresent, Never.
initContainers: # Contenedores que se ejecutarán antes que los contenedores principales.
- name: init-my-service
image: busybox:1.28
command: ['sh', '-c', 'echo Initializing... && sleep 5']
resources:
requests:
memory: "32Mi"
cpu: "100m"
volumes: # Define los volúmenes que se montarán en los contenedores.
- name: config-volume
configMap:
name: app-config # Nombre del ConfigMap del que se cargará la configuración.
- name: logs
emptyDir: {} # Volumen temporal que desaparece cuando el pod se reinicia o se borra.
nodeSelector: # Define en qué nodos pueden desplegarse los pods.
disktype: ssd # Ejemplo de nodo con un determinado tipo de disco.
affinity: # Afinidad de los pods con respecto a nodos.
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: "kubernetes.io/hostname"
tolerations: # Define tolerancias para nodos con taints específicos.
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
restartPolicy: Always # Política de reinicio del contenedor: Always, OnFailure, Never.
dnsPolicy: ClusterFirst # Política DNS para los pods.
serviceAccountName: my-service-account # Cuenta de servicio que se utilizará.
securityContext: # Configuración de seguridad para todo el pod.
runAsUser: 1000
fsGroup: 2000
schedulerName: default-scheduler # Define el scheduler que gestionará este pod.
hostNetwork: false # Si se debe usar el networking del host.
priorityClassName: high-priority # Define la prioridad de los pods.
minReadySeconds: 5 # Tiempo que un pod debe estar listo antes de ser considerado disponible.
revisionHistoryLimit: 10 # Número máximo de réplicas anteriores mantenidas.
progressDeadlineSeconds: 600 # Tiempo máximo para considerar que una actualización es exitosa.
paused: false # Si el deployment está pausado o no.
Daemon Set
Un DaemonSet asegura que un Pod específico esté corriendo en cada nodo (o en nodos seleccionados) del clúster.
No maneja el estado de las aplicaciones.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: my-daemonset # Nombre del DaemonSet.
namespace: default # Namespace donde se desplegará el DaemonSet.
labels:
app: my-daemon-app # Etiquetas para identificar el DaemonSet.
annotations:
description: "DaemonSet para ejecutar un pod en cada nodo del clúster."
spec:
selector:
matchLabels:
app: my-daemon-app # Etiquetas que deben coincidir con los pods gestionados por el DaemonSet.
template: # Define la plantilla para los Pods gestionados por este DaemonSet.
metadata:
labels:
app: my-daemon-app # Etiquetas que deben coincidir con el selector.
spec:
containers:
- name: my-daemon-container # Nombre del contenedor.
image: busybox:1.28 # Imagen del contenedor.
args: # Argumentos pasados al contenedor.
- "/bin/sh"
- "-c"
- "while true; do echo Hello DaemonSet; sleep 3600; done"
resources: # Configura los recursos solicitados y límites para este contenedor.
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
volumeMounts:
- name: logs
mountPath: /var/log/daemonset
ports:
- containerPort: 80
name: http
livenessProbe: # Verificación de si el contenedor está vivo.
httpGet:
path: /healthz
port: 80
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe: # Verificación de si el contenedor está listo para recibir tráfico.
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
initContainers: # Contenedores que se ejecutarán antes del contenedor principal.
- name: init-container
image: busybox:1.28
command: ['sh', '-c', 'echo Initializing DaemonSet... && sleep 5']
volumes: # Define los volúmenes que se utilizarán.
- name: logs
emptyDir: {}
nodeSelector: # Reglas para limitar los nodos donde se ejecutará el DaemonSet.
disktype: ssd
affinity: # Define la afinidad de los Pods con respecto a nodos.
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/e2e-az-name
operator: In
values:
- e2e-az1
- e2e-az2
tolerations: # Define tolerancias a ciertos taints de los nodos.
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
updateStrategy: # Estrategia de actualización de los DaemonSets.
type: RollingUpdate # Opciones: RollingUpdate o OnDelete.
rollingUpdate:
maxUnavailable: 1 # Número o porcentaje máximo de pods no disponibles durante la actualización.
revisionHistoryLimit: 10 # Número máximo de revisiones guardadas para el DaemonSet.
Stateful Set
El StatefulSet gestiona el despliegue y el escalado de un conjunto de Pods, garantizando un orden de despliegue, actualización y eliminación, manteniendo una identidad única para cada Pod.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-statefulset # Nombre del StatefulSet.
namespace: default # Namespace donde se desplegará.
labels:
app: my-stateful-app
annotations:
description: "StatefulSet para manejar aplicaciones con estado que requieren una identidad única en cada pod."
spec:
replicas: 3 # Número de réplicas gestionadas por el StatefulSet.
serviceName: "my-service" # Nombre del Headless Service asociado al StatefulSet.
selector:
matchLabels:
app: my-stateful-app
template: # Plantilla para los pods gestionados por el StatefulSet.
metadata:
labels:
app: my-stateful-app
spec:
containers:
- name: my-stateful-container
image: postgres:13 # Ejemplo con una base de datos Postgres.
ports:
- containerPort: 5432
name: postgres
env:
- name: POSTGRES_USER
value: "admin"
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: postgres-secret
key: password
volumeMounts:
- name: postgres-data
mountPath: /var/lib/postgresql/data # Donde se almacenan los datos persistentes.
initContainers:
- name: init-container
image: busybox:1.28
command: ['sh', '-c', 'echo Initializing StatefulSet... && sleep 5']
volumeClaimTemplates: # Define volúmenes persistentes para cada pod.
- metadata:
name: postgres-data # Nombre del volumen.
spec:
accessModes: ["ReadWriteOnce"] # Modo de acceso del volumen.
resources:
requests:
storage: 1Gi # Espacio de almacenamiento solicitado.
storageClassName: standard # Define la StorageClass que gestionará este PVC.
podManagementPolicy: Parallel # Controla cómo se crean o eliminan los pods. Opciones: OrderedReady, Parallel.
updateStrategy:
type: RollingUpdate # Estrategia de actualización.
rollingUpdate:
partition: 1 # Permite actualizar solo una parte de los pods a la vez.
revisionHistoryLimit: 10 # Número de revisiones mantenidas.
persistentVolumeClaimRetentionPolicy: # Define la política de retención de los volúmenes persistentes.
whenDeleted: Retain # Mantener el PVC cuando se elimine el StatefulSet.
whenScaled: Retain # Mantener el PVC cuando se escale el StatefulSet hacia abajo.
Service template
- Cluster IP
Descripción:
Este es el tipo de Service por defecto. Expone el servicio dentro del clúster a través de una IP interna, llamada ClusterIP. Solo los recursos dentro del clúster (como otros Pods) pueden acceder a este servicio.
Uso:
Se utiliza cuando solo necesitas exponer tu aplicación dentro del clúster, sin necesidad de que sea accesible desde fuera. Ideal para microservicios que necesitan comunicarse entre sí dentro del clúster. No es accesible desde fuera del clúster.
Ejemplo de uso: Imagina que tienes un conjunto de microservicios que se comunican entre ellos, pero no necesitas exponerlos al mundo exterior.
apiVersion: v1
kind: Service
metadata:
name: my-clusterip-service # Nombre del Service
namespace: default # Namespace donde se despliega el Service
labels:
app: my-app # Etiquetas para identificar el Service
annotations:
description: "ClusterIP Service que expone la aplicación solo dentro del cluster."
spec:
type: ClusterIP # Tipo de Service: expone el servicio solo dentro del cluster.
selector:
app: my-app # Selecciona los Pods que coinciden con esta etiqueta.
ports:
- protocol: TCP # Protocolo, puede ser TCP o UDP
port: 80 # Puerto que expone el Service dentro del cluster.
targetPort: 8080 # Puerto donde está escuchando la aplicación en los Pods.
name: http # Nombre del puerto, útil para algunas herramientas.
clusterIP: None # Si se desea crear un Headless Service, se debe establecer `None`.
sessionAffinity: None # Controla la afinidad de sesiones, opciones: None o ClientIP.
externalTrafficPolicy: Cluster # Define cómo manejar el tráfico externo. Opciones: Cluster, Local.
ipFamilies:
- IPv4 # Define la familia de IPs para el servicio: IPv4, IPv6, o ambas.
ipFamilyPolicy: SingleStack # Define la política de familia de IP: SingleStack, PreferDualStack o RequireDualStack.
- NodePort
Descripción:
Un NodePort expone el servicio a través de un puerto específico en cada nodo del clúster. Además de ser accesible dentro del clúster como un ClusterIP, este tipo de servicio permite que los usuarios accedan al servicio desde fuera del clúster a través del IP del nodo y un puerto específico en el rango 30000-32767.
Uso:
Se usa cuando necesitas exponer tu aplicación externamente y no tienes un balanceador de carga (por ejemplo, en entornos on-premise o de desarrollo). El servicio es accesible desde el exterior usando la IP de cualquier nodo del clúster y el puerto especificado. Es más simple que usar un LoadBalancer, pero tiene la desventaja de que debes lidiar manualmente con la exposición a través de los nodos.
Ejemplo de uso: Ideal para entornos de desarrollo o pruebas donde quieres acceder a tu servicio desde fuera del clúster sin la complejidad de configurar un balanceador de carga.
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
namespace: default
labels:
app: my-app
annotations:
description: "NodePort Service que expone el servicio en todos los nodos del cluster."
spec:
type: NodePort # Tipo de Service: expone el servicio en un puerto específico de todos los nodos.
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Puerto que expone el Service dentro del cluster.
targetPort: 8080 # Puerto donde está escuchando la aplicación en los Pods.
nodePort: 30036 # Puerto en los nodos donde estará disponible (rango: 30000-32767).
name: http
sessionAffinity: ClientIP # Mantiene la afinidad de sesión basada en la IP del cliente.
externalTrafficPolicy: Local # Tráfico externo se envía solo a nodos con pods activos.
healthCheckNodePort: 32000 # Puerto adicional para verificaciones de salud de los nodos (opcional).
- LoadBalancer
Descripción: Un LoadBalancer crea un balanceador de carga externo que distribuye el tráfico entre los pods de tu servicio. Este tipo de servicio asigna automáticamente una IP externa y maneja la creación del balanceador de carga en la nube (si estás en un proveedor de nube como AWS, GCP o Azure).
Uso:
Es ideal para exponer aplicaciones al exterior en producción en la nube. El proveedor de la nube gestionará el balanceador de carga. Permite distribuir el tráfico entre los diferentes pods que respaldan el servicio. Soporta la especificación de rangos IP para restringir el acceso externo.
Ejemplo de uso: Perfecto para exponer aplicaciones web o APIs que necesitan estar accesibles desde internet. Un proveedor de nube creará automáticamente un balanceador de carga y manejará la distribución del tráfico.
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
namespace: default
labels:
app: my-app
annotations:
description: "LoadBalancer Service que expone el servicio a través de un balanceador de carga externo."
service.beta.kubernetes.io/aws-load-balancer-type: nlb # Ejemplo de anotación específica de AWS para usar un Network Load Balancer.
spec:
type: LoadBalancer # Tipo de Service: expone el servicio a través de un Load Balancer externo.
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # Puerto que el balanceador expone públicamente.
targetPort: 8080 # Puerto donde está escuchando la aplicación en los Pods.
name: http
- protocol: TCP
port: 443 # Puerto adicional para HTTPS, por ejemplo.
targetPort: 8443
name: https
loadBalancerIP: 192.168.0.100 # IP externa preasignada para el balanceador de carga (opcional, depende del proveedor).
externalTrafficPolicy: Cluster # Cómo manejar el tráfico externo.
sessionAffinity: None # Controla la afinidad de sesiones, opciones: None o ClientIP.
loadBalancerSourceRanges:
- 203.0.113.0/24 # Restringe el acceso al balanceador de carga a estos rangos de IP (opcional).
- ExternalName
Descripción:
Un ExternalName no redirige el tráfico a los Pods del clúster, sino que actúa como un alias para un nombre DNS externo. Básicamente, resuelve el nombre de servicio en un nombre DNS externo (como una redirección).
Uso:
Se usa cuando necesitas acceder a un servicio externo, fuera del clúster, mediante un nombre DNS específico. No crea ningún ClusterIP, ni interactúa con los Pods. Sirve para configurar aplicaciones dentro del clúster para que accedan a servicios externos sin tener que modificar el código de la aplicación, solo cambiando el nombre de servicio.
Ejemplo de uso: Si tienes una base de datos o una API externa (por ejemplo, una API SaaS) a la que necesitas acceder desde dentro de tu clúster, puedes usar un ExternalName para simplificar la configuración.
apiVersion: v1
kind: Service
metadata:
name: my-externalname-service
namespace: default
labels:
app: my-app
annotations:
description: "ExternalName Service que actúa como un alias DNS para servicios externos."
spec:
type: ExternalName # Tipo de Service: actúa como un alias para un nombre DNS externo.
externalName: my-external-service.example.com # Nombre DNS al que se redirige el tráfico.
ports:
- protocol: TCP
port: 80 # Puerto que usará el servicio para redirigir el tráfico (opcional).
Ingress template
Descripción:
El recurso Ingress en Kubernetes permite gestionar el acceso externo a los servicios dentro de un clúster, normalmente mediante HTTP y HTTPS. Ingress proporciona reglas para enrutar solicitudes basadas en nombres de host, rutas, o incluso basándose en headers, hacia los servicios correspondientes dentro del clúster. A diferencia de NodePort o LoadBalancer, Ingress ofrece más control sobre el enrutamiento de tráfico y permite configurar reglas para múltiples servicios en un solo punto de entrada (puerta de enlace).
Uso:
Ingress se utiliza para exponer servicios HTTP/HTTPS a través de reglas de enrutamiento. Permite:
- Enrutar solicitudes basadas en el nombre de dominio (host).
- Dirigir diferentes rutas (URL) a diferentes servicios.
- Gestionar certificados SSL para el tráfico HTTPS.
- Utilizar un único punto de acceso para múltiples servicios.
- Configurar reglas avanzadas como redireccionamientos, autenticación o balanceo de carga.
Uso común de Ingress:
- Controlar el acceso HTTP/HTTPS de manera centralizada.
- Proveer un único dominio para múltiples servicios en el clúster, cada uno con diferentes rutas.
- Implementar balanceo de carga HTTP avanzado y TLS (SSL).
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress # Nombre del recurso Ingress.
namespace: default # Namespace donde se despliega el Ingress.
labels:
app: my-app
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # Ejemplo de anotación para reescribir URL.
kubernetes.io/ingress.class: "nginx" # Especifica la clase de controlador Ingress.
nginx.ingress.kubernetes.io/ssl-redirect: "true" # Redirige automáticamente HTTP a HTTPS.
cert-manager.io/cluster-issuer: "letsencrypt-prod" # Para gestionar certificados SSL con cert-manager.
spec:
rules:
- host: example.com # Define el nombre de dominio que será gestionado por el Ingress.
http:
paths:
- path: / # Ruta principal.
pathType: Prefix # Especifica que todas las rutas con este prefijo serán redirigidas.
backend:
service:
name: my-service # Nombre del servicio al que se redirige.
port:
number: 80 # Puerto del servicio (puerto HTTP en este caso).
- path: /api # Ruta para la API.
pathType: Prefix
backend:
service:
name: api-service # Servicio que manejará las solicitudes de la ruta "/api".
port:
number: 8080
- path: /static # Ruta para servir contenido estático.
pathType: Prefix
backend:
service:
name: static-service # Servicio para manejar la ruta "/static".
port:
number: 8081
tls: # Configuración para el manejo de certificados SSL.
- hosts:
- example.com # Nombre de dominio que se asegura con TLS.
secretName: tls-secret # Nombre del Secret que contiene el certificado TLS.
defaultBackend: # Define un backend por defecto si no se cumplen las reglas anteriores.
service:
name: default-service # Servicio por defecto al que se enviará el tráfico si ninguna regla coincide.
port:
number: 80
POD identities
Utilizan el IAM de la nube en conjunto con cuentas de servicio del propio K8S para proveer un token en las variables de entorno.
Firewall
- Master
sudo firewall-cmd --permanent --add-port=6443/tcp
sudo firewall-cmd --permanent --add-port=2379-2380/tcp
sudo firewall-cmd --permanent --add-port=10250/tcp
sudo firewall-cmd --permanent --add-port=10259/tcp
sudo firewall-cmd --permanent --add-port=10257/tcp
sudo firewall-cmd --reload
- Worker
sudo firewall-cmd --permanent --add-port=10250/tcp
sudo firewall-cmd --permanent --add-port=30000-32767/tcp
sudo firewall-cmd --reload
SELinux
sudo setenforce 1
sed -i 's/SELINUX=permissive/SELINUX=enforcing/g' /etc/selinux/config
CRI-O
curl https://raw.githubusercontent.com/cri-o/packaging/main/get | sudo bash
sudo systemctl enable --now crio
sudo systemctl enable --now podman.socket
Kube repo
- /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.29/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
sudo dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
kube-controller-manager
Archivo; /etc/kubernetes/manifests/kube-controller-manager.yaml
Debe llevar los siguientes flags;
- "--allocate-node-cidrs=true"
- "--cluster-cidr=
"
Ubicaciones
- Kubeconfig
Todas las distribuciones
~/.kube/config
kubectl --kubeconfig [path_location]
$KUBECONFIG
Rancher Goverment (RKEv2)
/etc/rancher/rke2/rke2.yaml
Kubernetes bare metal
/etc/kubernetes/admin.conf
Tags - Roles
Posibles roles para los nodos;
- worker
- control-plane
- etcd
- master
Asignar un rol
kubectl label node [node_name] node-role.kubernetes.io/[role]=[tag_any_name]
Borrar un rol
kubectl label node [node_name] node-role.kubernetes.io/[role]-
Persistent Volume (PV)
Sirve para que independientemente de la instancia de POD, se pueda usar el volumes en cada despliegue, se definen mediante el StorageClass.
Si se maneja bien los espacios y los nombres, se puede usar un PV y su PVC para pods especificos.
A diferencia de los volumenes comunes, estos no varian dependiendo de la instancia, por eso son "persistent".
El PV no se usa en el master, si no que afecta a los worker.
- Volumen persistente manual
apiVersion: v1
kind: PersistentVolume
metadata:
name: [pv_name]
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
Luego se puede crear el PersistentVolumeClaim para que pueda usar un espacio determinado según el PV que lo satisfaga
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: [pvc_name]
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
Ejemplo de un POD con un PVC específico
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
Backups
- ETCD
Rancher Goverment (RKEv2)
rke2 etcd-snapshot save --name pre-upgrade-snapshot
systemctl stop rke2-server && rke2 server --cluster-reset --cluster-reset-restore-path=[PATH-TO-SNAPSHOT] && systemctl start rke2-server
Comandos
sudo KUBECONFIG=[path_absoluto] kubectl ....
- Unir al cluster
Kubernetes bare metal
kubeadm join --discovery-token [master_token] --discovery-token-ca-cert-hash sha256:[HASH] --control-plane [master_IP]:6443
- Aplicar deployment
Apply sobre escribirá si ya existe el recurso
kubectl apply -f [file_or_URLfile]
- "-l [key]=[value]" asignar tag
- "-k [ditectory]" aplica varios deployments a la vez
Mientras que "create" no sobre escribirá
kubectl create -f [file_or_URLfile]
- "-l [key]=[value]" asignar tag
- "-k [ditectory]" aplica varios deployments a la vez
En ambos ("create" y "apply") los tipos que se soportan son;
- clusterrole
- clusterrolebinding
- configmap
- cronjob
- deployment
- ingress
- job
- namespace
- poddisruptionbudget
- priorityclass
- quota
- role
- rolebinding
- secret
- secret docker-registry
- secret generic
- secret tls
- service
- service clusterip
- service externalname
- service loadbalancer
- service nodeport
- serviceaccount
- token
- pv
- pvc
- Editar deployment
Se usa el editor especificado en la variable de entorno KUBE_EDITOR ó EDITOR
kubectl edit [type]/[resource_name]
- "-o json" edita usando el modo json
- "-o yaml" edita usando el modo yaml
- Mostrar eventos
Para todo el clúster
kubectl events --all-namespaces
Para un pod específico
kubectl events --for pod/[pod_name] --watch
- Customizar salida
... -o [yaml,json,wide,etc]
- Obtener información
kubectl get [info] -o yaml
- nodes
- deployments
- pods
- svc (services)
- rc (replication controller)
- pv (persistent volume)
- pvc (persistent volume claim)
kubectl cluster-info
- "--storage-driver-password [string]" contraseña para la base de datos
- "--storage-driver-host [ip]:[port]" ip y puerto para la base de datos
- "--storage-driver-db [name]" nombre de la base de datos
- "--storage-driver-table [name]" nombre de la tabla
- "--storage-driver-user [name]" nombre de usuario
- "-s [ip]:[port]" ip y puerto del servidor
- Obtener una descripción
kubectl describe [recurso] -o yaml
Recursos compatibles
- nodes
- deployments
- pods
- svc (services)
- rc (replication controller)
- Inspeccionar pod
kubectl inspect pods/[podname]
- Ver registros (logs)
kubectl logs [pod_name]
- "--tail=X" las últimas X líneas
- "--since=Xh" las últimas X horas
- "-c [container_name]" de un contenedor específico de ese POD
- "--previous" contenedores previos fallidos
- "--all-containers" todos los contenedores de ese pod
- Adjuntar a container
kubectl attach [pod_name]
- "-c [container_name]" a un contenedor específico
- "... -i -t" interactive y TTY
- "rs/[pod_name]" primera réplica del pod
- Ejecutar en un contenedor
kubectl exec [pod_name] -c [container] -i -t -- [comand] [command_arguments]
- Auditar autenticación
kubectl auth
- "--storage-driver-password [string]" contraseña para la base de datos
- "--storage-driver-host [ip]:[port]" ip y puerto para la base de datos
- "--storage-driver-db [name]" nombre de la base de datos
- "--storage-driver-table [name]" nombre de la tabla
- "--storage-driver-user [name]" nombre de usuario
- "-s [ip]:[port]" ip y puerto del servidor
- Setear auto escalado horizontal
kubectl autoscale [type] [resource] --min=[X] --max=[Y] --cpu-percent=[Z]
Tipos;
- deployments
- pods
- svc (services)
- rc (replication controller)
- Setear escalado manual
kubectl scale --replicas=[X] [type]/[resource_name]
- Aprobar una solicitud de firmar un certificado (CSR: Certificate Signing Request)
kubectl certificate approve [CSR_name]
- "-f [file_or_URLFile]" si no está el nombre, se puede usar un archivo
- "-R" si se usó "-f" y son más de un archivo se puede especificar esto para que lea todo el directorio
- "--force"
- "-h"
- Marcar nodo como inusable
Esto hace que el scheduler del master no mande algo a ejecutar
kubectl cordon [node]
También se lo puede marcar como "drain" para realizar tareas de mantenimiento
kubectl dran [node]
- Copiar desde/hacia el POD
El src ó dest puede ser la máquina local, el otro tiene que ser el POD.
El pod se especifica; [namespace]/[pod_name]:[absolute_path]
kubectl cp [src] [dest]
- Debug resource
kubectl debug [type]/[resource_name] -it --image=[busybox,debian,etc]
- "-c [containers_pod]" especificamente para los tipos; pod
- Borrar recursos
kubectl delete [type-1],[type-n] [resource_name]
- Ver diferencias entre configuraciones
La diferencia es entre el archivo de deployment original y la configuración actual del recurso
kubectl diff -f [file]
- Crear un servicio en un pod existente
kubectl expose [type] [resource_name] --port=[host_port] --target-port=[container_port] --name=[service_name]
- "-f [archivo].yaml" también se puede usar un archivo en vez de especificar el tipo
- Actualizar labels en un recurso
kubectl label --overwrite [type] [resource_name] [label]=[value]
- "-f [archivo].yaml" también se puede usar un archivo en vez de especificar el tipo
- Exponer puerto sin crear servicios
kubectl port-forward [type]/[resoource_name] [host_port]:[container_port] --address [ip_where_allow_incoming]
- Proxy HTTP para acceder a la API de Kubernetes
Se inicia un proxy entre el host donde ejecutamos y el clúster para poder consumir la API de Kubernetes
kubectl proxy --port=[port_to_use] --address=[ip_master_node]
La URL luego tiene esta forma;
http://localhost:8080/api/v1/proxy/namespaces/[namespace]/services/[service]
Se debe usar kubectl config para especificar usar ese proxy
kubectl config set-context [name] --proxy=http://[proxy_ip]:[port]
kubectl proxy -n default --url http://[proxy_ip]:[port]
- Remplazar/actualizar POD
kubectl replace -f [file].[yaml/json]
- Rollback
Son soportados; deployments, daemonsts, statefulsets.
kubectl rollout undo [type]/[resource_name]
kubectl rollout status [type]/[resource_name]
kubectl rollout restart [type]/[resource_name]
kubectl rollout history
kubectl rollout [pause/resume] [type]/[resource_name]
kubectl rollout undo [type]/[resource_name]
Se puede incluir el argumento "--selector=app=[name]" en vez del tipo y nombre_recurso.
- Crear POD
kubectl run [name] --image=[image] --port=[container_port] --env=[environment_variable] --labels="[var]=[value],[var2]=[value2]" --restart=[Never/Always] -t -i
- Ver consumo de recursos
kubectl top [node/pod]/[resource_name]