Déploiement de Portainer sous Kubernetes

Introduction sur Portainer

Portainer est un outil de management pour des environnements Docker. Historiquement disponible pour le daemon Docker et un cluser SWARM, il dispose désormais (au moment de l’écriture de cet article) d’une version bêta pour Kubernetes.

J’ai décidé de le déployer pour avoir une alternative au dashboard Kubernetes et disposer d’une GUI de gestion de mon cluster Kubernetes.

Il très fortement conseillé à minima de lire les différentes étapes liées au déploiement de mon cluster K8S avant de suivre les consignes suivantes, car je vais réutiliser beaucoup d’éléments vus dans ces parties.

Méthode de déploiement de Portainer sous K8S

J’ai récupéré le fichier de déploiement disponible sur le repo GIT de l’éditeur

Je me suis permis de le découper en différent yaml et de l’adapter à mon installation, à commencer par l’utilisation d’un stockage persistant pour sa configuration.

01-nam-portainer.yaml

Création d’un namespace dédié pour Portainer

02-sac-portainer.yaml

Création d’un compte de service pour Portainer

03-crm-portainer.yaml

Association du compte de service à un rôle de cluster admin

04-svc-portainer.yaml

Création d’un service pour publier l’accès à Portainer

05-pvc-persistent-volume-storageclass-portainer.yml

Demande d’un volume dans la classe SSD pour stocker la configuration de Portainer

06-dep-portainer.yaml

Déploiement de portainer

07-rot-portainer.yaml

Création d’une route pour Traefik et la publication de la GUI Portainer

Déploiement de portainer

Création du namespace

Je débute par la création d’un namespace dédié pour les objets portainer

apiVersion: v1

kind: Namespace

metadata:

 name: portainer

kubectl.exe apply -f .\01-nam-portainer.yaml

Création d'un compte de service

Je crée un compte de service pour Portainer

apiVersion: v1

kind: ServiceAccount

metadata:

  name: portainer-sa-clusteradmin

  namespace: portainer

kubectl.exe apply -f 02-sac-portainer.yaml

Association du compte de service à un rôle

J’associe ce compte de service à un rôle de cluster admin pour qu’il puisse avoir accès à tous les objets du cluster

apiVersion: rbac.authorization.k8s.io/v1beta1

kind: ClusterRoleBinding

metadata:

  name: portainer-crb-clusteradmin

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: ClusterRole

  name: cluster-admin

subjects:

- kind: ServiceAccount

  name: portainer-sa-clusteradmin

  namespace: portainer

kubectl.exe apply -f 03-crm-portainer.yaml

Création d'un service K8S

Afin de rendre disponible l’interface portainer au sein du cluster, j’utilise un objet service

apiVersion: v1

kind: Service

metadata:

  name: svc-portainer

  namespace: portainer

spec:

  selector:

    app: app-portainer

  ports:

    - name: http

      protocol: TCP

      port: 9000

      targetPort: 9000

    - name: edge

      protocol: TCP

      port: 8000

      targetPort: 8000

kubectl.exe apply -f 04-svc-portainer.yaml

Création d'un volume de stockage

J’ai besoin d’un volume pour stocker la configuration du Portainer. J’utilise la classe de stockage SSD que j’ai créé dans l’étape 4 du déploiement de mon cluster K8S. J’ai juste à rédiger un objet PersistentVolumeClaim pour demander la création d’un espace de stockage.

---

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: pvc-portainer

  namespace: portainer

spec:

  accessModes:

    - ReadWriteOnce 

  resources:

    requests:

      storage: 5Gi

  storageClassName: vsphere-dts-ssd

kubectl.exe apply -f 05-pvc-persistent-volume-storageclass-portainer.yml

Création du fichier de Deployment

Je déploie Portainer

apiVersion: apps/v1

kind: Deployment

metadata:

  name: portainer

  namespace: portainer

spec:

  selector:

    matchLabels:

      app: app-portainer

  template:

    metadata:

      namespace: portainer 

      labels:

        app: app-portainer

    spec:

      serviceAccountName: portainer-sa-clusteradmin

      containers:

      - name: portainer

        image: portainer/portainer-k8s-beta:linux-amd64

        imagePullPolicy: Always

        ports:

        - containerPort: 9000

          protocol: TCP

        - containerPort: 8000

          protocol: TCP

        volumeMounts:

         - mountPath: "/data"

           name: data-portainer  

      volumes:

      - name: data-portainer

        persistentVolumeClaim:

         claimName: pvc-portainer    

kubectl.exe apply -f 06-dep-portainer.yaml

Accès externe à portainer

Il ne me reste plus qu’à fournir un accès HTTPS depuis l’extérieur du cluster grâce à Traefik et à la création d’un objet IngressRoute.

apiVersion: traefik.containo.us/v1alpha1

kind: IngressRoute

metadata:

  name: portainer-http

  namespace: portainer 

spec:

  entryPoints:

    - web

  routes:

  - kind: Rule

    match: Host(`portainer.inf.prd.k8s.coolcorp.priv`) 

    services:

    - name: svc-portainer

      port: 9000

    middlewares:

      - name: https-redirectscheme     

---

apiVersion: traefik.containo.us/v1alpha1

kind: IngressRoute

metadata:

  name: portainer-https

  namespace: portainer

spec:

  entryPoints:

    - websecure

  routes:

  - kind: Rule

    match: Host(`portainer.inf.prd.k8s.coolcorp.priv`) 

    services:

    - name: svc-portainer

      port: 9000

  tls:

    certResolver: le      

kubectl.exe apply -f 07-rot-portainer.yaml

Il ne faut pas que j'oublie l'enregistrement DNS pour faire pointer mon URL vers mon load balancer HA Proxy

Enregistrement DNS pour Portainer

Je peux maintenant me rendre sur l’interface de Portainer.

Interface de Portainer

Aperçu de Portainer sous K8S

L’application est très pratique, elle permet d’avoir une vue sur l’état de son cluster et de ses nœuds.

Informations sur les noeuds du cluster K8S depuis Portainer

Elle peut aussi être utilisée pour déployer une application et des objets K8S.

Déploiement d'une application depuis Portainer pour K8S.

Sur ce point, étant donné qu’au moment de la rédaction de cet article, Portainer est toujours en bêta pour k8S, je vous invite à être prudent dans son utilisation. Personnellement, je m’en sers pour l’instant uniquement comme un élément de supervision et de visualisation du statut de mon cluster.