DEV Community

Robert Waffen for betadots

Posted on

Puppet und Kubernetes

Heute zeigen wir, wie man einen Kubernetes Cluster mit Puppet aufsetzen und verwalten kann.

Puppet Modul Auswahl

Es gibt einige Puppet Module auf der Puppet Forge, mit denen man Kubernetes verwalten kann.
So findet man unter anderem die Module Puppetlabs Kubernetes und Voxpupuli k8s.
Alle weiteren Module haben seit geraumer Zeit keine Aktualisierungen mehr erhalten. Daher betrachten wir diese Module als verwaist.

Hinweis: auf dem CfgMgmtCamp 2023 hat die Puppet Open Source Community mit den Puppet Mitarbeitern geredet und darum gebeten, das puppetlabs-kubernetes Modul zu archivieren. Dieses Modul benötigt für das initiale Setup eine bereits laufende Kubernetes Umgebung und möchte die Konfiguration mit Hilfe eines besonderen Containers auslesen.

Wir empfehlen dringend, das neue, moderne Voxpupuli k8s Modul zu verwenden.

Puppet-K8S Modul

Mit dem Puppet K8S Modul kann man Controller Nodes und Worker Nodes einrichten. Beide benötigen dazu die Klasse k8s.
Alle Einstellungen können mit Hilfe von Hiera Daten vorgenommen werden. Dabei sind die Parameter über 3 Klassen verteilt:

Allgemeine Daten: k8s Klasse
Controller Daten: k8s::server Klasse
Worker Daten: k8s::node Klasse

Ein einfacher Cluster benötigt die folgenden Parameter:

Kubernetes controller (apiserver, controller-manager und scheduler)

k8s::role: 'server'
k8s::master: 'http://controller-0.example.com:6443'
Enter fullscreen mode Exit fullscreen mode

Das Setup der notwendigen etcd Server Instanzen kann auf 2 unterschiedliche Arten vorgenommen werden:

  1. Statische Liste (FQDN)
  2. Verwendung von PuppetDB
# PuppetDB
k8s::puppetdb_discovery: true
# oder Liste
k8s::server::etcd_servers:
  - 'https://node1:2379'
  - 'https://node2:2379'
  - 'https://node3:2379'
Enter fullscreen mode Exit fullscreen mode

Das Erzeugen der für Kubernetes notwendigen Zertifikate kann das Modul übernehmen. Man kann auch bestehende Zertifikate hinterlegen.
Beim Aufsetzen einer geclusterten Control Plane, muss man beachten, dass die Zertifikate des ersten Cluster Control Nodes auf die weiteren Control Nodes verteilt wird. Dies betrifft die folgenden Verzeichnisse:
/etc/kubernetes/certs und /var/lib/etcd/certs.
Die Verteilung ist noch nicht Bestandteil des Moduls.

k8s::server::etcd::generate_ca: true
k8s::server::generate_ca: true
Enter fullscreen mode Exit fullscreen mode

Kubernetes worker (kubelet)

k8s::role: 'node'
k82::master: 'https://controller-0.example.com:6443'
Enter fullscreen mode Exit fullscreen mode

Beispiel für containerd und bridge networking

Controller

k8s::role: 'server'
k8s::master: 'https://controller-0.example.com:6443' # default
k8s::container_manager: 'containerd'

k8s::manage_firewall: true    # default: false
k8s::puppetdb_discovery: true # default: false

k8s::server::node_on_server: false # don't use controller as worker
k8s::server::etcd::generate_ca: true
k8s::server::generate_ca: true

# bind apiserver to a interface the worker and controller can communicate with
k8s::server::apiserver::advertise_address: "%{facts.networking.interfaces.enp0s8.ip}"

# flannel networking is default in the module
# but we want to showcase bridged networking here
k8s::server::resources::manage_flannel: false

k8s::service_cluster_cidr: '10.20.0.0/20' # overlay network for cluster services
k8s::cluster_cidr: '10.20.16.0/20'        # overlay network for the pods in the cluster
Enter fullscreen mode Exit fullscreen mode

Worker

k8s::role: 'node'
k8s::master: 'https://controller-0.example.com:6443' # default
k8s::container_manager: 'containerd'

k8s::manage_fireall: true
k8s::puppetdb_discovery: true

# the same as in k8s::server::resources::bootstrap::secret but prefixed with "puppet."
k8s::node::node_token: "puppet.%{lookup('k8s::server::resources::bootstrap::secret')}"

# for debugging
k8s::node::manage_crictl: true
k8s::install::crictl::config:
  'runtime-endpoint': 'unix:///run/containerd/containerd.sock'
  'image-endpoint': 'unix:///run/containerd/containerd.sock'

