Pular para o conteúdo principal

Ambiente de Estudo CKS

Ao invés de montar um ambiente local, vamos utilizar uma cloud qualquer. Queremos no final o nosso cluster de frente para Internet.

Crie uma nova conta no google para ter 300 dólares gratuitos. Depois você deleta a conta quando acabar o estudo, você tem 90 dias. Crie um compromisso na sua agenda e pronto.

O que nos importa é ter 2 máquinas virtuais uma para o master e uma para o worker.

Todo o cluster será montado em cima dessas duas máquinas do zero. Obviamente não vamos usar nenhuma solução de kubernetes da cloud pois queremos desenvolver o estudo e trabalhar em cima de todos os pontos. Geralmente a cloud não nos dá acesso aos nodes masters que rodam o nosso control plane.

alt text

O ambiente do exame é exatamente como proposto acima.

Google Cloud

Se você criou a sua conta verifique se os 300 dólares de crédito está lá.

Você pode ir em Billing depois em credits e conferir.

alt text

Antes de criar a nossa máquina vamos instalar o 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 deixar a CLI funcionando na conta certa vamos logar
# Se o navegador não abrir copie o link e cole no seu navegador
gcloud auth login

# Depois vamos setar o nosso 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.

O próximo passo é criar a vm. Repita esse passo duas vezes sendo que uma vm será a cks-master e a outra cks-worker.

Você irá em Compute Engine depois em VM Instances. Como é a primeira vez irá aparecer para ativar, então ative. Uns dois minutos depois quando for novamente vai direto para a tela de criação de vm.

Siga os passos e lembre de trocar o nome da máquina, criar as duas na mesma região, mudar sistema operacional para ubuntu 20.04 LTS com 50GB e a máquina é uma E2 medium. Depois é só criar.

alt text

alt text

alt text

alt text

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 entra via ssh na instância
gcloud compute ssh cks-master
gcloud compute ssh cks-worker

Setup Master

Vamos dividir em 2 scripts. Um comum que será utilizado em ambas as máquinas, master e worker e uma segunda parte que será só do master. Vou comentar o script todo, mas a maioria do que temos aqui foi aprendido durante o CKA.

Esse comando será nas duas máquinas.

# Vamos executar como sudo
sudo -i
vi common.sh # Copie o script abaixo
bash common.sh

Não vamos usar o Docker, vamos usar o containerd. Então, para interagir com containers, usaremos o crictl.

Common Script common.sh

#!/bin/sh

# Source: http://kubernetes.io/docs/getting-started-guides/kubeadm

set -e

# Conferindo o 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

### setup 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


### disable linux swap and remove any existing swap partitions
swapoff -a
sed -i '/\sswap\s/ s/^\(.*\)$/#\1/g' /etc/fstab


### remove packages
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

### install 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

### install packages
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

### install containerd 1.6 over apt-installed-version
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

### containerd config
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 uses containerd as default
{
cat <<EOF | sudo tee /etc/crictl.yaml
runtime-endpoint: unix:///run/containerd/containerd.sock
EOF
}

### kubelet should use containerd
{
cat <<EOF | sudo tee /etc/default/kubelet
KUBELET_EXTRA_ARGS="--container-runtime-endpoint unix:///run/containerd/containerd.sock"
EOF
}

### start services
systemctl daemon-reload
systemctl enable containerd
systemctl restart containerd
systemctl enable kubelet && systemctl start kubelet

Script específico para o master iniciar o cluster.

# Permancendo como sudo
vi initcluster.sh # copie o script abaixo e :wq para sair e salvar
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 rodar esse script no worker node e por último o comando acima para fazer o join desse node no cluster. Se quiser pode colar a saída gerada pelo comando no master kubeadm token create --print-join-command --ttl 0.

# Permanecendo como sudo
vi joincluster.sh # copie o script abaixo
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

alt text

No master que é onde temos o kubeconfig configurado já podemos conferir o cluster.

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] Lembre de parar as máquinas quando não tiver estudando. Parar, não destruir.

alt text

Acesso Externo

O kubernetes precisa oferecer serviços nas portas entre 30000 e 32767, então precisamos liberar essas portas nas 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