Kubestronaut - Guia de Estudos Kubernetes
Bem-vindo ao Kubestronaut, um guia completo de estudos sobre Kubernetes em português. Este guia foi desenvolvido para ajudar profissionais e entusiastas a dominarem os conceitos e práticas do Kubernetes, desde o básico até tópicos avançados.
O que você encontrará neste guia
- Fundamentos do Kubernetes e containers
- Arquitetura e componentes do cluster
- Workloads e objetos da API
- Networking e segurança
- Operações e manutenção
- Observabilidade e troubleshooting
- Ferramentas essenciais do ecossistema
Certificações Kubernetes
Este guia abrange conteúdos relevantes para as principais certificações Kubernetes:
-
CKAD (Certified Kubernetes Application Developer)
- Foco em desenvolvimento de aplicações
- Nível: Intermediário
-
CKA (Certified Kubernetes Administrator)
- Foco em administração e operações
- Nível: Intermediário/Avançado
-
CKS (Certified Kubernetes Security Specialist)
- Foco em segurança
- Nível: Avançado
-
KCNA (Kubernetes and Cloud Native Associate)
- Certificação inicial para Cloud Native
- Nível: Iniciante
Código Fonte
Este guia é open source e está disponível no GitHub:
- Repositório: github.com/fabioluciano/kubestronaut
- Licença: MIT
- Contribuições são bem-vindas!
Navegue pelo sumário à esquerda para começar seus estudos. Bom aprendizado!
Semantic Versioning Changelog
1.2.3 (2025-05-02)
Bug Fix(es) 🐛️
1.2.2 (2025-05-02)
Bug Fix(es) 🐛️
1.0.0 (2025-05-02)
New Feature(s) 🚀
Bug Fix(es) 🐛️
Introdução
Num modelo sem kubernetes, onde implementamos um pseudo-cluster, como resolver os seguintes problemas:
- O que fazer quando um container apresenta problemas?
- O que fazer quando um nó, de seu pseudo-cluster morrer?
- O que fazer quando um nó, não renponder a uma requisição?
Quanto mais de um artefato está implantando para construir uma aplicação(microserviços);
- Naked Pod, executado pelo K8s, mas não gerenciado por ele
- O replicaset guarda a quantidade de replicas que um container deve rodar, o deployment, fica em cima do replicaset... O deployment guarda as versões dos containers que estão rodando.
- O service é um balanceador de carga para os deployments
É necessário a criação de mecanismos de monitoramento do estado de todos os elementos do pseudo-cluster, implementação de lógicas complexas e customizadas para garantir a disponibilidade de sua aplicação.
-
Também conhecido como
K8s
é um orquestrador de aplicações containerizadas. -
Provê mecanismos para construção e implantação de aplicações distribuídas de maneira a manter a confiabilidade e escalabilidade
Conceitos
Confiabilidade: Os serviços não podem falhar. Se partes do sistema falhar, outras deverão continuar a funcionar.
Disponibilidade: O sistema deve se manter disponível mesmo em atualizações/manutenções.
Escalabilidade: Estratégia de alocação de recursos em operação. Controlar o aumento e diminuição de recursos de acordo com a demanda.
- Horizontal: Adição ou remoção de nós
- Vertical: Adição de mais recursos computacionais aos nós
Elasticidade: Adapta a capacidade em relação a demanda. Geralmente está diretamente associada ao monitoramento e automação de disponibilização de recursos
A utilização de um orquestrador como K8s
habilita, entre outras: velocidade, escalabilidade, abstração da infraestrutura e eficiência.
Velocidade
Não é o número de funcionalidades entregues, mas sim o número de coisas
entregues, enquanto o sistema se mantêm altamente disponível.
A interrelação entre imutabilidade, configuração declarativa e self-healing, aumenta a velocidade com que se implanta aplicações de maneira confiável.
Imutabilidade
A utilização de containers e um orquestrador como o K8s
encoraja o desenvolvimento de sistemas distribuídos que aderem ao princípio de infraestrutura imutável
Infraestrutura mutável: O estado da infraestrutura é representado como um acúmulo de mudanças e atualizações, ou seja, as atualizações, mesmo que feitas de maneira automatizadas, seguem uma sequência definida de procedimentos que devem ser executados.
Infraestrutura imutável: É representado com um único artefato. Para trocar a versão de uma biblioteca ou VM ou container toda a imagem será refeita, enquanto que a antiga permanece disponível para casos de necessidade de um rollback. Containers imutáveis estão no cerne do kubernetes. Apesar de possível, não é recomendado a modificação de containers em execução.
Configuração Declarativa
É o contrário da configuração imperativa. A configuração no K8s
é feita com a definição de objetos de configuração de como a aplicação deve existir. A configuração declarativa descreve o [[Desired State#Definição | estado desejado]] de algo.
Imperativa: Descreve ações que devem ser executadas para se alcançar o estado esperado da aplicação; Declarativa: Descreve todos os elementos necessários para que o estado esperado seja alcançado;
É possível utilizar ferramentas e metodologias utilizadas no desenvolvimento de software, tais como controle de versão, revisão de código e testes unitários.
Self Healing
Continuamente executa ações para alcançar o estado desejado(idempotência). O daemon não somente criará o que foi declarado, mas continuamente garantirá que o estado desejado seja mantido/ancaçado.
Escalonamento
A utilização do k8s
habilita o fácil escalonamento, tanto da solução desenvolvida, quanto da equipe envolvida.
Desacoplamento: Permite separar cada parte do sistema de forma a aumentar a facilidade de identificação da necessidade de escalonamento das partes. O Desacoplamento dos times permite a construção de soluções robustas por conta do foco empregado por cada time.
- O tamanho ideal de uma equipe pode ser mensaurada utilizando a técninca
two-pizza team
; - Para ajudar na implantação de micro serviços, o
k8s
dispõem das seguintes abstrações:- [[Pods]]: Grupo de containers;
- Namespace: Provê isolamento e controle de acesso para restringir a interação com os recursos;
- Service: Provê o lanceamento de carga, nomeação e descoberta para isolamento de um microserviço de outro;
- Ingress: Frontend que combina múltiplos micro serviços em uma única API externalizada;
SE uma parte dos sistema não é escalável, toda a aplicação não é escalável
[[Pods#Conceitos| Vou te contar viu]]
Abstração da infraestrutura
A infraestrutura é abstraída pois os elementos presentes em uma solução são descritos de maneira abstrata, separando o desenvolvimento da implementação e aproximando as equipes dos conceitos relacionados. A utilização do k8s
habilita a portabilidade entre infraestrutura on premises e provedores de cloud computing.
Service -> ALB PersistentVolume -> EBS
Arquitetura
Nó (nodes)
- É uma máquina onde o
k8s
lançará containers; - É uma máquina onde o
k8s
e o container runtime será instalado; - Um nó é uma máquina que aumentará a capacidade física de recursos do cluster;
- Os nós são transparentes ao cluster. A aplicação verá apenas uma máquina gigante.
- No passado eram referidas como
minion
; - Um nó é uma máquina(virtual ou física) em que é instalado os componentes do
k8s
e a container runtime; - Existem dois tipos de nós disponíveis: master e worker;
- Deve existir pelo menos um nó
master
(1..*) e 0..* nósworker
; - Cada nó contêm [[Pods]] que contêm um ou mais containers de uma aplicação;
- Por padrão, a informação da localização de implantação dos componentes não possuem importância;
- O kubernetes pode transferir todos os componentes de um nó para outro sem que os usuários notem;
- Um
cluster
é um conjunto de nós agrupados, garantindo que se um nó falhar, outro nó responderá pela requisição. Além disso, quando se está utilizando nós, existe a premissa de compartilhar oload(processamento)
.
Master - Control Plane
- Responsável por gerenciar o cluster;
- É onde todos os componentes do core do Kubernetes estão rodando
- Conhecido como master plane;
- Pode-se haver mais de um master para manter a alta disponibilidade
- Guarda as informações dos membros(nodes), do cluster;
- Monitora os nós;
- Quando um nó falha, é responsável por mover o processamento para outros nós, garantindo a resiliência;
- Responsável pela orquestração dos containers nos
worker
nodes;
master
possui okube-api-server
.
- Todas as informações capturadas(do worker node) são guardadas no
etcd
do master - Possui o
controller manager
e oscheduller
; - É responsável por iniciar e executar as instruções de um
spec
para implantar uma aplicação
Componentes do master-plane
- API Server(
kube-apiserver
): Atua como uma fachada do Kubernetes. Os usuários, gerenciadores de dispositivos, ferramentas cli, conversam com o API Server para interagir com o Kubernetes; Funciona como um hub de comunicação entre todos os outros elementos. É o único componente que se comunica com oetcd
. Todos os outros componentes se comunicarão com a API para modificar o estado do cluster.- É o componente ao qual se comunica quando executa um comando com
kubectl
- É o componente ao qual se comunica quando executa um comando com
- Scheduler(
kube-scheduler
): Responsável por distribuir o processamento entre os nós. Observa por novas requisições de containers e os atribui a nós. Atribui as aplicações a um nodeworker
. Automaticamente colocará o pod baseado em seus prerequisitos(hardware); - Controller Manager(
kube-controller-manager
): É o cérebro por trás da orquestração. É responsável por sinalizar quando nós ou containers morrem. Toma decisões para criar novos containers nestes cenários. Mantem a replicação de componentes e a quantidade de [[Pods]] correta- Gerencia os processos do Core do kubernetes
- Etcd service:
key-value store
distribuído utilizado pelok8s
para guardar todos os dados gerenciados pelo cluster. É responsável por implementar travas entre os nósmaster
para não haver conflitos; Guarda as configurações do cluster. É importante manter um backup dessas informações. - Container Runtime: (RKT, Docker, CRI-O, containerd): É o software responsável por rodar os containers nos nós.
- Kubelet service: Agente que roda em todos os nós do cluster. É responsável por garantir que os containers estão rodando nos nós, como esperado. Executa e gerenciar os containers em um nó, e se comunica com o API Server. Além disso, se comunicará com o Container Runtime para que baixe imagens para rodar um pod
Worker
- Responsável por executar containers([[Pods]]);
- Responsável por rodar as aplicações
- Responsável por monitorar as aplicações, e prover os serviços que ela necessitar
worker
possui o kubelet, agente responsável por interagir com o master. Provê informações sobre a saúde do nó e executar tarefas requisitadas pelo master
Componentes do nó
- Kubelet service: Agente que roda em todos os nós do cluster. É responsável por garantir que os containers estão rodando nos nós, como esperado. Executa e gerenciar os containers em um nó, e se comunica com o API Server. Além disso, se comunicará com o Container Runtime para que baixe imagens para rodar um pod
- kube-proxy: Balanceia o trafego entre os componentes da aplicação. Garante que os containers em nós diferentes se comuniquem em problemas.
- É quem vai criar as regras usando, geralmente, o
iptables
para que todos os pods no cluster possam se comunicar entre si.
- É quem vai criar as regras usando, geralmente, o
- Container Runtime: (RKT, Docker, CRI-O, containerd): É o software responsável por rodar os containers nos nós.
Quando as especificações da sua aplicação estiverem completas, o scheduler
notificará os nós, por intermédio do kubelet
, e o mesmo instruirá que o container runtime
baixe as imagens necessárias da aplicação.
O master
fará com que as aplicações sempre estejam no estado especificado, caso mude, o mesmo fará procedimentos para que isso seja alcançado.
Declarative Intent
[[Pods]] e Services, por exemplo, são entidades persistentes.
Comandos úteis
Recupera o status dos componentes do control plane
kubectl get componentstatus
Recupera os nós do cluster
kubectl get nodes
Recupera informações sobre todos os nós
kubectl describe nodes
Lista todos os tipos de objetos disponíveis no cluster
kubectl api-resources
- Provê a possibilidade de isolar aplicações usando os namespaces do Kernel do linux
- Contém a aplicação e todas suas dependências
- As imagens dos containers são capturadas de um registrador
- As imagens são altamente parametrizas para serem rodadas em qualquer computador
Container Runtime
- Aplicação que roda um container
- Dá pra comparar com o systemD do linux, = subindo aplicações
- Um examplo é o
runc
- O Docker e o Podman e o Kubenetes, como Container Engine, manipularão o runc
Container Registry
- É uma loja de imagens de container
- É possível ter registradores publicos ou pirvados
- Para rodar uma imagem de um container é necessário um FQCN(Fully Qualified Container name)
- Se for utilizar o podman, você deve passar o endereço inteiro (eg. docker.io/library/nginx)
docker run -d nginx
podman run -d docker.io/library/nginx
kubectl run -d nginx --image docker.io/library/nginx
docker [image] inspect image
docker commit CONTAINER IMAGE:TAG
Docker
- Existem duas formas de definir um entrypoint, a forma
exec
e a formashell
- Por padrão, o docker rodará o comando usando o usuário root.
- Todas as capabilities do linux estão descritas no arquivo
/usr/include/linux/capability.h
ouman 7 capabilities
Exec
ENTRYPOINT ["command", "ARG", "ARG"]
CMD ["-c"]
- Fará com que o comando seja executado com o PID 1
- O
CMD
é o args doKubernetes
Shell
ENTRYPOINT command argument argument
- Fará com que qualquer
CMD
seja ignorado - Não será o PID 1, visto que o comando do entrypoint será executado como subcomando do
sh -c
ConainerD
- É parte do docker, mas é um projeto separado e doado para a CNCF
- O CRICTL é usado para interagir com todos os container runtimes que forem aderentes ao CRI
- O [[kubelet]] vai usar o [[crictl]] para baixar as imagens e criar os containers,
tags:
- Kubernetes
- Pods
- Annotations
- Labels
Labels
- Utilizado para categorizar os recursos do kubernetes.
- Usa-se seletores para selecionar recursos baseados em labels
- Todos os recursos criados usando
kubectl create deployment RESOURCENAME
vão criar uma labelapp=RESOURENAME
e ekubectl run RESOURCENAME
run=RESOURCENAME
- Labels adicionadas após a criação de um objeto, não serão herdadas automaticamente pelos filhos. Será necessário recriá-la.
kubectl label RESOURCE LABEL=VALUE
kubectl label RESOURBE LABEL-
kubectl get pods --selector LABEL=VALUE
apiVersion: v1
metadata:
labels:
teste: dsdlsdlsl
Annotation
- Provê informações adicionais ao objeto a ser criado
apiVersion: v1
metadata:
annotations:
teste: dsdlsdlsl
kubectl annotate pod podname annotation="value"
Namespace
Definição
- É um recurso para separar as entidades em ambientes
- Para recursos de um namespace acessar conteúdo de outro namespace, é necessário passar a URL fqnd, visto que a service sempre vai criar
service.name.namespace.svc.cluster.local
- Usa os conceitos do Kernel do Linux para isolar recursos
Comandos úteis
Troca de namespace
kubectl config set current-context kind-teste --namespace resource-quota
kubectl get pods -A # Mesmo que --all-namespaces
- Os arquivos de configuração utilizados para subir os componentes do cluster estão em
/etc/kubernetes/manifests
- Esses são chamados static pods
Kubelet
- Executa comando ordenados pelo [[kube-scheduler]]
- Regularmente informa ao apiserver o estado do nó
- Registra os nós no cluster
- Quando recebe a ordem de criar um container, vai chamar o CRI para baixar a imagem, e monitorar a saúde dos pods para o api server
- O kubelet não é instalado pelo kubeadm. Deve ser instalado manualmente
Security
- As configurações são feitas utilizando o parametro --config, que carregará um arquivo do
kind
KubeletConfiguration - O Kubelet serve duas portas:
- 10250 - Serve a API habilitando acesso full
- 10255 - Serve a API que permite requisições não atenticadas readonly
- Só estará disponbível se a opção read-only-port for configurada
- O kubeapi é um cliente do kubelet, e utiliza certificado/key para fazer a comunicação com o kubelet
- É necessário utilizar o authorization.mode para Webhook, para que o kubelet faça uma chamada ao kubeapi sever para determinar se a requisição é autorizada
curl -X GET http://127.0.0.1:8001/api/v1/nodes/<node-name>/proxy/configz | jq .
PARA MODIFICAR AS CONFIGURACOES DOS KUBELETS DE NOVOS NOS, EH NECESSARIO MODIFICAR O CONFIGMAP kubelet-config
no namespace kube-system
kubectl edit cm -n kube-system kubelet-config
DEPOIS DISSO... EH PRECISO RODAR O COMANDO KUBEADM NAS MAQUINAS PRA PODER ATUALIZAR AUTOMOTICAMENTE SEM PRECISAR EDITAR O ARQUIVO DE CONFIGURACAO
kubeadm upgrade node phase kubelet-config
RESTART DO KUBELET
systemctl restart kubelet
kube-proxy
- Todo pod pode se comunicar com qualquer outro pod
- A rede de pods é a mesma utilizada por todos os nós do cluster
- É um daemonset que garante que quando um serviço é criado, as regras de firewall(iptables) apropriadas sejam criadas
kube-apiserver
- Quando você está utilizando o
kubectl
você está interagindo okube-apiserver
. - Quando uma requisição é criada, primeiro ela é autentica e validada pelo [[Admission Controllers]]
- É possível criar objetos utilizando o curl fazendo uma requisição para a api
- usa o [[kubectl]]proxy e faz as requisições
- É o único componente que interage com o [[Kubernetes/nodes-components/etcD|etcd]]
- Todos os outros componentes vão fazer chamadas para o [[kube-apiserver]]
Para visualizar suas configurações
- Instalado pelo kubeadm
/etc/kubernetes/manifest/kube-apiserver.yaml
- instalado na mão:
/etc/systemd/system/kube-apiserver.service
kube-controller-manager
- Observa o estado dos recursos
- toma medidas para remediar situações específicas. atingir o [[Desired State]]
- São os cérebros do cluster
Tipos: - Node controller - Toma de conta dos controllers - Monitora Informa a cada 5 segundos - Grace period: 40 . SE o pod ficar unreachable por ... ele ... - Eviction: 5 minutos - Replication Controller - Toma de conta de [[ReplicaSet]]
Para visualizar suas configurações
- Instalado pelo kubeadm
/etc/kubernetes/manifest/kube-controller-manager.yaml
- instalado na mão:
/etc/systemd/system/kube-controller-manager.service
Kube-scheduler
- Decide onde um pod deve ser colocado. Ele não coloca. Quem coloca é o kubelet;
- Observa cada pod e tentar encontrar qual o melhor nó para ele;
- Ranqueia os nós pra identificar qual o melhor nó para se colocar o pod
- Você pode customizar o scheduler, criando o seu próprio. Karpenter.,
Pode ser usar para definir um nó de um pod:
- Requests e Limits
- Taints e tolerations
- node selector/affinity
- nodename
Para visualizar suas configurações
- Instalado pelo kubeadm
/etc/kubernetes/manifest/kube-scheduler.yaml
- nstalado na mão:
/etc/systemd/system/kube-scheduler.service
Etcd
- Banco de dados que guarda os dados em formato
chave/valor
- Roda na porta
2379
etcdctl
controla o etcd- guarda todas as configurações de todos os recursos implantados no cluster
kubectl exec etcd-controlplane -n kube-system -- sh -c "ETCDCTL_API=3 etcdctl get / --prefix --keys-only --limit=10 --cacert /etc/kubernetes/pki/etcd/ca.crt --cert /etc/kubernetes/pki/etcd/server.crt --key /etc/kubernetes/pki/etcd/server.key"
API
- O Kubernetes fornece uma API para interagir com o cluster
- Todos os recursos são acessíveis usando Restful resources
- A API representa recursos dentro do cluster
- Suporta configuração declarativa usando
JSON
ouYAML
. - Permite a autenticação e autorização usando diferentes soluções
- É extensível, permitindo a criação de outros recursos
- O que está na versão v1 é GA
- Os grupos podem ter mais de uma versão ativa
- O kube-proxy roda na máquina cliente, permitindo a comunicação com o apiserver utilizando as mesmas configurações do
.kube/config
Api Groups
As APIs são divididas em grupos:
/metrics
e/healthz
: Usadas para monitorar a saúde do cluster/version
: Visualizar a versão do cluster/api/v1
: Core groupns
,po
,rc
,events
,endpoints
,nodes
,bindings
,pv
,pvc
,cm
,sercrets
,services
/apis
: Named group- É mais organizado, logo, todas as novas funcionalidades serão adicionadas a essa lista organizada por nome
- API GROUPS:
/apps
,/extensions
,networking.k8s.io
,storage.k8s.io
,authentication.k8s.io
,certificates.k8s.io
- apps/v1: RESOURCES
- deployments
- replicasets
- statefulsets
- networking.k8s.io/v1
- networkpolicies
- Cada recurso possui um verbo RESTful associado:
- list, get, create, delete, update e watch
/logs
: Integração com aplicações de terceiros
# Primeio ddescobre-se o endereço do control plane
k get nodes -o wide
## Faz-se uma requisição para o endpoint de versão
curl https://172.18.0.4:6443/version -k
kubectl api-resources
kubectl api-versions
kubectl proxy
curl 127.0.0.1:8001/api/v1/namespaces/default/pods | jq '.items[].metadata.name'
API Deprecations
- Com o lançamento de novas versões do kubernetes, as APIs de recursos podem ser depreciadas
- O padrão é o Kubernetes manter a versão com suporte por mais duas versões
apiserver --runtime-config=rbac.authoraization.k8s.io/v1alpha1,batch/v1beta1=false
kubectl-convert -f ARQUIVOANTIGO --output-version GROUP/VERSIONNOVO
API Extensions
- Api pode ser ser estendida de diversas maneiras:
- CustomResourceDefinitions
- Controllers customizados
- Agregação de API
Custom Resource Definition
- Permite a adição de recursos a API de maneira simples
- É adicionado ao servidor do kubernetes e segue seu mecanismo de atualização
- É o padrão de facto, para adição de recursos a API
- São adicionads como extensões da API do Kubernetes
Controller customizados
- É um processo que monita modificações na APi do kubernetes
- Quando as modificações acontecem, o controller garante que o estado desejado seja mantido\
- Permite a automação de tarefas no cluster
- Os ontroler utilizam bibliotecas (SDKs) para se comunicarem com a API
Agregação de API
- Adiciona funcionalidades a API do Kubernetes por extensão
- Permite um alto nível de cuustomização
- Permite a integração de recursos de diferentes fontes
kubectl get crd
Operators
- Aplicações customizadas que se baseaim no CustomResourceDefinition
- Pode ser visto como uma maneira de empacotar, rodar e gerenciar aplicações no Kubernetes
- Utiliza controller para continuamente operar dinamicamente o sistema
Api Objects
- São dados que representam o estado do cluster
- Quase tudo no K8s é representado como um objeto([[Arquitetura#Nó nodes | nós]], services, pods, e etc.)
Propriedades padrão de qualquer objeto definido no cluster: apiVersion
, kind
, metadata
e spec
apiVersion: v1 # Versão da API do Kubernetes, que está sendo utilizada para criar o objeto
kind: Pod # Referencia o tipo de objeto que está sendo descrito no documento
metadata: # Referencia informações sobre o objeto. É um dicionário
name: myapp-prod # só pode conter 253 caracteres [.-a-z]
annotations:
dadsasd/res: "1"
labels: # Pode-se colocar quantas labels achar necessário
app: myapp
enviroment: qa
spec: # Especificações do objeto a ser criado. Varia de objeto para objeto
containers: # Lista / Array
- name: nginx-container
image: nginx:latest
status: # DEscreve o status atual do objeto no cluster. É fornecido e atualizado pelo k8s
ApiObjects
spec: Define o estado desejado do objeto status: Define o estado atual do objeto
O que o k8s
fará para alcançar o estado esperado.
Comandos úteis
Pods
Conceitos
- O
k8s
não implanta containers diretamente no nósworker
. Os containers são encapsulados em objeto interno, conhecido comoPod
; - É uma instância de uma aplicação
- É o menor objeto que se pode criar no k8s;
- Para escalar uma aplicação para aguentar uma maior quantidade de trafego, aumenta-se o número de
Pods
(réplicas) e não de containers em umPod
; - Caso o [[Arquitetura#Nó nodes | nó]], não tenha recursos necessários para rodar mais que uma instância da aplicação, é possível subir o
pod
em um novo [[Arquitetura#Nó nodes | nó]]. .spec.volumes.projected
são para montar vários arquivos dentro de uma mesma localização- Todo pod requer uma certa quantidade de recursos para rodar
Multi-container pods
- Geralmente um
pod
possui uma relação1:1
com containers rodando a aplicação. Parascale up
você adiciona um pod, parascale down
remove-se o pod. - Um
pod
pode conter mais que um container, geralmente com tarefas de suporte ao container principal da aplicação; Os containers dentro dopod
escalarão juntos. - Pode-se referenciar os containers por
localhost
para comunicação, já que compartilham o mesmo namespace de rede. Assim como o namespace de storage (IPS?)
Existem alguns tipos de padrões para pods com multicontainers, os principais são:
- Ambassor - Funciona como um proxy do container principal com outros componentes. funciona como faixada para o container principal
- Adapter - Padroniza e normaliza as saídas do container principal
- Sidecar - Estende e melhora o container principal - É um initcontainer que têm o restartPolicy set to Always DESDE a versão 1.29
InitContainer
- São containers que rodarão antes dos containers normais
- Geralmente executarão tasks
- Se existir mais de um, vai rodar em sequência
- Caso falhe, o pod entrará em Crashloop, e o container principal nunca se iniciará
tip
Pods com initcontainers
apiVersion: v1
kind: Pod
metadata:
name: pod-with-initcontainer
spec:
initContainers:
- image: busybox
name: get-file
command:
- "wget"
- "-O"
- "/data/index.html"
- https://google.com
volumeMounts:
- name: data
mountPath: /data
containers:
- image: nginx
name: pod-with-initcontainer
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
emptyDir: {}
Os valores editáveis de um pod são:
spec.containers[*].image
spec.initContainers[*].image
spec.tolerations
spec.terminationGracePeriodSeconds
Quando há mais de um container no mesmo Pod, eles sempre compartilharão o mesmo nó, visto que compartilharão a mesma camada de rede(namespace?)
spec.containers[*].command
é uma alternativa para sobrescrever o entrypoint dos containers que estiverem rodando em um pod.spec.containers[*].command
é o programa a ser executado ao container subir, espec.containers[*].args
são os argumentos a serem passados para ospec.containers[*].command
spec.containers[*].command
vai substituir oentrypoint
definido noDockerfile
da imagem utilizada espec.containers[*].args
vai substituir oCMD
doDockerfile
.
tip
Pod com múltiplos containers
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: nginx-multiple-container
name: nginx-multiple-container
spec:
containers:
- image: nginx
name: nginx
resources: {}
- image: redis
name: redis
ports:
- containerPort: 6379
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
tip
Pod com argumentos
apiVersion: v1
kind: Pod
metadata:
name: sleep
spec:
containers:
- args:
- sleep
- "1000"
image: busybox
name: sleep
env:
- name: teste
value: " rapidam teste"
Security Context
- As configurações de segurança podem ser feitas ao nível de pod, ou container
- Somente containers possuem capabilities.
pod.spec.containers.securityContext.capabilities
- As definições feitas ao nível de container vão sobrescrever as definições feitas ao nível de pod.
- Quando o container é privilegiado, são habilidatas TODAS as capabilities to linux
pod.spec.securityContext.runAsUser
: Faz com que o usuário seja um numero especficopod.spec.securityContext.runAsGroup
: Faz com queo grupo seja um numero especificopod.spec.securityContext.fsGroup
: Faz com que o sistema de arquivos esteja em um numero especifico- Para garantir a imutabilidade do container, deve-se aplicar
pod.spec.securityContext.readOnlyRootFilesystem
para true, e o que for modificável, montar um volumeemptyDir
tip
Pod com security context
apiVersion: v1
kind: Pod
metadata:
name: pod-with-security-context
spec:
securityContext:
runAsUser: 1000
containers:
- command:
- sleep
- "3600"
image: ubuntu
name: pod-with-security-context
tip
Pod com volumes projetados
apiVersion: v1
kind: Pod
metadata:
name: pod-with-projected-volumes
spec:
containers:
- image: nginx
name: pod-with-projected-volumes
volumeMounts:
- name: teste
mountPath: /data
volumes:
- name: teste
downwardAPI:
items:
- path: labels
fieldRef:
fieldPath: metadata.labels
- path: annotations
fieldRef:
fieldPath: metadata.annotations
Resource Request
- Por padrão um container não possui limite de recursos consumidos
- O scheduler vai olhar para esses recursos para determinar onde ele alocará o workload
- Os recursos são por container, e não por pod
- CPU = 1 Cores 1000m == 1 Core
- Memory = G = 1000M Gi=1024M
- O request serve para saber em qual nó ele vai alocar os container, baseado nos recursos necessários, o limit, limita o quanto ele pode chegar
- Caso o container comece a usar mais CPU que o limit, o pod começará a limitar os recursos utilizados pelo container. No caso do container começar a utilizar mais memória que o limit, ele matará o pod com a message OOM(Out of memory)
- Se você setar somente o limit, o kubernetes encarará como sendo o request=limit
- Para CPU, o melhor cenário é fazer o request necessário de CPU, mas não limitar, visto que pode haver recursos não utlizados, que podem ser utilizados pelo POD.
- É possível definir que um pod tenha um conjunto de recursos garantidos. Para isso é necessário definir um [[LimitRange]]]
tip
Pod com resource request
apiVersion: v1
kind: Pod
metadata:
name: pod-with-resource-request
spec:
containers:
- image: nginx
name: pod-with-resource-request
resources:
requests:
memory: 4Gi
cpu: 2
tip
Pod com resource request
apiVersion: v1
kind: Pod
metadata:
name: pod-with-resource-request-and-limits
spec:
containers:
- image: nginx
name: pod-with-resource-request-and-limits
resources:
limits:
memory: 4G
cpu: 3
tip
Setando os limits de um container imperativamente
kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi
Restart Policy
- Gerencia o que acontece com um container quando ele crasha
- O valor padrão é
Always
, fazendo com que o container continue reiniciando
Comandos úteis
tip
Cria um pod a partir de uma imagem
kubectl run nginx --image nginx`
tip
Recupera a lista de todos os Pods
kubectl get pods
tip
Edita um pod a partir de sua definição
kubectl edit pod podname
tip
Aplica(cria ou atualiza) uma definição de um objeto no cluster
kubectl apply -f pod-definition.yaml
tip
Cria uma definição de um objeto no cluster
kubectl create -f pod-definition.yaml
tip
Descreve todas as informações de todos os pods em um determinado namespaces
kubectl describe pod
tip
Descreve todas as informações de um pod em um determinado namespaces
kubectl describe pod/pod-name
tip
Recupera todos os pods de todos os namespaces e imprime mais informações
kubectl get pods --all-namespaces -o wide
tip
Recupera todos os pods com a informação das labels
kubectl get pods --show-labels
tip
Recupera todos os pods que estão estão rodando
kubectl get pods --field-selector status.phase==Running
tip
Recupera todos os pods que estão estão rodando no namespace default
kubectl get pods --field-selector status.phase==Running,metadata.namespace=default
tip
Executa um comando no container principal do pod
kubectl exec -ti nginx -c container -- bash
- Quando não há API server, o kubelet, agindo sozinho no cluster, pode criar pods usando staticpod
- Voce pode configurar o kubelet para ler um diretório contendo manifestos.
- Somente PODS podem ser criados usando esse método
- Como o Kubelet só entende sobre PODS ele não conhece outros elementos
- Por isso, quem mexe com o replicasets é o controller
- O diretório pode ser configurado utilizando a flag
--pod-manifest-path
do systemd service do kubelet - Também pode ser configurado utilizando um arquivo de configuração, utilizando a flag
--config
, e dentro desse arquivo setar a chavestaticPodPath
- Como não temos [[kube-apiserver]]para responder os comandos, você tem que usar o [[crictl]]pra poder ver os pods sendo criados
- Os pods estaticos têm o seu nome acrescido do nome do nó ao qual foi criado
ReplicaSet
- É um controller (Replication Controller);
- Garante que um determinado número de pods esteja rodando;
- ReplicaSet é um conjunto de pods que possibilita a execução e controle de réplicas. Visando garantir a disponibilidade de um número especificado/desejado de pods.
- ReplicaSet utiliza
apiVersion: apps/v1
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: teste
labels:
tier: "frontend"
spec:
replicas: 10
selector:
matchLabels:
tier: "frontend"
template:
metadata:
name: replicase-teste
labels:
tier: "frontend"
spec:
containers:
- image: nginx
name: nginx
- image: redis
name: redis
- o
metadata.labels
devem bater comspec.template.metadata.labels
- pode-se utilizar dois tipos de seletores
matchLabels
ematchExpressions
matchLabels
:matchExpressions
:
- Quando for criar um replicaset em que já existam pods com os seletores iguais, ele vai capturar os podes para o replicaset
- Não se pode atualizar informações do replicaset. É possível alterar o replicaset e manualmente matar os pods. Para ter atualização nesse nível, utilizase o [[Deployments]]
- Pode conter pods que não foram criados pelo
.spec.template
, mas que casam comspec.selector
. Os pods criados fora do replicaset serão contabilizados na contagem despec.replicas
.spec.template
é necessário neste cenário, ja que se um dos pods existentes morrer, ele têm que criar mais um para manter o [[Desired State]]
[!NOTE]- Replication Controller
filePath: "@/Attachments/Kubernetes/replicaset/teste-replicationcontroller.yaml"
[!NOTE]- Replicaset with
spec.selector.matchExpressions
filePath: "@/Attachments/Kubernetes/replicaset/teste-replicaset-matchexpressions.yaml"
[!NOTE]- Replicaset with
spec.selector.matchLabels
filePath: "@/Attachments/Kubernetes/replicaset/teste-replicaset-matchlabels.yaml"
[!NOTE]- Replicaset with
spec.selector.matchLabels
and existing pods
filePath: "@/Attachments/Kubernetes/replicaset/teste-replicaset-matchlabels-existing-pods.yaml"
Comandos úteis
Recupera replicaset dos nós
kubectl get replicaset
oukubectl get rs
Recupera informações sobre todos os replicasets
kubectl describe replicaset
Recupera informações sobre um replicaset específico
kubectl describe replicaset name-replicaset
Cria replicaset
kubectl create -f replicaset-file-definition.yml
deleta replicaset
kubectl delete replicaset name-replicaset
escala o número de pods do replicaset
kubectl scale replicaset --replicas=5 name-replicaset
Deployment
Deployments são recursos capazes de realizar a manipulação de pods e [[ReplicaSet]], configurando o estado desejado de um deployment ele permite de maneira controlada a implantação/alteração do estado atual do recurso para o estado desejado.
- Possui quase a mesma estrutura básica de um [[ReplicaSet]]
- Deployments utiliza
apiVersion: apps/v1
- Controla e versiona [[ReplicaSet]], sempre criando um novo, quando houver modificações.
.spec.revisionHistoryLimit
, quantas versões serão guardadas no deploy- É possível com o comando
kubectl rollout pause
, fazer com que modificações feitas no deployment, não sejam refletidas nos replicasets/pods. O comportamento normal do deployment pode ser retormado comkubectl rollout resume
Existem duas estrategias de deploy(.spec.strategy.type
), Recreate
e RollingUpdate
. O padrão é RollingUpdate
.
* Recreate
- Vai apagar todos os [[Pods]] existentes substituindo pelos novos, quando modificado. Blue-green. Têm downtime
* RollingUpdate
- Define quantos pods estarão indisponíveis e quantos pods serão criados por vez.
* Caso haja um erro apresente erro durante o rollout, os pods não subirão se o maxUnavailable não estiver com 100%
* Quando definido, é necessário também adicionar .spec.strategy.rollingUpdate.maxSurge
e .spec.strategy.rollingUpdate.maxUnavailable
* .spec.strategy.rollingUpdate.maxSurge
- Máximo de pods que serão criados por vez. Pode ser um valor absoluto, ou um percentual;
* .spec.strategy.rollingUpdate.maxUnavailable
- Máximo de pods que podem ficar indisponíveis durante a atualização. Pode ser um valor absoluto, ou um percentual;
[!NOTE]-
Deployment
example
filePath: "@/Attachments/Kubernetes/deployment/teste-deployment.yaml"
[!NOTE]-
Deployement
withspec.strategy = Recreate
filePath: "@/Attachments/Kubernetes/deployment/deployment-strategy-recreate.yaml"
[!NOTE]-
Deployement
withspec.strategy = RollingUpdate
filePath: "@/Attachments/Kubernetes/deployment/deployment-strategy-rollingupdate.yaml"
Estratégias adicionais
Blue/Green
- Existem diversas formas de implementar:
- Usando Services
- Acontece num nível mais baixo,
- Os usuários podem notar a modificação
- Usando Ingress
- Só funciona eh HTTP / HTTPS
- Usando Services
- As duas versões da aplicação rodam em paralelo.
- É definida uma label para cada versão(blue/green)
- Existe um serviço que aponta para a bl;ue
- Dado que todos os testes da green foram feitos o mudo o seletor da blue para green
Service Based
filePath: "@/Attachments/Kubernetes/deployment/bluegreen-service-based.yaml"
Ingress Based
filePath: "@/Attachments/Kubernetes/deployment/bluegreen-ingress-based.yaml"
kodekloud/webapp-color:v1
Canary
- Apenas uma fração das requisições é direcionada para a nova versão
- É criada uma label comum entre os dois deployments
- a service deixa de apontar para a v1, mas para essa nova label criada
- Diminui-se o número de replicas da nova versão
- Assim trafego será dividido entre a versão v1`e v2
Ingress Based
filePath: "@/Attachments/Kubernetes/deployment/canary-ingress-based.yaml"
Service Based
filePath: "@/Attachments/Kubernetes/deployment/canary-service-based.yaml"
Comandos úteis
Recupera deployments dos nós
kubectl get deployments
Recupera informações sobre o deployment
kubectl describe deployment deployment-name
export kdry="--dry-run=client -o yaml"
kubectl create deployment nginx --image nginx --port 80 $kdry
Salvar motivo de modificação de um deployment
kubectl (apply|replace) -f deployment meu deploy --record
Aumentar o número de replicas de um replicationController
kubectl scale --replicas NUMREPLICAS -f arquivodeployment.yaml
kubectl scale deployment deployment-teste --replicas NUMREPLICAS
kubectl rollout history deploy meu-deploy
kubectl rollout history deploy meu-deploy --revision=REVNUMBER
kubectl rollout undo deployment meu-deploy --to-revision NUMREVISION
kubectl rollout pause deployment meu-deploy
kubectl rollout resume deployment meu-deploy
kubectl create -f deployment-file-definition.yml
kubectl delete deploy deployment-name
StatefulSet
- Assim como [[Deployments]], também possuem um template do pod que subirá , pode escalar o número de pods, rollbacks.
- Mantêm a identidade dos pods que são criados
- No StatefulSet, os pods presentes são criados em uma order sequencial. O primeiro pod têm que estar no status running e ready para que o próximo suba.
- Atribui um indice a cada pod, começando com 0, que refletirá na criação de um DNS único
- Mesmo que o pod morra, ele voltará com o mesmo nome. Ele mantêm sua identidade.
- É necessária um service
statefulset.sepc.volumeClaimTemplates
: Cria um PVC que criará um PV- Pare remover um statefulset, primeiro se scala ara 0, depois deleta
[!NOTE]- Replication Controller
filePath: "@/Attachments/Kubernetes/statefulset/statefulset-test.yaml"
Propriedades importantes
spec.podManagementPolicy = Parallel
: Não seguir a order de esperar um ser criado/destruído para iniciar/apagar o próximo.spec.serviceName
: Service a ser utilizada para compor os dns dos pods criados.spec.volumeClaimTemplate
: Cria uma PVC para cada replica do Statefulset
- Roda uma aplicação em todos os nós
- Não vai rodar se tiver um taint impedindo-o
- É útil quando quando se instala um agent que precisa estar rodando em TODOS os nós do cluster
- DaemonSet não possui replicas. Ele segue o número de nós em seu cluster
filePath: "@/Attachments/Kubernetes/daemonset/daemonset-test.yaml"
Passos para criação de um daemonset
- Criar um deployment
- Transformar o kind para daemonset
- Remover spec.replicas e spec.strategy
- Feitos para executar uma tarefa específica e finalizar
- Você pode fazer a mesma coisa com um pod normal, mas ele vai ficar reexecutando o processamento diversas vezes, resultando em um
CrashLoopBackOff
. Isso por que [[Pods]]são idealizados para executar Long running workloads. Esse comportamento é dado pela propriedadepod.spec.restartPolicy
- É um pod em que o
pod.spec.restartPolicy
é setado para Never - É bom lembrar que cada Job criará um ou mais pods para executar sua tarefa
job.spec.ttlSecondsAfterFinished
limpa automaticamente os jobs- Para executar múltiplos pods da task, utilize
job.spec.completions
. Os pods são criados de maneira sequencial. O segundo só será criado se o primeiro finalizar.- O scheduler vai continuar a executar pods, até o numero de completions seja atingido
- É possível alterar esse comportamento adicionando a propriedade
job.spec.parallelism
, dizendo quantos serão criados em paralelo. job.spec.backoffLimit
é o número de vezes que vai dar erro até ele desistir
filePath: "@/Attachments/Kubernetes/job/pod-with-expr.yaml"
filePath: "@/Attachments/Kubernetes/job/job-execute-expression.yaml"
filePath: "@/Attachments/Kubernetes/job/job-execute-expression-completions.yaml"
Comandos uteis
create job job-execute-expression --image ubuntu $kdry -- expr 3 + 4 > job-execute-expression.yaml
- Feito para executar uma tarefa em um dado período do dia baseado no
cronjob.spec.schedule
- Basicamente é um wrapper para o Job. Você coloca o
job.spec
dentro decronjob.spec.jobTemplate
- É importante notar que é possível setar o
cronjob.spec.timeZone
que afetará o funcionamento docronjob.spec.schedule
- O Cronjob vai criar um job, assim como um deployment cria uma replicaset
filePath: "@/Attachments/Kubernetes/cronjob/cronjob-date.yaml"
Comandos úteis
k create cronjob date --image busybox --schedule="*/1 * * * *" -- date
kubectl create job JOBNAME --from cronjob/CRONJOBNAME
Scheduling
Utilizando o Taints e spec.tolerations
PARA GARANTIR QUE UM POD SEJA ALOCADO EM UM NÓ É NECESSÁRIO CONFIGURAR TANTO A TOLERATION
QUANTO O NODESELECTOR
A TOLERATION GARANTE QUE O POD TENHA A TOLERANCIA AO TAINT DEFINIDO NO NÓ, E O NODESELECTOR GARANTE QUE O POD SEJA ADICIONADO A UM NÓ QUE TENHA OS LABELS DEFINIDOS
- Define uma relação entre pods e nodes, restringindo quais pods pertencem a quais nós
- Define quais pods são scheduled em um pod
- Taints são restrições anexadas a um nó
- Tolerations são anexadas a um pod
- Por padrão, nós não possuem taints, e pods não possuem tolerations
- O efeito é o que acontecerá com os pods que não tiverem essa tolerância
- Não há garantia de que um pod vá para um nó em particular, mesmo com a tolerância aplicada;
- Caso seja um pod sem um replication controller, ele será simplesmente apagado :)
- Tipos de efeitos de taint:
NoSchedule
: Os pods que não tiverem essa tolerância não serão alocados a este pod.PreferNoSchedule
: O Scheduler vai tentar não alocar um pod no nó, mas não é garantidoNoExecute
: Os pods que não tiverem essa tolerância não serão alocados a este pod. Se existirem pods existentes no nó, serão migrados.
kubectl taint nodes node-name key=VALUE:TAINT-EFFECT
kubectl taint nodes node-name app=blue:NoSchedule
Para remover um taint basta adicionar um sinal de -
kubectl taint nodes node-name app=blue:NoSchedule-
[!NOTE]-
Pod
with tolerations
filePath: "@/Attachments/Kubernetes/pod/pod-with-toleration.yaml"
Utilizando o spec.nodeSelector
- Aloca um pod a um nó baseado em labels anexadas ao nó
- Não têm
matchLabels
oumatchExpressions
. Para usar esse tipo de lógica deve-ser usar onodeAffinity
kubectl label nodes minikube-m04 disk=nvme
[!NOTE]-
Pod
withspec.nodeSelector
filePath: "@/Attachments/Kubernetes/pod/pod-with-nodeselector.yaml"
kubectl label nodes node-name LABEL=VALUE
Para remover um tente basta adicionar um sinal de -
kubectl label nodes node-name LABEL-
Utilizando o spec.affinity
- Garante que nós serão alocados em determinados nodes.
- Caso haja mudanças nas affinities, e o
spec.strategy
de um deployment esteja comoRollingRelease
, ainda ficarão pods esperando caso não seja configurado o maxUnavailable para 100%.
Utilizando o spec.affinity.nodeAffinity
spec.affinity.nodeAffinity.requiredDuringSchedulingIgnoredDuringExecution
: Quer dizer que o pod precisa que exista um nó com essa label. Caso não exista, o pod não será alocado. Quer dizer que o pod precisa que exista um nó com as condições especificadas emmatchExpression
spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution
: Ele vai tentar colocar o pod em um nó com a afinnity definida, porem alocará em qualquer lugar, se não conseguir. Com o weight, você pode definir a ordem que ele tentará alocar.
IgnoreDuringExecution
significa que pods que não serão afetados, caso as labels dos nodes mudem após os pods serem atribuídos ao nó.
Utilizando o spec.affinity.podAffinity
- define uma relação do pod sendo criado com outros pods presentes no nó
- topologykey será a chave utilizada para filtrar os nós que contenham aquela label
Utilizando o spec.affinity.podAntiAffinity
- define uma relação do pod sendo criado com outros pods presentes no no
Utilizando o spec.nodeName
- Se voce não selecionar, o scheduler vai selecionar por voce
- Só pode ser adicionada na criação do Pod. Não é possível editar
filePath: "@/Attachments/Kubernetes/pod/deploy-with-nodeaffinity-required.yaml"
filePath: "@/Attachments/Kubernetes/pod/deploy-with-nodeaffinity-preferred.yaml"
Taints and Tolerations - x nodeAffinity
- Com taints e tolerations você diz que certo nó só aceita um certo tipo de pod, mas não garante que todo pod criado cairá para este nó
- Você restringe um nó ao que ele pode rodar
- Você marca um pod com o taint que é aceito
- Para isso, usa-se node affinity, para garantir que esse pod vá para o tal nó.
- Você diz que ele deve rodar naquele nó
- Quanto se têm mais de um scheduler no sistema, é possível passar qual scheduler será usado pelo pod usando a opção
pod.spec.schedulerName
. O nome pode ser visto no--config
scheduler
Scheduler Profiles
- Os pods quando são criados entram na fila do scheduler, e é necessário criar um priorityClass e definir uma
priorityClassName
para organizar a fila - Após a fila, os pods são filtrados, para saber em quais nós podem ser alocados
- Após ele passa pela etapa de scoring, para saber qyal é o melhor nó pra ele ser alocado
- Após ele passa para etapa de bind, onde o pod será associado a um nó
![[CleanShot 2024-09-30 at 12.37.18.png]]
- Cada etapa pode ser customizada
[!NOTE]- Criação de um
ConfigMap
simples
filePath: "@/Attachments/Kubernetes/hpa/hpa.yaml"
ConfigMap
- Forma de guardar dados não sensíveis
- Guarda arquivos ou itens usando chave=valor
- Pode ser utilizado como um volume dentro do pod, ou como variável de ambiente
- Ao alterar um configmap, é necessário um restart no pod, visto que a alteração não é automaticamente atualizada
- Um configmap pode ser marcado como imutável utilizando
configmap.immutable = true
[!NOTE]- Criação de um
ConfigMap
simples
filePath: "@/Attachments/Kubernetes/configmap/configmap-teste.yaml"
[!NOTE]- Utilização de um
ConfigMap
. Sendo que todas as variáveis definidas serão carregas como variáveis de ambiente
filePath: "@/Attachments/Kubernetes/configmap/pod-with-configmap-env-valuesfrom.yaml"
[!NOTE]- Utilização de um
ConfigMap
. Sendo que apenas akey
especficada será carregada como variável de ambiente
filePath: "@/Attachments/Kubernetes/configmap/pod-with-configmap-env-key.yaml"
[!NOTE]- Utilização de um
ConfigMap
. Sendo que todas as variáveis serão carregadas como um arquivo dentro do pod.
filePath: "@/Attachments/Kubernetes/configmap/pod-with-configmap-volume.yaml"
[!NOTE]- Utilização de um
ConfigMap
. Sendo que será montada um arquivo com umakey
definida.
filePath: "@/Attachments/Kubernetes/configmap/pod-with-configmap-volume-items.yaml"
Comandos úteis
kubectl create configmap teste --from-literal chave=valor --from-literal chave1=valor1 $kdry
kubectl set env deploy MYDEPLOY CHAVE=VALOR
kubectl create cm cif --from-literal teste=teste
kubectl set env deploy teste --from configmap/cif
kubectl create configmap teste --from-file=index.html
Secrets
- Secrets não são exatamente seguras. Se usa
base64 -n
para codificar, o que pode ser facilmente "descodificado" usando o comandobase64 -d
; - Secrets não são criptografadas no ETCd;
- Qualquer pessoa que puder criar Deployments/Pods no namespace da secret, vai ser capaz de visualizar os dados.
- Para criar uma secret a partir de um manifesto, é necessário codificar o valor com
echo -n 'string' | base64
. O mesmo não se aplica a forma imperativa - Uma secret pode ser marcado como imutável utilizando
secret.immutable = true
- mudar o default mode
pod.spec.volumes.secret.defaultMode: 0400
- Secrets montadas são automaticamente atualizadas no POD caso sejam modificadas
- As variáveis de ambiente não são atualizadas por que estão anexadas ao processo de PID 1... logo não tem como atualizar
[!NOTE]- Criação de uma
Secret
filePath: "@/Attachments/Kubernetes/secrets/secret-teste.yaml"
[!NOTE]- Criação de um pod com secrets carregadas com
env.valueFrom
filePath: "@/Attachments/Kubernetes/secrets/pod-with-secrets-env-value.yaml"
[!NOTE]- Criação de um pod com secrets carregadas com
envFrom
filePath: "@/Attachments/Kubernetes/secrets/pod-with-secrets-envfrom.yaml"
[!NOTE]- Criação de um pod com secrets carregadas com
volume
filePath: "@/Attachments/Kubernetes/secrets/pod-with-secrets-volume.yaml"
[!NOTE]- Criação de um pod com secrets carregadas com
env.volume-items
filePath: "@/Attachments/Kubernetes/secrets/pod-with-secrets-volume-items.yaml"
Comandos úteis
kubectl create secret generic secretname --from-literal password=12345
kubectl create secret tls myCert --cert my.crt --key my.key
kubectl create secret generic mySecret --fromfile ssh-private-key=./id_rsa
k get secret teste -o jsonpath="{.data.password}" | base64 -d
kubectl set env deploy DEPLOYMENT --from secret/mysecret
kubectl create secret docker-registry docker-credentials \
--docker-server https://index.docker.io/v1/ \
--docker-email [email protected] \
--docker-username fabioluciano \
--docker-password xxxxxxx
[!NOTE]- Criação de um pod com secrets carregadas com
env.volume-items
filePath: "@/Attachments/Kubernetes/secrets/deploy-with-imagepullsecrets.yaml"
ResourceQuota
- Restringe o total de recursos que podem ser criados em um namespace;
- Pode ser restringido tanto recurso computacional, quanto objetos dentro do namespace(ex. pods, sa...)
[!NOTE]- Resourcequota
filePath: "@/Attachments/Kubernetes/resourcequota/resourcequota-test.yaml"
- É utilizado para definir valores padrão para containers, [[Pods]] e [[PersistentVolumes]]
- É aplicável a nível de namespace
- Afetará somente containers, [[Pods]] e [[Storage]] criados após a sua criação. Pods preexistentes não serão afetados pelo limit range; Por que a validação será feita pelo admission controller.
- É importante notar que, ao definir um limit range, e não definir um resource para seu recurso, ele vai pegar automaticamente o que foi definido no limitrange
- Caso editado, os valores definidos no limitrange só serão refletidos nos pods do namespace caso sejam recriados.
- Caso o tipo seja pod, os valores de CPU/Memoria serão da soma de requests/limits de todos os containers,
- Quando você definir um LimitRange, será obrigatória o preenchimento do resources para PODS
Propriedades importantes
spec.limits.type
: O tipo de componente a ser configurado. Pode ser Pod
, Container
ou PersistentVolumeClaim
.
spec.limits.default
: Define o limit default que será implementado caso não seja fornecido. Não funciona para pods
spec.limits.defaultRequest
: Define o requests default que será implementado caso não seja fornecido. Não funciona para pods
spec.limits.min
: Define o mínimo de recurso sque pode ser declarado cpu
, memory
storage
spec.limits.max
: Define o máximo de recurso sque pode ser declarado cpu
, memory
storage
[!NOTE]- LimitRange de recursos de um container
filePath: "@/Attachments/Kubernetes/limitrange/limitrange-container-test.yaml"
[!NOTE]- LimitRange de recursos de um pod
filePath: "@/Attachments/Kubernetes/limitrange/limitrange-pod-test.yaml"
[!NOTE]- LimitRange de recursos de um pvc
filePath: "@/Attachments/Kubernetes/limitrange/limitrange-pvc-test.yaml"
Networking
Service
- É um componente utilizado para fazer com que os pods sejam acessíveis ao mundo externo, ou mesmo dentro do cluster;
- Aplica o load balancing round-robin, direcionando para os pods
- As requisições são "mais ou menos" divididas entre os pods
- Cada Service recebe um nome acessível em
NOMEDASERVICE.NAMESPACE.svc
Tipos de service
Existem 4 tipos de services:
-
service.spec.type = ClusterIP
: Torna o serviço acessível apenas dentro do cluster. É oserviceType
padrão. - Existe uma faixa de ips para os pods e outra para os serviços - É criado um ip virtual para que o serviço seja acessível dentro do CLuster -
service.spec.type = NodePort
: Torna o serviço acessível ao mundo externo, colocando uma porta anexada a um nóNodeIP:NodePort
. Também possui umClusterIp
. - A porta, se não setada, é automaticamente preenchida. - A porta deve estar entre 30000 e 32767 - Qualquer nó responderá pela porta - Quando há multiplas portas sendo expostas, é necessário informar o name -
service.spec.type = LoadBalancer
: - É necessário um agente externo para seu funcionamento. Possui umNodePort
e umClusterIp
-
service.spec.type = ExternalName
- Cria umCNAME
dns registry para algo que está fora do cluster -
HEADLESS SERVICE
service.spec.type = ClusterIP
eservice.spec.ClusterIP = None
- Vai usar os IPS dos pods e não o IP a service... Já que ela nem tem - PESQUISAR MAIs -
Endpoints são para quantos pods o trafego está sendo direcionado com determinado serviço
-
Quando um serviço é criado, um registro
A/AAAA
e umSRV
é gerado no coredns
As informações da service utilizada pelo pod podem ser visualizadas também pelas variáveis de ambiente definidas. Só serão disponibilizadas em pods que estejam rodando no mesmo namespace
export # executar commando
#### SAIDA
### SERVICENAME_SERVICE_HOST
export TESTE_SERVICE_HOST='10.109.105.76'
export TESTE_SERVICE_PORT='80'
Vai mostrar
[!NOTE]- Criação de uma
Secret
filePath: "@/Attachments/Kubernetes/service/deploy-service-nodeip.yaml"
[!NOTE]- Service para um Pod utilizando
spec.type.ClusterIP
filePath: "@/Attachments/Kubernetes/service/service-clusterip.yaml"
[!NOTE]- Service para um Pod utilizando
spec.type.NodePort
filePath: "@/Attachments/Kubernetes/service/service-nodeport.yaml"
Comandos úteis
kubectl cluster-info dump | grep service-cluster-ip-range
kubectl cluster-info dump | grep cluster-cidr
kubectl expose pod service-test-nodeport --port 8080 --target-port 80 --selector svcType=NodePort
Cria service
kubectl create -f service-file-definition.yml
Recupera informações sobre o service
kubectl get svc
Deleta service
kubectl delete svc name-service
kubectl run -ti --rm testpod --image nginx -- cat /etc/resolv.conf
DNS
- Se você tiver no mesmo namespace, voce vai conseguir acessar uma service apenas por seu nome, sem mencionar o namespace http://SERVICENAME
- Se voce tiver em outro namespace você precisa mencionar o namespace https://SERVICENAME.NAMESPACE
- Service name :
SVCNAME.NAMESPACE.svc.cluster.local
- Pods por padrão não recebem um DNS, mas podem ser configurados
- Quando configurado, o DNS do pod será o número do IP substituindo o dot pelo dash 192.168.56.10 `192-168-56-10'
- O endereço é
IPWITHDASHES.NAMESPACE.pod.cluster.local
- A forma contraída não funciona da para pods, já que não é colocada no resolv,conf
Core DNS
- Para habilitar que pods também recebam DNS, ative a opção
pods insecure
no Corefile do coredns
Endpoints
- Coleção de Ips e portas expostas pelos pods selecionados pelo pod
- Todas vez que um pod é removido ou adicionado ao seletor, o endpoint é atualizado
- Só podem ter 1000 ips dentro de um endpoint. ou seja, não pode ter mais de 1000 replicas rodando...
- Foi criado o EndpointSlice para resolver os problemas dos endpoints. Ele também guarda informação do nó
EndpoitsSlices
- Faz o mapeamento dos Ips dos pods para a service criada
Gateway API
- Provê o gerenciamento de políticas de roteamento e tráfego
- Gerencia o
Ingress
e oEgress
- Sendo um [[Ingress]] somente para requisições HTTP, o Gateway API, funciona para TCP, UDP e gRPC
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: cilium
listeners:
- name: http
protocol: HTTP
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-app-1
spec:
parentRefs:
- name: my-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: teste
port: 80
color: var(--mk-color-red)
Role
- Pra definir uma role, você informa três parâmetros:
- É por namespace
rules.apiGroups
: Informar o apiGroup que se deseja autorizar. Caso seja um recurso do api group core, não é necessário informarrules.resources
: Recursos a serem autorizados pela rolerules.verbs
: Operações authorizadas pela rolerules.resourceNames
: autoriza recursos específicos
RoleBinding
- Anexa uma Role a um elemento
user
,serviceaccount
group
- É por namespace
rolebinding.subject
: O usuario que se deseja associarrolebinding.roleRef
: A role que se deseja associar
ClusterRole
- Para recursos que não são específicos de um namespace
- Você pode configurar, por exemplo, que um usuário possui uma clusterrole associada com pods. ele terá acesso a TODOS os pods em TODOS os namespaces
- Não fazem parte de NENHUM namespace
ClusterRoleBinding
- Anexa uma Clusterrole a um usuário
filePath: "@/Attachments/Kubernetes/rbac/rbac-reader-test.yaml"
Comandos úteis
kubectl api-resources --namespaced=false
kubectl auth can-i create deployment
kubectl auth can-i create deployment --as user
kubectl auth can-i get pods --as system:serviceaccount:default:reader
kubectl api-resources -o wide
kubectl create role developer --verb=create,list,delete --resource=pods
kubectl create rolebinding user-x-developer --role=ROLE --user=USER
kubectl create rolebinding --serviceaccount NAMESPACE:SERVICEACCOUNT --role ROLE
kubectl set serviceaccount deployment SERVICEACCOUNT DEPLOYMENT
Inspecting Secrets
filePath: "@/Attachments/Kubernetes/rbac/rbac-cli-access-pod.yaml"
kubectl get pod rbac-cli-access -o yaml | grep serviceAccountName
k get pod rbac-cli-access -o yaml | yq '.spec.containers[].volumeMounts[0].mountPath'
TOKEN=$(k exec -ti rbac-cli-access -- cat /var/run/secrets/kubernetes.io/serviceaccount/token)
echo -n $TOKEN | jwt decode - --json | jq
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1 | jq '.resources[].name'
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/default/pod
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes/apis/authentication.k8s.io/v1/selfsubjectreviews -X POST --json '{"kind":"SelfSubjectReview","apiVersion":"authentication.k8s.io/v1"}'
filePath: "@/Attachments/Kubernetes/rbac/rbac-cli-access-sa.yaml"
filePath: "@/Attachments/Kubernetes/rbac/rbac-cli-access-role.yaml"
filePath: "@/Attachments/Kubernetes/rbac/rbac-cli-access-rolebinding.yaml"
filePath: "@/Attachments/Kubernetes/rbac/rbac-cli-access-pod-with-sa.yaml"
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/default/pod
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes/apis/authentication.k8s.io/v1/selfsubjectreviews -X POST --json '{"kind":"SelfSubjectReview","apiVersion":"authentication.k8s.io/v1"}'
Combinações de Roles/Rolebindings
Role
+RoleBinding
= A role estará disponivel no namespace, o rolebinding será aplicado no namespaceClusterRole
+ClusterRoleBinding
= A Role estará disponível em todos os namespaces, a ClusterRolebinding será dada em TODOS os namespacesClusterRole
+RoleBindind
= A role estará disponível em todos os namespaces, a permissão será dada em apenas um namespace
EH POSSIVEL COM O VERBO LIST VER TODAS AS SECRETS, VISTO QUE VOCE PODE LISTAR USANDO JSON/JSONPATH
- Existem dois tipos de ServiceAccounts, uma de usuário e outra de serviço;
- Usada para autenticar um serviço para se comunicar com a API do kubernetes;
- A partir da versão 1.24, tokens não são criados automaticamente na criação de uma SA
- Você pode criar uma secret do tipo service account e associar a serviceaccount. Esse token não terá expiração
- ou usar a api para recuperar o token
kubectl create token pod-with-serviceaccount
. Terá a expiração dada pelo servidor... default 1hora
- Todo namespace possui uma service account criada.
- Essa service account é automaticamente montada dentro do pod.
- Não é possível editar a serviceaccount de um pod. É necessário deletar e recriar o pod;
- As credenciais fornecidas pela service account, serão automaticamente montadas no diretório
/var/run/secrets/kubernetes.io/serviceaccount
. A propriedadepod.automountServiceAccountToken: false
desabilita esse comportamento.- Essa opção funciona tanto para sa.spec quanto pod.spec
[!NOTE]- Service Account
filePath: "@/Attachments/Kubernetes/serviceaccount/serviceaccount-test.yaml"
[!NOTE]- Pod with service account
filePath: "@/Attachments/Kubernetes/serviceaccount/pod-with-serviceaccount.yaml"
[!NOTE]- Pod with service account
filePath: "@/Attachments/Kubernetes/serviceaccount/pod-with-serviceaccount-automount-false.yaml"
[!NOTE]- Service Account with token attached
filePath: "@/Attachments/Kubernetes/serviceaccount/serviceaccount-with-token.yaml"
kubectl create serviceaccount teste
kubectl create token SERVICEACCOUNT --duration=3600s
-
Controla o trafego entre os pods
-
A CNI precisa ser compatível com a network policy
-
O trafego é dividido em duas categorias:
- Ingress: O que entra
- Egress: O que sai
-
Por padrão todos os pod se comunicam entre sí sem nenhuma configuração adicional
-
Caso não seja mencionado, o PolicyType manterá o padrão. Ou seja, vai poder se comunicar com qualquer um
-
Quando é configurado um ingress, o egress daquela porta é configurado automaticamente
-
Por padrão, desde de que o podSelector do from case com o podlabel, vai funcionar para qualquer namespace
-
A porta que referenciada por ports é a targetPort do service. Ou seja, aporta do container
-
Para selecionar o pod que se conectará ao elemento restringido, é possível selecionar por:
networkpolicy.spec.ingress.from.ipBlock
networkpolicy.spec.ingress.from.namespaceSelector
networkpolicy.spec.ingress.from.podSelector
-
Para definir uma NetworkPolicy siga os seguintes passos:
- Defina qual o pod que receberá a regra usando `networkpolicy.spec.podSelector.matchLabels
- Defina qual tipo de regra que será aplicada
Egress
ouIngress
ou ambas - Caso seja ingress, defina o
networkpolicy.spec.ingress.from
bem como asnetworkpolicy.spec.ingress.ports
- Caso seja egress, defina o
networkpolicy.spec.ingress.to
bem como asnetworkpolicy.spec.ingress.ports
[!NOTE]- Criação de uma
Secret
filePath: "@/Attachments/Kubernetes/networkpolicy/netpol-ingress-test.yaml"
[!NOTE]- Criação de uma
Secret
filePath: "@/Attachments/Kubernetes/networkpolicy/netpol-egress-test.yaml"
[!NOTE]- Criação de uma
Secret
filePath: "@/Attachments/Kubernetes/networkpolicy/netpol-allow-all-test.yaml"
[!NOTE]- Criação de uma
Secret
filePath: "@/Attachments/Kubernetes/networkpolicy/netpol-deny-all-test.yaml"
Node metadata protection
- Dado que tenho uma aplicação comprometida na cloud e ela consegue fazer requisições para o endpoint de metadados, qualquer informação sensível estará exposta.
- O endereço padrão de metadado é
http://169.254.169.254/latest/meta-data
filePath: "@/Attachments/Kubernetes/networkpolicy/cks/default-deny.yaml"
filePath: "@/Attachments/Kubernetes/networkpolicy/cks/block-metadata-retrieval.yaml"
MUITO IMPORTANTE LEMBRAR QUE 0.0.0.0/0 LIBERA PRA TODOS E CIDR/32 'e um IP SO'
- Garantir que ao menos um mecanismo de política de controle seja implementado. Pod Security Admission
- No namespace, utilizando a label
pod-security.kubernetes.io/<MODE>: <LEVEL>
. Sendo: - Level:
privileged
: Propositalmente aberta, e irrestrita;baseline
: Prevê o prevenimento de escalação de privilégiosrestricted
: Complemetamente restrita. Segue as melhores práticas de hardening de pods
- Modes:
enforce
: Violações a política farão com que a requisição seja rejeitada;audit
: Violações a política farão com que auditadas e o evento guardado, porém permitida;warn
: Dispararão um Warning para o usuário, mas serão permitidas
- É um admission control,
PodSecurity
habilitado por padrão
kubectl exec -n kube-system kube-apiserver-controlplane \
-- kube-apiserver -h | grep enable-admission
'E UMA LABEL E NAO UMA ANOTATION'
kubectl label ns NAMESPACE pod-security.kubernetes.io/MODE=LEVEL
apiVersion: admissionregistration.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
configuration:
apiVersion: pod-security.admission.config.k8s.io/v1
kind: PodSecurityConfiguration
defaults:
enforce: baseline
enforce-version: latest
audit: restricted
audit-version: latest
warn: restricted
warn-version: latest
exemptions:
usernames: []
runtimeClassNames: []
namespaces: [my-namespace]
- Projeto opensource de uso gen'erico, N~ao precisa ser especifico do kubernetes
- Prov^e uma linaguagem declarativa de politicas para validar o que está sentrndo no cluster.
- Trabalha junto ao Admission Controller, promovendo validações e mutações de objetos
- Só bloqueia se for true
- A política é escrita usando REGO
- O Kubernetes usa o OPA gatekeeper
- É necessario criar um
ConstraintTemplate
, que conterá uma contraint... - A contraint será criada e pode ser usada para definir os troços
Certificado
- Utilizado para garantir a confiabilidade entre a comunicação entre duas entidades
- Criptografia assimétrica é quando uma chave se usa uma chave pública para criptografar, a a chave privada para descriptografar
- Criptografia simétrica é quando a mesma chave é utilizada para criptografar e descriptografar uma informação
- Autoridade certificadora é uma organização conhecida que assina seu certificado
- Todo o processo de geração de chaves, incluindo as pessoas, as CAs, é chamado DE PKI - Public Key Infraestruture
- Geralmente as chaves públicas são
.crt
e.pem
- Chaves privadas geralmente são
.key
ou*-key.pem
openssl genrsa -out mykey.key 1024
openssl rsa -in mykey.key -pubout > pub.pem
Kubernetes
- Todos os componentes do cluster têm um par de certificados
openssl x509 -in cert.crt -text -noout
![[CleanShot 2024-11-02 at 02.37.04.png]]
- Primeiro se cria um certificado
- Depois se cria uma Request de assinatura
- Base64 nessa request que será enviada para o [[kube-apiserver]]
- O controller manager que controlará o que será assinado
openssl genrsa -out fabioluciano.key 2048
openssl req -new -key fabioluciano.key -subj "/CN=fabioluciano" -out fabioluciano.csr
cat fabioluciano.csr | base64 -w 0
filePath: "@/Attachments/Kubernetes/certificates/certificatesignrequest.yaml"
kubectl certificate approve fabioluciano
kubectl get certificatesigningrequests fabioluciano \
-o jsonpath='{.status.certificate}' | base64 -d > certificate.crt
OU
sudo openssl x509 -req -in benicio.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial -out benicio.crt -days 10000
kubectl config set-credentials fabioluciano \
--client-key=$(pwd)/fabioluciano.key\
--client-certificate=$(pwd)/fabioluciano.crt \
--embed-certs=true
kubectl config set-context fabioluciano \
--cluster=kubernetes
--user=fabioluciano
- Usar um service mesh para habilitar a comunicaçào criptografada entre pods
- o istio vai criar um sidecar em todos os pods, que captura as comunicações e as criptografa e descriptografa no proximo
Reduzir a superficie de ataque
- Use o principio do least prigilégio
- Remove pacotes obsoletos
- Limite o acesso
- Remove serviços obsoletos
- Restrinja módulos do kernel obsoletos
- identifique e corrija portas abertas
Limitar o acesso a nós
- os nós não devem estar expostos à internet
- autorizar conexões a partir de fontes conhecidas
SSH Hardening
- habilitar a conexão aos nós usando keypair
- desabilitar o usuário root a fazer ssh e setar
PermitRootLogin no
- desabilitar password
PasswordAuthentication no
open ports
Qual processo tá sendo usado na porta tal...
sudo netstat -tunpl | grep -w LISTEN
sudo ss -tupl
sticker: emoji//1f4a5 color: var(--mk-color-red)
Center for internet Security (CIS)
- Provê melhores práticas para proteção de ataques virtuais pervasivos
- Prove benchmarks para
- Sistemas Operacionais
- Cloud Providers
- Mobile
- Dispositivos de Rede
- Aplicações de Desktop
- Servidores de Aplicações
- É possível visualizar todas as ameaças possíveis em um sistema, quais sua descrição e como resolver.
- Também disponibiliza ferramentas para fazer a validação destes benchmarks
- CIS-CAT - Faz validações relacionadas a sistemas operacionais
Kube-bench
- Diponibilizado azspela Aqua security
- É uma ferramenta utilizada para validar se o cluster que se pretende avaliar está usando as melhores práticas relacionadas a segurança
- A ferramenta não vai para os nós. É necessário executar o comando em cada um dos nós
- Ele vai avaliar os componentes do cluster, não objetos que são criados pelos usuários
- É possível fazer o check de uma opção em específico passando a opção -c/--check="1.1.1,1.1.2"
sudo ./kube-bench run --config-dir ./cfg --config ./cfg/config.yaml --targets=WHATTORUN --check="1.1.1"
kube-bench run --targets=node # RODAR NO WORKERNODE
kube-bench run --targets=master # RODAR NO CONTROLPLANE
Resumão
Control plane host
Arquivos
- Os arquivos de configuração do control plane devem estar com a permissão configurada para
600
e o dono e grupo configurado pararoot:root
/etc/kubernetes/manifests/kube-apiserver.yaml
/etc/kubernetes/manifests/kube-controller-manager.yaml
/etc/kubernetes/manifests/kube-scheduler.yaml
/etc/kubernetes/manifests/etcd.yaml
/etc/cni/net.d/arquivo-de-configuracao
/etc/kubernetes/admin.conf
/etc/kubernetes/scheduler.conf
/etc/kubernetes/controller-manager.conf
/etc/kubernetes/pki/
/etc/kubernetes/pki/*.crt
- O diretório de dados do etcd(
/var/lib/etcd
) deve estar com a permissão700
e o dono/grupo paraetcd:etcd
Api Server
- Desabilitar o acesso anônimo usando a flag
--anonymous-auth=false
- Não utilizar autenticação baseada em tokens. Logo, não habilitar a flag
--token-auth-file
- Habilitar o Admission Plugin
DenyServiceExternalIPs
- Habilitar a comunicação com o Kubelet usando certificado/key usando as flags
--kubelet-client-certificate
e--kubelet-client-key
- Habilitar a comunicação com o Kubelet usando uma CA usando a flag
--kubelet-certificate-authority
- Confirmar que a flag
--authorization-mode
seja configurada para usarRBAC
eNode
e nãoAlwaysAllow
- Para proteger a api do
api-server
deDoS
é necessário o Admission PluginEventRateLimit
na flag--enable-admission-plugins
, bem como, configurar o plugin, usando um arquivo informando a flag--admission-control-config-file
- Garantir que o Admission Plugin
AlwaysAdmit
não está configurado na flag--enable-admission-plugins
- Garantir que o Admission Plugin
AlwaysPullImages
não está configurado na flag--enable-admission-plugins
. O plugin garante que a imagem será sempre baixada, mesmo que ela já esteja presente no servidor. Já que pode existir um pod que não tem permissão de usá-la, mas ela já está lá. - Garantir que o Admission Plugin
ServiceAccount
não está configurado na flag--enable-admission-plugins
. O plugin garante que quando um pod seja criado, a service accountdefault
seja associada a ele. - Garantir que o Admission Plugin
NamespaceLifecycle
não está configurado na flag--enable-admission-plugins
. O plugin garante nenhum objeto será criado em um namespace que está no estado de remoção, ou inexistente. - Garantir que o Admission Plugin
NodeRestriction
não está configurado na flag--enable-admission-plugins
. O plugin garante que o Kubelet pode gerenciar apenas objetosNode
ePod
presentes no nó que toma de conta - Garantir que a flag
--profiling
esteja configurada parafalse
- Garantir que as opções de auditoria sejam informadas:
--audit-log-path
- Informa a localização onde os logs de auditoria serão salvos--audit-log-maxage
- Informa por quantos dias os logs serão guardados. O recomendado são 30 dias--audit-log-maxbackup
- Informa quantos arquivos de rotação serão retidos. O recomendado são 10.--audit-log-maxsize
- Informa o tamanho máximo que o arquivo poderá ter. O recomendado são 100
- Garantir que a flag
--request-timeout
seja configurada para utilizar um valor que considere conexões mais lentas. - Garantir que a flag
--service-account-lookup
está configurada paratrue
. Se não estiver habilitada, o api-server apenas verifica que o token de autenticação é válido e não verificará se o token está presente no etcd - Garantir que a flag
--service-account-key-file
, seja informada. Por padrão o apiserver utiliza a fave privada TLS para verificar os tokens. - Garantir que as flags
--etcd-certfile
e--etcd-keyfile
para que o apiserver se comunique com oetcd
de maneira segura - Para garantir que a comunicação com os clientes sejam segura em transito, é necessário informar as flags
--tls-cert-file
e--tls-private-key-file
- Garantir que a flag
--client-ca-file
seja configurada com a CA utilizada - Garantir que a flag
--etcd-cafile
seja configurada com a CA utilizada - Garantir que a flag
--encryption-provider-config
seja configurada. A flag aceita um arquivo do tipoEncryptionConfig
- Garantir que os provedores de criptogradia sejam configurados. Usando a um arquivo do tipo
EncryptionConfig
, garantir que esteja usando uma das opçõesaescb
,kms
ousecretbox
- Garantir que o apiserver esteja usando apenas cifras de criptografia fortes usando a flag
--tls-cipher-suites
Controller Manager
- Garantir que a flag
--terminated-pod-gc-threshold
seja configurada com um valor apropriado. O valor padrão é muito alto(12500), o que pode ser desnecessário para muitos usuários - Garantir que a flag
--profiling
esteja configurada parafalse
- Garantir que a flag
--use-service-account-credentials
, fazendo que cada controller manager use uma sa diferente para interagir com o apiserver - Garantir que a flag
--service-account-private-key-file
seja configurada, fazendo com que uma chave privada seja usada pelas services accounts do controller manager - Garantir que a flag
--root-ca-file
seja informada, garantindo que os pods façam verificações do certificado antes de estabelecer uma conexão - Garantir que a opção
RotateKubeletServerCertificate=true
, seja configurada na flag--feature-gates
, garantirndo que os certificados do kubelet sejam rotacionados - Garantir que a flag
--bind-address
seja configurada para127.0.0.1
. Esta configuração garante que o controller manager não se comunique com endereços externos
Scheduler
- Garantir que a flag
--profiling
esteja configurada parafalse
- Garantir que a flag
--bind-address
seja configurada para127.0.0.1
. Esta configuração garante que o scheduller não se comunique com endereços externos
etcd
- Garantir que as flags
--cert-file
e--key-file
, sejam configuradas, para que a criptografia TLS do etcd seja ativada - Garantir que a flag
--client-cert-auth
seja configurada paratrue
. Garante que a autenticação de clientes usando certificados - Garantir que a flag
--auto-tls
não seja configurada paratrue
. Caso seja informada como true, somente certificados que não sejam auto assinados serão aceitos - Garantir que as flags
--peer-cert-file
e--peer-key-file
sejam configuradas. Garantindo que as conexões peer utilizem criptografia TLS - Garantir que a flag
--peer-client-cert-auth
seja configurada paratrue
, garantindo que as conexões peer sejam autenticadas utilizando certificados - Garantir que a flag
--peer-auto-tls
não seja configurada paratrue
. Caso seja informada como true, somente certificados que não sejam auto assinados serão aceitos - Garantir que a flag
--trusted-ca-file
seja configurada com um certificado CA diferente do que é utilizado pelos componentes do kubernetes
Autenticação e autorização
- Não permitir que certificados de client para serem usados como métodos de autenticação. Não há como revogar a permissão de certificados, uma vez que emitidos. É necessário utilizar mecanimos como OIDC(Como funciona?)
- Tokens fornecidos por service accounts não podem ser utilizados por usuários para fazer interações com o apiserver
- Tokens bootstrap não podem ser utilizado por usuários, visto que são projetados para que novos nós sejam incluídos ao cluster
Logging
- Garantir que a policy de auditoria seja configurada de maneira a expor apenas informações necessárias.
- Garantir que as políticas de auditoria incluam somente objetos que se seja observer preocupações com segurança, como secret, configmaps e tokenreviews. Modificações a pods e deployments. Utilizaçào de pods/exec, pods/portforward , pods/proxy e service/proxy
Worker node
Arquivos
- Os arquivos de configuração do worker node devem estar com a permissão configurada para
600
e o dono e grupo configurado pararoot:root
:/etc/systemd/system/kubelet.service.d/kubeadm.conf
/etc/kubernetes/kubelet.conf
/etc/kubernetes/pki/ca.crt
/var/lib/kubelet/config.yaml
Kubelet
- Desabilitar o acesso anônimo usando a flag
--anonymous-auth=false
- Garantir que a flag
--authorization-mode
, não esteja configurada paraAlwaysAllow
. De preferencia esteja configurada paraWebhook
, fazendo com que a autorização das requisições sejam passadas ao apiserver - Garantir que a configuração
authentication.x509.clientCAFile
esteja presente no arquivo de configuração do kubelet/var/lib/kubelet/config.yaml
, garantindo que as conexões serão validadas usando a CA - Garantir que a flag
--read-only-port
seja configurada para 0, não permitindo que nenhuma informação do kubelet seja exposta sem autenticação - Garantir que a flag
--streaming-connection-idle-timeout
não esteja configurada para 0, desabilitando o timeout, possibilitando ataques DOS. Por padrão está configurado para 4 horas, o que pode ser muito para muitos sistemas - Garantir que a flag
--make-iptables-util-chains
seja configurada para true, fazendo com que o kubelet manipule o iptables - Garantir que a flag
--hostname-override
não seja configurada, possibilitando a quebra de conexões TLS - Garantir que a configuração
eventRecordQPS
esteja presente no arquivo de configuração do kubelet/var/lib/kubelet/config.yaml
, garantindo o limit que eventos são capturados. - Garantir que as flags
--tls-cert-file
e--tls-private-key-file
sejam informadas, garantindo a conexão segura entre o kubelet e o apiserver - Garantir que a flag
--rotate-certificates
não esteja setada para false, fazendo com que os certificados não sejam rotacionados - Garantir que a opção
RotateKubeletServerCertificate=true
, seja configurada na flag--feature-gates
, garantirndo que os certificados do kubelet sejam rotacionados - Garantir que o apiserver esteja usando apenas cifras de criptografia fortes usando a flag
--tls-cipher-suites
- Garantir que um limit de
PID
seja configurado, usando a flag--pod-max-pids
ouPodPidsLimit
Kube-proxy
- Garantir que o serviço de métricas seja bindado ao localhost usando a opção
--metrics-bind-address=127.0.0.1
Políticas
RBAC e SA
- Garantir que a role
cluster-admin
seja utilizada apenas onde for necessária - Minimizar o acesso a secrets. Quando possível remova os verbos
get
,list
, ewatch
do acesso ao recursosecret
. - Minimizar a utilização de wildcards em Roles e ClusterRoles ao escolher quais são os recursos que o objeto interagirá
- Minimizar o acesso à criação de pods dimiuindo a possibilidade de escalonamento de privilégio
- Garantir que a service account não seja ativamente utilizada. Se um pod precisar acessar a API do kubernetes uma nova SA deve ser criada.
- Garantir que a montagem dos tokens de uma SA sejam montadas apenas quando realmente necessária. Sempre que possível informe a opção
automountServiceAccountToken: false
- Evite a utilização do grupo
system:masters
para permissionar usuários ou service accounts a não ser que necessário - Limite a utilização das permissões
Bind
,Impersonate
eEscalate
, a não ser que seja realmente necessárioBind
- Permite que o Subject adicione um binding a uma clusterrole ou role, permitindo que sua permissão seja escaladaImpersonate
- Como o nome já diz, permite que um usuário aja como um usuário, ganhando suas permissõesEscalate
- Permite que o subject modificar roles as quais seja anexado, aumentando seus privilégios
- Minimize o acesso à criação de PVs, visto que utilizando
hostPath
é possível montar um diretório qualquer dentro do sistema operacional. - Minimize o acesso ao subrecurso approval do objeto
certificatesigningrequests
, visto que esse pode aprovar certificados a serem autorizados a interagir com o apiserver - Minimize o acesso a objetos webhook, visto que permissões aos objetos
validatingwebhookconfigurations
oumutatingwebhookconfigurations
podem ler qualquer objeto admitidos pelo cluster, em no caso do mutate, pode modificar objetos. Por exemplo, mutar uma role criada para dar permissão a um objeto - Minimize o acesso ao subrecurso token de service accounts, visto que esses podem criar long lived tokens que podem ser utilizados para interagir com a API, dado um certo nível de permissão
Padrões de Segurança do POD
- Garantir que ao menos um mecanismo de política de controle seja implementado. Pod Security Admission
- No namespace, utilizando a label
pod-security.kubernetes.io/<MODE>: <LEVEL>
. Sendo:- Modes:
enforce
: Violações a política farão com que a requisição seja rejeitada;audit
: Violações a política farão com que auditadas e o evento guardado, porém permitida;warn
: Dispararão um Warning para o usuário, mas serão permitidas
- Level:
privileged
: Propositalmente aberta, e irrestrita;baseline
: Prevê o prevenimento de escalação de privilégiosrestricted
: Complemetamente restrita. Segue as melhores práticas de hardening de pods
- Modes:
- No namespace, utilizando a label
- Minimizar a admissão de containers privilegiados. Visto que um container privilegiado têm acesso a todas as capacidades que um host tem
- Minimizar a admissão de containers que permitem a intenção de compartilhar o PID do host usando a opção
hostPID
. Visto que este pode inspecionar processos que estão rodando fora do container - Minimizar a admissão de containers que permitem a intenção de compartilar o IPC namespace usando a opção
hostIPC
. Visto que este pode inspecionar processos que estão rodando fora do container - Minimizar a admissão de containers que permitem a intenção de compartilhar a rede do host utilizando a opção
hostNetwork
, visto que este pode acessar a rede loopback, permitindo observar o tráfego de rede de outros pods\ - Minimizar a admissão de containers que utiliza a opção
allowPrivilegeEscalation
. Faz com que um processo de um container tenha mais permissão do que deveria. Permitir osudo
- Minimiar a admissão de containers que rodem com o usuário root. Que é o padrão. MustRunAsNonRoot or MustRunAs
- Minimizar a admissão de containers que utilizem capabilities fora do pacote padrão.
- Minimizar a admissão de containers que utilizem volumes do tipo hostPath
- Minimizar a admissão de containers que utilizem hosts ports
CNI e Network Policies
- Garantir que a CNI utilizada suporte a utilização de network policies
- Garantir que todos os namespaces tenham Network Policies definida, visto que um pod de outro namespace pode acessar pods neste namespace
Secrets
- Prefira secrets montadas como arquivos em um container que variáveis de ambiente. É comum aplicações cuspirem as variaveis de ambiente configuradas, e a secret estará lá
- Considere a utilização do armazenamento de secrets externamente.
Admission Control Extensível
- Configure a proviniencia de imagens utilizando o admission controller
ImagePolicyWebhook
, garantindoq ue apenas imagens aprovadas sejam implantadas no cluster
Políticas gerais
- Crie barreiras administrativas entre recursos usando namespaces.
- Garanta que o profile seccomp está configurado para docker/default nas definições do pods. Restringindo o conjunto de systemcalls que uma aplicação pode executar.
- Aplique securityContext aos seus pods e containers
- O namespace default não deve ser utilizado
- Módulo de segurança do kernel do linux
- Sumplementa os permissionamentos de usuários e grupos do linux
- Pode-se limitar que programas leia/escrevam em diretórios
- Desabilitar a rede
- Todos estes permissionamentos são atrelados a perfis
- Os perfis precisam ser adicionados aos workernodes
- Existem três tipos de modos de appamor
- enforce - o app armor vai monitorar e forçar as regras
- complain - vai permitir executar o processo, mas um log será gerado
- unconfined - permite qualquer coisa sem fazer nada
apt install apparmor-utils
###Serviço
systemctl status apparmor
sudo aa-status
cat /sys/module/apparmor/parameters/enabled
cat /sys/kernel/security/apparmor/profiles
aa-genprof curl
aa-logprof
apparmor_parser -r ARQUIVOPROFILE
# Dentro do pod
cat /proc/1/attr/current
filePath: "@/Attachments/Kubernetes/security/apparmor/denyall-profile"
filePath: "@/Attachments/Kubernetes/security/apparmor/apparmor-test-annotations.yaml"
filePath: "@/Attachments/Kubernetes/security/apparmor/apparmor-test-securitycontext.yaml"
- Módulo de segurança do Kernel
- FAz restrição de systemcalls da user space para o kernel namespace
mkdir -p /var/lib/kubelet/seccomp/profile
filePath: "@/Attachments/Kubernetes/security/seccomp/seccomp-teste.yaml"
tail -f /var/log/syslog
- Permite que seja utilizado mais que um container runtime instalado
Gvisor
- Adiciona mais uma camada entre o userspace e o kernel space
- Como é feito para funcionar com containers, vai fornecer um número limitado de syscalls para que as aplicações funcionem
- É composto de dois componentes:
- Sentry - Intercepta e responde a requisições
- Ele vai funcionar ocmo um proxy entre o kernel e a aplicação
- Sem utilizar um sandbox, o mesmo kernel da máquina, será o kernel do container
- Como tem mais instruções, pode ser mais lento
- Não funciona para qualquer aplicações
filePath: "@/Attachments/Kubernetes/security/runtimeclass/runtimeclass-runsc.yaml"
filePath: "@/Attachments/Kubernetes/security/runtimeclass/runtimeclass-teste.yaml"
kubectl exec -ti runtimeclass-teste -- uname -a
kubectl exec -ti runtimeclass-teste -- dmesg
Falco
- Usado para monitorar atividades suspeitas nos containers.
- Observa quais são as system calls que estão sendo invocadas no user usepace
- Usa um módulo do falco para ficar em frente ao kernel e capturar a syscalls `
journalctl -fu falco
- um arquivo rule do falco pode possuir tres tipos de elementos: rules, lists e macros
- o arquivo de configuração padrão do falco está localizado em
/etc/falco/falco.yaml
- regras são carregadas usando a opção
rules_file
no arquivo de configuração
rules
-
rule: nome da rule
-
desc: descrição da rule
-
condition: quando o evento será disparado.
-
output: Saida a ser gerada pelo evento
-
priority: severidade do evento
-
as variáveis definidas no conditions e output, são fornecidas pelo sysdig
-
macros são reduções de variaveis... por exemplo
container.id
pode ser referenciado apenas como `container
- Permitem responder perguntas como:
- Quem fez?
- Quando fez?
- O que foi feito?
- Como a modificação foi feita?
- Garante aderência as regulações de compliance
- Provê uma trilha que pode ser utilizada para investigar e entender o impacto de um incidente
- Histórico de mudança
- Garantir que os recursos são gerenciados de maneira eficiente
- Identifica a causa raiz de uma problema
Estágios
-
RequestReceived
- Assim que recebe a requisição -
RequestStarted
- Os cabeçalhos foram enviados mas não o corpo da mensagem... watch -
RequestComplete
- A resposta foi enviada e não serão enviadas outras informações -
Panic
- Ocorreu um panico -
Tipos de políticas
- None - Não logará eventos - Util quando se quer excluir certos eventos
- Metadata - Logará os metadados relacionados a uma requisição. Mas não a requisição
- Request - Metadados e o corpo da requisição
- RequestResponse - Metadata/Request e Response
-
--audit-log-path
- Informa a localização onde os logs de auditoria serão salvos -
--audit-policy-file
- Arquivo que contém as políticas configuradas do audit -
--audit-log-maxage
- Informa por quantos dias os logs serão guardados. O recomendado são 30 dias -
--audit-log-maxbackup
- Informa quantos arquivos de rotação serão retidos. O recomendado são 10. -
--audit-log-maxsize
- Informa o tamanho máximo que o arquivo poderá ter. O recomendado são 100
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
- level: Metadata
namespaces: ["prod"]
verbs: ["delete"]
resources:
- group: ""
resources: ["secrets"]
ADICIONAR - level: None
PARA DESABILITAR TODOS OS OUTROS E DEIXAR SOMENTE O QUE FOR CONFIGURADO
volumeMounts:
- mountPath: /etc/kubernetes/prod-audit.yaml
name: audit
readOnly: true
- mountPath: /var/log/prod-secrets.log
name: audit-log
readOnly: false
volumes:
- name: audit
hostPath:
path: /etc/kubernetes/prod-audit.yaml
type: File
- name: audit-log
hostPath:
path: /var/log/prod-secrets.log
type: FileOrCreate
- Criar service account
- k create sa admin-dashboard
- criar clusterolebinding clusterrole
- k create clusterrolebinding aaaaab --clusterrole cluster-admin --serviceaccount default:admin-dashboard k create token admin-dashboard -n default
- **Não habilitar --insecure-port --enable-insecure-login
- habilitar --auto-generate-certificates
- A service deve ser ClusterIP, não nodeport**
- É possível acessar o endereço de uma service usando o
kubectl proxy
e depois pegando o endereço de uma service e adicionando proxy na frente
curl -X GET http://127.0.0.1:8001/api/v1/namespaces/default/services/seccomp-test/proxy
- Pegar o pid de um container rodando
sudo crictl inspect 79b11c0376a81 | jq '.info.pid'
Extrair o certificado de um dado usuario usando jsonpath
k config view --raw \
-ojsonpath="{.users[?(.name == 'restricted@infra-prod')].user.client-certificate-data}"
curl -k -H "Authorization: Bearer $(cat /run/secrets/kubernetes.io/serviceaccount/token)" https://kubernetes.default/api/v1/namespaces/restricted/secrets
Os Quatro Cs
Primitivos de segurança
Host
- Todos os hosts precisam ser seguros
- Desabilitar o acesso root
- Desabilitar a autenticação baseada em user/pass
- Autorizar somente usando chaves
- A primeira linha de defesa é o [[kube-apiserver]]. Como ele recebe todas as requisições sobre o que acontecerá no cluster
- Quem acessa o cluster [[Primitivos de Segurança#Autenticação]]
- O que, quem acessa o cluster, pode fazer [[Primitivos de Segurança#Autorização]]
- A comunicação entre todos os componentes é assegurada utilizando certificados TLS
Autenticação
- O kubernetes não gerencia usuários por padrão. Ele depende de outras fontes externas para sua administração
- Todo acesso de usuários é gerenciado pelo
kube-apiserver
. Seja pelokubectl
, ou pela API. Okube-apiserver
, autentica as requisição antes de processá-la. - Existem diversas maneiras de autenticação:
- Arquivo com usuarios e senhas
- Arquivo com usuários e tokens
- Certificados
- Serviço de identidade(LDAP)
Arquivo com usuarios e senhas e token
- Cria um arquivo csv com quatro(a última e opcional) columas:
password
,username
,userid
,group
e se passa como opção para o kube-api server--basic-auth-file=user-datails.csv
- Tanto a lista de usuários, quanto a lista de tokens não são recomendadas
curl -v -k https://localhost:6443/api/v1/pods -u "user1:password123"
KubeConfig
- Localização padrão
~/.kube/config
, pode ser utilizar a variável $KUBECONFIG - Arquivo de configuração que guarda informações relativas aos clusters e autenticação a eles.
- São configuradas três informações:
current-context
: Contexto utilizado no momentoClusters
: Informações referentes ao cluster disponíveis para conexão- server: Endereço do servidor do cluster
- certificate-authority: Certificado
Users
: Usuários autorizado a se conectar ao cluster- client-certificate
- client-key
Contexts
: União entre os Clusters e os Usuários- Cluster
- User
- Namespace
export KUBECONFIG=~/.kube/config**:**/path/cluster1:/path/cluster2
kubectl config view --flatten > all-in-one-kubeconfig.yaml
Autorização
- Como administrador, você pode performar qualquer operação
- Há diversos mecanismos de autorização disponíveis no kubernetes
- Node
- O Kubelet acessa o kube-api server para gerenciar, assim como nós usuários
- O Kubelet acessa o kube api para ler informações sobre servi;os , endpoints nós e pods
- O kubelet também informa o kube-api com informações sobre nós pods e events
- Todas essas requisições são manipuladas pelo
Node Authorizer
- Qualquer requisição provinda de um usuário prefixado com
system:node:
é autorizado peloNode Authorizer
- Qualquer requisição provinda de um usuário prefixado com
- Attribute Based Authorization (ABAC)
- Quando você autoriza um usuário ou um grupo de usuários a um conjunto de permissões
- É feito utilizando um arquivo
Policy
json com o que o dado usuário pode fazer - Toda vez que há edição nesse arquivo, você precisa reiniciar o
kube-apiserver
- RoleBased Authorization ([[RBAC]])
- É definido um papel, e quais permissões aquele papel possui, então todos os usuários que precisam daquela role é associado
- Webhook
- Permite a externalização da autorização do kubernetes
- AlwaysAllow - autoriza qualquer requisição sem fazer qualquer filtro de autorização
- AlwaysDeny - nega qualquer requisição sem fazer qualquer filtro de autorização
- Node
- Se você não definir o
--authorization-mode
nokube-apiserver
, ele é setado automaticamente paraAlwaysAllow
. É possível ter multiplos authorization mode, separador por vírgula.- Caso seja provido mais que um, ele vai autorizar em cada um, de modo separado e sequencial
- O apiserver vai testar a requisição para cada authorization mode informado, até que um retorne TRUE, se não, passa para o próximo
-
Basicamente se trata da implementação de pipelines para fazer verificações e validações dos componentes
-
Permite a identificação prematura de vulnerabilidades
-
Melhor gereciamento de recursos
-
Melhoria de compliance
-
Respostas efetivas a incidentes
-
Melhhora a postura de segurança da organização
SBOM
-
Software Bill of Materials
-
Funciona como uma receita do que o software é composto
- Componentes de software
- Dependencias
- Composições de software
- Vulnerabilidades de segurança
- Licenças
- Versões
-
Dá dois formatos:
SPDX
eCycloneDX
-
GERAR SBOM -> SCAN -> Analyzar -> Remediar -> Monitorar
Ferramenta: syft
syft dockerimage:tag -o spdx-json
syft docker.io/kodekloud/webapp-color:latest -o spdx-json > /root/webapp-spdx.sbom
grype do sbom.json
grype sbom:/root/webapp-sbom.json -o json > /root/grype-report.json
bom generate -i registry.k8s.io/kube-apiserver:v1.21.0 --format json > spdx.json
bom document outline spdx.json
Minimize base image footprint
- Não buildar multiplas aplicações em uma imagem
- usar imagens de fontes confiáveis
- deixar as imagen o menor possivelk
- usar distroless images
Kube-linter
kube-linter lint teste-deployment.yaml
Kubesec
kubesec scan bluegreen-service-based.yam
trivy
trivy config Dockerfile
trivy k8s --report summary all
trivy k8s pod/nginx
trivy image --severity HIGH --output /root/python.txt public.ecr.aws/docker/library/python:3.9-bullseye
trivy image --input alpine.tar --format json --output /root/alpine.json
trivy image nginx --format json
-
Múltiplos interessados acessando o mesmo cluster
-
usar RBAC pra limitar quais recursos os usuários podem manipular
-
usar namespaces
-
usar network policies
-
Control Plane
- Namespace
- Access Control - RBAC ABAC
- Quotas - limita os recursos computacionais utilizados por um namespace
-
Data Plane
- NetWork Isolation - Network Policy
- Storage Isolation - StorageClass
- Node Isolation - Taints e Tolerations
-
Definir
PriorityClass
para definir quais pods têm mais prioridade que outros. No Pod, usar a opçãospec.priorityClassName
Quality of Service
- Separa os pods em categorias usando os limites e requests de recursos
- São três tipos:
- Guaranteed - Quanto os requests e limits são os mesmos
- Burstable - Quando o limit é maior que o request
- BestEffort - Não é configurado request nem limits
DNS
- É possível limitar a resolução de DNS por namespace usandoa a opção
fallthrough in-namespace
do CoreDNS
Pop to pod encryption
- Usar service mesh
- Cilium
- Calico IPSEC
Instalação do Cluster Kubernetes
- Primeiro instalar o container runtime: Containerd
- Instalar kubeadm
Upgrade do Cluster
- os componentes do controlplane não precisam todos estarem na mesma versão
- porém nenhum outro componente pode estar acima da versão do [[kube-apiserver]]
- o [[kube-controller-manager]] e o [[kube-scheduler]] podem estar em uma versão abaixo
- o [[kubelet]] e o [[kube-proxy]] podem estar a duas versões abaixo
- o[[Kubectl]]pode estar a uma versão abaixo ou uma versão acima do [[kube-apiserver]]
- O suporte do kubernetes são somente para as três últimas versões lançadas
- Para fazer o upgrade é necessário subir uma minor por vez
- Primeiro se atualiza os controlplanes, depois os workernodes
- durante a atualização, o [[kube-apiserver]] e o [[kube-scheduler]] ficarão fora por um tempo
- TODAS as funcionalidades de manutenção serão paradas, porém, as aplicações nos worker nodes continuarão a funcionar
- O Kubeadm NÃO vai atualizar o kubelet
Atualização do Sistema Operacional
- Se os nó ficar mais de cinco minutos sem reponder. Os pods daquele nós serão terminados.
- Caso sejam partes de um replicaset, serão recriados em outro nó;
- Caso seja um pod que não seja parte de um replication controller, ele vai ser perdido
- Caso você faça uma tarefa que fará com que um nó entre no estado de notready
- executar o drain no nó
- O drain matará os pods neste node e criará em outro
- ao mesmo tempo, o nó será marcado como cordoned(marcado no unschedule)
- após estar tudo certo, o nó deve ser uncordon
- o comando cordon vai marcar o nó como unshedulable, sem mover nada... nenhum novo pod será alocado
- executar o drain no nó
Backup e Restore do etcd
Etcd
--data-dir
é a flag que mostra qual é o diretório que guarda os dados do etcd
ETCDCTL_API=3 etcdctl snapshot save snapshot.db
- pra restaurar primeiro para-se o [[kube-apiserver]]
ETCDCTL_API=3 etcdctl snapshot restore snapshot.db --data-dir /var/lib/etcd-from-backup
- configurar o etcd data-dir para apontar para o novo caminho
- reload daemon
- restart etcd
- restart [[kube-apiserver]]
- é necessário informar o
--endpoints=https://127.0.0.1:2379
--cacert=/etc/etcd/ca.crt
--cert=/etc/etcd/etcd-server.crt
--key=/etc/etcd/etcd-server.key
- Quando a master não está configurada como HA e a máquina morrer, os nodes continuarão a rodar
- Se algum pod morrer e ele for parte de um replication controller, ele não vai subir, já que o schedular e controll manager não estão funcionando
- não será possível acessar o api server, logo comandos kubectl não funcionarão
- O kubeapi deve ser colocaco atrás de um proxy reverso para garantir HA
- Os outros componentes rodarão em um esquema de ativo/standy, sendo que um responde, e outro fica aguardando a indisponibilidade do outro
- Deve-se eleger o líder dos seguintes
ETCd
- O etc garante que todos os nós do cluster tenham a possibilidade de ler e escrever
- Um lider é eleito e mesmo que uma scrita aconteça em um follower(slave), ele vai pasasar para o lider
- Um registro é considerado completo quando a maioria dos membros dizem ok
- Maioria = Quorum = Numero de insitancia / 2 + 1
- Se o kubectl não estiver respondendo é o kubeapi server que não está funcionando...
- Olhar com critrl o que está acontecendo
- Se um pod está em pending state e nàoi alocado nenhum nó, é o scheduler
- Se ao scalar a aplicação, não é escalado, é o controller manager
![[troubleshhoting-procedure.png]]
Aplicação
-
Assim que é executado um pod run, o scheduler vai buscar por pods que possar rodar a aplicação
-
Achando, a imagem do pod será baixada para o nó
-
Os containers dos pod começarão a rodar, e o entrypoint será chamado
-
Dependendo no estado do container no entrypoint, a
pod.spec.restartPolicy
entrará em ação -
Estados de um pod
- Pending - A requisição foi autenticada e autorizada pelo admission controller e o registro foi criado no etcd, mas alguns prerequisitos não foi alcançados;
- Running - Todos os procedimentos deram certo
- Completed - É uma task e não uma Long running task, e ela foi executada com sucesso
- Failed - O pod foi finalizado, mas algum problema aconteceu
- CrashLoopbackOff - Houve um erro no pod e o cluster está o restartando
-
Em caso de erros, usa-se o
kubectl describe pod
-
Observar o exitCode dos containers, se el for diferente de 1, é por que deu erro no entrypoint, e é necessário um
kubectl logs --previous
pare olhar os logs da aplicação containerizada
Redes
f
kubectl top nodes kubectl top pods
Probes:
-
Fornece uma solução padrão para monitorar aplicações
-
É um simples teste fornecido como uma propriedade do container
-
Existem três tipos de probes:
livenessProbe
- Checa se o container está vivo;readinessProbe
: Checa se a aplicação está pronta para receber tráfego- O container vai ser removido da lista de serviços disponíveis se falhar( o endepoint some?)
startupProbe
: Usado para verificar se a aplicação inicializou corretamente. Usado para aplicações que demora muito, por que ele não vai usar os outros probes- Nenhum outro probe será validado
-
pode ser
exec
httpGet
,tcpSocket
ougrpc
-
configurações do
pod.spec.containers[*].(liveness|readiness|startup)Probe
initialDelaySeconds
: Quanto tempo ele vai demorar até mandar o primeiro comandoperiodSeconds
: Com qual frequencia ele vai executar esse probesuccessThreshout
: Quantas vezes eu preciso que dê sucesso pra considerar o container up. No liveness e no readiness tem que ser 1failureThreshoud
: Quantas vezes eu preciso que dê erro pra considerar o container up. No liveness e no readiness tem que ser 1
-
- /healthz - Informa se aplicação está saudável
-
- /livez - Indica que a api está "alive"
-
- /readyz - Indica que a aplicação está pronta pra receber trafego
curl -k https://$(minikube ip):8443/healthz
curl -k https://$(minikube ip):8443/healthz?verbose
tags: K8s, kubernetes
KubeCtl
kubectl
kubecontrol kubecâtâl: Utilizado para implantar e gerenciar aplicações em um cluster k8s
Habilita o autocomplete
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
kubectl get --raw='/healthz?verbose'
`
Recuperar informações sobre um determinado recurso
kubectl explain pod --recursive #explicação sobre qualquer conteudo de um objeto
Criar um manifesto de pod
export kdry="--dry-run=client -o yaml"
kubectl run nginx --image nginx $kdry
Editar informações de um recurso
kubectl edit pod meu-pod
Editar informações com replace
export kdry="--dry-run=client -o yaml"
kubectl get pod meu-pod $kdry > meu-pod.yaml
kubectl replace -f meu-pod.yaml
Executa uma operação em todos os recursos filtrados
for i in $(k get po --namespace default --output jsonpath="{.items[*].metadata.name}" ); do; echo $i ; done;
Executar um comando em um pod
kubectl exec -ti meu-pod -- command
Remover recurso sem esperar
kubectl delete pod sleep --force --grace-period 0 #ignorará o pod.spec.terminationGracePeriodSeconds
Replace sem esperar
kubectl replace -f pod-sleep.yaml --force --grace-period 0
Efetua um patch em um recurso
metadata:
labels:
labelaaaa: dsds
dlsldslds: asda
kubectl patch -f pod-sleep-patch.yaml pod sleep
Recuperar informações mais informações dos pods
kubectl get pods -o wide
Aumentar o número de replicas de um replicationController
kubectl scale --replicas NUMREPLICAS -f arquivoreplicationcontroller.yaml
kubectl scale rs replicaset-teste --replicas NUMREPLICAS
Cria um pod com um command definido
export kdry="--dry-run=client -o yaml"
kubectl run --image nginx $kdry --command -- /bin/bash -c sleep
kubectl exec -ti pod-with-configmap -- env
kubectl port-forward pod/svc resource 8080:80 # A primeira porta é a do host, a segunda do POD/SERVICE
sudo kubeadm init --pod-network-cidr=10.1.1.0/24 --apiserver-advertise-address 192.168.56.10
crictl ps stop # ISSO PARA A PORRA DE UM CONTAINER DENTRO DO NODE
- É um gerenciador de pacotes do Kubernetes
- Consiste nas ferramenta helm e os charts, que são as aplicações que serão instaladas
- Um helm chart contém o seguinte:
- Descriçao do pacote
- Templates dos manifestos
helm repo add REPONAME REPOURL
helm repo update
helm repo list
helm search repo REPONAME
helm install RELEASENAME CHART
helm list
Helm Chart
- São templates de manifestos a serem aplicados em um cluster
- Os valores customizados são guardados num arquivo chamado values.yaml
- Os valores disponíveis em values.yaml são os valores padrão do chart
helm show values
helm install NAME CHART --values values.yaml
helm install NAME CHART --set KEY=VALUE
helm show values RELEASENAME
- Utiliza o arquivo kustomization.yaml para aplicar mudan;cas em um conjunto de recursos
- É uma funcionalidade do kubectl
kubectl apply -k ./
Configuraões para o vim
set ai
set et
set cursorcolumn
set cursorline
set sw=2
set sts=2
set si
set ts=2
syntax on
Configurações para o .bashrc
alias k=kubectl`
complete -o default -F __start_kubectl k
alias kg='kubectl get'
alias kd='kubectl describe'
alias ke='kubectl explain'
alias kl='kubectl logs'
alias kp='kubectl port-forward'
alias kr='kubectl run'
alias ked='kubectl edit'
alias kex='kubectl exec -it'
source .bashrc
export kdry="--dry-run=client -o yaml"
Auto Scaling
- Horizontal - Adicionar instancias a partir de uma demanda
- Vertical - Aumentar os recursos computacionais
Patterns
CNI - Container Network Interface - Garante padrões para a rede OVERLAY CRI - Container Runtime Interface CSI - Container Storage Interface SMI - Service Mesh Interface\
OCI - Open Container Initiative - Cuida dos aspectos relacionados a containers CNCF - Cloud Native Computing Foundation - Cuida dos aspectos relacionados a núvem
CNCF project stages
- Sandboxed - Projetos em estágios iniciais de desenvolvimento
- pode ser removido a cada 12 meses
- Incubated - Usado por tres empresas, e possui uma comunidade ativa
- Graduated - Technical Oversight Committee (TOC) vota para suvir o estágio de um projeto
Technical Oversight Committee
- Aprova novos projetos
- Definem práticas padrões
- Mantem a visão técnica
- Praticam a Minimal Viable governance - o projeto deve ser autoadministrado. A CNCF provê guidelines de como a governnaça deve ser implementada, mas o dojno é a comunidade
Papeis
- Cloud Architect - Projeta infraestrutura em cloud
- Devops Engineer - Responsável por todo o ciclode vida da aplicação, combinando responsabilidades de desenvolvimento e operação
- Security Engineer - Responsável pela segurança em cloud
- DevSecOps Engineer - Responsável elo ciclo de vida + segurança
- Data Engineer - Gerencia os dados daa cloud
- Full Stack Developer - Responsável por toda a stack
- SRE - Site Reliabilidaty Engineer - Responsável pela confiabilidade e escalabilidade das aplicações
- Service Level Indicators (SLI) - Mede aspectos do serviço levando em consideraçào LATÊNCIA, ERROR RATE e SYSTEM THOUGHPUT
- Service Level Objectives (SLO) - O alvo ou grupo de valores que se deseja atingir quando medido pelo SLI - Latência menor que 50ms - UMA COISA QUE PODE SER MEDIDA
- Service Level Agreements (SLA)- contrato explicito ou implicito com seu usuário que inclue as concecquencias de antigir ou não os SLOs
Containers
![[vlcsnap-2024-10-23-16h35m39s207.png]]