k8s::service_cluster_cidr: '10.20.0.0/20' # overlay network for cluster services
k8s::cluster_cidr: '10.20.16.0/20'        # overlay network for the pods in the cluster
Enter fullscreen mode Exit fullscreen mode

Shared data

lookup_options:
  k8s::server::resources::bootstrap::secret:
    convert_to: Sensitive

# Sensitive[Pattern[/^[a-z0-9]{16}$/]]
k8s::server::resources::bootstrap::secret: 'a23456789bcdefgh'
Enter fullscreen mode Exit fullscreen mode

Beispiel für containerd und cilium

Zuerst wird kube-proxy benötigt um ein initiales Setup zu erzeugen.
Danach wird Cilium installiert, welches kube-proxy ersetzt.
Nach der Cilium Installation kann kube-proxy wieder entfernt werden.

Controller

k8s::role: 'server'
k8s::master: 'https://controller-0.example.com:6443' # default
k8s::container_manager: 'containerd' # default: crio

k8s::manage_firewall: true    # default: false
k8s::puppetdb_discovery: true # default: false

k8s::server::node_on_server: false # don't use controller as worker
k8s::server::etcd::generate_ca: true
k8s::server::generate_ca: true


# bind apiserver to a interface the worker and controller can communicate with
k8s::server::apiserver::advertise_address: "%{facts.networking.interfaces.enp0s8.ip}"

# we want to showcase cilium here
k8s::server::resources::manage_flannel: false
Enter fullscreen mode Exit fullscreen mode

Worker

k8s::role: 'node'
k8s::master: 'https://controller-0.example.com:6443'
k8s::container_manager: 'containerd'


k8s::manage_firewall: true
k8s::puppetdb_discovery: true

# the same as in k8s::server::resources::bootstrap::secret but prefixed with "puppet."
k8s::node::node_token: "puppet.%{lookup('k8s::server::resources::bootstrap::secret')}"

# for debugging
k8s::node::manage_crictl: true
k8s::install::crictl::config:
  'runtime-endpoint': 'unix:///run/containerd/containerd.sock'
  'image-endpoint': 'unix:///run/containerd/containerd.sock'

k8s::service_cluster_cidr: '10.20.0.0/20' # overlay network for cluster services
k8s::cluster_cidr: '10.20.16.0/20'        # overlay network for the pods in the cluster
Enter fullscreen mode Exit fullscreen mode

Shared data

lookup_options:
  k8s::server::resources::bootstrap::secret:
    convert_to: Sensitive

# Sensitive[Pattern[/^[a-z0-9]{16}$/]]
k8s::server::resources::bootstrap::secret: 'a23456789bcdefgh'
Enter fullscreen mode Exit fullscreen mode

Nach dem initialen Setup kann Cilium installiert werden.

Initialize cilium

⚠️ Alle hier genannten Schritte müssen auf EINEM der Controller ausgeführt werden!

Das Cilium Paket muss heruntergeladen werden. Dies ist noch nicht Bestandteil des Moduls. Die notwendige Konfiguration erfolgt in der Datei cilium-values.yaml.

Installation laut cilium quick installation

CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/master/stable.txt)
CLI_ARCH=amd64
if [ "$(uname -m)" = "aarch64" ]; then CLI_ARCH=arm64; fi
curl -L --fail --remote-name-all https://github.com/cilium/cilium-cli/releases/download/${CILIUM_CLI_VERSION}/cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-${CLI_ARCH}.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-${CLI_ARCH}.tar.gz /usr/local/bin
rm cilium-linux-${CLI_ARCH}.tar.gz{,.sha256sum}
Enter fullscreen mode Exit fullscreen mode

Die cilium-values.yaml Datei

---
k8sServiceHost: controller-0.example.com
k8sServicePort: 6443
autoDirectNodeRoutes: true
rollOutCiliumPods: true
kubeProxyReplacement: strict
tunnel: disabled
ipv4NativeRoutingCIDR: 10.20.16.0/20 # overlay network for the pods in the cluster
priorityClassName: system-cluster-critical
ipam:
  mode: kubernetes
nodePort:
  enabled: true
  directRoutingDevice: ens192
bpf:
  clockProbe: true
  masquerade: true
  tproxy: true
loadBalancer:
  mode: hybrid
  algorithm: maglev
  hashSeed: uWul3Twb7mKCmNSN
hubble:
  relay:
    enabled: true
    rollOutPods: true
  ui:
    enabled: true
    rollOutPods: true
