|
Este documento ha sido traducido utilizando tecnología de traducción automática. Si bien nos esforzamos por proporcionar traducciones precisas, no ofrecemos garantías sobre la integridad, precisión o confiabilidad del contenido traducido. En caso de discrepancia, la versión original en inglés prevalecerá y constituirá el texto autorizado. |
|
Esta es documentación inédita para Admission Controller 1.34-dev. |
Usando la Admisión de Seguridad de Pods con SUSE Security Admission Controller
Las Políticas de Seguridad de Pods (PSP) se han eliminado desde la versión 1.25 de Kubernetes. Se reemplazan por la Admisión de Seguridad de Pods (PSA).
La PSA simplifica la seguridad de los Pods en los clústeres de Kubernetes.
La PSA tiene tres perfiles (descritos en los Estándares de Seguridad de Pods) para los espacios de nombres:
-
privilegiado, proporcionando el rango más amplio de permisos
-
base, para prevenir nuevas escaladas de privilegios
-
restringido, restringido para endurecer los Pods
Un controlador de PSA realiza acciones al detectar violaciones.
Las acciones son: enforce, audit y warn.
Se pueden configurar.
En el momento de escribir, con Kubernetes 1.28, el controlador de PSA tiene las siguientes limitaciones:
-
Sin capacidades de mutación
-
Los objetos de nivel superior (como
Deployment,Job) se evalúan solo cuando los modosauditowarnestán habilitados
Admission Controller se puede usar para integrar un perfil de PSA para evitar estas limitaciones.
|
Podrías usar Admission Controller para reemplazar la antigua configuración de PSP como se muestra en migración de PSP. Sin embargo, el objetivo de este artículo es mostrar cómo Admission Controller puede complementar el nuevo PSA. |
Ejemplo
En este ejemplo estamos creando un espacio de nombres y aplicando políticas PSA restrictivas:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: my-namespace
labels:
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: v1.25
EOF
Este perfil de PSA no permite crear contenedores que ejecuten su aplicación como el usuario root.
Al definir este contenedor:
-
el atributo
runAsNonRootdebe establecerse entrue -
el
runAsUserno puede establecerse en0.
Por lo tanto, el siguiente recurso no alcanzará su estado deseado:
kubectl comando configurando un recurso con runAsUser: 0 (marcado como ➀)
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
runAsUser: 0 (1)
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
| 1 | runAsUser: 0 |
Si comprobamos la ampliación, podemos ver que el PSA impide la creación del pod:
kubectl get deploy -n my-namespace nginx-deployment -o json | jq ".status.conditions[] | select(.reason == \"FailedCreate\")"
{
"lastTransitionTime": "2022-10-28T19:09:56Z",
"lastUpdateTime": "2022-10-28T19:09:56Z",
"message": "pods \"nginx-deployment-5f98b4db8c-2m96l\" is forbidden: violates PodSecurity \"restricted:v1.25\": runAsUser=0 (container \"nginx\" must not set runAsUser=0)",
"reason": "FailedCreate",
"status": "True",
"type": "ReplicaFailure"
}
Puedes solucionar esto eliminando el runAsUser: 0 de la definición del contenedor:
kubectl comando configurando un recurso sin runAsUser: 0
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
Ahora la PSA permite un intento de creación de pod pero aún falla.
kubectl get pods -n my-namespace
NAME READY STATUS RESTARTS AGE
nginx-deployment-57d8568bbb-h4bx7 0/1 CreateContainerConfigError 0 47s
Es porque la definición del contenedor no especificó un usuario que se utilizará al iniciar un programa dentro del contenedor.
El valor por defecto es ejecutar como raíz si este es el caso.
Eso no está permitido por la directiva runAsNonRoot:
kubectl get pods -n my-namespace nginx-deployment-57d8568bbb-h4bx7 -o json | jq ".status.containerStatuses"
[
{
"image": "nginx:1.14.2",
"imageID": "",
"lastState": {},
"name": "nginx",
"ready": false,
"restartCount": 0,
"started": false,
"state": {
"waiting": {
"message": "container has runAsNonRoot and image will run as root (pod: \"nginx-deployment-57d8568bbb-8mvkc_my-namespace(add7bcc5-3d23-43d0-94e9-6e78f887a53f)\", container: nginx)",
"reason": "CreateContainerConfigError"
}
}
}
]
Aquí es donde Admission Controller puede ayudar.
Puedes usar la política user-group-policy para modificar la definición de la ampliación.
Esto configura un usuario por defecto para los contenedores omitiendo esa información.
|
Necesitas la pila Admission Controller en el clúster de Kubernetes para este ejemplo. Consulta el QuickStart para más detalles. |
Es posible imponer un rango de ID de usuario, por ejemplo, 1000—2000 y 4000—5000:
comando kubectl que impone un rango de ID de usuario
kubectl apply -f - <<EOF
apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
name: user-group-psp
spec:
policyServer: default
module: registry://ghcr.io/kubewarden/policies/user-group-psp:latest
rules:
- apiGroups: ["", "apps"]
apiVersions: ["v1"]
resources: ["pods", "deployments"]
operations:
- CREATE
- UPDATE
mutating: true
settings:
run_as_user:
rule: "MustRunAs"
overwrite: false
ranges:
- min: 1000
max: 2000
- min: 4000
max: 5000
run_as_group:
rule: "RunAsAny"
supplemental_groups:
rule: "RunAsAny"
EOF
Verifica que la directiva esté activa antes de continuar:
kubectl get clusteradmissionpolicy.policies.kubewarden.io/user-group-psp
Cuando la directiva esté activa, vuelve a crear la ampliación:
comando kubectl que recrea la ampliación
kubectl delete deployment -n my-namespace nginx-deployment && \
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
Ahora la ampliación está mutada por la directiva de Admission Controller que permite que el Pod se inicie.
El contenedor definido dentro del Pod tiene un valor por defecto de runAsUser:
kubectl get pods -n my-namespace nginx-deployment-57d8568bbb-nv8fj -o json | jq ".spec.containers[].securityContext"
{
"allowPrivilegeEscalation": false,
"capabilities": {
"drop": [
"ALL"
]
},
"runAsNonRoot": true,
"runAsUser": 1000,
"seccompProfile": {
"type": "RuntimeDefault"
}
}
La integración de Admission Controller puede hacer más en este escenario.
Puede verificar el valor del runAsUser proporcionado.
Este recurso es rechazado por la directiva de Admission Controller de antes:
comando kubectl para mostrar el rechazo del recurso
kubectl apply -n my-namespace -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment2
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: template-nginx
template:
metadata:
labels:
app: template-nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
securityContext:
runAsNonRoot: true
runAsUser: 7000 (1)
allowPrivilegeEscalation: false
capabilities:
drop:
- "ALL"
seccompProfile:
type: "RuntimeDefault"
ports:
- containerPort: 80
EOF
| 1 | runAsUser: 7000 |
Es rechazado porque el valor de runAsUser está establecido en 7000, que está fuera de los rangos permitidos por la directiva:
kubectl get deploy -n my-namespace nginx-deployment -o json | jq ".status.conditions[] | select(.reason == \"FailedCreate\")"
{
"lastTransitionTime": "2022-10-28T19:22:04Z",
"lastUpdateTime": "2022-10-28T19:22:04Z",
"message": "admission webhook \"clusterwide-user-group-psp.kubewarden.admission\" denied the request: User ID outside defined ranges",
"reason": "FailedCreate",
"status": "True",
"type": "ReplicaFailure"
}