Esta guía te ayudará a configurar un clúster de Kubernetes con una o más Raspberry Pi. Este método te permitirá aprender y experimentar con Kubernetes y sus funciones de una manera reproducible y rentable.
Requisitos
- Uno o más Raspberry Pi 4+ con 8 GB de RAM
- Raspberry Pi OS (64 bits) o similar instalado en cada dispositivo
- Conectado a una red (Wi-Fi o LAN)
- SSH habilitado en los dispositivos
Prepare sus dispositivos Raspberry Pi
El kubelet y el tiempo de ejecución de contenedores subyacente deben interactuar con cgroups para hacer cumplir la gestión de recursos para pods y contenedores, lo que incluye solicitudes y límites de CPU/memoria para cargas de trabajo contenerizadas. Por defecto, el Raspberry Pi OS no habilita todos los grupos de control (cgroup) requeridos para que el Kubelet y la Interfaz del Tiempo de Ejecución de Contenedores operen.
Para el propósito de esta instalación, estamos interesados en habilitar los siguientes controles de grupo:
- cgroup_enable=cpuset
- cgroup_enable=memory
- cgroup_memory=1
Para lograr esto, podemos añadirlos a /boot/cmdline.txt
ejecutando el siguiente comando en una terminal:
$ echo " cgroup_enable=cpuset cgroup_enable=memory cgroup_memory=1" | sudo tee -a /boot/cmdline.txt
A continuación, debes desactivar la memoria swap en todos tus dispositivos Raspberry Pis para que el Kubelet pueda funcionar correctamente. Hay varias formas de hacerlo y depende del sistema operativo que estés utilizando. En nuestro caso, la memoria swap se puede desactivar en Raspberry Pi OS con los siguientes comandos:
$ sudo dphys-swapfile swapoff
$ sudo systemctl disable dphys-swapfile
Como alternativa, puedes añadir una entrada en crontab para desactivar la memoria swap al reiniciar. Ejecuta:
$ sudo crontab -e
Agregue la línea:
@reboot /sbin/swapoff -a
Finalmente, reinicia cada uno de tus dispositivos para que los cambios requeridos tomen efecto.
Interfaz de Tiempo de Ejecución del Contenedor (CRI)
El CRI es una interfaz de complemento que permite a Kubelet utilizar una amplia variedad de tiempos de ejecución de contenedores, sin necesidad de volver a compilar los componentes del clúster. Los CRI más populares para Linux son:
Tiempo de Ejecución | Ruta al socket de dominio Unix |
---|---|
Containerd | unix:///var/run/containerd/containerd.sock |
CRI-O | unix:///var/run/crio/crio.sock |
Docker Engine (utilizando cri-dockerd) | unix:///var/run/cri-dockerd.sock |
Instalar y configurar requisitos previos
Los siguientes pasos aplican configuraciones comunes para los nodos de Kubernetes en Linux.
Reenviar IPv4 y permitir que iptables vea el tráfico puenteado
Ejecute los siguientes comandos:
$ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
$ sudo modprobe overlay
$ sudo modprobe br_netfilter
# parametros sysctl requeridos por la configuracion, se mantienen al reiniciar
$ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# Aplicar parametros sysctl sin reiniciar
$ sudo sysctl --system
Verifique que br_netfilter, overlay estén cargados ejecutando las siguientes instrucciones:
$ lsmod | grep br_netfilter
$ lsmod | grep overlay
Verifique que net.bridge.bridge-nf-call-iptables, net.bridge.bridge-nf-call-ip6tables, net.ipv4.ip_forward variables del sistema estén en 1 en la configuración de sysctl ejecutando la instrucción:
$ sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
Instalar Containerd
Hay varias formas de instalar Containerd. Para esta guía, utilizamos apt-get y los paquetes distribuidos por docker para debian. Para otras distribuciones consulte la documentación de Containerd: https://github.com/containerd/containerd/blob/main/docs/getting-started.md
Asegúrese de eliminar las instalaciones anteriores si esta no es una máquina nueva.
$ sudo apt-get remove docker docker-engine docker.io containerd runc
Configurar el repositorio
1. Actualice el índice del paquete apt e instale los paquetes para permitir que apt use un repositorio a través de HTTPS:
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
2. Agregue la clave GPG oficial de Docker:
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
3. Configure el repositorio:
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Instalar containerd.io
Para instalar la última versión, ejecute:
$ sudo apt-get update
$ sudo apt-get install -y containerd.io
Usted ahora ha instalado satisfactoriamente containerd.io.
Nota: Esta configuración no utiliza Docker Engine para mantener los paquetes requeridos al mínimo y porque no crearemos imágenes en los nodos trabajadores.
Configurar containerd.io
1. Cree una configuración predeterminada:
$ containerd config default | sudo tee /etc/containerd/config.toml > /dev/null
2. Abra el archivo de configuración en su editor preferido (para vi):
$ sudo vi /etc/containerd/config.toml
3. Encuentre la sección [plugins.”io.containerd.grpc.v1.cri”.containerd.runtimes.runc.options] y actualice SystemdCgroup valor a true. El containerd plugin debe verse:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
cni_conf_dir = ""
cni_max_conf_num = 0
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
runtime_path = ""
runtime_root = ""
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
BinaryName = ""
CriuImagePath = ""
CriuPath = ""
CriuWorkPath = ""
IoGid = 0
IoUid = 0
NoNewKeyring = false
NoPivotRoot = false
Root = ""
ShimCgroup = ""
SystemdCgroup = true
4. Asegúrese de que el plugin cri no esté deshabilitado. Busque el elemento disabled_plugins en la parte superior del archivo y verifique que disabled_plugins = []
5. Reinicie containerd para aplicar los cambios:
$ sudo systemctl restart containerd
6. Puedes verificar el estado de containerd para verificar que todo salió bien:
$ sudo systemctl status containerd
Nota: Si este archivo no está configurado correctamente, el proceso kubelet no se iniciará al crear el servidor con kubeadm.
Instalación de kubeadm, kubelet y kubectl
Instalará estos paquetes en todas sus máquinas:
- kubeadm: el comando para iniciar el clúster.
- kubelet: el componente que se ejecuta en todas las máquinas de su clúster y hace cosas como iniciar pods y contenedores.
- kubectl: la utilidad de línea de comando para comunicarse con su clúster.
1. Descargue la llave pública de Google Cloud:
$ sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://dl.k8s.io/apt/doc/apt-key.gpg
2. Agregue el repositorio apt de Kubernetes:
$ echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
3. Actualice el índice de apt, instale kubelet, kubeadm y kubectl y fije su versión:
$ sudo apt-get update
$ sudo apt-get install -y kubelet kubeadm kubectl
$ sudo apt-mark hold kubelet kubeadm kubectl
El kubelet ahora se reinicia cada pocos segundos, mientras espera en un crashloop a que kubeadm le indique qué hacer.
Cree un clúster de un solo nodo
Cree un archivo de configuración que contendrá las instrucciones básicas para que kubeadm cree el clúster. En un archivo single_node_cluster.yml agregue:
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
networking:
podSubnet: "10.244.0.0/16" # --pod-network-cidr
dnsDomain: "cluster.local"
serviceSubnet: "10.96.0.0/16"
clusterName: "mycluster"
---
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: systemd
Con esta configuración, crearemos un clúster con el nombre mycluster e indicaremos al kubelet que utilice el controlador systemd para los cgroups. . La configuración también proporciona la configuración de red básica que será necesaria al instalar un plugin de red.
Puede obtener más información sobre estas opciones y configuración de red en: https:// kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/
Inicialize el nodo del control-plane
Si siguió todas las instrucciones, debería estar listo para inicializar su primer nodo del control-plane. En una terminal, ejecute:
$ sudo kubeadm init --config single_node_cluster.yml
Si todo ha ido bien, cuando termine verás:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a Pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Nota: si desea crear un clúster de múltiples nodos, repita todos los pasos hasta aquí en sus nodos trabajadores. Luego, ejecute el último comando que obtuvo en este paso, que contiene instrucciones sobre cómo unirse al clúster desde un segundo nodo (incluidos los secretos que se han eliminado de esta guía). Por ejemplo, en un segundo nodo, ejecute:
$ sudo kubeadm join <control-plane-host>:<control-plane-port> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
Kubectl para usuario local
Para que kubectl funcione para su usuario no root, ejecute estos comandos, que también forman parte de la salida de kubeadm init:
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
Pruebe que puede ejecutar comandos kubectl en su nodo del control-plane:
$ kubectl get pods --all-namespaces
Verías todos los pods en los namespaces:
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-5d78c9869d-dz2pq 0/1 Pending 0 4m9s
kube-system coredns-5d78c9869d-mdjqk 0/1 Pending 0 4m9s
kube-system etcd-mycluster 1/1 Running 0 4m22s
kube-system kube-apiserver-mycluster 1/1 Running 0 4m23s
kube-system kube-controller-manager-mycluster 1/1 Running 0 4m25s
kube-system kube-proxy-2n4t2 1/1 Running 0 4m9s
kube-system kube-scheduler-mycluster 1/1 Running 0 4m25s
Aislamiento del nodo control-plane (opcional)
De forma predeterminada, su clúster no programará Pods en los nodos del control-plane por razones de seguridad. Si desea poder programar Pods en los nodos del control-plane, por ejemplo, si solo desea trabajar con un clúster de nodo único, ejecute el siguiente comando para contaminar su nodo control-plane y elimina la restricción:
$ kubectl taint nodes --all node-role.kubernetes.io/control-plane-
El resultado se verá así:
node "mycluster" untainted
Nota: esto no se recomienda en un entorno de producción y es muy preferible tener un clúster de múltiples nodos, donde tenga un nodo como control-plane y el otro como nodo trabajador.
Interfaz de Red de Contenedores (CNI)
El modelo de red lo implementa el tiempo de ejecución del contenedor en cada nodo. Los tiempos de ejecución de contenedores más comunes utilizan plugins de interfaz de red de contenedores (CNI) para administrar sus capacidades de red y seguridad. Existen plugins CNI de múltiples proveedores.
Hay numerosos complementos de red disponibles, consulte: https:/ /kubernetes.io/docs/concepts/cluster-administration/addons/#networking-and-network-policy.
Para esta configuración de clúster, usaremos Flannel. La documentación se puede encontrar en: https://github.com/flannel-io/flannel #implementar-franela-manualmente
Descargue el archivo de configuración predeterminado ubicado en: https://github .com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
$ curl -L -o kube-flannel.yml -s https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
Abra el archivo en su editor preferido y actualice el cidr de la red predeterminada para que coincida con el podSubnet del single_node_cluster.yml. Para este ejemplo, el cambio en kube-flannel se vería así:
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
Instale el complemento de red:
$ kubectl apply -f kube-flannel.yml
Luego, verá un nuevo namespace kube-flannel, un pod kube-flannel-ds y los pods coredns del namespace kube-system, se volverán saludable.
Esto indica que su clúster está listo para aceptar trabajo y que los pods pueden comunicarse entre sí.
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-flannel kube-flannel-ds-cc94c 1/1 Running 0 36s
kube-system coredns-5d78c9869d-dz2pq 1/1 Running 0 17m
kube-system coredns-5d78c9869d-mdjqk 1/1 Running 0 17m
kube-system etcd-mycluster 1/1 Running 0 18m
kube-system kube-apiserver-mycluster 1/1 Running 0 18m
kube-system kube-controller-manager-mycluster 1/1 Running 0 18m
kube-system kube-proxy-2n4t2 1/1 Running 0 17m
kube-system kube-scheduler-mycluster 1/1 Running 0 18m