logo
< Back Post-Image

Utiliser les PodSecurityPolicy avec Kubernetes Kapsule de Scaleway

Kubernetes Kapsule est le service de Kubernetes managé de Scaleway. Nous avons déjà traité la présentation du service dans un précédent article. Nous avions été assez élogieux, mettant particulièrement en avant le travail effectué sur le provider Terraform permettant de déployer et de manager, entièrement en infrastructure as code, nos clusters Kubernetes.

C’est d’ailleurs sur ce point que commence notre problème. La ressource Terraform permettant de déployer des clusters Kubernetes chez Scaleway permet de configurer ces clusters en choisissant les Admission Controllers à activer.

C’est quoi un Admission Controller ?

Un Admission Controller est controller dans Kubernetes qui permet d’effectuer un vérification sur une requête à l’API après l’authentification et avant l’exécution de la requête. Ces Admission Controllers peuvent valider qu’une requête correspond à certaines règles mais peuvent aussi modifier la requête pour la forcer à respecter une règle. On parle de validating ou mutating Admission Controller.

J’ai donc souhaité activer les PodSecurityPolicy sur mon cluster. On a déjà parlé de cet objet chez Particule, il s’agit de règles de sécurité concernant nos pods que l’Admission Controller va vérifier avant d’appliquer ou non le pod dans notre cluster. On peut par exemple interdir les pods qui utilisent le mode privileged, interdire les conteneurs qui tournent en root ou ceux qui tentent d’utiliser des hostPath. C’est extrêmement puissant.

Extrêmement puissant mais ça ne marche pas out of the box. Et Kapsule de Scaleway ne fait pas exception.

Voici déjà le code Terraform pour déployer l’Admission Controller :

resource "scaleway_k8s_cluster_beta" "k8s" {
  name = "particule"
  version = "1.18.2"
  cni = "weave"
  admission_plugins = ["PodSecurityPolicy"]
}

Normalement cela va très vite mais là étonnement, mon node reste en NotReady après plus de 10 minutes… Étrange.

NAME                                             STATUS     ROLES    AGE   VERSION
scw-particule-commonpool-dbfe057a9ee64e56b50f9   NotReady   <none>   11m   v1.18.2

Le problème est qu’activer les PodSecurityPolicy ça ne suffit pas, pire ça “casse” le cluster si rien d’autre n’est effectué.

Comme nous l’avons déjà expliqué, une fois les PSP activées, tous les pods qui souhaiteront être schédulés devront fournir une PSP à l’API Server afin que celui ci valide qu’ils respectent bien les règles. Si aucune PSP n’est disponible ou qu’un pod n’a le droit d’accéder à aucune d’entre elles, l’API Server lui refusera le déploiement.

Et c’est exactement ce qu’il se passe chez Kapsule. Aucun pod ne peut se schéduler car :

  • Aucune PSP n’est présente
  • Aucun droit n’est donné pour utiliser une PSP

On va donc corriger cela en créant une PSP privileged qui permettra d’absolument tout faire (comme si il n’y avait pas de PSP en fin de compte) et autoriser l’ensemble du cluster à utiliser cette PSP.

---
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: privileged
spec:
  allowPrivilegeEscalation: true
  allowedCapabilities:
  - '*'
  allowedUnsafeSysctls:
  - '*'
  fsGroup:
    rule: RunAsAny
  hostIPC: true
  hostNetwork: true
  hostPID: true
  hostPorts:
  - max: 65535
    min: 0
  privileged: true
  runAsUser:
    rule: RunAsAny
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  volumes:
  - '*'
---

Puis le ClusterRole et le ClusterRoleBinding qui permettront à tous les éléments authentifiés de votre cluster d’utiliser (use) la PSP :

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: psp:privileged
rules:
- apiGroups:
  - policy
  resourceNames:
  - privileged
  resources:
  - podsecuritypolicies
  verbs:
  - use
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: psp:any:privileged
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: psp:privileged
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:authenticated

On applique tout ce petit monde et on attend tranquillement que les pods CNI et kube-proxy se déploient pour que notre node passe en Ready.

NAME                                             STATUS   ROLES    AGE    VERSION
scw-particule-commonpool-dbfe057a9ee64e56b50f9   Ready    <none>   17m   v1.18.2

Et chez les autres Cloud Provider ?

Il est évidemment important de noter qu’il ne s’agit pas d’une faute de configuration de Scaleway. Le composant demandé est bien appliqué, il manque seulement certaines ressources que n’importe quel utilisateur peut créer pour profiter pleinement de la fonctionnalité. On pourra aussi remarquer que GKE ne fourni pas non plus de PSP lors de l’activiation de celles ci. Quant à EKS, une PSP ressemblant beaucoup à la notre est appliquée par défaut.

Conclusion

Les PSP sont des éléments importants de tout cluster et devraient toujours être pensées et crées en même temps que le cluster. Les appliquer ou les supprimer sur un cluster running nécessite d’être extrêmement rigoureux au risque de casser le cluster en fonctionnement.

Merci à Patrik de Scaleway pour m’avoir pointé dans la bonne direction.

Romain Guichard, CEO & co-founder