Logo

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:


Navegue pelo sumário à esquerda para começar seus estudos. Bom aprendizado!

Semantic Versioning Changelog

1.2.3 (2025-05-02)

Bug Fix(es) 🐛️

  • adiciona fundo branco aos diagramas plantuml (#12) (04a7eb4)

1.2.2 (2025-05-02)

Bug Fix(es) 🐛️

1.0.0 (2025-05-02)

New Feature(s) 🚀

Bug Fix(es) 🐛️

  • transforming from obsidian for mddocs (c3bf85d)
  • transforming Pods.md for mdbook (64150a8)

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ós worker;
  • 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 o load(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 o kube-api-server.
  • Todas as informações capturadas(do worker node) são guardadas no etcd do master
  • Possui o controller manager e o scheduller;
  • É 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 o etcd. 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
  • 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 node worker. 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 pelo k8s para guardar todos os dados gerenciados pelo cluster. É responsável por implementar travas entre os nós master 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.
  • 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 forma shell
  • 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 ou man 7 capabilities

Exec

ENTRYPOINT ["command", "ARG", "ARG"]
CMD ["-c"]
  • Fará com que o comando seja executado com o PID 1
  • O CMD é o args do Kubernetes

Shell

ENTRYPOINT command argument argument
  • Fará com que qualquer CMDseja 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 RESOURCENAMEvão criar uma label app=RESOURENAME e e kubectl 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 o kube-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 JSONou YAML.
  • 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 group
    • ns, 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ós worker. Os containers são encapsulados em objeto interno, conhecido como Pod;
  • É 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 um Pod;
  • 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ção 1:1 com containers rodando a aplicação. Para scale up você adiciona um pod, para scale 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 do pod 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, e spec.containers[*].args são os argumentos a serem passados para o spec.containers[*].command
  • spec.containers[*].command vai substituir o entrypointdefinido no Dockerfile da imagem utilizada e spec.containers[*].args vai substituir o CMD do Dockerfile.

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 especfico
  • pod.spec.securityContext.runAsGroup: Faz com queo grupo seja um numero especifico
  • pod.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.readOnlyRootFilesystempara true, e o que for modificável, montar um volume emptyDir

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 chave staticPodPath
  • 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 com spec.template.metadata.labels
  • pode-se utilizar dois tipos de seletores matchLabels e matchExpressions
    • 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 com spec.selector. Os pods criados fora do replicaset serão contabilizados na contagem de spec.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 ou kubectl 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 com kubectl 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 with spec.strategy = Recreate

filePath: "@/Attachments/Kubernetes/deployment/deployment-strategy-recreate.yaml"

[!NOTE]- Deployement with spec.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
  • 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

  1. Criar um deployment
  2. Transformar o kind para daemonset
  3. 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 propriedade pod.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 de cronjob.spec.jobTemplate
  • É importante notar que é possível setar o cronjob.spec.timeZone que afetará o funcionamento do cronjob.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

IMPORTANTE

PARA GARANTIR QUE UM POD SEJA ALOCADO EM UM NÓ É NECESSÁRIO CONFIGURAR TANTO A TOLERATIONQUANTO 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 é garantido
    • NoExecute: 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 ou matchExpressions. Para usar esse tipo de lógica deve-ser usar o nodeAffinity
kubectl label nodes minikube-m04 disk=nvme

[!NOTE]- Pod with spec.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.strategyde um deployment esteja como RollingRelease, 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 em matchExpression
  • 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 priorityClassNamepara 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 a key 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 uma keydefinida.

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 comando base64 -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 modepod.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. É o serviceType 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 um ClusterIp. - 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 um NodePort e um ClusterIp

  • service.spec.type = ExternalName - Cria um CNAME dns registry para algo que está fora do cluster

  • HEADLESS SERVICEservice.spec.type = ClusterIP e service.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 um SRV é 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 o Egress
  • 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 informar
    • rules.resources: Recursos a serem autorizados pela role
    • rules.verbs: Operações authorizadas pela role
    • rules.resourceNames: autoriza recursos específicos

RoleBinding

  • Anexa uma Role a um elemento user, serviceaccount group
    • É por namespace
    • rolebinding.subject: O usuario que se deseja associar
    • rolebinding.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 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 namespace
  • ClusterRole + ClusterRoleBinding = A Role estará disponível em todos os namespaces, a ClusterRolebinding será dada em TODOS os namespaces
  • ClusterRole+ 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 propriedade pod.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 ou Ingress ou ambas
    • Caso seja ingress, defina o networkpolicy.spec.ingress.from bem como as networkpolicy.spec.ingress.ports
    • Caso seja egress, defina o networkpolicy.spec.ingress.to bem como as networkpolicy.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égios
    • restricted: 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 .keyou *-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 para root: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ão 700e o dono/grupo para etcd: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-certificatee --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 usar RBACe Node e não AlwaysAllow
  • Para proteger a api do api-server de DoS é necessário o Admission Plugin EventRateLimit 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 account defaultseja 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 objetos Nodee Podpresentes no nó que toma de conta
  • Garantir que a flag --profiling esteja configurada para false
  • 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 para true. 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-certfilee --etcd-keyfile para que o apiserver se comunique com o etcd 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 tipo EncryptionConfig
  • Garantir que os provedores de criptogradia sejam configurados. Usando a um arquivo do tipo EncryptionConfig, garantir que esteja usando uma das opções aescb, kms ou secretbox
  • 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 para false
  • 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-fileseja 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 para 127.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 para false
  • Garantir que a flag --bind-address seja configurada para 127.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-authseja configurada para true. Garante que a autenticação de clientes usando certificados
  • Garantir que a flag --auto-tls não seja configurada para true. 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 para true, garantindo que as conexões peer sejam autenticadas utilizando certificados
  • Garantir que a flag --peer-auto-tls não seja configurada para true. 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 para root: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 para AlwaysAllow. De preferencia esteja configurada para Webhook, fazendo com que a autorização das requisições sejam passadas ao apiserver
  • Garantir que a configuração authentication.x509.clientCAFileesteja 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 eventRecordQPSesteja 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-filesejam 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 PIDseja configurado, usando a flag --pod-max-pids ou PodPidsLimit

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, e watch do acesso ao recurso secret.
  • 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 e Escalate, a não ser que seja realmente necessário
    • Bind - Permite que o Subject adicione um binding a uma clusterrole ou role, permitindo que sua permissão seja escalada
    • Impersonate - Como o nome já diz, permite que um usuário aja como um usuário, ganhando suas permissões
    • Escalate - 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 ou mutatingwebhookconfigurations 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égios
        • restricted: Complemetamente restrita. Segue as melhores práticas de hardening de pods
  • 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 o sudo
  • 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.idpode 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 proxye 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 pelo kubectl, ou pela API. O kube-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 momento
    • Clusters: 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 pelo Node Authorizer
    • 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
  • Se você não definir o --authorization-mode no kube-apiserver, ele é setado automaticamente para AlwaysAllow. É 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: SPDXe CycloneDX

  • 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ção spec.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

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 ou grpc

  • configurações do pod.spec.containers[*].(liveness|readiness|startup)Probe

    • initialDelaySeconds: Quanto tempo ele vai demorar até mandar o primeiro comando
    • periodSeconds: Com qual frequencia ele vai executar esse probe
    • successThreshout: Quantas vezes eu preciso que dê sucesso pra considerar o container up. No liveness e no readiness tem que ser 1
    • failureThreshoud: 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]]