Kubernetes
Intro til hva systemet brukes til
Kubernetes er et system for å administrere og automatisere containere. Det kan følge med på helsen til containere, starte opp nye containere og fjerne ubrukte containere. Kubernetes er et system som ligger oppå, og tett inntil containerne og kommuniserer mellom nodene, altså containerne, via et virtuelt nett. Kubernetes administreres via kubernetes klienten «kubectl», eller via en av de mange tilgjengelige tredjepartsklientene som Kubernetes Dashboard eller Lens.
Innstalasjon
Først må du kjøpe like mange servere som du ønsker noder i kubernetes clusteret ditt pluss minimum 1 master (denne kan være liten, for eksempel 8GB RAM og 4 vCPU). Masteren bør ikke brukes som en worker-node. Vi anbefaler dessuten å kjøpe en Disk per worker node dersom du ønsker å legge opp distribuert lagring.
Først må modprob kjøres for å klargjøre linux kjernen, dette kan gjøres med følgende kommandoer;
sudo modprobe overlay sudo modprobe br_netfilter cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF
Vi må også sørge for at IPv4 packet forwarding er på. Dette kan gjøres ved å kjøre følgende kommandoer;
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.ipv4.ip_forward = 1 EOF # Apply sysctl params without reboot sudo sysctl --system
Container Runtime
Du må så installere en “Container Runtime” på hver server du planlegger å bruke som en node.
Før du laster ned må du først kjøre følgende kommando for å oppdatere;
sudo apt update
Deretter må avhengighetene til kubernetes lastes ned, dette kan gjøres med følgende kommando;
sudo apt install -y curl gnupg2 software-properties-common apt-transport-https ca-certificates
Deretter må de legges inn i ubuntu sine pakker, dette kan gjøres med følgende kommando
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmour -o /etc/apt/trusted.gpg.d/containerd.gpg sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
Så kan «containerd» innstalleres med følgende commando;
sudo apt update && sudo apt install containerd.io -y
Sett så opp containerd så den bruker systemd, dette kan gjøres med følgende kommandoer;
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null 2>&1 sudo sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
Til slutt må containerd restartes med følgende kommando;
sudo systemctl restart containerd
Kubernetes
Videre må du installere kubernetes. Først må du legge de til i ubuntu repoet med følgende kommand;
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/k8s.gpg echo 'deb [signed-by=/etc/apt/keyrings/k8s.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/k8s.list
Deretter må du oppdatere pakkene med følgende kommando;
sudo apt update
For så å installere kubelet, kubeadm og kubectl. Du må i tillegg skru av automatiske oppdateringer for Kubernetes slik at vi kan bestemme når disse skal oppgraderes.
sudo apt install kubelet kubeadm kubectl sudo apt-mark hold kubelet kubeadm kubectl
Master
Velg et domene du skal bruke for Kubernetes. Hvis du har domene example.com kan feks master kalles kubemaster.example.com og workerene kubeworker1.example.com. Pek kubemaster.example.com til IP-adressen du ønsker å bruke når du administrerer Kubernetes.
IP-adressene og domenenavnene til både workerne og serveren legges inn i /etc/hosts som vist under;
192.0.2.2 kubemaster.example.com 192.0.2.3 kubeworker1.example.com 192.0.2.4 kubeworker2.example.com 192.0.2.5 kubeworker3.example.com
Videre må følgende gjøres KUN på master noden. Først må kubeadmin initialiseres med følgende kommando. Noter ned token og hash, ettersom disse må brukes for å legge til nye workers.
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=kubemaster.example.com
Bytt tilbake til din egen bruker, deretter kjør følgende kommandoer på hjemmeområdet ditt for å få admin tilgang til kubernetes;
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
Til slutt må Flannel installeres for å kommunisere mellom nodene via et virtuelt nettverk. Dette kan gjøres med følgende kommando;
kubectl apply -f https://github.com/flannel-io/flannel/releases/download/v0.26.0/kube-flannel.yml
Worker
På hver worker node må «–control-plane-endpoint” domenenavnet, i dette eksempelet kubemaster.example.com, legges inn i /etc/hosts, sammen med alle workerne som blir opprettet i følgende format;
192.0.2.2 kubemaster.example.com 192.0.2.3 kubeworker1.example.com 192.0.2.4 kubeworker2.example.com 192.0.2.5 kubeworker3.example.com
Dersom du ikke har notert ned token og hash kan følgende kommando kjøres på master for å finne disse;
kubeadm token create --print-join-command
Deretter kan workeren legges til i clusteret ved hjelp av følgende kommando;
kubeadm join kubemaster.example.com:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Info om versjoner, releases og sikkerhetshull
For å se informasjon om nye versjoner sjekk følgende nettside;
For offisielle sikkerhetshull se:
Official CVE Feed | Kubernetes
Kubernetes: Løsning på vanlige oppgaver
Oppdatere plugins
For å oppdatere plugins må du på generell basis konsultere oppdateringssiden til pluginen du har lastet ned. De fleste plugins har github-sider eller nettsider hvor de dokumenterer hvordan du kan oppdatere og vedlikeholde pluginen. Merk at en oppdatering av en plugin må planlegges, feil i denne prosessen kan medføre nedetid. Vi kommer likevel med noen eksempler her.
Ingress kontroller
Git at det ikke er noen store endringer kan du gjøre følgende. Husk å sjekke nettsiden for endringer før du starter. Først må du finne versjonen du skal oppdatere til. Deretter må du bruke wget kommandoen til å hente yaml filen fra github repositoriet. Videre må du gjøre de samme redigeringene som i innstasjonsveiledningen. Deretter kan du applye endringene. For en mer teknisk forklaring se Ingress controller
Cert manager
Git at det ikke er noen store endringer kan du gjøre følgende. Husk å sjekke nettsiden for endringer før du starter. Først må du finne versjonen du skal oppdatere til. Deretter kan du applye versjonen du ønsker å oppdatere til ved hjelp av samme kommando som i installasjonen.
Flannel
Git at det ikke er noen store endringer kan du gjøre følgende. Husk å sjekke nettsiden for endringer før du starter. Først må du finne versjonen du skal oppdatere til. Deretter kan du applye versjonen du ønsker å oppdatere til ved hjelp av samme kommando som i installasjonen.
Brukeradministrasjon (service accounts)
Legg til bruker
For å opprette en bruker må man først lage en service account som må ha noen rettigheter. I dette eksempelet er rettighetene cluster admin.
cat <<EOF | kubectl create -f - apiVersion: v1 kind: ServiceAccount metadata: name: <navn> --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: <navn>-cluster-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: <navn> namespace: default --- apiVersion: v1 kind: Secret metadata: name: <navn>-kube-secret annotations: kubernetes.io/service-account.name: <navn> type: kubernetes.io/service-account-token EOF
Etter å ha opprettet service-accounten må du lage fil som gir brukeren tilgang til clusteret. Du må først finne brukeren sitt login token, dette kan gjøres med følgende kommando;
kubectl get secret/<name>-kube-secret -o jsonpath='{.data.token}' | base64 --decode
Etter å ha funnet login tokenet må du kjøre følgende kommando for å få en template;
kubectl config view --raw
Videre må du bevege deg inn i mappen .kube på hjemmeområdet på master noden. Her må du opprette en ny fil, kall den for eksempel <navn>-conf. Redigert filen du nettopp opprettet og legg inn outputen fra kommandoen over. Endre user til navnet du valgte på brukeren og gjør det samme users -> name. Videre må alt under users -> user slettes og erstattes med token:<token>. Her skal du legge inn tokenet du fikk ved den tidligere kommandoen. Referer til før og etter bildene.
Før:
apiVersion: v1 clusters: - cluster: certificate-authority-data: <base64-data> server: https://kubemaster.example.com:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: kubernetes-admin user: client-certificate-data: DATA+OMITTED client-key-data: DATA+OMITTED
Etter:
apiVersion: v1 clusters: - cluster: certificate-authority-data: <base64-data> server: https://kubemaster.example.com:6443 name: kubernetes contexts: - context: cluster: kubernetes user: martin-tuhus name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config preferences: {} users: - name: <username> user: token: REDACTED
Du vil da kunne logge inn som denne brukeren dersom du endrer navnet på den nye filen til config
Fjerne bruker
For å fjerne bruker, slett brukerens service account, binding og secret.
kubectl delete serviceaccount <name> kubectl delete clusterrolebindings <name>-cluster-admin
Certs (cert manager)
For å installere og applye cert manager må du først finne den nyeste versjonen, dette kan finnes her; https://cert-manager.io/docs/releases/. Bruk deretter følgende kommando for å applye certmanager;
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v<Latest version number>/cert-manager.yaml
Deretter må du velge en utsteder av sertifikater. Følgende er hvordan du kan legge opp lets encrypt;
cat <<EOF | kubectl create -f - apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: # You must replace this email address with your own. # Let's Encrypt will use this to contact you about expiring # certificates, and issues related to your account. email: <email> server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: # Secret resource that will be used to store the account's private key. name: letsencrypt-prod # Add a single challenge solver, HTTP01 using nginx solvers: - http01: ingress: ingressClassName: nginx EOF
Ingress controller (nginx-ingress-controller)
Først må pakken lastes ned med følgende kommando;
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/cloud/deploy.yaml
Du må deretter gå inn i filen du nettopp lastet ned med din prefererte tekst editor.
Du må deretter endre type fra:
type: LoadBalancer
Til:
type: NodePort
Deretter må følgende linje legges til under det du endret over:
externalTrafficPolicy: Local
Videre må du fra endre:
kind: Deployment
Til:
kind: DaemonSet
Til slutt må følgende linjer slettes;
strategy: rollingUpdate: maxUnavailable: 1 type: RollingUpdate
Så kan du applye med følgende kommando;
kubectl apply -f deploy.yaml
Om du ønsker at ingress-controlleren skal være tilgjengelig på portene 80 og 443 må du gjøre følgende. Rediger denne filen:
sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
Og legg til eller endre følgende linje under kube-apiserver:
- --service-node-port-range=80-32767
Rediger instillingene til ingess-controller
kubectl edit service ingress-nginx-controller -n ingress-nginx
Og sett nodePort til 80 og 443.
Distribuerte disk RWO og RWX
Forberede master node
sudo snap install helm --classic
Deretter må openebs lastes ned ved hjelp av helm, dette kan gjøres med følgende kommandoer;
helm repo add openebs https://openebs.github.io/openebs helm repo update helm install openebs --namespace openebs openebs/openebs --create-namespace
Det kan ta ganske lang tid for kubernetes å sett opp det nye miljøet, du kan følge med på framgangen med følgende kommando;
watch kubectl get pods -n openebs
Forberede worker nodene
Først må Huge Pages skrus på og gjøres vedvarende ved hjelp av følgende kommandoer;
echo 1024 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages echo vm.nr_hugepages = 1024 | sudo tee -a /etc/sysctl.conf
Deretter må du bruke modprobe med følgende kommando;
sudo modprobe nvme-tcp
og så legge inn følgende linje nederst i filen /etc/modules-load.d/k8s.conf:
nvme-tcp
Du må deretter lage en partisjon på hele disken, dette kan gjøres med følgende kommando;
sudo fdisk <diskpath>
Du vil få opp et interaktivt vindu i konsollen, her må du først taste inn: “g” og så klikke enter. Deretter må du taste “n” og klikke enter og deretter klikke enter på de tre neste spørsmålene, og til slutt kan du taste inn “w” og klikke enter. Se figuren under.
Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Device does not contain a recognized partition table. Created a new DOS (MBR) disklabel with disk identifier 0xe9b18fa9. Command (m for help): g Created a new GPT disklabel (GUID: 9268637E-8450-4DC8-9028-8D1894A074E0) Command (m for help): n Partition number (1-128, default 1): First sector (2048-4194270, default 2048): Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-4194270, default 4192255): Created a new partition 1 of type 'Linux filesystem' and of size 2 GiB. Command (m for help): w The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.
Deretter må du lage et filsystem på den nye partisjonen, dette kan gjøres med følgende kommando;
mkfs.ext4 <diskpath>
Deploye OpenEBS
Deretter må worker nodene må merkes med følgende kommando;
kubectl label node <node_name> openebs.io/engine=mayastor
For å finne ID-en til disken kan følgende kommando brukes;
ls -la /dev/disk/by-uuid/
Deretter må følgende kommando gjøres for å legge inn informasjon i kubectl, merk at her må du selv gjøre endringer på navn;
cat <<EOF | kubectl create -f - apiVersion: "openebs.io/v1beta2" kind: DiskPool metadata: name: pool-on-<Node Name> namespace: openebs spec: node: <Node Name> disks: ["aio:///dev/disk/by-uuid/<disk uuid>"] topology: labelled: <Label group>: <Label name> EOF
Før du kan bruke mayastor må dette først lastes ned, det kan gjøres med følgende kommandoer;
wget https://github.com/openebs/mayastor-control-plane/releases/download/v2.7.1/kubectl-mayastor-x86_64-linux-musl.tar.gz tar xvfz kubectl-mayastor-x86_64-linux-musl.tar.gz sudo mv kubectl-mayastor /usr/local/bin/
Deretter burde du kunne se diskpoolet med følgende kommando;
kubectl get dsp -n openebs
Deretter må du legge til en storage class med følgende kommando;
cat <<EOF | kubectl create -f - kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: <name> parameters: ioTimeout: "60" protocol: nvmf repl: "<amount of replication>" provisioner: io.openebs.csi-mayastor volumeBindingMode: Immediate EOF
Dersom du ønsker RWX må du i tillegg gjøre følgende;
Du må opprette et namespace for å deploye en NFS server, dette kan gjøres med følgende kommando;
kubectl create ns <nfs server name>
Deretter må en PVC opprettes med den ønskede mengden lagring;
cat <<EOF | kubectl create -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: <pvc name> namespace: <nfs server name> spec: accessModes: - ReadWriteOnce resources: requests: storage: <size>Gi storageClassName: <storage class name> EOF
Deretter må deployment serveren opprettes med følgende kommando;
cat <<EOF | kubectl create -f - apiVersion: apps/v1 kind: Deployment metadata: name: <nfs server name> namespace: <nfs server name> spec: replicas: 1 selector: matchLabels: role: nfs-server template: metadata: labels: role: nfs-server spec: volumes: - name: nfs-vol persistentVolumeClaim: claimName: nfs-server-claim restartPolicy: Always containers: - name: nfs-server image: itsthenetwork/nfs-server-alpine env: - name: SHARED_DIRECTORY value: /nfsshare ports: - name: nfs containerPort: 2049 securityContext: privileged: true volumeMounts: - mountPath: /nfsshare name: nfs-vol EOF
Deretter må du lage en service med følgende kommando;
cat <<EOF | kubectl create -f - apiVersion: v1 kind: Service metadata: name: <nfs server name> namespace: <nfs server name> spec: ports: - name: nfs port: 2049 selector: role: nfs-server EOF
Etter dette må du opprette NFS CSI driver, dette kan gjøres med følgende kommando;
cat <<EOF | kubectl create -f - apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: <Storage Class Name> provisioner: nfs.csi.k8s.io parameters: server: nfs-server.nfs-server.svc.cluster.local share: / reclaimPolicy: Delete volumeBindingMode: Immediate mountOptions: - nfsvers=4.1 EOF
Så må du opprette et nytt namespace, samme som navnet du valgte i kommandoen over, med følgende kommando;
kubectl create ns <Storage Class Name>
Deretter må du laste ned et repository og så deploy det med følgende kommandoer;
helm repo add csi-driver-nfs https://raw.githubusercontent.com/kubernetes-csi/csi-driver-nfs/master/charts
helm install csi-driver-nfs csi-driver-nfs/csi-driver-nfs --namespace csi-nfs --version v4.9.0
Peke domene til IP lokalt
Du kan sette hva et domene skal peke til lokalt i kubernetes. Dette fungerer ca. på sammen måte som /etc/hosts. Begynt med å redigere coredns sin config map:
kubectl -n kube-system edit configmap/coredns
Legg deretter til følgende:
hosts custom.hosts mycustom.host { 1.2.3.4 mycustom.host fallthrough }
Så må du reloade CoreDNS pod ved å slette de som er der.
kubectl delete pod -n coredns-<id>
Dette vil peke mycustom.host til 1.2.3.4.
Installere metric server
For å kunne se ressursbruken på clusteret anbefales Kubernetes Metrics Server.
Denne kan installeres med følgende kommando:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Hvis tjenesten sliter med å starte kan du gjøre følgende:
kubectl edit deploy metrics-server -n kube-system
og legge til følgende under container args:
- --kubelet-insecure-tls
Når metric server kjører kan du aktivere følgende
kubectl top node
Som viser ressursbruk per node, og
kubectl top pod
Som viser ressursbruk per pod.
Oppdatering
Det første du må gjøre ved en oppdatering er å finne ut av hvilken versjon du har og hvilken versjon du skal oppdatere til. For å finne ut av hvilken versjon du har kan du kjøre følgende kommando;
kubeadm version
Før du oppdaterer kubernetes er det viktig at du drainer alle nodene. Dette kan du gjøre med følgende kommando;
kubectl drain --ignore-daemonsets <node name>
Videre må du sette deg inn i hvilken versjon du ønsker å oppgradere til. Merk at det kan være “breaking changes” mellom versjoner, så sett deg godt inn i hvilken versjon som passer deg. Først kan de nyeste versjonene hentes med følgende kommando
sudo apt update
Deretter må den aktiveres for oppdateringer igjen med følgende kommando;
apt-mark unhold kubelet kubeadm kubectl
Så må de versjonene du ønsker å oppdatere til installeres, dette kan gjøres med følgende kommando;
apt install kubelet=<versjonsnummer> kubeadm=<versjonsnummer> kubectl=<versjonsnummer>
Deretter må de igjen markeres for å ikke gjøre automatiske oppdateringer, dette kan gjøres med følgende kommando;
apt-mark hold kubelet kubeadm kubectl
Videre må systemet oppdateres med følgende kommandoer;
sudo apt update sudo apt upgrade
Så må kubeadmin oppgraderes, først må versjonen sjekkes med følgende kommando;
kubeadm version
Så må du sjekke om oppgraderingsplanen er riktig, dette kan gjøres med følgende kommando;
kubeadm upgrade plan
Deretter kan kubeadm oppgraderes med følgende kommando;
kubeadm upgrade apply v<versjonsnummer>
Til slutt må du ucordne alle nodene igjen med følgende kommando;
kubectl uncordon <node name>
Backup
Fullstendig backup av hele clusteret
Bestill backup for dine VPS-er inkludert backup for alle diskene. Da vil Deploi utføre backup av hele clusteret.
Backup av kubernetes sine interne filer (certificates, etcd og andre config filer)
Her er måten å ta backup av de vanligste filene på kubernetes. Denne guiden er ikke komplett og det kan være mangler i backupsene.
Deployment:
kubectl get deployment <deployment-name> -o yaml > deployment-backup.yaml
Service:
kubectl get service mywebserver-nginx -o yaml > service-backup.yml
Configmap:
kubectl -n <namespace> get configmap <configmap-name> -o yaml > configmap-backup.yaml
Secrets:
kubectl -n <namespace> get secret <secret-name> -o yaml > Secret-backup.yaml
Merk: Både configmap og secrets må kopieres fra alle namespaces. Dessuten er det lurt å kryptere disse filene ettersom de inneholder sensitive data.
For å finne alle namespaces kan du bruke;
kubectl get namespaces
For å ta backup av etcd må du laste ned etcd klienten på master noden, dette kan gjøres med følgende kommando;
sudo apt install etcd-client
Deretter må du finne riktige fillokasjoner dette kan finnes med følgende kommando;
kubectl describe -n kube-system pod etcd | grep -i file
Til slutt kan du kjøre snapshot backup med følgende kommando. Merk at du må velge riktig fil-lokasjoner basert på kommandoen over og til slutt backup dato
sudo ETCDCTL_API=3 etcdctl snapshot save --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key <Backup mappe/filnavn>
Backup av persistent volumes
Først må du finne navnet på klassen du ønsker å backe opp. Så må en snapshotclass opprettes, dette kan gjøres med følgende kommando;
cat <<EOF | kubectl create -f - apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: <SnapClassName> annotations: snapshot.storage.kubernetes.io/is-default-class: "true" driver: io.openebs.csi-mayastor deletionPolicy: Delete parameters:
Du kan så ta en snapshot med følgende kommando
cat <<EOF | kubectl create -f - apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: <SnapName> spec: volumeSnapshotClassName: <SnapClassName> source: persistentVolumeClaimName: <persistent volume name> EOF
En snapshot er en form for backup, men dersom du ønsker backup et annet sted kan du lage en PersistentVolumeClaim fra Snapshotet for å få tilgang til innholdet i snapshotet og ta backup. Følg denne guiden: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#volume-snapshot-and-restore-volume-from-snapshot-support