operator:
  rollOutPods: true
  prometheus:
    enabled: true
hostPort:
  enabled: true
ipv4:
  enabled: true
ipv6:
  enabled: true
socketLB:
  enabled: true
prometheus:
  enabled: true
Enter fullscreen mode Exit fullscreen mode

Vor der Cilium Installation muss man prüfen, dass alle Worker Nodes verbunden sind. Diese können auch im Status NotReady sein.

# kubectl get nodes

NAME                   STATUS     ROLES    AGE   VERSION
worker-1.example.com   NotReady   <none>   83s   v1.26.4
worker-2.example.com   NotReady   <none>   83s   v1.26.4
Enter fullscreen mode Exit fullscreen mode

Installation von Cilium:

cilium install --version v1.13.2 --helm-values /path/to/cilium-values.yaml
Enter fullscreen mode Exit fullscreen mode
ℹ️  Using Cilium version 1.13.2
🔮 Auto-detected cluster name: default
🔮 Auto-detected datapath mode: tunnel
🔮 Auto-detected kube-proxy has not been installed
ℹ️  Cilium will fully replace all functionalities of kube-proxy
ℹ️  helm template --namespace kube-system cilium cilium/cilium --version 1.13.2 --set autoDirectNodeRoutes=true,bpf.clockProbe=true,bpf.masquerade=true,bpf.tproxy=true,cluster.id=0,cluster.name=default,encryption.nodeEncryption=false,hostPort.enabled=true,hubble.relay.enabled=true,hubble.relay.rollOutPods=true,hubble.ui.enabled=true,hubble.ui.rollOutPods=true,ipam.mode=kubernetes,ipv4.enabled=true,ipv4NativeRoutingCIDR=10.20.16.0/20,ipv6.enabled=true,k8sServiceHost=localhost,k8sServicePort=6443,kubeProxyReplacement=strict,loadBalancer.algorithm=maglev,loadBalancer.hashSeed=uWul3Twb7mKCmNSN,loadBalancer.mode=hybrid,nodePort.directRoutingDevice=enp0s8,nodePort.enabled=true,operator.prometheus.enabled=true,operator.replicas=1,operator.rollOutPods=true,priorityClassName=system-cluster-critical,prometheus.enabled=true,rollOutCiliumPods=true,serviceAccounts.cilium.name=cilium,serviceAccounts.operator.name=cilium-operator,socketLB.enabled=true,tunnel=disabled
ℹ️  Storing helm values file in kube-system/cilium-cli-helm-values Secret
🔑 Created CA in secret cilium-ca
🔑 Generating certificates for Hubble...
🚀 Creating Service accounts...
🚀 Creating Cluster roles...
🚀 Creating ConfigMap for Cilium version 1.13.2...
🚀 Creating Agent DaemonSet...
🚀 Creating Operator Deployment...
⌛ Waiting for Cilium to be installed and ready...
✅ Cilium was successfully installed! Run 'cilium status' to view installation health
Enter fullscreen mode Exit fullscreen mode

Nun sollten alle Worker im Ready Status sein:

kubectl get nodes

NAME                   STATUS   ROLES    AGE   VERSION
worker-1.example.com   Ready    <none>   5m    v1.26.4
worker-2.example.com   Ready    <none>   5m    v1.26.4
Enter fullscreen mode Exit fullscreen mode
cilium status

    /¯¯\
 /¯¯\__/¯¯\    Cilium:          OK
 \__/¯¯\__/    Operator:        OK
 /¯¯\__/¯¯\    Hubble Relay:    disabled
 \__/¯¯\__/    ClusterMesh:     disabled
    \__/

Deployment        cilium-operator    Desired: 1, Ready: 1/1, Available: 1/1
DaemonSet         cilium             Desired: 1, Ready: 1/1, Available: 1/1
Containers:       cilium             Running: 1
                  cilium-operator    Running: 1
Cluster Pods:     1/1 managed by Cilium
Image versions    cilium             quay.io/cilium/cilium:v1.13.2@sha256:85708b11d45647c35b9288e0de0706d24a5ce8a378166cadc700f756cc1a38d6: 1
                  cilium-operator    quay.io/cilium/operator-generic:v1.13.2@sha256:a1982c0a22297aaac3563e428c330e17668305a41865a842dec53d241c5490ab: 1
Enter fullscreen mode Exit fullscreen mode

Nach der erfolgreichen Installation von Cilium kann kube-proxy deinstalliert werden:

k8s::server::resources::kube_proxy::ensure: absent
Enter fullscreen mode Exit fullscreen mode

Weitere Dokumentation

Top comments (0)