Tout ensemble : une application

Rappels K8s

Vocabulaire

  • Node : Master ou Worker

  • Control plane : tous les master

  • Objets : pod / deployment / service / etc.

  • namespace

Un objet est une spécification et un état; il appartient à un namespace (sauf exception).

On fixe la spécification et kubernetes se débrouille pour que l’état corresponde à cette spécification.

Les objets peuvent suivre des spécifications nouvelles (CRD : Custom Resource Definition ). Il faut imaginer alors k8s comme un espace de stockage de ces objets, et c’est à nous de faire une application qui les traite. Les « addons » de k8s s’appuient beaucoup sur ce mécanisme.

Manipulation

Au travers de l’API qui est exposée sur le port 6443 d’un master node.

(Note : comme le port 6443 n’est pas ouvert, on fait un tunnel ssh entre localhost et un noeud master via ssh -L 6443:127.0.0.1:6443 147.100.164.212 . Ceci expose le port 6443 de la machine sur laquelle on se connecte sur le port 6443 de localhost)

On configure un fichier kubernetes.conf contenant l’adresse d’un master node + identifiants.

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: ......
    server: https://127.0.0.1:6443
  name: cluster.local
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: .....
    client-key-data: LS.......

On peut alors accéder aux objets k8s :

export KUBECONFIG=$(pwd)/kubernetes.conf
kubectl get pods -o wide --all-namespaces

Exemple d’application

Une application pour moi

Une application c’est à la fois :

  • plusieurs programmes qui communiquent entre eux

  • un point d’entrée (https://truc.com)

  • un certificat ssl

  • une base de données

C’est tout l’écosystème qui doit être déployé pour que ce soit en état de marche et qu’on puisse l’utiliser.

Exemple

Je suis développeur, j’écris une application pour laquelle, pour chaque nouvelle version, je crée un conteneur :

  • registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask:0.1

  • registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask:0.2

  • etc.

Ce conteneur écoute sur le port 8000. Je le sais car je suis développeur et en plus je le documente dans le Dockerfile :

FROM python:3
WORKDIR /app/
COPY . /app/
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["flask","run","-h","0.0.0.0","-p","8000"]

Pour le déployer sur k8s il faut beaucoup d’objets :

---
# UN DEPLOIEMENT
apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-hello-flask
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: hello-flask
      app.kubernetes.io/instance: app
  template:
    metadata:
      labels:
        app.kubernetes.io/name: hello-flask
        app.kubernetes.io/instance: app
    spec:
      containers:
        - name: hello-flask
          image: "registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask:0.1"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8000
              protocol: TCP
---
# UN SERVICE
apiVersion: v1
kind: Service
metadata:
  name: app-hello-flask
spec:
  type: ClusterIP
  ports:
    - port: 8000
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: hello-flask
    app.kubernetes.io/instance: app
---
# UN INGRESS
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-hello-flask
spec:
  rules:
    - host: "test.amoi"
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              service:
                name: app-hello-flask
                port:
                  number: 8000

Pour essayer, créez un fichier yaml pour chaque objet : deployment.yaml, service.yaml, ingress.yaml.

Créez l’objet deployment :

kubectl apply -f deployment.yaml

Observez la création du pod.

De la même manière créez les autres objets :

kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

Et kubernetes fait le reste : il crée d’autres objets si nécessaire (par exemple pour les certificats) et fait converger les états.

Après avoir modifié le fichier /etc/hosts, vous pourrez accéder à l’application en allant sur http://test.amoi.

Pour mettre à jour mon application, il suffira de modifier l’image pointée par ce fichier.

Remarque : ce serait sympa d’avoir un template et de séparer les données utiles du reste..

Helm

Helm permet justement d’avoir un template et de séparer les données utiles du reste :

helm create hello-flask.

Cela génère une arborescence avec à la racine un fichier values.yaml et dans le reste de l’arborescence, des templates contenant le yaml de description d’objets k8s.

Dans les values on a l’essentiel :

replicaCount: 1

image:
  repository: registry.forgemia.inra.fr/sol_k8s/argocd_examples/hello_flask
  pullPolicy: IfNotPresent
  tag: 0.1

service:
  type: ClusterIP
  port: 8000

ingress:
  enabled: true
  className: ""
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-clusterissuer
  hosts:
    - host: hello.inrae.jrobert-orleans.fr
      paths:
        - path: /
          pathType: ImplementationSpecific
  tls:
    - secretName: hello-flask-ssl
      hosts:
        - hello.inrae.jrobert-orleans.fr

Et si je veux voir le résultat de ce “helm chart” :

helm template .

Argocd

Et si on versionne ce « helm chart » dans un dépot git, on a une application toute prète à être déployée.

Pour déployer une application versionnée dans un dépot on doit alors faire le lien entre git et kubernetes :

  1. télécharger le helm chart

  2. helm template

  3. appliquer ce qu’on obtient avec kubectl

  4. vérifier que tout s’est bien passé (et alerter si ce n’est pas le cas)

  5. rester en veille sur des changements du dépot et revenir au point 1 si c’est le cas.

Argocd fait tout ça pour nous. À voir en live :

  • déclaration d’un dépot dans argocd

  • modification des valeurs dans App details -> parameters

  • visualisation de l’état:

    • pods

    • network

    • logs des pods

    • différence entre état demandé et actuel

  • sync / rollback

Petits détails

  • Accès à la forge par argocd pour cloner le dépot

  • Accès à la forge par kubernetes pour télécharger l’image