Catégorie dans Astuces techniques

Ajouter un self-signed certificat dans Kubernetes avec Containerd

Dans cet article (Déployer Harbor avec type loadBalancer) j’ai expliqué comment déployer Habor et utiliser le certificat self-signed pour que Docker puisse l’utiliser. Si vous utilisez Kubernetes avec docker, vous pouvez aussi suivre cette procédure sur chaque worker node. Sinon vous risquez d’avoir l’erreur suivante :

Unknown desc = failed to pull and unpack image “harbor.cpod-tkg.az-lab.shwrfr.com/memecached/hello-world:latest”: failed to resolve reference “harbor.cpod-tkg.az-lab.shwrfr.com/memecached/hello-world:latest”: failed to do request: Head https://harbor.cpod-tkg.az-lab.shwrfr.com/v2/memecached/hello-world/manifests/latest: x509: certificate signed by unknown authority
Warning Failed 12s (x2 over 24s) kubelet, tkg-utility-md-0-798c695db5-pjgsk Error: ErrImagePull

Si vous utilisez Kubernetes avec Containerd, la procédure est différente. Mon collègue Rob Hardt (https://gist.github.com/rhardt-pivotal/) a développé un script pour ça : https://gist.githubusercontent.com/rhardt-pivotal/4aa09ced6302194561936717262bb203/raw/623c707748925c969c525ade4bb432f95b61cff0/node-ca-updater-daemonset.yaml

Il faut néanmoins modifier les 3 champs en rouge :

apiVersion: v1
data:
  ca.pem: |+
    —–BEGIN CERTIFICATE—–
    Mettre votre certificat
    —–END CERTIFICATE—–

kind: ConfigMap
metadata:
 name: trusted-ca-cm
 namespace: default

   —-

apiVersion: v1
data:
    build-ca.sh: “#!/usr/bin/env bash \nset -euxo pipefail\ntdnf update \ntdnf install -y ca-certificates\ntdnf install -y openssl-c_rehash\necho \”$TRUSTED_CERT\” > /etc/ssl/certs/my-trusted-cert.pem\n/usr/bin/rehash_ca_certificates.sh\ncurl -vv https://<Votre URL HARBOR>\n”
kind: ConfigMap
metadata:
    name: rehash-script
    namespace: default
—   
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: trusted-ca-updater
  namespace: default
  labels:
    k8s-app: trusted-ca-updater
spec:
  selector:
    matchLabels:
      name: trusted-ca-updater
  template:
    metadata:
      labels:
        name: trusted-ca-updater
    spec:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can’t run pods
      – key: node-role.kubernetes.io/master
        effect: NoSchedule
      initContainers:
      – name: script-runner
        image: photon:3.0
        command: [“/bin/sh”, “-c”, “/root/build-ca.sh” ]
        volumeMounts:
        – name: update-trusted-certs-script
          mountPath: /root/
        – name: certs-dir
          mountPath: /etc/ssl/certs
        – name: agg-certs-dir
          mountPath: /etc/pki/tls/certs/
        env:
        – name: TRUSTED_CERT
          valueFrom:
            configMapKeyRef:
              name: trusted-ca-cm
              key: ca.pem   
        resources:
            limits:
              ephemeral-storage: 30G # mettre une plus petite taille
      containers:
      – name: sleepy
        image: photon:3.0
        command: [“/bin/sh”]
        args: [“-c”, “while true; do sleep 3600;done”]
      volumes:
      – name: update-trusted-certs-script
        configMap:
            name: rehash-script
            defaultMode: 0766
      – name: certs-dir
        hostPath:
          path: /etc/ssl/certs
          type: Directory
      – name: agg-certs-dir
        hostPath:
          path: /etc/pki/tls/certs/
          type: Directory

 

Il faut ensuite se connecter sur les workernodes pour relancer containerd. Ci-dessous un exemple pour TKG (Une solution Kubernetes as a Service pour tous les Clouds)

# ssh capv@<ip-YourWokerNode>

capv@YourWokerNode$ sudo systemctl restart containerd

Déployer Kubeapps

Kubeapps est un projet Bitnami. Bitnami a été racheté par VMware en 2019 et fait partie maintenant de la gamme Tanzu et se nomme Tanzu Application Catalog. Kubeapps est un catalogue de déploiement et de management d’applications et de services. Il arrive déjà connecté à la marketplace bitnami et il est possible de synchroniser une registry type docker. https://bitnami.com/kubernetes/kubeapps

La documentation d’installation est assez bien faite, je n’ai trouvé de complexité, juste un peu de vigilance au niveau des rôles si vous êtes en production. Un utilisateur peut avoir un accès en lecture seul et/ou en lecture/écriture (nécessaire pour déployer des applications), le scope des droits peut être le cluster et/ou le namespace. L’utilisateur à la possibilité de créer des namespaces pour y déployer des applications. https://github.com/kubeapps/kubeapps

Installation via Helm (version 3 dans mon exemple)

$ helm repo add bitnami https://charts.bitnami.com/bitnami

$ kubectl create namespace kubeapps

$ helm install kubeapps –namespace kubeapps bitnami/kubeapps –set useHelm3=true –-set fontend.service.type=LoadBalancer

 

Créer un compte et le rôle pourvoir accéder à Kubeapps et pour installer des applications, créer des namespace directement depuis l’interface. Récupérez le token pour se logger à l’interface

$ kubectl create -n default serviceaccount loeilduse

$ kubectl create clusterrolebinding loeilduse –clusterrole=cluster-admin –serviceaccount=default:loeilduse

$ kubectl get -n default secret $(kubectl get -n default serviceaccount loeilduse -o jsonpath='{.secrets[].name}’) -o go-template='{{.data.token | base64decode}}’ && echo

Récupérer le token, il sera demandé lors de la connexion à Kubeapps via le navigateur (ci-dessous un exemple)

eyJhbGciOiJSUzI1NiIsImtpZCI6IkV5bEdwMDU2dkVqTld5dFJtR03RHNVSmhmd09rc1licnJFSm81Nm1EZ3MifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImxvZWlsZHVzZS10b2tlbi1yOGJiZyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZShY2NvdW50Lm5hbWUiOiJsb2VpbGR1c2UiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5NTMwZjZmNy1jMzEzLTQ5MzctODY2ZS1mMDUwNzY0YmI0MDEiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpb2VpbGR1c2UifQ.kTZhrfFXrOS-S2a3x6oiyO6mqi7d62lrsmy-pTLpFX-XsjAK8NZQ95WaKqJ1gHkQfJa4ah-gvSQOVeI0y8-TueS24iAbrMfFwuocbHOJa6d9x9dfBSNGfxgW2DZaA22TokAVm_VT_DmFbV7uqsOSdFNRC6GnogoUmaO0P2-X1A8HHXuur04zRU5pH-8kNUrmIclIlpUPIaDlkRV1v94nZfn1S0RswG4wzTY1IeqQn4Nn5vh9XKfavp7l42vSWH7F0AHnkpTpY94GN8TNVoninPBkl5ktcF6PZJ7qbYlEK4wz5Y_cEgJFArGYn3kaihzZaZsAH7a6scVsk7KcTuYRQ

Récupérer l’IP fournit par le service Load Balancer

$ Kubectl get svc -n kubeapps

 

 

Ouvrir la page web avec l’IP fourni par le load balancer et renseigner le token récupéré :

 

Si vous avez le message ci-dessous, revoyez la partie création user/droit décrite juste avant

 

Vous devriez avoir ces types d’écrans

 

Lorsque vous déployez des applications depuis le catalogue Kubeapps, n’oubliez pas de modifier le fichier yaml si vous voulez y accéder depuis l’extérieur de votre cluster Kubernetes. Ci-dessous, un exemple de déploiement de Dokuwiki pour qu’il soit accessible via un load balancer (voir tout en bas) :

 

Déployer Harbor avec type loadBalancer

Pour rédiger mes articles de vulgarisation, je suis amené à tester certains produits. C’est très chronophage surtout quand ça ne fonctionne pas du premier coup. Je fais pas mal de recherche sur Internet pour voir si des posts donnent des astuces mais des fois, il faut tenter d’autres pistes. C’est pour cela que j’ai créé une rubrique Astuces Techniques, j’y posterai un résumé des résultats de mes recherches qui pourrait aider d’autres personnes.

Je consacre ce premier article au déploiement de la registry Harbor développée initialement par VMware puis donné à la CNCF. J’ai beaucoup galéré pour la déployer afin qu’elle soit accessible derrière un loadbalancer, j’avais le message suivant lorsque que docker tentait de s’y connecter :

#docker login harbor.cpod-tkg.az-lab.shwrfr.com
Authenticating with existing credentials…
Login did not succeed, error: Error response from daemon: Get https://harbor.cpod-tkg.az-lab.shwrfr.com/v2/: Get https://core.harbor.domain/service/token?account=admin&client_id=docker&offline_token=true&service=harbor-registry: dial tcp: lookup core.harbor.domain: no such host

J’utilise un environnement vSphere 7 pour héberger un cluster Kubernetes V1.17.3 déployé via TKG V1. Le loadbalancer est un Metallb V0.82, Habor V1.10.1 et HELM 3

Télécharger Harbor via Helm 3 :

#helm repo add harbor https://helm.goharbor.io

#helm fetch harbor/harbor –untar

Créer une storage class nécessaire aux volumes persistent, cette storage class utilise une storage policy que j’ai déjà créé dans vSpehre :

kind: StorageClass

apiVersion: storage.k8s.io/v1

metadata:

  name: silver-storage-class

  annotations:

    storageclass.kubernetes.io/is-default-class: “true”

provisioner: csi.vsphere.vmware.com

parameters:

  storagepolicyname: “silver-storage-class”

Installer Harbor avec les bons paramètres notamment externalURL :

# helm install -n harbor-system registry harbor/harbor –set expose.type=loadBalancer,expose.tls.commonName=harbor.cpod-tkg.az-lab.shwrfr.com,externalURL=https://harbor.cpod-tkg.az-lab.shwrfr.com

Si vous n’utilisez pas de certificats signés, il faut que docker soit autorisé à utiliser une registry “Insecure” :

#cat /etc/docker/daemon.json

{

        “insecure-registries” : [“172.20.4.71”, ’’harbor.cpod-tkg.az-lab.shwrfr.com’’]

}

# systemctl restart docker

Télécharger le certificat depuis l’UI d’Harbor => projets => <votre nom de projet> => Reprositories => REGISTRY CERTIFICATE et le copier dans le répertoire docker prévu à cet effet :

#mkdir -p /etc/docker/certs.d/172.20.4.71 et/ou mkdir -p /etc/docker/certs.d/’harbor.cpod-tkg.az-lab.shwrfr.com’

Normalement vous devriez pouvoir vous connecter à Harbor via Docker :

#docker login harbor.cpod-tkg.az-lab.shwrfr.com
Authenticating with existing credentials…
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded