DéveloppeurWeb.Com
    DéveloppeurWeb.Com
    • Agile Zone
    • AI Zone
    • Cloud Zone
    • Database Zone
    • DevOps Zone
    • Integration Zone
    • Web Dev Zone
    DéveloppeurWeb.Com
    Home»Uncategorized»Ouvrir l’agent de stratégie avec Kubernetes : 1ère partie
    Uncategorized

    Ouvrir l’agent de stratégie avec Kubernetes : 1ère partie

    février 22, 2023
    Ouvrir l'agent de stratégie avec Kubernetes : 1ère partie
    Share
    Facebook Twitter Pinterest Reddit WhatsApp Email

    Comme Kubernetes est devenu la plate-forme de facto pour orchestrer les charges de travail conteneurisées, de plus en plus d’utilisateurs ont commencé à chercher des moyens de contrôler et de sécuriser leurs clusters Kubernetes.

    Le durcissement est une chose sûre, mais qu’en est-il application des politiques à l’intérieur d’un cluster ? Il s’agit d’une tâche complètement différente qui nécessite un ensemble d’outils différent.

    Comme vous l’avez déjà deviné, une façon appropriée de le faire serait de définir politiques en tant que code, et un bon outil pour cela est « Open Policy Agent » ou OPA. Si vous ne savez pas de quoi je parle, veuillez d’abord prendre le temps de lire cette introduction : « Qu’est-ce que Policy-as-Code ? Une introduction à Open Policy Agent.

    Pourquoi ne pas simplement utiliser RBAC ?

    Pour mieux comprendre pourquoi nous devons utiliser un nouvel outil pour les politiques, prenons un exemple concret : imaginez que vous êtes un administrateur de cluster et que vous souhaitez restreindre ce qui peut s’exécuter dans votre cluster.

    À première vue, cela ressemble à un cas d’utilisation parfaitement valide pour le contrôle d’accès basé sur les rôles (RBAC, un système d’autorisation pour créer et gérer des objets Kubernetes au niveau des ressources) : avec RBAC, vous pouvez facilement autoriser des cas tels que « l’utilisateur X peut faire Y dans l’espace de noms Z. »

    Vous commencez par définir un Rôle dans le default espace de noms pour accorder un accès en lecture aux pods :

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: pod-reader
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "watch", "list"]

    Maintenant, un peu plus délicat : comment feriez-vous si vous vouliez restreindre, non pas l’accès aux ressources comme les pods, mais comment ils sont configurés?

    C’est là que s’arrêtent les pouvoirs du RBAC : les contrôles d’accès ne peuvent pas aller au-delà et restreindre les configurations, les paramètres et le contenu des objets de Kubernetes. Pourtant, en tant qu’administrateur de cluster, vous pouvez absolument le souhaiter.

    Pourquoi ne pas écrire mon propre contrôleur d’admission ?

    Pour les besoins de l’exercice, nous allons imaginer que vous devez exiger que tous les objets de ressource de votre cluster avoir une étiquette spécifique.

    Comme vous pouvez le voir, ceci n’est pas lié à un rôle ou à un groupe, en fait, il est lié à un champ très spécifique pour toutes les ressources de votre cluster.

    Supposons que vous ayez besoin de contrôler les champs de pod (ou tous les champs d’autres types de ressources, d’ailleurs). Dans ce cas, vous avez une option : créer votre propre contrôleur d’admission validant. Un contrôleur d’admission est un morceau de code qui intercepte les requêtes adressées au serveur d’API Kubernetes avant la persistance de l’objet.

    Dans le détail, cela fonctionnerait comme suit : une demande de création d’un nouveau pod est effectuée auprès du service d’API du cluster ; cela déclencherait une coutume ValidatingAdmissionWebhook correspondant à cette demande ; le contrôleur appellerait un webhook de validation ; si le contrôleur rejette la demande, le service API la rejettera également.

    Le problème avec cela est qu’il n’est pas évolutif : vous devrez écrire autant de contrôleurs d’admission personnalisés que de règles ou de politiques que vous souhaitez appliquer.

    C’est là qu’intervient OPA, et nous verrons ensemble comment le mettre en place.

    Ouvrir l’agent de stratégie dans Kubernetes

    Pour résoudre le défi ci-dessus, ce dont nous avons vraiment besoin ici, c’est d’un système qui prend en charge plusieurs configurations couvrant différents types et champs de ressources et permet la réutilisation. Open Policy Agent (OPA) fournit exactement cela.

    En un mot, le moteur de politique OPA évalue les demandes pour déterminer si elles sont conformes aux politiques configurées.

    OPA peut facilement s’intégrer à Kubernetes : il attend une entrée JSON, est facile à conteneuriser et prend en charge la configuration dynamique, ce qui le rend bien adapté pour fournir une évaluation de politique pour le service d’API Kubernetes.

    Plongeons-nous et montrons comment déployer et intégrer OPA avec Kubernetes.

    Comment utiliser OPA avec Kubernetes

    Dans cet exemple, nous montrerons comment intégrer OPA à Kubernetes en déployant une stratégie qui garantit que le nom d’hôte Ingress doit figurer sur la liste d’autorisation de l’espace de noms contenant Ingress.

    C’est-à-dire que nous voulons refuser toutes les créations d’objets Ingress dont le nom d’hôte ne correspond pas à la liste d’autorisation.

    Avant de commencer, téléchargez OPA si vous ne l’avez pas encore fait.

    Préparer le cluster Kubernetes

    Ce didacticiel nécessite Kubernetes 1.20 ou une version ultérieure. Pour exécuter le didacticiel localement, démarrez un cluster avec Kubernetes version 1.20+. minikube est recommandé.

    Si vous utilisez Kubernetes dans un service cloud, par exemple Amazon EKS, les contrôleurs d’admission dynamiques sont probablement déjà activés par défaut, ce qui vous permet de déployer des webhooks personnalisés. Sinon, vous devez activer le ValidatingAdmissionWebhook lorsque le serveur d’API Kubernetes est démarré. Le ValidatingAdmissionWebhook contrôleur d’admission est inclus dans l’ensemble recommandé de contrôleurs d’admission à activer.

    Commençons minikubeactivez le minikube Module complémentaire Ingress, créez un espace de noms (pour déployer OPA) et configurez le contexte Kubernetes :

    minikube start
    minikube addons enable ingress
    kubectl create namespace opa
    kubectl config set-context opa-tutorial --user minikube --cluster minikube --namespace opa
    kubectl config use-context opa-tutorial

    La communication entre Kubernetes et OPA doit être sécurisée à l’aide de TLS. utilisons openssl pour faire juste ça :

    openssl genrsa -out ca.key 2048
    openssl req -x509 -new -nodes -sha256 -key ca.key -days 100000 -out ca.crt -subj "/CN=admission_ca"
    
    # generate the TLS key and certificate for OPA:
    cat >server.conf <<EOF
    [ req ]
    prompt = no
    req_extensions = v3_ext
    distinguished_name = dn
    
    [ dn ]
    CN = opa.opa.svc
    
    [ v3_ext ]
    basicConstraints = CA:FALSE
    keyUsage = nonRepudiation, digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth, serverAuth
    subjectAltName = DNS:opa.opa.svc,DNS:opa.opa.svc.cluster,DNS:opa.opa.svc.cluster.local
    EOF
    
    openssl genrsa -out server.key 2048
    openssl req -new -key server.key -sha256 -out server.csr -extensions v3_ext -config server.conf
    openssl x509 -req -in server.csr -sha256 -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 100000 -extensions v3_ext -extfile server.conf
    
    # create a secret to store the TLS credentials for OPA
    kubectl create secret tls opa-server --cert=server.crt --key=server.key --namespace opa

    Définir la politique avec Rego

    Maintenant que le cluster Kubernetes est prêt, écrivons quelques stratégies. Commencez par créer un nouveau dossier pour les stocker :

    mkdir policies && cd policies

    Nous voulons une politique qui limite les noms d’hôte qu’un Ingress peut utiliser. Seuls les noms d’hôte correspondant aux expressions régulières spécifiées seront autorisés. Créer un fichier ingress-allowlist.rego avec le contenu suivant :

    package kubernetes.admission
    
    import data.kubernetes.namespaces
    
    operations := {"CREATE", "UPDATE"}
    
    deny[msg] {
      input.request.kind.kind == "Ingress"
      operations[input.request.operation]
      host := input.request.object.spec.rules[_].host
      not fqdn_matches_any(host, valid_ingress_hosts)
      msg := sprintf("invalid ingress host %q", [host])
    }
    
    valid_ingress_hosts := {host |
      allowlist := namespaces[input.request.namespace].metadata.annotations["ingress-allowlist"]
      hosts := split(allowlist, ",")
      host := hosts[_]
    }
    
    fqdn_matches_any(str, patterns) {
      fqdn_matches(str, patterns[_])
    }
    
    fqdn_matches(str, pattern) {
      pattern_parts := split(pattern, ".")
      pattern_parts[0] == "*"
      suffix := trim(pattern, "*.")
      endswith(str, suffix)
    }
    
    fqdn_matches(str, pattern) {
        not contains(pattern, "*")
        str == pattern
    }

    Si vous ne savez pas encore grand-chose sur le langage de politique Rego, lisez la documentation officielle.

    Essentiellement, ce morceau de code fait ce qui suit :

    • Le valid_ingress_hosts La fonction obtient l’annotation « ingress-allowlist » dans la section des métadonnées d’un espace de noms.
    • Ensuite, il essaie de faire correspondre le nom d’hôte à celui-ci à l’aide d’une expression régulière.
    • S’il n’y a pas de correspondance, la demande sera refusée avec un message.

    Ensuite, nous définirons la politique principale qui importera la politique de restriction de nom d’hôte ci-dessus et répondrons par une décision politique globale.

    Note: dans cet exemple, puisque nous n’utilisons qu’une seule politique, cette politique principale est un peu redondante. Pourtant, dans des situations réelles où vous souhaitez appliquer plusieurs politiques, la politique principale est nécessaire pour prendre une décision globale à la fin.

    Créer un fichier main.rego avec le contenu suivant :

    package system
    
    import data.kubernetes.admission
    
    main := {
      "apiVersion": "admission.k8s.io/v1",
      "kind": "AdmissionReview",
      "response": response,
    }
    
    default uid := ""
    
    uid := input.request.uid
    
    response := {
        "allowed": false,
        "uid": uid,
        "status": {
            "message": reason,
        },
    } {
        reason = concat(", ", admission.deny)
        reason != ""
    }
    
    else := {"allowed": true, "uid": uid}

    Construire et publier le bundle OPA

    Avec le code de politique Rego prêt, il est temps de le construire. Exécutez les commandes suivantes dans le dossier des stratégies pour créer et publier :

    cat > .manifest <<EOF 
    { 
    "roots": ["kubernetes/admission", "system"] 
    }
    EOF 
    opa build -b . 
    
    # serve the OPA bundle using Nginx:
    docker run --rm --name bundle-server -d -p 8888:80 -v ${PWD}:/usr/share/nginx/html:ro nginx:latest

    Ici, nous allons créer un « bundle » à partir du code Rego, puis nous servons le bundle dans un serveur Nginx dans un conteneur Docker, localement, qui sera intégré à OPA à l’étape suivante.

    Installer OPA en tant que contrôleur d’admission

    Tout d’abord, déployons OPA :

    kubectl apply -f https://gist.githubusercontent.com/IronCore864/035f7feca2c89ffd2809ec604fb3b873/raw/3e85364f72970b82f418544fd009fd478bc655ae/admission-controller.yaml

    Voyons une partie de cela admission-controller.yaml déposer:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: opa
      namespace: opa
      name: opa
    # ...
            - name: opa
              image: openpolicyagent/opa:0.47.3-rootless
    # ...
            - name: kube-mgmt
              image: openpolicyagent/kube-mgmt:2.0.1
              args:
                - "--replicate-cluster=v1/namespaces"
                - "--replicate=networking.k8s.io/v1/ingresses"

    Il existe un conteneur nommé kube-mgmtqui s’exécute en tant que side-car du conteneur OPA. kube-mgmt gère les politiques/données des instances OPA dans Kubernetes en…

    Share. Facebook Twitter Pinterest LinkedIn WhatsApp Reddit Email
    Add A Comment

    Leave A Reply Cancel Reply

    Catégories

    • Politique de cookies
    • Politique de confidentialité
    • CONTACT
    • Politique du DMCA
    • CONDITIONS D’UTILISATION
    • Avertissement
    © 2023 DéveloppeurWeb.Com.

    Type above and press Enter to search. Press Esc to cancel.