'

Tudo sobre PaaS

Resource Limits e Requirements.

limits

Vamos começar analisando um cluster Kubernetes de três nós. Utilizando o resourece limits e requests. Cada nó tem um conjunto de recursos de CPU e memória disponíveis. Agora, cada pod requer um conjunto de recursos para ser executado. Agora, sempre que um pod é colocado em um nó, ele consome os recursos disponíveis nesse nó. Como discutimos anteriormente, é o schedule do Kubernetes que decide para qual nó um pod vai.

Aprenda a instalar um cluster kubernetes em Kubeadm Multi-Master

O schedule leva em consideração a quantidade de recursos exigidos por um pod e os disponíveis nos nós e identifica o melhor nó para colocar um pod.

Se os nós não tiverem recursos suficientes disponíveis, o schedule evitará colocar o pod nesses nós e, em vez disso, colocará o pod em um nó em que haja recursos suficientes disponíveis.

E, se não houver recursos suficientes disponíveis em nenhum dos nós, o schedule retém o agendamento do pod. E você verá o pod em um estado pendente. E se você observar os eventos usando o comando kubectl describe pod, verá que há uma mensagem de CPU insuficiente.

Resource Requests

Agora vamos nos concentrar nos requisitos de recursos para cada pod. Então, o que são esses blocos e quais são seus valores?

Agora você pode especificar a quantidade de CPU e memória necessária para um pod ao criá-lo. Por exemplo, poderia ser 1 CPU e 1 gibibyte de memória. Isso é conhecido como resource requests para um contêiner.

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    function: font-end
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
      - containerPort: 80
    resources:
      requests:
        memory: "1Gi"
        cpu: 1

Isso indica, a quantidade mínima de CPU e memória solicitada pelo contêiner. Portanto, quando o schedule tenta colocar o pod em um nó, ele usa esses números para identificar um nó que tenha uma quantidade suficiente de recursos disponíveis.

Unidades de recurso são as mesmas para solicitações de recurso do pod e limites de recurso. Por exemplo: Gi significa GiB e m significa millicores. Um millicore é o equivalente a 1/1000 de um único núcleo de CPU.

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    function: font-end
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
      - containerPort: 80
    resources:
      requests:
        memory: "256Mi"
        cpu: 100m

O G é gigabyte e se refere a 1.000 megabytes, enquanto Gi se refere a gibibyte e seria igual a 1.024 mebibytes. Portanto, o mesmo se aplica ao megabyte e ao mebibyte, e ao kilobyte e ao kibibyte.

Limits

E, por padrão, um contêiner não tem limite para os recursos que pode consumir em um nó. Portanto, digamos que um contêiner que faz parte de um pod comece com uma CPU em um nó, ele pode aumentar e consumir o máximo de recursos que precisar, sufocando os processos nativos no nó ou outros contêineres de recursos. No entanto, você pode definir um limite para o uso de recursos nesses pods. Por exemplo, se você definir um limite de uma vCPU para os contêineres, um contêiner será limitado a consumir apenas uma vCPU desse nó.

O mesmo acontece com a memória. Por exemplo, você pode definir um limite de 512 mebibyte. Agora você pode especificar os limites na seção de limites, na seção de recursos do seu arquivo de definição de pod. Portanto, aqui, especifique os novos limites de memória e CPU da seguinte forma. Agora, quando o pod é criado, o Kubernetes define novos limites para o contêiner.

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
    function: font-end
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
      - containerPort: 80
    resources:
      requests:
        memory: "256Mi"
        cpu: 100m
      limits:
        memory: "512Mi"
        cpu: 1

E lembre-se de que as limits e as requests são definidos para cada contêiner em um pod. Portanto, se houver vários contêineres, cada um deles poderá ter uma solicitação ou um limite definido para si próprio.

Então, o que acontece quando um pod tenta exceder os recursos além do limite especificado?

Um contêiner não pode usar mais recursos de CPU do que o seu limite. Entretanto, esse não é o caso da memória. Um contêiner pode usar mais recursos de memória do que o seu limite. Portanto, se um pod tentar consumir mais memória do que seu limite constantemente, o pod será encerrado e você verá que o pod foi encerrado com um erro OOM nos logs ou na saída de eventos. Portanto, o termo OOM refere-se à Out of Memory.

Então, agora que aprendemos o que são resources resquets e o que são limits, como eles funcionam e o que acontece quando um determinado contêiner ou pod atinge os limites definidos, vamos ver qual é a configuração padrão, certo? Portanto, por padrão, o Kubernetes não tem uma solicitação ou limite de CPU ou memória definido.

Isso significa que qualquer pod pode consumir a quantidade de recursos necessária em qualquer nó e sufocar os recursos de outros pods ou processos que estejam em execução no nó.

LimitRange

