Entorno de Estudio CKS
En lugar de montar un entorno local, vamos a utilizar una cloud cualquiera. Queremos al final nuestro clúster de frente a Internet.
Crea una nueva cuenta en google para tener 300 dólares gratuitos. Después puedes borrar la cuenta cuando termines el estudio, tienes 90 días. Crea un compromiso en tu agenda y listo.
Lo que nos importa es tener 2 máquinas virtuales una para el master y una para el worker.
Todo el clúster será montado encima de estas dos máquinas desde cero. Obviamente no vamos a usar ninguna solución de kubernetes de la cloud pues queremos desarrollar el estudio y trabajar encima de todos los puntos. Generalmente la cloud no nos da acceso a los nodos masters que ejecutan nuestro control plane.

El entorno del examen es exactamente como propuesto arriba.
Google Cloud
Si creaste tu cuenta verifica si los 300 dólares de crédito están ahí.
Puedes ir en Billing después en credits y verificar.

Antes de crear nuestra máquina vamos a instalar el gcloud cli.
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates gnupg curl
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
sudo apt-get update && sudo apt-get install google-cloud-cli
gcloud --version
Google Cloud SDK 488.0.0
alpha 2024.08.09
beta 2024.08.09
bq 2.1.8
bundled-python3-unix 3.11.9
core 2024.08.09
gcloud-crc32c 1.0.0
gsutil 5.30
# Para dejar la CLI funcionando en la cuenta correcta vamos a loguearnos
# Si el navegador no se abre copia el link y pégalo en tu navegador
gcloud auth login
# Después vamos a establecer nuestro project ID
gcloud projects list
PROJECT_ID NAME PROJECT_NUMBER
refined-byte-432619-k6 My First Project 750256581768
gcloud config set project refined-byte-432619-k6
Updated property [core/project].
gcloud compute instances list
Listed 0 items.
El siguiente paso es crear la vm. Repite este paso dos veces siendo que una vm será la cks-master y la otra cks-worker.
Irás en Compute Engine después en VM Instances. Como es la primera vez aparecerá para activar, entonces activa. Unos dos minutos después cuando vayas nuevamente irás directo a la pantalla de creación de vm.
Sigue los pasos y recuerda cambiar el nombre de la máquina, crear las dos en la misma región, cambiar sistema operativo para ubuntu 20.04 LTS con 50GB y la máquina es una E2 medium. Después solo crear.




