CKA als doel: bouw een testomgeving

In een IT wereld waarin alles zo snel verandert is het lastig om bij te blijven. Om op alle vlakken bij te blijven is te veel van het goede dus ligt de keuze voor de hand om iets te kiezen wat bij je past, en waar behoefte aan is in de markt. Jaren geleden werd al geroepen dat ‘alles in containers komt’. Een concept waarin ik wel geloof. Gelukkig kreeg ik de kans om iets met Docker te gaan doen. Kubernetes. Ik had er van gehoord; ik zag een klok, geen klepel en laat staan dat er muziek kwam. het concept wilde niet landen. Nu leer ik ook beter door dingen te doen. Moeilijke taal lezen met onbekende concepten en hypewoorden, daar kan ik niet de concentratie voor vinden.

Intussen ben ik goed bekend met Docker. Ik kan mijn eigen container bouwen en begrijp de meeste concepten intussen wel. Goeroe? In het land der blinden is eenoog koning. Dus ja, waar ik werk ben ik Koning Guru. Maar ik als zelfbenoemde Koning Eenoog moet wel verder en heb ik besloten me te gaan certificeren voor CKA: Certified Kubernetes Administrator. Niet alleen omdat de markt daarom vraagt, maar ook om mezelf uit te dagen. Als extra uitdaging ga ik het hier ook nog eens documenteren. Zo word ik Koning Goeroe met een visie; kijkend in de spiegel.

Ik moet toegeven dat ik een enorme aversie heb tegen certificeren. Voor mij betekent het niet veel. Een certificaat hebben betekent nog niet dat je je werk goed kan doen. Het betekent alleen dat je je zenuwen in bedwang had en kennis A had op moment B. Veel admin-taken die je doet, doe je hooguit een paar keer per jaar. En dan nog is het vaak met Ansible geautomatiseerd. Vervolgens moet je je na 2 of 3 jaar opnieuw certificeren. Waarom? Commercie! het zou beter zijn als je elke 5 jaar je rijbewijs opnieuw moest halen. Maar goed, CKA, dat wordt de uitdaging.

Mijn testomgeving

Mijn testomgeving is vrij simpel. Ik heb een 6 jaar oude PC (i7, 16Gb) als server met Centos 7 en een recente Intel Nuc (i5, 32Gb) met Debian Buster. Beide zijn voorzien van libvirt KVM waarop de VM’s met kubernetes draaien. Alle VM’s zijn uitgerust met 2Gb geheugen, 2 vCPU’s en Centos 7. De VM’s worden ge-pxeboot en via een kickstart bestand geinstalleerd. De VM’s worden met de hand voorzien van een vast IP-adres en een hostname, maar met dnsmasq moet het ook te doen zijn. Alles zit op hetzelfde netwerk. Op zich allemaal niet zo veel bijzonders, gewoon een testomgeving om te oefenen voor mijn examen CKA. Ik heb er voor gekozen om 9 nodes (kub0 t/m kub8) te gebruiken. Maar 3 was ook voldoende. Omdat ik een ansible script heb om de hosts te configureren maakt het niet uit of ik 3, 9 of 27 hosts wil gebruiken. Bovendien, als Koning Eenoog wil ik een groot rijk! Dus 9 nodes…

Om de nodes te configureren is er uitstekende documentatie te vinden op https://kubernetes.io/docs/home/ . Maar er zit ook een nadeel aan. Kubernetes ontwikkelt zich snel. Tegen de tijd dat je de documentatie leest, is het weer vernieuwd en veranderd. Maar door te lezen op ‘het internet’ vond ik uit dat mijn hosts de volgende wijzigingen moest hebben in de configuratie om als kubernetesnode te kunnen werken. Misschien heb jij wat extra wijzigingen nodig.

Kub0 wordt gebruikt als admin node (Control Plane). The rest zijn kubelets.

De Configuratie

De configuratie op de VM’s moet als volgt worden aangepast:

  • Installatie van de docker repository
  • Installatie van de Kubernetes repository
  • Installatie van kubeadm, docker, chrony, bash-completion en enkele extra packages als je wil.
  • Zorg dat docker en kubelet gestart worden op alle hosts. Chronyd moet ook worden gestart omdat alle nodes in tijd synchroon moeten lopen.
  • Ik wil geen firewall, dus firewalld zet ik uit. Misschien een minder goed idee voor een productieomgeving.
  • Kubernetes houdt niet van swap, dus disable swap en verwijder swap van /etc/fstab
  • Maak een daemon.json file
  • Herstart de docker daemon.

De daemon.json file die ik gebruik is als volgt:

{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}

Dit is omdat Centos 7 gebruik maakt van cgroups waarvan systemd de eigenaar is. Voor die tijd had docker zijn eigen cgroupfs-driver. Als je dit niet wijzigt zal docker niet opstarten. Wil je er meer over lezen: https://github.com/kubernetes/kubeadm/issues/1394

Hoef je maar drie hosts te configureren, dan red je je prima met linker en rechterhand. Een vierde wordt vervelend en de negende komt je de neus uit. Dus: automatiseren. In mijn Koninkrijk ben ik niet alleen de goeroe op K8S, maar ook op Ansible. Dus schreef ik een fantastisch script dat alle hosts voor mij configureert. Het is fantastisch omdat het goed genoeg werkt voor mij. Maar in een ander Koninkrijk zijn vast betere script. Er zit ook geen enkele logica in; het alleen een sequentiële uitvoering van een setje commando’s.

---
- hosts: kubernetes
  remote_user: root
  tasks:
  - name: Add repositories for Docker
    yum_repository:
      name: docker
      description: Official Docker repository
      baseurl: https://download.docker.com/linux/centos/7/$basearch/stable
      gpgcheck: yes
      gpgkey: https://download.docker.com/linux/centos/gpg

  - name: Add repositories for Kubernetes
    yum_repository:
      name: Kubernetes
      description: Official Kubernetes repository
      baseurl: https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
      gpgcheck: yes
      gpgkey: https://packages.cloud.google.com/yum/doc/yum-key.gpg
              https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg

  - name: Check if yum-utils and bash-completion are installed
    yum:
      name:
        - firewalld
        - bash-completion
        - yum-utils
        - docker-ce-18.06.3.ce-3.el7.x86_64
        - chrony
        - kubeadm
        - nfs-utils

  - name: Update to latest level
    yum:
      name=* state=latest

  - name: Make sure services are enabled/started
    service:
      name: "{{ item }}"
      enabled: yes
      state: started
    with_items:
      - docker
      - kubelet
      - chronyd

  - name: Make sure services are disabled/started
    service:
      name: "{{ item }}"
      enabled: no
      state: stopped
    with_items:
      - firewalld

  - name: Disable SWAP since kubernetes can't work with swap enabled (1/2)
    shell: |
      swapoff -a
#    when: kubernetes_installed is changed

  - name: Disable SWAP in fstab since kubernetes can't work with swap enabled (2/2)
    replace:
      path: /etc/fstab
      regexp: '^(.*?\sswap\s+swap.*)$'
      replace: '# \1'
#    when: kubernetes_installed is changed

  - name: Deploy Docker daemon.json.
    copy:
      src: files/daemon.json
      dest: /etc/docker/daemon.json


  - name: restart service docker, in all cases, also issue daemon-reload to pick up config changes
    systemd:
      state: restarted
      daemon_reload: yes
      name: docker

Maar het werkt!

Nu ben ik klaar om met het configureren van Kubernetes te starten.