Tecnologia Kubernetes

Preparazione cluster KinD

Questi sono i passi per la preparazione di un cluster Kubernetes basato su Kind.

Partiamo da un sistema con il seguente software installato:

  • Docker - meglio se ultima versione
  • Docker Compose
    • come script standalone in Python
    • (meglio) come componente di Docker stesso

I comandi qui illustrati useranno l'utility standalone. Per usare invece il Docker Compose integrato in Docker, sostituire docker compose al posto di docker-compose.

NOTA

I files di configurazione del cluster Kind standard sono raccolti nel file tar cluster-kind-std.tar Scompattare tale file nella directory di login. Procedere quindi alla sezione Lancio del Cluster Kubernetes.

kubectl

Scaricare e installare kubectl:

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s \
https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl

chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
sudo chown root:root /usr/local/bin/kubectl

kind

Installiamo ora kind:

curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.14.0/kind-linux-amd64 && \
  chmod +x ./kind && \
  sudo mv ./kind /usr/local/bin/kind

Script di Attivazione del Cluster

Tutti gli esercizi utilizzeranno la versione del cluster costruito con Kind.

Editare il file di configurazione:

cd
vim std.sh
#!/bin/sh
set -o errexit

# crea il contenitore del registry se non esiste
reg_name='kind-registry'
reg_port='5000'
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
  docker run \
    -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \
    -v $HOME/.docker/registry:/var/lib/registry registry:2
fi

# crea un cluster con il registry locale abilitato in containerd
cat <<EOF | kind create cluster --image kindest/node:v1.24.0 --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
containerdConfigPatches:
- |-
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${reg_port}"]
    endpoint = ["http://${reg_name}:5000"]
nodes:
- role: control-plane
  extraMounts:
    - hostPath: /data
      containerPath: /data
- role: worker
  extraMounts:
    - hostPath: /data
      containerPath: /data
- role: worker
  extraMounts:
    - hostPath: /data
      containerPath: /data
EOF

# connette il registry alla rete del cluster se non connesso
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
  docker network connect "kind" "${reg_name}"
fi

# Documenta il local registry
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: local-registry-hosting
  namespace: kube-public
data:
  localRegistryHosting.v1: |
    host: "localhost:${reg_port}"
    help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
EOF

Renderla eseguibile:

chmod +x ~/std.sh

Shell Scripts per la Gestione del Cluster

setup

sudo vim ~/setup.sh
#! /bin/sh
echo "Creating cluster ..."
echo
echo "~/std.sh"
~/std.sh
echo "Cluster info follows ..."
kubectl cluster-info --context kind-kind

echo
echo "---> Loading and configuring the Metallb load balancer ..."
echo
echo "-- Namespace"
echo "kubectl apply -f scripts/metallb-ns.yml"
kubectl apply -f scripts/metallb-ns.yml
echo
echo "-- Deployment and service"
echo "kubectl apply -f scripts/metallb-svc.yml"
kubectl apply -f scripts/metallb-svc.yml
echo
echo "-- Configmap"
echo "kubectl apply -f scripts/metallb-configmap.yml"
kubectl apply -f scripts/metallb-configmap.yml
echo
echo "Wait up to 120s for Metallb controller deployment to be ready ..."
kubectl wait deployment -n metallb-system controller --for condition=Available=True --timeout=120s
echo
echo "    CLUSTER NOW READY"
echo " ===> All resources in namespace 'default'"
kubectl get all
echo
echo " ===> All resources in namespace 'metallb-system'"
kubectl get all -n metallb-system

Renderla eseguibile:

sudo chmod +x ~/setup.sh

teardown

sudo vim ~/teardown.sh
echo "About to delete cluster 'kind'"
echo "Press Control-C within 10 seconds to interrupt"
sleep 10
kind delete cluster
echo "Cluster deleted"

Renderla eseguibile:

sudo chmod +x ~/teardown.sh

Manifests di Gestione del Cluster

Metallb Load Balancer

Scarico dei manifest necessari dalla rete e trasferimento al contenitore kub:

mkdir -p ~/scripts

wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
sudo mv namespace.yaml ~/scripts/metallb-ns.yml

wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
sudo mv metallb.yaml ~/scripts/metallb-svc.yml

Configmap per Metallb

sudo vim ~/scripts/metallb-configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 172.18.255.200-172.18.255.250

Lancio del Cluster Kubernetes

Scaricare l'immagine del cluster:

docker pull kindest/node:v1.24.0

Partenza del cluster:

~/setup.sh

Impiegherà un po' di tempo aggiuntivo, poichè scaricherà la sua immagine di default del cluster.

Il File Kubeconfig

Kubeconfig è un file Yaml con tutti i dettagli del cluster Kubernetes, i certificati, i token segreti.

Può essere autogenerato dall'utility di costruzione cluster o ricevuto dal cloud provider.

La sua locazione tipica ès $HOME/.kube/config.

Si può usare un altro file, ma occorre indicarlo con la variabile d'ambiente KUBECONFIG.

Per esempio:

export KUBECONFIG=$HOME/.kube/dev_cluster_config

oppure:

kubectl get nodes --kubeconfig=$HOME/.kube/dev_cluster_config
KUBECONFIG=$HOME/.kube/dev_cluster_config kubectl get nodes

Per esaminare il nostro, generato da Kind:

less ~/.kube/config

Una struttura più generica può essere:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <ca-data-here>
    server: https://your-k8s-cluster.com
  name: <cluster-name>
contexts:
- context:
    cluster:  <cluster-name>
    user:  <cluster-name-user>
  name:  <cluster-name>
current-context:  <cluster-name>
kind: Config
preferences: {}
users:
- name:  <cluster-name-user>
  user:
    token: <secret-token-here>

Qualora vi fossero più files di configurazione di cluster, si può compiere il merge coi comandi, per esempio:

KUBECONFIG=config:dev_config:test_config kubectl config view --merge --flatten > config.new
mv $HOME/.kube/config $HOME/.kube/config.old
mv $HOME/.kube/config.new $HOME/.kube/config

Vi sono tre configurazioni principali:

  • clusters - con il nome, la URL del server e il certificato
  • contexts - con il nome, il cluster a cui si riferisce e l'utente con cui accede
  • users - con il nome e le credenziali d'accesso, spesso un Client Certificate

Sono degli arrays, e possono avere più elementi.

Contesto di kubectl

kubectl invia le sue richieste al Server API di un determinato cluster, il contesto.

Listare i contesti disponibili:

kubectl config get-contexts

Cambiare contesto:

kubectl config use-context <context-name>  

Si può anche cancellare un contesto, ma non è consigliabile, meglio usare l'utility specifica per la gestione del cluster, p.es. kind.

kubectl config delete-context <context-name>