gcloud compute instances list
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
cks-master us-central1-c e2-medium 10.128.0.5 34.46.7.233 RUNNING
cks-worker us-central1-c e2-medium 10.128.0.4 34.27.56.155 RUNNING
# Para entrar vía ssh en la instancia
gcloud compute ssh cks-master
gcloud compute ssh cks-worker
Setup Master
Vamos a dividir en 2 scripts. Uno común que será utilizado en ambas máquinas, master y worker y una segunda parte que será solo del master. Voy a comentar el script todo, pero la mayoría de lo que tenemos aquí fue aprendido durante el CKA.
Este comando será en las dos máquinas.
# Vamos a ejecutar como sudo
sudo -i
vi common.sh # Copia el script abajo
bash common.sh
No vamos a usar Docker, vamos a usar containerd. Entonces, para interactuar con contenedores, usaremos
crictl.
Common Script common.sh
#!/bin/sh
# Source: http://kubernetes.io/docs/getting-started-guides/kubeadm
set -e
# Verificando el SO
source /etc/lsb-release
if [ "$DISTRIB_RELEASE" != "20.04" ]; then
echo "################################# "
echo "############ WARNING ############ "
echo "################################# "
echo
echo "This script only works on Ubuntu 20.04!"
echo "You're using: ${DISTRIB_DESCRIPTION}"
echo "Better ABORT with Ctrl+C. Or press any key to continue the install"
read
fi
KUBE_VERSION=1.30.3
# get platform
PLATFORM=`uname -p`
if [ "${PLATFORM}" == "aarch64" ]; then
PLATFORM="arm64"
elif [ "${PLATFORM}" == "x86_64" ]; then
PLATFORM="amd64"
else
echo "${PLATFORM} has to be either amd64 or arm64/aarch64. Check containerd supported binaries page"
echo "https://github.com/containerd/containerd/blob/main/docs/getting-started.md#option-1-from-the-official-binaries"
exit 1
fi
### configuración terminal
apt-get --allow-unauthenticated update
apt-get --allow-unauthenticated install -y bash-completion binutils
echo 'colorscheme ron' >> ~/.vimrc
echo 'set tabstop=2' >> ~/.vimrc
echo 'set shiftwidth=2' >> ~/.vimrc
echo 'set expandtab' >> ~/.vimrc
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'alias c=clear' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
sed -i '1s/^/force_color_prompt=yes\n/' ~/.bashrc
### desactivar linux swap y eliminar cualquier partición swap existente
swapoff -a
sed -i '/\sswap\s/ s/^\(.*\)$/#\1/g' /etc/fstab
### eliminar paquetes
kubeadm reset -f || true
crictl rm --force $(crictl ps -a -q) || true
apt-mark unhold kubelet kubeadm kubectl kubernetes-cni || true
apt-get remove -y docker.io containerd kubelet kubeadm kubectl kubernetes-cni || true
apt-get autoremove -y
systemctl daemon-reload
### instalar podman
. /etc/os-release
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:testing.list
curl -L "http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/Release.key" | sudo apt-key add -
apt-get update -qq
apt-get -qq -y install podman cri-tools containers-common
rm /etc/apt/sources.list.d/devel:kubic:libcontainers:testing.list
cat <<EOF | sudo tee /etc/containers/registries.conf
[registries.search]
registries = ['docker.io']
EOF
### instalar paquetes
apt-get install -y apt-transport-https ca-certificates
mkdir -p /etc/apt/keyrings
rm /etc/apt/keyrings/kubernetes-1-28-apt-keyring.gpg || true
rm /etc/apt/keyrings/kubernetes-1-29-apt-keyring.gpg || true
rm /etc/apt/keyrings/kubernetes-1-30-apt-keyring.gpg || true
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-1-28-apt-keyring.gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-1-29-apt-keyring.gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-1-30-apt-keyring.gpg
echo > /etc/apt/sources.list.d/kubernetes.list
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-1-28-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-1-29-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-1-30-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
apt-get --allow-unauthenticated update
apt-get --allow-unauthenticated install -y docker.io containerd kubelet=${KUBE_VERSION}-1.1 kubeadm=${KUBE_VERSION}-1.1 kubectl=${KUBE_VERSION}-1.1 kubernetes-cni
apt-mark hold kubelet kubeadm kubectl kubernetes-cni
### instalar containerd 1.6 sobre versión instalada con apt
wget https://github.com/containerd/containerd/releases/download/v1.6.12/containerd-1.6.12-linux-${PLATFORM}.tar.gz
tar xvf containerd-1.6.12-linux-${PLATFORM}.tar.gz
systemctl stop containerd
mv bin/* /usr/bin
rm -rf bin containerd-1.6.12-linux-${PLATFORM}.tar.gz
systemctl unmask containerd
systemctl start containerd
### containerd
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
sudo mkdir -p /etc/containerd
### configuración containerd
cat > /etc/containerd/config.toml <<EOF
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
version = 2
[plugins]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
base_runtime_spec = ""
container_annotations = []
pod_annotations = []
privileged_without_host_devices = false
runtime_engine = ""
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
EOF
### crictl usa containerd como predeterminado
{
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
EOF
}
### kubelet debe usar containerd
{
cat <<EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS="--container-runtime-endpoint unix:///run/containerd/containerd.sock"
EOF
}
### iniciar servicios
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
systemctl enable kubelet && systemctl start kubelet
Script específico para el master iniciar el clúster.
# Permaneciendo como sudo
vi initcluster.sh # copia el script abajo y :wq para salir y guardar
bash initcluster.sh
#!/bin/sh
# Source: http://kubernetes.io/docs/getting-started-guides/kubeadm
set -e
KUBE_VERSION=1.30.3
### init k8s
rm /root/.kube/config || true
kubeadm init --kubernetes-version=${KUBE_VERSION} --ignore-preflight-errors=NumCPU --skip-token-print --pod-network-cidr 192.168.0.0/16
mkdir -p ~/.kube
sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
### CNI
kubectl apply -f https://raw.githubusercontent.com/killer-sh/cks-course-environment/master/cluster-setup/calico.yaml
# etcdctl
ETCDCTL_VERSION=v3.5.1
ETCDCTL_ARCH=$(dpkg --print-architecture)
ETCDCTL_VERSION_FULL=etcd-${ETCDCTL_VERSION}-linux-${ETCDCTL_ARCH}
wget https://github.com/etcd-io/etcd/releases/download/${ETCDCTL_VERSION}/${ETCDCTL_VERSION_FULL}.tar.gz
tar xzf ${ETCDCTL_VERSION_FULL}.tar.gz ${ETCDCTL_VERSION_FULL}/etcdctl
mv ${ETCDCTL_VERSION_FULL}/etcdctl /usr/bin/
rm -rf ${ETCDCTL_VERSION_FULL} ${ETCDCTL_VERSION_FULL}.tar.gz
echo
echo "### COMMAND TO ADD A WORKER NODE ###"
kubeadm token create --print-join-command --ttl 0
Setup Worker Node
Vamos a ejecutar este script en el worker node y por último el comando arriba para hacer el join de este nodo en el clúster. Si quieres puedes pegar la salida generada por el comando en el master kubeadm token create --print-join-command --ttl 0.
# Permaneciendo como sudo
vi joincluster.sh # copia el script abajo
bash joincluster.sh
joincluster.sh
#!/bin/sh
# Source: http://kubernetes.io/docs/getting-started-guides/kubeadm
set -e
KUBE_VERSION=1.30.3
### init k8s
kubeadm reset -f
systemctl daemon-reload
service kubelet start
echo
echo "EXECUTE ON MASTER: kubeadm token create --print-join-command --ttl 0"
echo "THEN RUN THE OUTPUT AS COMMAND HERE TO ADD AS WORKER"
echo

En el master que es donde tenemos el kubeconfig configurado ya podemos verificar el clúster.
root@cks-master:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
cks-master Ready control-plane 4m22s v1.30.3
cks-worker Ready <none> 2m12s v1.30.3
root@cks-master:~# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system calico-kube-controllers-75bdb5b75d-d2tl9 1/1 Running 0 6m1s
kube-system canal-665nh 2/2 Running 0 4m10s
kube-system canal-8nn2f 2/2 Running 0 6m1s
kube-system coredns-7db6d8ff4d-cmcff 1/1 Running 0 6m1s
kube-system coredns-7db6d8ff4d-kdb4t 1/1 Running 0 6m1s
kube-system etcd-cks-master 1/1 Running 0 6m16s
kube-system kube-apiserver-cks-master 1/1 Running 0 6m16s
kube-system kube-controller-manager-cks-master 1/1 Running 0 6m19s
kube-system kube-proxy-c2qx6 1/1 Running 0 6m1s
kube-system kube-proxy-gb77r 1/1 Running 0 4m10s
kube-system kube-scheduler-cks-master 1/1 Running 0 6m16s
root@cks-master:~#
[!CAUTION] Recuerda parar las máquinas cuando no estés estudiando. Parar, no destruir.

Acceso Externo
Kubernetes necesita ofrecer servicios en los puertos entre 30000 y 32767, entonces necesitamos liberar esos puertos en las máquinas.
gcloud compute firewall-rules create nodeports --allow tcp:30000-32767
Creating firewall...⠹Created [https://www.googleapis.com/compute/v1/projects/refined-byte-432619-k6/global/firewalls/nodeports].
Creating firewall...done.
NAME NETWORK DIRECTION PRIORITY ALLOW DENY DISABLED
nodeports default INGRESS 1000 tcp:30000-32767 False