Déploiement de kubernetes

Déployer kubernetes en production est une tâche complexe : installation physique de différentes machines, installation des OS, configuration du réseau, installation des différents éléments constituant kubernetes, etc. Les providers « cloud » en profitent pour offrir du « kubernetes as a service ».

Il existe cependant des solutions lightweight ou dédiées développeur. En particulier :

  • K3D / K3S

  • Docker desktop

  • Minikube

  • Et des tas d’autres ..

Je ne les ai pas tous utilisé, pour les besoins d’un développeur il me semble que les différentes solutions se valent ; le fonctionnement sera le même et le choix devrait être transparent à l’usage (sauf bugs ou besoins spécifiques).

Dans la suite je vous propose d’utiliser Minikube.

Minikube

Installation

La documentation est ici : https://minikube.sigs.k8s.io/docs/start/ ; *suivez uniquement la partie « installation » pour votre système. Par exemple pour linux à l’heure où j’écris ce texte :

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64

Creation d’un cluster

Pour lancer un nouveau cluster :

minikube start --cni=calico

OU avec deux noeuds :

minikube start --nodes 2 --cni=calico

Observation des noeuds:

minikube node list

Ou encore avec docker ps on voit les noeuds (et on peut entrer dedans avec docker exec -it nom_du_conteneur bash)

On constate aussi que ça met à jour notre fichier de configuration kubernetes (celui pointé par la variable d’environnement KUBECONFIG : echo $KUBECONFIG). Ce fichier est utilisé par kubectl pour savoir comment communiquer avec l’API k8S.

On liste les pods (les objets qui représentent la volonté qu’un conteneur existe) :

kubectl get pods --all-namespaces -o wide  #On peut remplacer --all-namespaces par -A
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
kube-system   calico-kube-controllers-7df895d496-lmvbx   1/1     Running   0          2m35s   10.244.120.65   minikube       <none>           <none>
kube-system   calico-node-2ldkj                          0/1     Running   0          2m35s   192.168.49.2    minikube       <none>           <none>
kube-system   calico-node-84sqn                          0/1     Running   0          38s     192.168.49.3    minikube-m02   <none>           <none>
kube-system   coredns-565d847f94-6jsxn                   1/1     Running   0          2m35s   10.244.120.66   minikube       <none>           <none>
kube-system   etcd-minikube                              1/1     Running   0          2m48s   192.168.49.2    minikube       <none>           <none>
kube-system   kube-apiserver-minikube                    1/1     Running   0          2m48s   192.168.49.2    minikube       <none>           <none>
kube-system   kube-controller-manager-minikube           1/1     Running   0          2m48s   192.168.49.2    minikube       <none>           <none>
kube-system   kube-proxy-g9297                           1/1     Running   0          38s     192.168.49.3    minikube-m02   <none>           <none>
kube-system   kube-proxy-tc75c                           1/1     Running   0          2m35s   192.168.49.2    minikube       <none>           <none>
kube-system   kube-scheduler-minikube                    1/1     Running   0          2m47s   192.168.49.2    minikube       <none>           <none>
kube-system   storage-provisioner                        1/1     Running   0          2m46s   192.168.49.2    minikube       <none>           <none>  

Ici on retrouve les controleurs « reseau » (les calico-**), et les éléments de base de kubernetes.

À faire pour s’habituer :

kubectl get -n <completion automatique avec tab et voir les namespaces> pods
kubectl get -n <completion automatique avec tab et voir les namespaces> <completion automatique pour voir le type d objets>
kubectl cluster-info #Pour avoir des infos sur le cluster actuellemnt configuré

Ingress controler

On ajoute à notre cluster un « ingress controler » qui va gérer les objets de type ingress :

minikube addons enable ingress

On a alors un namespace de plus, et des pods dedans :

kubectl get -n ingress-nginx pods -o wide
  • Avec minikube : l’ingress controller écoute sur les ports 80 et 443 du noeud master

  • Avec un vrai cluster : il est joignable sur les ports 80 et 443 de n’importe quel noeud.

Vérification

On écrit un fichier ingress_test.yaml contenant :

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: hello-world.info
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web
                port:
                  number: 8080

Puis :

kubectl create deployment web --image=gcr.io/google-samples/hello-app:1.0
kubectl expose deployment web --type=NodePort --port=8080
kubectl apply -f ingress_test.yaml

Et dans le fichier /etc/hosts, on rajoute une entrée contenant l’addresse de notre cluster :

<RESULTAT DE minikube ip> hello-world.info 

Le site est alors joignable sur hello-world.info (Sinon c’est qu’il y a un problème)

Debug ingress

Si jamais on a envie de modifier le comportement du ingress controller, on crée un fichier configmap.yaml :

kind: ConfigMap
apiVersion: v1
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
data:
  error-log-level: info
  enable-access-log-for-default-backend: "true"
  log-format-upstream: '{"time": "$time_iso8601", "remote_addr": "$proxy_protocol_addr", "x_forwarded_for": "$proxy_add_x_forwarded_for", "request_id": "$req_id", "remote_user": "$remote_user", "bytes_sent": $bytes_sent, "request_time": $request_time, "status": $status, "vhost": "$host", "request_proto": "$server_protocol", "path": "$uri", "request_query": "$args", "request_length": $request_length, "duration": $request_time,"method": "$request_method", "http_referrer": "$http_referer",  "http_user_agent": "$http_user_agent" }'

Et on l’applique (kubectl apply -f configmap.yaml)

On obtient les logs du pod nginx controller en :

  1. obtenant le nom du pod avec kubectl get pods -n <completion automatique>

  2. kubectl -n <completion auto> logs <nom_du_pod par completion automatique> -f

Installation Argocd

En suivant la documentation : (premier lien google avec recherche “installation argocd”)

kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

Puis en créant un fichier ingress_argocd.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: argocd-server-ingress
  namespace: argocd
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" # argocd backend using HTTPS
spec:
  rules:
  - host: argocd.amoi
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: argocd-server
            port:
              name: https

Et en applicant l’objet :

kubectl apply -f ingress_argocd.yaml

On accède alors à la page sur https://argocd.amoi à condition d’avoir ajouté ce qu’il faut dans /etc/hosts, c’est-à-dire la ligne obtenue en exécutant :

echo $(minikube ip) argocd.amoi

Pour le mot de passe :

passw=$(kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 --decode)
echo Login : admin, password : $passw