🐳 Dump Kubernetes Cka
intro
isso é um dump do que eu aprendi e anotei estudando kubernetes pra CKA.
essas anotações foram feitas pra mim, então se não entendeu algo se vira (ou me pergunta github@mtonio.com).
hoje em dia tudo da pra copiar e colar pra uma LLM, então o importante é manter palavras-chave, explicações de conceitos e edge cases, os especificos
core
kubectl
k get all -A
lembra de usar a API reference ao invés de ficar perdido na documentação deles https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
pods
k get pods –selector env=dev
k run podname –image=x –labels=”a=foo,b=bar”
k run podname –image=x –dry-run=client -o=yaml
use k get pod x -o=yaml > pod.yaml pra recriar o pod
k get pods -o=wide (pode ver em que node os pods estão)
você pode especificar Requests minimos e Limits máximos para os cpu e memória de um pod
quando você coloca –expose –port 80, ele cria um service clusterIp pra você junto com o pod
CrashLoopBackOff num pod pode ser varias coisas, se você der k get pod, dentro do yaml tem a razão pela qual ele deu erro
k logs podname –container=x pra ver os logs do pod
quando um pod é filho de um controller dá pra ver em k describe pod podname | grep ControlledBy:
volumes hostPath montam a pasta do pod diretamente no host, é muito usado em static pods
imagePullSecrets dentro da spec do pod pra usar um registry do docker privado
k delete pod –force pra não ter que ficar esperando
lembra de olhar os configmaps dos pods (que são montados como volumes), as vezes uma config importante está num configmap do pod e vc não sabe
sidecar containers e init containers
sidecar containers são tipos especificos de init containers que tem restartPolicy: Always
se um init container tem restartPolicy: Always, ele só morre quando o container principal morrer tambem
Init Containers são usados na spec de pods pra criar um container itermediario pra fazer algum build ou setup antes do container principal, da pra dividir um volume entre os dois containers com volumeMounts pra eles terem acesso aos mesmos arquivos
init containers rodam um depois do outro, não simultaneamente
pra ver pq o init container falhou, usa k logs podname -c init-container-name
nodes
pods tambem podem rodar no node controlplane
você pode forçar um node manualmente num pod com k edit -> nodeName (manual scheduling)
k get nodes -o wide para pegar os ips dos nós
ssh node-ip para dar ssh num nó
k top pods/nodes (precisa do metrics server rodando)
kubectl drain node01 –ignore-daemonsets (adiciona taint de unschedulable pra fazer manutencao e mata todos os pods dentro)
drain não funciona pra dar evict em pods sem controler, pq ele deletaria algo pra sempre
kubectl uncordon node01 (deixa o node schedulable de novo)
use o comando ip a
pra ver todas as network interfaces
a interface com (172.0.0.0/16) é a dos containeres
(kube-controller-manager.yaml dentro dos manifests é onde você encontra o range de ips dos pods)
ip route show default
mostra o gateway padrão do nó (ip do roteador)
containeres tem um ip do roteador virtual que não precisa estar na mesma subnet da rede, se o nó for um container tipo minikube já sabe
deployments
deployments são controllers feitos só pra pods e replicasets
depois de uma mudança, você tem que dar scale=0 ou deletar os pods manualmente pro controller recriar
k create deploy –image=x –replicas=3
k scale –replicas=5 rs/new-replica-set
selector labels e template labels no spec de um controller é como o controller sabe de quais pods ele é dono
deployments do tipo RollingUpdate trocam pods um por um sem precisarem ser deletados
services
dns dos serviços tbm funciona se quebrado em partes (tanto service-name quanto service-name.default.svc.cluster.local) funcionam
o service tipo clusterIP é virtual, expõe uma porta acessado só internamente por outros pods
o service tipo nodeport expõe uma porta alta em todos nodes, a nodePort, mas ele tambem expõe uma porta interna port e leva em sua config a targetPort, do pod
da pra usar pod: nameselector pra escolher quais pods o service vai servir de proxy
kube-system, static pods, daemonsets and etcd
static pod é um pod sem controller definido por padrão em em /etc/kubernetes/manifests/ ()
daemonset é um controller que roda um pod pra cada nó do cluster, e é muito comum em ferramentas de logging, monitoramento e networking
kube-proxy é um daemonset que implementa os services, ele tbm lida com firewalls de services
coredns roda no kube-system e é o que resolve os dns tipo .svc.cluster.local
o coredns é definidos nos pods como um servidor dns mesmo, na porta 53 e tudo mais
se você fizer ps aux | grep kubelet você consegue ver onde ficam os arquivos de configuração do kubelet, incluindo o –config que é o mais importante
é possivel deployar mais de um scheduler no kubernetes, e as vezes pra setups de infraestrutura muito customizados, ou que sofrem trafego de criacao/destruicao de pods muito alto é o que eles fazem
da pra usar o help dos binarios dos containeres que você não faz ideia do que fazem, tipo k exec -it kube-apiserver-controlplane -n kube-system – kube-apiserver –help
crictl ps -a (é tipo docker ps -a mas para os containeres que implementam o kubernetes)
crictl logs container-id
etcd node roda como pod mas você pode usar etcdctl no controlplane pra usar ele
etcd guarda todas as resource definitions e metadata de pods rodando
etc é um static pod em /etc/kubernetes/manifests/etcd.yaml, tipo o kube-apiserver
pra fazer um backup do etcd:
etcdctl snapshot save --endpoints --cacert --cert --key /opt/snapshot-pre-boot.db
etcdctl snapshot restore /opt/snapshot-pre-boot.db data-dir/
rm -rf /var/lib/etcd/ && mv data-dir /var/lib/etcd
o port do etcd 2379 é pra comunicação controlplane -> node
o port etcd 2380 é pra comunicação controlplane <-> controlplane (peer to peer)
dicas para debugging
se for application failure: olhe a config do service e do pod
se for failure no controlplane: olha os pods do kube-system e o /etc/kubernetes/manifests
se for failure no worker node: olha o systemctl status kubelet, a /var/lib/kubelet/config.yaml, e o /etc/kubernetes/kubelet.conf (acho que essas coisas estão no comando de instalação do kubelet ou no service)
se for network failure: olha se o CNI tá instalado, olha os pods do CNI (eles ficam em outros namespaces normalmente)
pvs, pvc
persistent volumes são como definições de espaço a ser usado em disco, tipo definições de uma pasta
da pra cirar um persistentvolume de tipo hostPath, que monta direto numa pasta do host
volumes com tipo readwritemany podem ser montados em varios nodes, readwriteonce só em um
se vc usar a config do pv retain ele fica unavailable depois de usado pra evitar que ele autodelete quando outro pod quiser usar ele
persistent volume claims são “escrituras/reservas” de persistent volume
pvc é como os pods usam o storage do pv, você referencia a pvc no spec
enquanto o pvc tiver criado, os dados vão continuar lá, reservados
1 pvc = 1 pv, sempre são de um pra um, nunca da pra fazer varios pvcs pra 1 pv, são monogamicos
PVCs com storageclass especificada não precisam de nenhum PV pré-criado, criam automaticamente
storageclassname é especificado na spec do pvc
kubectl describe pvc pvcname
pod management
taints, tolerations
taints afastam pods que não tenha toleration
tolerations toleram pods com taints especificas
taints normalmente são um key-value pair
k taint nodes node1 afasta=tudo:NoSchedule
node affinity
node affinity é uma config do pod pra preferir/requisitar nodes com certas labels
k label node node01 gpu=True
o node affinity é editado no spec do deployment ou do pode
node affinity pode ser required ou preferred, with conditions key has value x or key exists
priorityclasses
k get priorityclasses
k create priorityclass low-priority –value=1000 –description=”bla” –global-default=false
priorityclasses são classes que fazerm um pod ter prioridade sobre outros pods
priorityClassName pode ser especificado no spec de pods
a priorityclass do tipo PreemptLowerPriority dá evict em outros pods, a Never não
configmaps e secrets
configmap é tipo um secret só que sem criptografia
dá pra usar os valores do configmap em environment variables
o único outro jeito de usar é em volumes (ai cada par key-value vira um arquivo no volume)
tem muitas vezes onde secrets são do tipo TLS, onde tem arquivos .crt, .key and .ca
tem secret do tipo docker-registry tambem, pra registries privados do docker
Horizontal Pod autoscaler e Vertical Pod autoscaller
HPA precisa de requests / limits especificados no pod, pq ele calcula o threshold pra criar uma nova replica baseado nesses requests
VPA é um custom resource definition que vc precisa instalar, ele deleta o pod e cria de novo com mais memoria/cpu
o VPA usa machine learning pra dar update em limites de CPU e memoria
o VPA da erro quando tem só uma replica do que você tá autoscaling, pq o serviço ficaria indisponivel na recriação
security settings
users and certificates
o jeito mais comum sem um provider externo de criar um user no kubernetes é criado um certificado e uma clusterrole
certificado tls é composto por .crt, .key and .ca
.ca pode ser compartilhado as vezes, as vezes não, pq certificados TLS conseguem fazer uma chain de pai CAzão pra filho CAzinho pra filho CAzito
quando tu usa o comando do openssl x509, vem varios campos
nesses campos Subject CN: dentro do .crt é o CommonName, mostra o que ele representa, tipo o username dele
o campo Issuer CN mostra o pai dele, o CAzão
o Subject Alternative Name: tem todos os DNSs onde o certificado é usado
certificatesigningrequest é um recurso que é usado pra pedir aprovação de certificados TLS pra usuários da API
k get csr
k certificate approve fulano
RBAC, roles e clusterroles
a diferença de roles e clusterroles é que as clusterroles não se restringem por namespace
uma rolebinding binda uma role com permissões em um ou vários subjects, mas ela não consegue usar mais de uma role ao mesmo tempo não
dar acesso pra alguem é: criar role com permissão x + criar rolebinding dessa role no user
nas roles, os “apigroups” na spec são o que fica em cima da spec de todos recursos (o api:)
nas roles, resourceNames é tipo prefixo da role do IAM da aws, e.g.: quero permissão x pra todos pods com prefixo bonito-*
cluster roles são pra coisas tipo permissões de usuário ou pra dar permissão pra recursos sem namespace como nodes ou storageclasses
admission controllers
admission controllers podem ter o tipo mutating ou validating,
admission controllers são hookzinhos validadores de template que rodam depois que tu dá o comando de criar o recurso, mas antes dele serem efetivamente criados
exemplos de admission controller validating NamespaceExists (quando tu cria e ele da erro, valida se ja existe)
exemplos de admission controlller mutating NamespaceAutoProvision (quando tu da k create namespace e ele nao da erro)
tem recursos builtin pra fazer admission controllers customizados com webhooks
serviceaccounts
serviceaccounts são usados no campo serviceAccountName: dos pods pra dar direitos de kubectl pra eles
k create serviceaccount saname
k create token saname
networking
networkpolicies
é o firewall do kubernetes basicamente, tem ingress egress allow deny
o deny é meio que por padrao, se vc criar uma netpol e não botar nenhuma regra é tipo um deny all
k get netpol
da pra usar pod: nameselector na network policy e filtrar por pods
essa porra é mto complexa então usa essas receitas aqui https://github.com/ahmetb/kubernetes-network-policy-recipes
cni
container network interface é quem decide como os ips entre os pods vão funcionar
eles são como se fossem plugins e você escolhe qual vai usar
flannel nao tem suporte pra networkpolicy
calico tem suporte pra networkpolicy
plugins cni são instalados em /etc/cni/net.d/
aliás, paths com unix:// paths são sockets unix (que são diferentes de sockets de rede)
ingress e gateway
um ingress no k8s é tipo um nginx, ele faz port forwarding usando http e regras de dns
vc tem que instalar um ingress especifico pra usar, no meu caso foi o nginx-ingress
o ingress associa um subdomínio tal com um service x e manda toda requisição q vc faz no subdominio pro service, você até associa um service default em caso de 404 no deployment do ingress
no ingress resourceannotation no metadata costuma importar, pelo menos no nginx-ingress entao toma cuidado
gateway é tipo um ingress só que tunado e muito mais complexo
no gateway as gateway routes definem quais namespaces podem usar o gateway,
a gatewayclass define um tipo de gateway, e tem o gateway que é a implementacao do gateway per se
no gateway tem o httproute que é um resource dedicado só pra uma rota subdominio -> service
cluster
cluster installation
add repo to apt repositories
apt install kubeadm='1.33.0-*' kubelet='1.33.0-*' kubectl='1.33.0-*'
no controlplane você dá kubeadm init
no worker você dá kubeadm join
depois você instala uma CNI, tipo o flannel
upgrade de cluster
em cada upgrade de 1.32 -> 1.33 você tem que mudar o repositorio do APT, pra fazer upgrade do kubeadm kubectl e kubelet
em cada node:
apt install kubeadm='1.33.0-*' kubelet='1.33.0-*' kubectl='1.33.0-*'
kubeadm upgrade plan
kubeadm upgrade apply v1.33.0
kubeadm upgrade node
systemctl daemon-reload
systemctl restart kubelet
kubeconfig
k config use-context research
a environment variable KUBECONFIG pode ser usada pra especificar o diretorio da kubeconfig tbm
k get pods –as my-context pra usar outro contexto programaticamente
plugins and exstensions
custom resource definitions
custom resource definitions sao bem faceis de entender
vc define um plural e um grupo (que é o que fica na api version la em cima)
helm
comandos de repos
helm search hub
helm repo add
helm install releasename repo/chart
helm upgrade releasename repo/chart –version 2.0.0
helm get manifest releasename
helm rollback releasename
kustomize:
touch ./kustomization.yaml && k apply -k .
o nome é kustomize pq vc pode pegar yamls prontos e dar override em valores deles num lugar central com mta facilidade, usando vários kustomize.yaml, um em cada folder
kustomize tem configs como dar overwrite em tudo com uma commonLabel, commonAnnotation, commonNamespace, e prefixos de nomes em comum tambem
no kustomize você exclui/inclui recursos separando eles em diretorios e referenciando eles no kustomize.yaml
kustomize tem os tipos de patch. change patch, $patch: delete e JSON 6902 patch
change patch exemplo: images: name: newName: pra trocar o nome da img, newTag pra trocar a tag
$patch: delete consegue deletar containeres de um pod
patch JSON 6902 permite trocar qualquer config de qualquer recurso
k patch é um comando default do kubernetes que edita recursos com um json
kustomize tem o conceito de bases e overlays
bases você importa
overlays são como dev/prod/staging, e tem patches e components