Con este documento, podrás planificar la migración de políticas de seguridad desde las restricciones del contexto de seguridad (SCC) de OpenShift definidas en un clúster de OpenShift de origen a un clúster de GKE de destino. La implementación usa las restricciones del Controlador de políticas para definir las políticas migradas en el clúster de destino.
En el documento, se supone que estás familiarizado con Migra contenedores a Google Cloud: migra de OpenShift a GKE Enterprise. Se supone que estás familiarizado con OpenShift y las restricciones del contexto de seguridad y que tienes acceso a un clúster de OpenShift de origen y un clúster de GKE de destino.
Este documento pertenece a una serie de varias partes sobre la migración a Google Cloud. Para obtener una descripción general de la serie, consulta Migración a Google Cloud: Elige la ruta de migración.
Este documento es parte de una serie en la que se analiza la migración de contenedores a Google Cloud:
- Migra contenedores a Google Cloud: Migra Kubernetes a Google Kubernetes Engine (GKE)
- Migra contenedores a Google Cloud: Migra de OpenShift a GKE Enterprise
- Migra contenedores a Google Cloud: Migra proyectos de OpenShift a GKE Enterprise
- Migra de OpenShift a GKE Enterprise: Migra las SCC de OpenShift a las restricciones del Controlador de políticas (este documento)
Este documento es útil si planeas migrar SCC de OpenShift a GKE Enterprise. Este documento también es útil si estás evaluando la posibilidad de migrar y deseas explorar cómo podría ser.
Este documento se basa en los conceptos que se describen en Migración a Google Cloud: Comienza ahora, Migra contenedores a Google Cloud: migra Kubernetes a GKE, Migra contenedores a Google Cloud: migra de OpenShift a GKE y Prácticas recomendadas para herramientas de redes de GKE. Incluye vínculos a los documentos cuando corresponda.
SCC de OpenShift
Las SCC son recursos específicos de OpenShift que se usan para definir políticas en Pods que especifican las acciones que un Pod puede realizar y a qué recursos puede acceder en los nodos. Cuando realizas una solicitud a la API para crear un Pod, las SCC evalúan las solicitudes de Pods en términos de privilegios de proceso frente a un conjunto de políticas que se definen a través de SCC. Las SCC evalúan las solicitudes para permitir o no la ejecución de los Pods según las políticas configuradas. Para obtener más información sobre las SCC de OpenShift, consulta Administra restricciones del contexto de seguridad.
SCC predeterminadas de OpenShift
Los clústeres 4.x de OpenShift contienen un conjunto de SCC predeterminadas que se describen en la entrada de blog Administra SCC en OpenShift de Red Hat.
Sincronización de configuración y Policy Controller
En esta sección, se describe el Sincronizador de configuración y el Controlador de políticas. Además, se proporcionan vínculos a la documentación relevante y orientación para configurar Policy Controller para que realice las tareas de migración que se describen más adelante en este documento.
Sincronizador de configuración
El Sincronizador de configuración te permite usar un repositorio común que cumpla con Git para definir de forma centralizada la configuración de cualquier recurso que se aplique a cualquier clúster de Kubernetes administrado por GKE Enterprise. Aplica esa configuración a varios clústeres.
Policy Controller
Policy Controller es un controlador de admisión dinámico de Kubernetes que verifica, audita y aplica el cumplimiento de tus clústeres con políticas definidas de forma central. Policy Controller se basa en el proyecto de código abierto Open Policy Agent (OPA) Gatekeeper.
Configuración del Sincronizador de configuración y el Policy Controller
Para prepararte para implementar las políticas de seguridad que duplican las SCC de OpenShift, habilita los componentes del Sincronizador de configuración y de Policy Controller para cada uno de los clústeres de destino. En esta sección, se describe cómo configurar estos componentes. En la sección Migra las SCC de OpenShift que aparece más adelante en este documento, se describe cómo usar las plantillas de restricciones del Controlador de políticas para implementar las políticas de seguridad.
Cuando configuras el Controlador de políticas, se recomienda colocar los espacios de nombres relacionados con el sistema que no ejecuten los Pods de la aplicación en el campo Espacios de nombres exentos. Eximir los espacios de nombres relacionados con el sistema te ayuda a evitar el riesgo de bloquear cualquier Pod del sistema que requiera privilegios elevados. Los espacios de nombres relacionados con el sistema en un clúster de GKE pueden incluir lo siguiente:
kube-system
kube-public
gke-connect
gke-system
config-management-system
config-management-monitoring
gatekeeper-system
istio-system
cnrm-system
knative-serving
monitoring-system
Después de configurar Policy Controller con las excepciones anteriores, agrega la etiqueta admission.gatekeeper.sh/ignore=true
a cada espacio de nombres para excluir los espacios de nombres de la aplicación de restricciones. Si no agregas la etiqueta a cada espacio de nombres, los Pods del sistema (y, por lo tanto, todo tu clúster) pueden verse afectados por políticas restringidas.
Migra las SCC de OpenShift a las restricciones de Policy Controller
En esta sección, se describe cómo puedes exportar las SCC desde tu clúster de OpenShift y configurar las restricciones del Policy Controller de GKE Enterprise de destino para que coincidan con las políticas obligatorias. En esta sección, también se describen algunas diferencias entre las SCC y las restricciones de Policy Controller para que puedas planificar la migración según corresponda.
Evalúa las SCC de OpenShift
Para exportar una lista y configuración de las SCC que se instalan en tu clúster de OpenShift, puedes usar los siguientes comandos:
Obtén una lista de todas las SCC:
oc get scc
Exporta la configuración de cada SCC:
oc get scc SCC_NAME > SCC_NAME.yaml
Reemplaza
SCC_NAME
por el nombre de la SCC para la que deseas exportar la configuración.
Después de exportar la configuración, puedes analizarla y usar la tabla en la siguiente sección Asigna las SCC de OpenShift para configurar las restricciones del Controlador de políticas que coincidan con los requisitos de seguridad de tu aplicación.
Asigna las SCC de OpenShift a las plantillas de restricciones del Controlador de políticas
En la siguiente tabla, se proporcionan las restricciones y la configuración del Controlador de políticas que corresponden a los campos de SCC de OpenShift y sus posibles valores. Usa la tabla para configurar las restricciones del Controlador de políticas de destino que coinciden con los requisitos de seguridad para aplicaciones que se implementaron a través de las SCC de OpenShift en el entorno de origen. En la sección Ejemplo de migración de extremo a extremo de este documento, se proporciona un ejemplo de cómo usar la información de la tabla.
Campo de SCC de OpenShift | Tipo/valores posibles | Plantilla de restricciones de Policy Controller | Especificación de restricciones de Policy Controller |
---|---|---|---|
allowPrivilegedContainer: |
Booleano | K8sPSPPrivilegedContainer | Evita los contenedores privilegiados si se aplican. |
allowHostIPC: |
Booleano | K8sPSPHostNamespace | Impide el acceso al espacio de nombres pid y ipc del host si se aplica. |
allowHostPID: |
Booleano | K8sPSPHostNamespace | Impide el acceso al espacio de nombres pid y ipc del host si se aplica. |
allowHostNetwork: |
Booleano | K8sPSPHostNetworkingPorts | Tiene un parámetro booleano a fin de evitar el acceso a la red de host y puede definir un rango para los puertos de host accesibles. |
allowHostPorts: |
Booleano | K8sPSPHostNetworkingPorts | Tiene un parámetro booleano a fin de evitar el acceso a la red de host y puede definir un rango para los puertos de host accesibles. |
readOnlyRootFilesystem: |
Booleano | K8sPSPReadOnlyRootFilesystem | Te permite activar el sistema de archivos raíz de contenedor como de solo lectura si se aplica. |
allowPrivilegeEscalation: true |
Booleano | K8sPSPAllowPrivilegeEscalationContainer | Evita que los Pods con el contexto de seguridad AllowPrivilegeEscalation se establezcan como verdaderos si se aplican. |
allowHostDirVolumePlugin: |
Booleano | K8sPSPVolumeTypes | Tiene un parámetro para definir una lista de tipos de volúmenes permitidos (como en las SCC) incluido el directorio de host. |
volumes: |
Lista de arrays con el tipo de volúmenes permitidos | K8sPSPVolumeTypes | Tiene un parámetro para definir una lista de tipos de volúmenes permitidos (como en las SCC) incluido el directorio de host. |
allowedCapabilities: |
Lista de arrays de capacidades de Linux que se pueden solicitar. | K8sPSPCapabilities | Tiene parámetros para definir las capacidades de Linux que se pueden solicitar (allowedCapabilities) y que están prohibidas (requiredDropCapabilites ).
No se puede usar para agregar ni descartar directamente las capacidades enumeradas, como se puede hacer en |
defaultAddCapabilities: |
Lista de arrays de capacidades de Linux que se deben agregar a cada contenedor. | K8sPSPCapabilities | Tiene parámetros para definir las capacidades de Linux que se pueden solicitar (allowedCapabilities) y que están prohibidas (requiredDropCapabilites ).
No se puede usar para agregar ni descartar directamente las capacidades enumeradas, como se puede hacer en |
requiredDropCapabilities: |
Lista de arrays de capacidades de Linux que se descartan de forma automática del Pod o contenedor. | K8sPSPCapabilities | Tiene parámetros para definir las capacidades de Linux que se pueden solicitar (allowedCapabilities) y que están prohibidas (requiredDropCapabilites ).
No se puede usar para agregar ni descartar directamente las capacidades enumeradas, como se puede hacer en |
fsGroup: |
Tiene una type: key que puede ser una de las siguientes opciones:
|
K8sPSPAllowedUsers | Te permite definir reglas que tengan una función similar a type: key en SCC y en los rangos id para runAsUser , runAsGroup , supplementalGroups y parámetros fsGroup .
Se puede usar a fin de definir rangos permitidos para usuarios, grupos, grupos complementarios o grupos de FS, pero no para configurar el ID de usuario directamente en el Pod, como se puede hacer en las SCC de OpenShift. |
runAsUser: |
Tiene una type: key que puede ser una de las siguientes opciones:
|
K8sPSPAllowedUsers | Te permite definir reglas que tengan una función similar a type: key en SCC y en los rangos id para runAsUser , runAsGroup , supplementalGroups y parámetros fsGroup .
Se puede usar a fin de definir rangos permitidos para usuarios, grupos, grupos complementarios o grupos de FS, pero no para configurar el ID de usuario directamente en el Pod, como se puede hacer en las SCC de OpenShift. |
supplementalGroups: |
Tiene una type: key que puede ser una de las siguientes opciones:
|
K8sPSPAllowedUsers | Te permite definir reglas que tengan una función similar a type: key en SCC y en los rangos id para runAsUser , runAsGroup , supplementalGroups y parámetros fsGroup .
Se puede usar a fin de definir rangos permitidos para usuarios, grupos, grupos complementarios o grupos de FS, pero no para configurar el ID de usuario directamente en el Pod, como se puede hacer en las SCC de OpenShift. |
seLinuxContext: |
Tiene una type: key que puede ser una de las siguientes opciones:
|
K8sPSPSELinuxV2 | Tiene un parámetro allowedSELinuxOptions en el que puedes establecer el nivel, el rol, el tipo y el usuario seLinuxOptions permitidos. |
Diferencias entre las SCC de OpenShift y las restricciones del Controlador de políticas
En esta sección, se describen algunas diferencias entre las restricciones del Controlador de políticas y las SCC de OpenShift. Ten en cuenta estas diferencias antes de usar la tabla anterior para implementar restricciones en el entorno de destino.
Cómo se aplican las restricciones a los recursos
Puedes asignar las SCC de OpenShift a los usuarios y grupos mediante la especificación users:
o group:
que está presente en el objeto SCC. Con OpenShift 4.x y versiones posteriores, también puedes asignar las SCC a los usuarios o grupos mediante el control de acceso basado en roles (RBAC).
Las SCC también tienen un campo priority:
que se usa para ordenar las SCC que se aplican a un Pod.
Las restricciones de Policy Controller se aplican a los clústeres, los espacios de nombres o los Pods de destino que usan selectores de recursos específicos en la restricción, en lugar de segmentarse al usuario o cuenta de servicio. Para obtener más información, consulta la documentación de Policy Controller. El uso de selectores de recursos específicos ayuda a garantizar que el Pod se comporte de la misma manera, ya sea que un usuario de bajo privilegio lo ejecute con una herramienta de implementación o que un administrador de clúster lo inicie desde la línea de comandos.
Las restricciones del Controlador de políticas también admiten un modo de ejecución de prueba, que te permite probar políticas y auditar incumplimientos antes de la aplicación real. El uso de este modo te ayuda a evitar el impacto en las cargas de trabajo existentes, mientras que las SCC siempre se aplican si corresponde al usuario.
Mutación del Pod de SCC con valores asignados previamente en espacios de nombres de OpenShift
En las SCC de OpenShift, puedes modificar el contexto de seguridad relacionado de cada Pod al que se aplica la SCC con un ID específico de un rango asignado previamente que proporcionan las anotaciones en los espacios de nombres. Para ello, usa los campos RunAsUser
, fsGroup
, supplementalGroups
y seLinuxContext
con un tipo de estrategia MustRunAs
o MustRunAsRange
.
Por ejemplo, considera una SCC restricted
que tiene un campo RunAsUser
con un tipo de estrategia MustRunAsRange
sin rango definido en la SCC. En este caso, cada Pod al que se aplica la SCC obtiene un ID RunAsUser
del rango especificado en la anotación openshift.io/sa.scc.uid-range
en el espacio de nombres del Pod.
Las restricciones de Policy Controller junto con las funciones de mutación proporcionan validación y mutación de Pods. Sin embargo, las restricciones no usan anotaciones en los espacios de nombres a fin de proporcionar valores para los contextos de seguridad de Pods. En la siguiente sección, Ejemplo de migración de extremo a extremo, se proporciona un ejemplo de cómo los equipos de entrega de aplicaciones deben configurar de forma explícita los contextos de seguridad en los Pods para que cumplan con las restricciones similares a las que se mencionaron antes.
Ejemplo de migración de extremo a extremo
En esta sección, se proporciona un archivo de manifiesto de destino de ejemplo que incluye todas las restricciones y los mutadores de políticas de Policy Controller que necesitas para asignar las siguientes SCC predeterminadas de OpenShift en tu clúster de GKE de destino:
privileged
anyuid
nonroot
restricted
Según el espacio de nombres en el que se ejecuta un Pod, este obtiene diferentes restricciones de Policy Controller cuando asignas las políticas SCC que se definen en un entorno de OpenShift de origen:
Las cargas de trabajo que necesitan el acceso con más privilegios, como la capacidad de ejecutarse en modo privilegiado o acceder a cualquier recurso de host, deben ejecutarse en uno de los espacios de nombres exentos que se definen en la configuración de Policy Controller.
No se aplican restricciones a los espacios de nombres exentos. Las cargas de trabajo que tienen este acceso con privilegios más altos suelen ser componentes del sistema o cualquier carga de trabajo a la que se haya aplicado la SCC privilegiada en el entorno de origen de OpenShift.
Todos los Pods que se crean en cualquier espacio de nombres no exento tienen las restricciones más limitantes. Estas restricciones deniegan el acceso a todas las funciones de host y requieren que los Pods se ejecuten con un UID que sea parte de un rango específico. Esta configuración coincide con las políticas que aplican las SCC
restricted
de OpenShift. Las excepciones a esta configuración incluyen las siguientes:- Los Pods que se crean en un espacio de nombres y que tienen la etiqueta
security=anyuid
obtienen las restricciones limitantes anteriores, pero se pueden ejecutar con cualquier UID y cualquier GID. Esto coincide con las restricciones de la SCCanyuid
en OpenShift. - Los Pods que se crean en un espacio de nombres que tiene la etiqueta
security=nonroot
obtienen las restricciones limitantes anteriores. Sin embargo, los Pods pueden ejecutarse con cualquier UID no raíz. Esto coincide con las restricciones de la SCCnonroot
en OpenShift.
- Los Pods que se crean en un espacio de nombres y que tienen la etiqueta
Ejemplo de manifiesto de destino
El siguiente es un ejemplo de un solo manifiesto que incluye un conjunto de restricciones y mutadores del Controlador de políticas que coinciden con el comportamiento descrito en el ejemplo de migración de extremo a extremo anterior. Te recomendamos que revises y ajustes las restricciones o su alcance en este ejemplo según las necesidades de tu organización.
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPHostNamespace
metadata:
name: psp-host-namespace
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPHostNetworkingPorts
metadata:
name: psp-host-network-ports
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
hostNetwork: false
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: psp-privileged-container
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
---
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: restricted-capabilities
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
scope: Namespaced
kinds:
- apiGroups: ["*"]
kinds: ["Pod"]
namespaceSelector:
matchExpressions:
- operator: NotIn
key: security
values: ["anyuid"]
location: "spec.containers[name:*].securityContext.capabilities.drop"
parameters:
assign:
value: ["KILL","MKNOD","SYS_CHROOT"]
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPCapabilities
metadata:
name: restricted-capabilities
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaceSelector:
matchExpressions:
- operator: NotIn
key: security
values: ["anyuid"]
parameters:
requiredDropCapabilities: ["KILL","MKNOD","SYS_CHROOT"]
---
apiVersion: mutations.gatekeeper.sh/v1alpha1
kind: Assign
metadata:
name: anyuid-capabilities
spec:
applyTo:
- groups: [""]
kinds: ["Pod"]
versions: ["v1"]
match:
scope: Namespaced
kinds:
- apiGroups: ["*"]
kinds: ["Pod"]
namespaceSelector:
matchExpressions:
- operator: In
key: security
values: ["anyuid"]
location: "spec.containers[name:*].securityContext.capabilities.drop"
parameters:
assign:
value: ["MKNOD"]
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPCapabilities
metadata:
name: anyuid-capabilities
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaceSelector:
matchExpressions:
- operator: In
key: security
values: ["anyuid"]
parameters:
requiredDropCapabilities: ["MKNOD"]
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPAllowedUsers
metadata:
name: restricted-users-and-groups
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaceSelector:
matchExpressions:
- operator: NotIn
key: security
values: ["anyuid","nonroot"]
parameters:
runAsUser:
rule: MustRunAs # MustRunAsNonRoot # RunAsAny
ranges:
- min: 1000
max: 2000
fsGroup:
rule: MustRunAs # MayRunAs # RunAsAny
ranges:
- min: 1000
max: 2000
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPAllowedUsers
metadata:
name: nonroot-users-and-groups
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaceSelector:
matchExpressions:
- operator: In
key: security
values: ["nonroot"]
parameters:
runAsUser:
rule: MustRunAsNonRoot
fsGroup:
rule: MustRunAsNonRoot
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPVolumeTypes
metadata:
name: psp-volume-types
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
volumes:
- configMap
- downwardAPI
- emptyDir
- nfs
- persistentVolumeClaim
- projected
- secret
La restricción restricted-users-and-groups
en el manifiesto de ejemplo usa la plantilla K8sPSPAllowedUsers
a fin de establecer de forma explícita un rango de ejemplo de 1,000 a 2,000 para los parámetros runAsUser:
y fsGroup:
. Cualquier Pod que no esté configurado para usar un ID en ese rango para runAsUser:
y fsGroup:
se bloquea.
GKE Enterprise y Kubernetes no usan anotaciones de espacio de nombres para mutar de forma automática los Pods con un ID de usuario o grupo específico. Por lo tanto, para limitar el rango de UID como en el ejemplo anterior, tus equipos de entrega de aplicaciones deben establecer de forma explícita un UID que cumpla con los requisitos en el Pod creado, o debes quitar por completo la restricción para permitir cualquier ID.
El siguiente es un ejemplo de un manifiesto de Pod que cumple con las restricciones anteriores en cualquier espacio de nombres en el que lo crees (el manifiesto cumple con la SCC restricted
):
apiVersion: v1
kind: Pod
metadata:
name: restricted-pod-example
spec:
securityContext:
runAsUser: 1000
fsGroup: 1100
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
¿Qué sigue?
- Explora arquitecturas de referencia, diagramas y prácticas recomendadas sobre Google Cloud. Consulta nuestro Cloud Architecture Center.