Tolerancia a fallos, escalabilidad, balanceo de carga: ReplicaSet
Para trabajar con los objetos ReplicaSet vamos a seguir trabajando con el usuario developer
pero vamos a crear un nuevo proyecto:
oc new-project proyecto-rs
En este caso también vamos a definir el recurso de ReplicaSet en un fichero replicaset.yaml
, por ejemplo como este:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: bitnami/nginx
name: contenedor-nginx
Algunos de los parámetros definidos ya lo hemos estudiado en la definición del Pod. Los nuevos parámetros de este recurso son los siguientes:
replicas
: Indicamos el número de Pods que siempre se deben estar ejecutando.selector
: Seleccionamos los Pods que va a controlar el ReplicaSet por medio de las etiquetas. Es decir este ReplicaSet controla los Pods cuya etiquetaapp
es igual anginx
.template
: El recurso ReplicaSet contiene la definición de un Pod. Fíjate que el Pod que hemos definido en la seccióntemplate
tiene indicado la etiqueta necesaria para que sea seleccionado por el ReplicaSet (app: nginx
).
Creación del ReplicaSet
De forma declarativa creamos el ReplicaSet ejecutando:
oc apply -f replicaset.yaml
Y podemos ver los recursos que se han creado con:
oc get rs,pod
Observamos que queríamos crear 2 replicas del Pod, y efectivamente se han creado.
Si queremos obtener información detallada del recurso ReplicaSet que hemos creado:
oc describe rs replicaset-nginx
Política de seguridad del Pod
Al crear el RepicaSet nos da un warning, de este estilo:
Warning: would violate PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (container "httpd" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "httpd" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "httpd" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "httpd" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost")
Este warning indica que el contenedor contenedor-nginx
no cumple con algunas de las restricciones de seguridad establecidas en la política de seguridad.
Las restricciones que se indican en el warning son:
allowPrivilegeEscalation != false
: Este parámetro debe ser false, lo que impide que el contenedor pueda obtener más privilegios de los que se le han asignado.unrestricted capabilities
: Esto significa que el contenedor debe establecersecurityContext.capabilities.drop=["ALL"]
para eliminar todas las capacidades adicionales del contenedor que no son necesarias.runAsNonRoot != true
: Este parámetro debe ser true para garantizar que el contenedor se ejecute como un usuario no privilegiado.seccompProfile
: Esto significa que el Pod o el contenedor deben establecersecurityContext.seccompProfile.type en "RuntimeDefault"
o"Localhost"
para garantizar que la política de seguridad de Seccomp esté configurada adecuadamente. Seccomp (modo de computación segura), es una característica del kernel de Linux que se puede utilizar para limitar el proceso que se ejecuta en un contenedor para que sólo llame a un subconjunto de las llamadas al sistema disponibles.
Solución 1: Actualizar la definición del Pod para indicar el contento de seguridad
Para resolver este warning, debe actualizar la definición del Pod o del contenedor para cumplir con estas restricciones de seguridad.
spec:
containers:
- image: bitnami/nginx
name: contenedor-nginx
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
seccompProfile:
type: RuntimeDefault
capabilities:
drop:
- ALL
Solución 2: Otorgar privilegios para ejecutar Pod privilegiados
Muchas de las interacciones que se hacen sobre la API de OpenShift se realizan por el usuario final, pero muchas otras se hacen internamente. Para hacer estas últimas peticiones a la API se utiliza una cuenta especial de usuario, que se llaman Service Account.
OpenShift crea automáticamente algunas Service Account en cada proyecto. Por ejemplo, hay una Service Account que se llama default y será la responsable de ejecutar los Pods.
Vamos a modificar los privilegios de ejecución al Service Account llamado default
, para ello:
oc login -u kubeadmin https://api.crc.testing:6443
oc project proyecto-rs
oc adm policy add-scc-to-user anyuid -z default
- Esta instrucción agrega el restricción de seguridad llamada anyuid al ServiceAccount predeterminado (
default
) en tu proyecto actual de OpenShift. - La restricción anyuid permite a los contenedores en el Pod ejecutarse con privilegios.
Esta segunda opción la utilizaremos más adelante para poder ejecutar Pods privilegiados.
Tolerancia a fallos
¿Qué pasaría si borro uno de los Pods que se han creado? Inmediatamente se creará uno nuevo para que siempre estén ejecutándose los Pods deseados, en este caso 2:
oc delete pod <nombre_del_pod>
oc get pod
Escalabilidad
Para escalar el número de Pods:
oc scale rs replicaset-nginx --replicas=5
oc get pod
NAME READY STATUS RESTARTS AGE
replicaset-nginx-88rzr 1/1 Running 0 9s
replicaset-nginx-gq8bs 1/1 Running 0 10m
replicaset-nginx-lrmwb 1/1 Running 0 9s
replicaset-nginx-wmcj6 1/1 Running 0 10m
replicaset-nginx-xzdq8 1/1 Running 0 9s
Otra forma de hacerlo sería cambiando el parámetro replicas
de fichero YAML, y volviendo a ejecutar:
oc apply -f nginx-rs.yaml
La escalabilidad puede ser para aumentar el número de Pods o para reducirla:
oc scale rs replicaset-nginx --replicas=1
Eliminando el ReplicaSet
Por último, si borramos un ReplicaSet se borrarán todos los Pods asociados:
oc delete rs replicaset-nginx
Otra forma de borrar el recurso, es utilizar el fichero YAML:
oc delete -f replicaset.yaml