En el caso de Kubernetes el nodo maestro no ejecuta ningún contenedor, (no es como swarm) solo tiene servicios que son necesarios para la infraestructura de Kubernetes. En el caso de Kubernetes se usan pods, un pod es la mínima unidad de trabajo de Kubernetes que contiene uno o más contenedores.
Kubernetes tiene este ciclo de vida para los pods:
- Pending: Se cargan los contenedores
- Failed: Error durante la carga
- Running: Todos los contenedores creados, al menos uno está funcionando.
- Succeded: Todos los contenedores en el pod han terminado correctamente.
Servicios
Kubernetes tiene varios servicios ejecutándose que interesa conocer, unos se ejecutan en el nodo maestro y otros son específicos del resto de nodos.
Maestro
kube-apiserver: Servidor REST API que consume datos JSON a través de archivos de manifiesto para la configuración de Kubernetes.
etcd: Almacenamiento clave/valor para pequeñas cantidades de datos en memoria, una parte principal de kubernetes que se recomienda guardar.
kube-controller-manager: Observa cambios en el sistema y reacciona para asegurar la configuración del sistema.
kube-scheduler: Asigna trabajo a los nodos e inspecciona el servidor API para la creación de nuevos pods.
Nodos
kubelet: Un agente que se comunica con el maestro para arrancar operaciones en el nodo e informar del estado del nodo.
kube-proxy: Componente que habilita el direccionamiento IP en el pod y balancea el tráfico a través de todos los pods del servicio.
Comandos
- kubectl create -f pod.yml
Crea un pod en base a un fichero - kubectl create -f service.yml
Crea un servicio en base a un fichero yml - kubectl create -f deployment.yml
Crea un deployment a partir de fichero - kubectl create secret generic secreto –from-literal=PASSWORD=»FooPass» –from-file=./<filename> –namespace=app
Crea un secreto- –from-literal lo crea desde el literal de texto indicado
- –from-file para colocar secretos en ficheros
- –namespace si se ha creado un namespace para agrupar se puede especificar aquí
- kubectl create namespace app
Crea un espacio de nombre para agrupar a todos los elementos del cluster, también es útil para separar tus proyectos y limitar los recursos disponibles para cada uno de ellos. Es como tener un cluster virtual sobre uno físico. El namespace también sirve como DNS servicename.namespace.svc.cluster.local
- kubectl describe pod
Muestra toda la información disponible sobre el pod y los contenedores que incluye. - kubectl describe service app-rc-service
Información sobre el servicio - kubectl describe deployment app-dpl
Muestra información sobre el deployment - kubectl describe hpa
Muestra las métricas en el cluster local
- kubectl get pods
Permite ver los pods creados y su estado - kubectl get pod
Recupera el nombre del pod, útil para poder referenciarlo luego con otros comandos - kubectl get deployment dpl
Permite ver información sobre el deployment creado, nombre, replica, pods actuales, acutalizados, disponibles… - kubectl get persistentvolumes
Devuelve todos los volúmenes - kubectl get persistentvolume volumen
Devuelve solo el volumen indicado - kubectl get pv
Devuelve información sobre los volúmenes indicando cuales han sido reclamados y cuales siguen disponibles - kubectl get persistentvolumeclaims
Devuelve todos los volúmenes reclamados - kubectl get persistentvolumeclaim volumen
Devuelve solo el volumen reclamado indicado - kubectl get secrets
Saca un listado de los secretos creados - kubectl get secret secreto -o yaml
Devuelve el valor de un secreto - kubectl get namespaces
Obtiene los espacios de nombre disponibles - kubectl get hpa
Sirve para monitorizar HPA - kubectl get nodes
Muestras los nodos del cluster - kubectl get service app-svc –watch
Muestra información de un servicio- –watch monitoriza el comando hasta que se asigne una IP pública
- kubectl run pod –image=autor/imagen –port 80 –restart=Never
Crea un pod y lo arranca- –image la imagen que se usará para el pod
- –port en que puerto estará escuchando
- –restart indica que hacer en caso de reinicio, en este caso Never indica que no se recreará, falla o muere.
- kubectl delete pod pod
Borra un pod - kubectl delete deployment dpl
Borra el deployment indicado
- kubectl -n kube-system get secret
Muestra todos los secretos del cluster. En general interesa el secreto que empieza por deployment-controller-token - kubectl -n kube-system describe secret deployment-controller-token-xyz
Obtener un token
- kubectl rollout status deployment app-deployment
Permite ver el progreso de una operación rollout - kubectl rollout history deployment app-deployment
Si se uso el parámetro –record al hacer un kubectl apply permite ver la historia del deployment - kubectl rollout undo deployment app-deployment –to-revision=1
Permite volver a una versión específica- –to-revision versión a la que volver
- kubectl expose rc app-rc –name=app-rc-service –type=NodePort
Servicio que expone el pod a otros pods o clientes.- –name indica el nombre del servicio
- –type indica el tipo de servicio
- ClusterIP: Valor por defecto que expone el pod interno al cluster
- NodePort: Expone el pod con un puerto estático en cada nodo que contiene el pod
- LoadBalancer: Expone el pod externamente usando un balanceador de carga de un proveedor de cloud
- ExternalName: Disponible desde la versión 1.7 de kube-dns para exponer los pods a través de los contenidos de el campo externalName
- kubectl cluster-info
Muestra información de estado del cluster.
- kubectl proxy
Arranca el servidor proxy de Kubernetes
- kubectl apply -f deployment.yml –record
Aplica los cambios hechos en el fichero- –record Sigue todos los cambios hechos durante el deployment, permite hacer un rollback a una versión previa de la aplicación.
- kubectl exec -it dpl — /bin/bash [–container container]
Ejecuta un comando- -it dpl el deployment que se usará
- — comando el comando a ejecutar
- –container el container donde se va a ejecutar
- kubectl cp fichero dpl:fichero
Copia el fichero al deployment indicado con el nombre dado en fichero
- kubectl config view
Muestra información de la configuración
- kubectl autoscale deployment app-deployment –cpu-percent=50 –min=1 –max=5 –horizontal-pod-autoscaler-sync-period=x
Este comando configura Horizontal Pod Autoscaler (HPA) , es un controlador que comprueba los recursos definidos en una configuración cada 15 segundos por defecto y los intenta implementar.- app-deployment Nombre del deployment a escalar
- –horizontal-pod-autoscaler-sync-period=x intervalo entre refresco de configuración
Scripts
Ficheros pod
Pod
Ejemplo para crear un pod, generalmente no se usa mucho porque no se querrá tener solo un pod, es más probable querer crear un deployment (ver más abajo) que tiene más características como ReplicaSet y proporciona alta disponibilidad y escalado así como capacidades de monitorización.
apiVersion: v1 # version de la sintaxis del fichero
kind: pod # se va a crear un pod
metadata:
name: web-pod # nombre del pod
labels: # agrega etiquetas personalizadas
app: app
zone: prod
version: v1
spec: # definición del pod
containers:
- name: app-web
image: autor/imagen
ports:
- containerPort: 80
ReplicationController
Ejemplo para ReplicationController, necesario cuando se quieren replicar pods específicos, si ya existiera uno del tipo especificado se tiene en cuenta para el total.
apiVersion: v1
kind: ReplicationController # Tipo necesario para ReplicationController
metadata:
name: app-rc
spec:
replicas: 5 # número de replicas
selector:
app: app # pod a replicar
zone: prod
version: v2
template: # plantilla con información sobre el pod
metadata:
labels:
app: app
zone: prod
version: v1
spec:
containers:
- name: app-web
image: autor/imagen
ports:
- containerPort: 80
Servicio
Script para crear un servicio (kubectl expose rc)
Normalmente un fichero deployment y otro service será lo necesario para crear un cluster kubernetes.
apiVersion: v1
kind: Service
metadata:
name: app-svc
spec:
selector:
app: app # que pods será expuestos
type: NodePort # diferentes tipos (ver kubectl expose rc)
ports: # mapeo de puertos
- port: 80 # puerto interno
nodePort: 30001 # puerto del cluster
El selector en este caso está usando una etiqueta, por lo que conectará todos los pods con esa etiqueta, las etiquetas se pueden establecer en un ReplicationController en la sección label la restricción es que se realiza una comparación por igualdad.
Deployment
Fichero para crear un deployment, opción recomendada para generar un cluster.
apiVersion: apps/v1
kind: Deployment
metadata: name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
matchExpressions:
- {key: zone, operator: In, values: [prod, test]} # ReplicaSet
strategy:
type: RollingUpdate
minReadySeconds: 5 # Segundos a esperar antes de crear el siguiente pod
rollingUpdate:
maxSurge: 1 # % o # de pods que pueden exceder las réplicas solicitadas
maxUnavailable: 1 # % o # de pods que pueden estar no disponibles durante la actualización
ports:
- protocol: TCP
port: 1433
targetPort: 1433
type: ClusterIP
template:
metadata:
labels:
app: myapp
zone: prod
version: v1
spec:
containers:
- name: app-web
image: apomic80/myapp:frontend-v1
ports:
- containerPort: 80
env:
- name: "Environment"
- value: "Production"
- name: "PASSWORD"
valueFrom:
secretKeyRef:
name: secreto
key: Password
volumeMounts: # volúmenes a montar
- name: mountVolume # volumen donde será montado
mountPath: ruta # ruta que será montada
- name: secret-volume
mountPath: /etc/secretVolume
volumes: # volúmenes reclamados a mapear en el host
- name: mountVolume # volumen lógico a ser usado por los contenedores
persistentVolumeClaim:
claimName: volume-claim # este volumen se tiene que haber creado previamente
- name: secret-volume # volumen lógico que tb es secreto
secret:
secretName: mssql # el nombre del secreto para poder acceder al volumen
Un deployment por defecto creará un ReplicaSet para poder indicar expresiones más complejas en las etiquetas, como si está contenida en un conjunto.
Hay dos estrategias de actualización:
- Recreate: Quita la versión previa y carga una nueva, útil para escenarios de desarrollo o prueba
- RollingUpdate: El valor por defecto, se mueve a una nueva versión gradualmente basado en los parámetros configurados, útil para entornos productivos
PersistentVolume
Un PersistentVolume es un recurso creado por un administrador de cluster con características específicas y un ciclo de vida independiente de tus aplicaciones
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-volume
labels:
type: local
spec:
storageClassName: hostpath
capacity:
storage: 10Gi # tamaño del almacenamiento
accessModes:
- ReadWriteOnce # modo de acceso lectura/escritura
hostPath:
path: /mnt/data # ruta donde se montará el volumen
Normalmente una ruta local para el almacenamiento solo se usa por razones de prueba o desarrollo.
PersistentVolumeClaim
PersistentVolumeClaim es un almacenamiento solicitado por el usuario basado en lo que necesita, como modos de acceso específico o tamaños.
El almacenamiento se crea con un fichero PersistentVolume con ciertas características y con un fichero PersistentVolumeClaim se solicita uno que tenga las características que quiere el usuario.
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-volume-claim
spec:
storageClassName: hostpath
accessModes:
- ReadWriteOnce # tipo de modo de acceso solicitado
resources:
requests:
storage: 3Gi # tamaño solicitado
Secret
Es posible crear un fichero que solo contenga un secreto que se usará para almacenar contraseñas por ejemplo.
apiVersion: v1
kind: Secret
metadata:
name: secreto
type: Opaque
data:
PASSWORD: UGFzc3dvcmRfMTIz # tiene que estar en base 64
En Linux se puede pasar un literal a Base64 como:
echo -n Password_123 | base64
Y para decodificarlo:
echo -n UGFzc3dvcmRfMTIz | base64 –decode
ResourceQuota
Establecer cuotas de recursos
apiVersion: v1
kind: ResourceQuota
metadata:
name: myapp-quota
spec:
hard:
limits.cpu: 1 # Cantidad de CPUs que pueden usar
limits.memory: 2Gi # Cantidad de memoria que pueden usar