Kubernetes

description: Comment faire tourner un cluster kube

lang: FR

Concepts

Terminologie

ReplicaSet

kind: ReplicaSet
metadata:
  name: unicorn-front-replicaset
  labels:
    app: unicorn-front
spec:
  template:
    metadata:
      name: unicorn-front-pod
      labels:
        app: unicorn-front
    spec:
      containers:
      - name: unicorn-front
        image: registry.takima.io/school/proxy/nginx
  replicas: 3
  selector:
    matchLabels:
      app: unicorn-front

DĂ©ploiement

Control des ressources

resources:
  requests:
    memory: "64Mi"
    cpu: "250m"
  limits:
    memory: "128Mi"
    cpu: "500m"
 Last State:     Terminated
      Reason:       OOMKilled

Services

Il agit comme un load balancer en transmettant les requêtes aux pods auxquels il est rattaché.

apiVersion: v1
kind: Service
metadata:
  name: unicorn-front-service
spec:
  selector:
    app: unicorn-front
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

Ingress

C'est un peu un load balancer pour le service.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 annotations:
   kubernetes.io/ingress.class: nginx
 name: unicorn-front-ingress
spec:
 rules:
 - host: replace-with-your-url
   http:
     paths:
     - backend:
         service:
           name: unicorn-front-service
           port:
             number: 80
       path: /
       pathType: Prefix

CertManager

Il faut rajouter les paramètres suivants et avoir un cluster-issuer à disposition dans le cluster.

# metadata:
#  annotations:
#    kubernetes.io/ingress.class: nginx
     cert-manager.io/cluster-issuer: letsencrypt-staging
     kubernetes.io/tls-acme: 'true'

# [...]
# spec:
#   rules:
    tls:
      - hosts:
        - replace-with-your-url
        secretName: unicorn-front-tls

Registry privé

# spec:
#   template:
#     spec:
imagePullSecrets:
  - name: takima-school-registry

Variable d'env

On peut ajouter des variables d'environnement

# spec:
#   template:
#     spec:
#       container:
#         - name:
#           env:
- name: K8S_NODE_NAME
  valueFrom:
    fieldRef:
      fieldPath: spec.nodeName

ConfigMap

Le ConfigMap stocke les données non-confidentielles. On enregistre les données comme suit:

apiVersion: v1
kind: ConfigMap
metadata:
  name: web-app
data:
  # property-like keys; each key maps to a simple value
  color: "#220"

On récupère les données comme suit dans le deployment.

env:
  - name: CUSTOM_COLOR # Vrai key de la variable d'env. Peut être différent de la valeur dans le config map
    valueFrom:
      configMapKeyRef:
        name: web-app  # Nom du configmap
        key: color     # nom de la clef dans le config map

/!\ Il faut penser Ă  restart !

Secret

Pour les données confidentielles, on utilise les secrets de deux façons:

  1. kubectl create secret generic my-secret --from-literal=username=user: on peut mettre plusieur littérals à la suite
  2. Via le yaml:
echo -n 'user' | base64
echo -n 'test123*' | base64
apiVersion: v1
kind: Secret
metadata:
  name: hello-secret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

On peut ensuite l'utiliser avec:

# container.[].env
- name: CUSTOM_COLOR
  valueFrom:
    secretKeyRef:
      name: secret-color
      key: color     # nom de la clef dans le config map

/!\ Dans lens, il est en base64, il faut penser Ă  le convertir.

Checkhealth

Permet d'appeler un endpoint réguliérement pour vérifier qu'il est sein.

# container.[]
livenessProbe:
  httpGet:
    path: /health
    port: 3000
    # httpHeaders:
    # - name: Custom-Header
    #   value: Awesome
  initialDelaySeconds: 1 # Initial check
  failureThreshold: 5 # Nombre de tentatives
  periodSeconds: 3   # Timing pour les checks

HorizontalPodAutoscaler: mise Ă  l'Ă©chelle automatique

Peut être créer en utilisant le -o yaml de autoscale.

NetworkPolicy

Permet de contrĂ´ler les flux entre les pods.

Redirection interne

Pour accèder à un service depuis un autre service, on peut utiliser le DNS interne. Pour un service api dans le namespace test, on peut appeler http://api.test. S'ils sont dans le même namespace, on peut juste utiliser le nom du service: http://api.

Persistence Volume

Cela correspond à l'abstraction du volume physique mappé sur les serveurs. Il s'agit d'une resources. Les Persistence Volume Claims sont une demande de stockage par l'utilisateur. On peut définir différents types de stockages avec les StorageClass. Les volumes peuvent être statiques ou dynamiques.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pg-pvc
spec:
  storageClassName: gp2
  accessModes:
  - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 3Gi
# spec:
#   template:
#       spec:
volumes:
- name: pg-data
  persistentVolumeClaim:
    claimName: pg-pvc
# spec:
#   template:
#     spec:
#       container:
volumeMounts:
- mountPath: /var/lib/postgresql/data
  name: pg-data

StatefulSet

Cela permet de scaler les ressources utilisées par un pod. Cependant, ça casse le fonctionnement du DNS.

# kind: StatefulSet
# spec:
  serviceName: pg-service
  volumeClaimTemplates:
  - metadata:
      name: pg-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

Il faut modifier le lien d'accès car le load balancer ne fonctionne plus. On doit pointer vers pod.service au lieu de service.

CronJob

Ressource qui permet de faire des jobs en fond à intervalle régulier.

Operators

Cela correspond à une resource personalisée. On peut le faire grâce à une Custom Resource Definition.

Helm

Helm est le "package manager" de Kubernetes. Il permet de faire des templates de toutes les ressources yaml d’une application donnée et les déployer sur Kubernetes. On peut déployer des stacks applicatives directement.

La stack applicative s'appelle une Chart Helm. On utilise les values pour faire des templates helm. On peut utiliser un système de variables grâce à _templates/helpers.tpl (il s'agit de templates Go).

Argo CD

Permet de faire du GitOps en faisant le lien entre l'Infra-As-Code et l'Infrastructure.

Cheatsheet