O Kubernetes não tem resource requests ou limits configurados para pods. Mas então como podemos garantir que cada pod criado tenha um conjunto padrão?

Agora isso é possível com limitRange. Os limitRange podem ajudá-lo a definir valores padrão a serem definidos para contêineres em pods que são criados sem uma solicitação ou limite especificado nos arquivos de definição de pod.

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-resource-constraint
spec:
  limits:
  - default:
      cpu: 500m
    defaultRequest:
      cpu: 500m
    max:
      cpu: "1"
      memory: "1Gi"
    min:
      cpu: 100m
      memory: "25Mi"
    type: Container

Isso é aplicável no nível do namespace. Crie um arquivo de definição para o LimitRange, Observe que esses limites são impostos quando um pod é criado. Portanto, se você criar ou alterar um limitRange, isso não afetará os pods existentes. Isso afetará apenas os pods mais novos que forem criados depois que o limitRange for criado ou atualizado.

Quota

Há alguma maneira de restringir a quantidade total de recursos que podem ser consumidos pelos aplicativos implantados em um cluster do Kubernetes?

Por exemplo, se tivéssemos que dizer que todos os pods juntos não deveriam consumir mais do que essa quantidade de CPU ou memória, poderíamos criar cotas em um nível de namespace. Portanto, uma resource quota é um objeto de nível de namespace que pode ser criado para definir limites rígidos (hard) para solicitações e limites.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-resource-quota
  namespace: dev
spec:
  hard:
    requests.cpu: 4
    requests.memory: 4Gi
    limits.cpu: 10
    limits.memory: 10Gi

Neste exemplo, essa resource quota limita a CPU total solicitada no namespace atual a 4 e a memória a 4Gi. E ele define um limite máximo de CPU consumida por todos os pods juntos como sendo 10 e a memória como sendo 10 gibibytes.

Portanto, essa é outra opção que pode ser explorada.

Prática Resource Requests e Limits

Definindo resource requests e limits em um Pod

Objetivo: Definir resource requests e limits para um Pod.

Passo: 1.1. Crie um arquivo YAML chamado pod.yaml e adicione o seguinte conteúdo:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx
      resources:
        requests:
          cpu: "100m"
          memory: "256Mi"
        limits:
          cpu: "200m"
          memory: "512Mi"

Passo: 1.2. Aplique o arquivo YAML para criar o Pod:

kubectl apply -f pod.yaml

Passo: 1.3. Verifique se o Pod foi criado corretamente:

kubectl get pods

Você deve ver o Pod my-pod na lista, indicando que foi criado com sucesso.

Configurando Quota

Objetivo: Criar uma quota para limitar os recursos consumidos por um namespace.

Passo: 2.1. Crie um arquivo YAML chamado quota.yaml e adicione o seguinte conteúdo:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

Passo: 2.2. Aplique o arquivo YAML para criar a quota:

kubectl apply -f quota.yaml

Passo: 2.3. Verifique se a quota foi criada corretamente:

kubectl get resourcequota

Você deve ver a quota my-quota na lista, indicando que foi criada com sucesso.

Definindo LimitRange

Objetivo: Configurar um LimitRange para definir limites de recursos padrão para os Pods em um namespace.

Passo: 3.1. Crie um arquivo YAML chamado limitrange.yaml e adicione o seguinte conteúdo:

apiVersion: v1
kind: LimitRange
metadata:
  name: my-limitrange
spec:
  limits:
    - default:
        cpu: "200m"
        memory: "512Mi"
      defaultRequest:
        cpu: "100m"
        memory: "256Mi"
      type: Container

Passo: 3.2. Aplique o arquivo YAML para criar o LimitRange:

kubectl apply -f limitrange.yaml

Passo: 3.3. Verifique se o LimitRange foi criado corretamente:

kubectl get limitrange
kubectl describe limitrange my-limit

Você deve ver o LimitRange my-limitrange na lista, indicando que foi criado com sucesso.

Crie um namespace selfservice-quotas.

Passo 4.1 Use o comando kubectl create para criar o namespace.

kubectl create namespace selfservice-quotas

Atividade 5. Crie um deployment com um contêiner que solicite uma CPU.

Passo 5.1. Use o comando kubectl create para criar a implantação.

kubectl create deployment test \
--image nginx \
-n selfservice-quotas

Passo 5.2. Use o comando kubectl set resources para solicitar uma CPU na especificação do contêiner.

kubectl set resources deployment test --requests=cpu=1 -n selfservice-quotas

Passo 5.3. Use o comando kubectl get para garantir que a implantação inicie um pod corretamente.

kubectl get pod,deployment -n selfservice-quotas

Execute o comando até que a implantação e o pod estejam prontos.

Tente dimensionar a implantação para oito réplicas.

Passo 6.1. Use o comando kubectl scale para dimensionar a implantação.

kubectl scale deployment test --replicas=8 -n selfservice-quotas
kubectl get pod,deployment

Dos oito pods que a implantação cria, apenas alguns deles mudam para o status Running. Os outros pods permanecem no status Pending. Nem todas as réplicas da implantação estão prontas e disponíveis.

Passo 6.2. Use o comando kubectl get para listar eventos. Classifique os eventos por carimbo de data/hora de criação.

kubectl get event --sort-by .metadata.creationTimestamp -n selfservice-quotas

As réplicas falham ao agendar porque o cluster tem CPU insuficiente.

Examine o cluster como um administrador.

Passo 7.1. Use o comando kubectl top para exibir o uso de recursos dos nós.

kubectl top node

O cluster não mostra o alto uso da CPU.

Passo 7.2. Use o comando kubectl describe para ver detalhes do nó.

kubectl describe node/master01

O nó tem uma capacidade para quatro CPUs e tem mais de quatro CPUs alocáveis. No entanto, como mais de quatro CPUs são solicitadas, menos de uma CPU está disponível para novas cargas de trabalho.

Atividade 8. Crie um namespace test como um administrador e verifique se não é possível criar novas cargas de trabalho que solicitem uma CPU.

Passo 8.1. Use o comando kubectl create namespace para criar o namespace.

kubectl create namespace test

Passo 8.2. Use o comando kubectl create para criar a implantação.

kubectl create deployment test --image nginx -n test

Passo 8.3. Use o comando kubectl set resources para solicitar uma CPU na especificação do contêiner.

kubectl set resources deployment test --requests=cpu=1 -n test

Passo 8.4. Use o comando kubectl get para revisar pods e implantações no namespace test.

kubectl get pod,deployment -n test

A implantação criou um pod antes de adicionar a solicitação de CPU. Quando você atualizou a implantação para solicitar uma CPU, a implantação tentou substituir o pod para adicionar a solicitação de CPU. O novo pod está no estado Pending porque o cluster tem menos de uma CPU disponível para solicitação.

A carga de trabalho no namespace selfservice-quotas impede a criação de cargas de trabalho em outros namespaces.

Passo 8.5. Use o comando kubectl delete para excluir o namespace test.

kubectl delete namespace test

Atividade 9. Como administrador, dimensione a implantação para uma réplica no namespace selfservice-quotas.

Passo 9.1. Use o comando kubectl scale para dimensionar a implantação test para uma réplica.

kubectl scale deployment test --replicas=1 -n selfservice-quotas

Atividade 10. Crie uma cota para evitar que as cargas de trabalho no namespace selfservice-quotas solicitem mais de duas CPUs.

Passo 10.1. Use o comando kubectl create para criar a cota.

kubectl create quota duas-cpus --hard=requests.cpu=2 -n selfservice-quotas

Passo 10.2. Use o comando kubectl get para verificar a cota.

kubectl get quota duas-cpus -o yaml -n selfservice-quotas

Atividade 11. Tente dimensionar a implantação para oito réplicas e criar uma segunda implantação.

Passo 11.1. Use o comando kubectl scale para dimensionar a implantação.

kubectl scale deployment test --replicas=8 -n selfservice-quotas

Passo 11.2. Use o comando kubectl create para criar uma segunda implantação.

kubectl create deployment test2 --image nginx -n selfservice-quotas

Passo 11.3. Use o comando kubectl get para revisar pods e implantações.

kubectl get pod,deployment -n selfservice-quotas

Passo 11.4. Use o comando kubectl get para examinar o status da cota.

kubectl get quota duas-cpus -o yaml -n selfservice-quotas

Os dois pods da implantação test solicitam uma CPU cada e usam todos os recursos na cota.

Passo 11.5. Use o comando kubectl get para listar eventos. Classifique os eventos por carimbo de data/hora de criação.

kubectl get event --sort-by .metadata.creationTimestamp -n selfservice-quotas

A implantação test não pode criar mais pods porque os novos pods excederiam a cota. A implantação test2 não pode criar pods porque a implantação não define uma solicitação de CPU.

Atividade 12. Crie um namespace test para verificar se você pode criar novas cargas de trabalho em outros namespaces que solicitam recursos de CPU.

Passo 12.1. Use o comando kubectl create namespace para criar o namespace.

kubectl create namespace test

Passo 12.2. Use o comando kubectl create para criar a implantação.

kubectl create deployment test --image nginx -n test

m” Passo 12.3. Use o comando kubectl set resources para solicitar uma CPU na especificação do contêiner.

kubectl set resources deployment test --requests=cpu=1 -n test

Passo 12.4. Use o comando kubectl get para revisar pods e implantações no namespace test.

kubectl get pod,deployment -n test

Embora não seja possível criar outras cargas de trabalho no namespace selfservice-quotas, você pode criar cargas de trabalho que solicitem CPUs em outros namespaces.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *