Uma maneira de melhorar o desempenho de aplicativos com base em contêineres é aumentar os recursos do cluster adicionando nós ou adicionando recursos, como CPUs ou memória, a eles. Essa abordagem, no entanto, pode se tornar cara. Ajustar os nós do cluster para melhorar o desempenho ajuda a otimizar a utilização de recursos das cargas de trabalho de maneira econômica. Neste documento, descrevemos como usar o operador de ajuste de desempenho para ajustar os nós de trabalho e otimizar o desempenho da carga de trabalho no Google Distributed Cloud.
Para aproveitar ao máximo o hardware e o software subjacentes, diferentes tipos de aplicativos, especialmente aplicativos de alto desempenho, se beneficiam do ajuste das configurações de nós, como o seguinte:
- CPUs dedicadas para cargas de trabalho sensíveis ao desempenho
- CPUs reservadas para daemons e serviços padrão do Kubernetes
- Aumento do tamanho das páginas de memória com páginas enormes de 1 GiB (gibibyte) ou 2 MiB (mebibyte)
- Distribuição de cargas de trabalho com base na arquitetura do sistema, como processadores de vários núcleos e NUMA
Com o operador de ajuste de desempenho, é possível definir configurações de desempenho no nível do nó criando recursos personalizados do Kubernetes que aplicam configurações de desempenho. Confira os benefícios:
Interface de configuração única e unificada: com o operador de ajuste de desempenho, é possível atualizar um ou mais manifestos
PerformanceTuningProfile
que podem ser aplicados a nós de trabalho com seletores de nós. Não é preciso configurar cada nó individualmente com várias configurações e definições de políticas. Essa abordagem permite gerenciar configurações no nível do nó e do contêiner de maneira única e unificada.Persistência e confiabilidade: com a arquitetura de alta disponibilidade, você também aproveita toda a confiabilidade do Kubernetes. Os recursos personalizados do
PerformanceTuningProfile
podem ser atualizados sempre que você quiser, e as configurações deles persistem nas principais operações de cluster, como upgrades.
O operador de ajuste de desempenho orquestra os seguintes recursos e ferramentas do Kubernetes e do sistema operacional (SO) relacionados ao desempenho:
Para evitar conflitos, ao usar o operador de ajuste de desempenho, recomendamos que você não use as ferramentas e os recursos do Kubernetes e do SO mencionados anteriormente de maneira independente.
Pré-requisitos e limitações
Veja os pré-requisitos e as limitações para usar o operador de ajuste de desempenho:
Somente Red Hat Enterprise Linux (RHEL): o operador de ajuste de desempenho é compatível apenas com nós que executam versões compatíveis do RHEL.
Cluster de usuário ou híbrido com nós de trabalho: o operador de ajuste de desempenho pode ser usado apenas com nós de trabalho em clusters híbridos ou de usuários. Não é possível usar o operador de ajuste de desempenho para ajustar os nós do plano de controle. O operador de ajuste de desempenho usa um seletor de nós para determinar como aplicar os perfis de ajuste. Para garantir que os perfis de ajuste sejam aplicados apenas aos nós de trabalho, o
nodeSelector
em cada recurso personalizado de perfil precisa incluir o rótulo de nó de trabalho padrãonode-role.kubernetes.io/worker: ""
. Se onodeSelector
em um perfil de ajuste corresponder a rótulos em um nó do plano de controle, esse nó não será ajustado e uma condição de erro será definida. Para mais informações sobre condições de erro, consulte Verificar status. Verifique se o cluster está funcionando corretamente antes de instalar o operador de ajuste de desempenho e aplicar perfis de ajuste.TuneD 2.22.0: o operador de ajuste de desempenho exige que a versão 2.22.0 do TuneD seja pré-instalada nos nós de trabalho que você pretende ajustar. Para mais informações sobre o TuneD, incluindo instruções de instalação, consulte Introdução ao TuneD na documentação do Red Hat Enterprise Linux. O operador de ajuste de desempenho usa o TuneD com o perfil
cpu-partitioning
. Se não tiver esse perfil, instale-o com o seguinte comando:dnf install -y tuned-profiles-cpu-partitioning
Requisitos de recursos de carga de trabalho: para aproveitar ao máximo o ajuste de desempenho, é preciso ter uma boa compreensão dos requisitos de memória e CPU (solicitações e limites de recursos) para suas cargas de trabalho.
Recursos de nó disponíveis: encontre os recursos de CPU e memória para seus nós. É possível receber informações detalhadas sobre CPU e memória do nó nos arquivos
/proc/cpuinfo
e/proc/meminfo
, respectivamente. Também é possível usarkubectl get nodes
para recuperar a quantidade de recursos de computação e memória (status.allocatable
) que um nó de trabalho tem disponíveis para pods.Requer diminuição: como parte do processo de ajuste, o operador de ajuste de desempenho primeiro drena os nós e depois aplica um perfil de ajuste. Como resultado, os nós podem informar um status
NotReady
durante o ajuste de desempenho. Recomendamos que você use a estratégia de atualização gradual (spec.updateStrategy.type: rolling
) em vez de uma atualização em lote para minimizar a indisponibilidade da carga de trabalho.Requer reinicialização: para que as alterações de ajuste de nós entrem em vigor, o operador de ajuste de desempenho reinicializa o nó depois de aplicar o perfil de ajuste.
Instalar o operador de ajuste de desempenho
O operador de ajuste de desempenho consiste principalmente em dois controladores (uma implantação e um DaemonSet)
que interagem entre si para ajustar os nós com base nas configurações do perfil.
Por padrão, o operador de ajuste de desempenho não é instalado com o Google Distributed Cloud. Faça o download
dos manifestos do operador de ajuste de desempenho do Cloud Storage e use kubectl apply
para
criar recursos do operador de ajuste de desempenho no cluster.
Para ativar o ajuste de desempenho com valores padrão para o cluster:
Crie um diretório
performance-tuning
na estação de trabalho do administrador.No diretório
performance-tuning
, faça o download do pacote mais recente do operador de ajuste de desempenho no bucket de lançamento do Cloud Storage:gcloud storage cp gs://anthos-baremetal-release/node-performance-tuning/0.1.0-gke.47 . --recursive
Os arquivos transferidos por download incluem manifestos para a implantação
performance-tuning-operator
e o DaemonSetnodeconfig-controller-manager
. Também estão incluídos manifestos para funções relacionadas, como controle de acesso baseado em função (RBAC) e controle de admissão dinâmica.Como usuário raiz, aplique todos os manifestos do Operador de ajuste de desempenho de maneira recursiva ao cluster de usuário (ou híbrido):
kubectl apply -f performance-tuning --recursive –-kubeconfig USER_KUBECONFIG
Depois que a implantação e o DaemonSet são criados e executados, sua única interação é editar e aplicar os manifestos
PerformanceTuningProfile
.
Confira os requisitos de recursos para suas cargas de trabalho
Antes de ajustar seus nós, você precisa entender os requisitos de recursos de computação e memória das suas cargas de trabalho. Se os nós de trabalho tiverem recursos suficientes, eles poderão ser ajustados para fornecer memória garantida (padrão e grandes páginas) às cargas de trabalho na classe garantida Qualidade de Serviço (QoS).
O Kubernetes atribui classes de QoS a cada um dos pods, com base nas restrições de recursos especificadas para os contêineres associados. Em seguida, o Kubernetes usa classes QoS para determinar como programar pods e contêineres e alocar recursos para suas cargas de trabalho. Para aproveitar ao máximo o ajuste de nós para suas cargas de trabalho, elas precisam ter solicitações de recursos de CPU ou memória ou configurações de limites.
Para receber uma classe de QoS garantida, seus pods precisam atender aos seguintes requisitos:
- Para cada contêiner no pod:
- Especifique valores para solicitações de recursos de memória
(
spec.containers[].resources.requests.memory
) e limites (spec.containers[].resources.limits.memory
). - O valor dos limites de memória precisa ser igual ao valor das solicitações de memória.
- Especifique valores para solicitações de recurso de CPU
(
spec.containers[].resources.requests.cpu
) e limites (spec.containers[].resources.limits.cpu
). - O valor dos limites da CPU precisa ser igual ao valor de solicitações da CPU.
- Especifique valores para solicitações de recursos de memória
(
O trecho de especificação de pod a seguir mostra as configurações de recursos da CPU que atendem aos requisitos garantidos da classe QoS:
spec:
containers:
- name: sample-app
image: images.my-company.example/app:v4
resources:
requests:
memory: "128Mi"
cpu: "2"
limits:
memory: "128Mi"
cpu: "2"
...
Quando você recupera detalhes do pod com kubectl get pods
, a seção status
precisa incluir a classe de QoS atribuída, conforme mostrado no exemplo a seguir:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: "2023-09-22T21:05:23Z"
generateName: my-deployment-6fdd69987d-
labels:
app: metrics
department: sales
pod-template-hash: 6fdd69987d
name: my-deployment-6fdd69987d-7kv42
namespace: default
...
spec:
containers:
...
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2023-09-22T21:05:23Z"
status: "True"
type: Initialized
...
qosClass: BestEffort
startTime: "2023-09-22T21:05:23Z"
Para mais informações sobre as classes de QoS, consulte Qualidade de pod de classes de serviço na documentação do Kubernetes. Para instruções sobre como configurar pods e contêineres para que recebam uma classe de QoS, consulte Configurar a qualidade de serviço para pods.
Requisitos de CPU
Ao ajustar um nó, é possível especificar um conjunto de núcleos de CPU reservados
(spec.cpu.reservedCPUs
) para executar daemons do sistema do Kubernetes, como o kubelet
e o ambiente de execução do contêiner. Esse mesmo conjunto de CPUs reservadas executa daemons do
sistema operacional, como sshd
e udev
, também. Os núcleos da CPU restantes são
alocados como isolados. As CPUs isoladas são destinadas a aplicativos vinculados à CPU, que exigem tempo de CPU dedicado sem interferência de outros
aplicativos ou interrupções de rede ou de outros dispositivos.
Para programar um pod nas CPUs isoladas de um nó de trabalho:
Configure o pod para ter uma Qualidade de Serviço (QoS) garantida.
Os requisitos e limites de CPU precisam ser especificados em números inteiros. Se você especificar recursos parciais de CPU na especificação do pod, como
cpu: 0.5
oucpu: 250m
(250 milicores), a programação não poderá ser garantida.
Requisitos de memória
Ao ajustar um nó com o operador de ajuste de desempenho, é possível criar páginas enormes e associá-las aos nós de acesso à memória não uniforme (NUMA) na máquina. Com base nas configurações de pod e nó, os pods podem ser programados com afinidade de nó NUMA.
Criar um perfil de ajuste de desempenho
Depois de instalar o operador de ajuste de desempenho, você interage apenas com o cluster que executa
suas cargas de trabalho. Recursos personalizados de PerformanceTuningProfile
são criados diretamente
no cluster de usuário ou no cluster híbrido, não no cluster de administrador. Cada
recurso PerformanceTuningProfile
contém um conjunto de parâmetros que especifica
a configuração de desempenho aplicada a um nó.
O nodeSelector
no recurso determina os nós em que o perfil de ajuste é aplicado. Para aplicar um perfil a um nó, coloque o rótulo do par de chave-valor correspondente no nó. Um perfil de ajuste é aplicado a
nós que têm todos os rótulos especificados no campo nodeSelector
.
É possível criar vários recursos PerformanceTuningProfile
em um cluster. Se
mais de um perfil corresponder a um determinado nó, uma condição de erro será definida no
status
do recurso personalizado PerformanceTuningProfile
. Para mais
informações sobre a seção status
, consulte Verificar status.
Defina o namespace do recurso personalizado PerformanceTuningProfile
como
kube-system
.
Para ajustar um ou mais nós de trabalho:
Editar o manifesto
PerformanceTuningProfile
.Para saber mais sobre cada campo e um manifesto de amostra, consulte a referência do recurso
PerformanceTuningProfile
.(Opcional) Para os nós de trabalho aos quais você está aplicando um perfil, adicione rótulos para corresponder ao par de chave-valor
spec.nodeSelector
.Se nenhum par de chave-valor
spec.nodeSelector
for especificado no recurso personalizadoPerformanceTuningProfile
, o perfil será aplicado a todos os nós de trabalho.Aplique o manifesto ao cluster.
kubectl apply -f PROFILE_MANIFEST --kubeconfig KUBECONFIG
Substitua:
PROFILE_MANIFEST
: o caminho do arquivo de manifesto para o recurso personalizadoPerformanceTuningProfile
.KUBECONFIG
: o caminho do arquivo kubeconfig do cluster.
Remover um perfil de ajuste
Para redefinir um nó para seu estado original não ajustado:
Exclua o recurso personalizado
PerformanceTuningProfile
do cluster.Atualize ou remova os rótulos no nó para que ele não seja selecionado pelo perfil de ajuste novamente.
Se você tiver vários perfis de ajuste associados ao nó, repita as etapas anteriores, conforme necessário.
Pausar um perfil de ajuste
Se você precisar realizar manutenção no cluster, será possível pausar
temporariamente o ajuste editando o recurso personalizado PerformanceTuningProfile
. Recomendamos
que você pause o ajuste antes de executar operações críticas de cluster, como um
upgrade de cluster.
A aplicação de perfil malsucedida é outro caso em que você pode pausar o ajuste. Se o processo de ajuste não for bem-sucedido, o controlador pode continuar tentando ajustar o nó, o que pode resultar na reinicialização do nó repetidamente. Se você observar o status do nó alterna entre os estados "pronto" e "não pronto", pause o ajuste para se recuperar do estado corrompido.
Para pausar a sintonização:
Edite o manifesto do recurso personalizado
PerformanceTuningProfile
para definirspec.paused
comotrue
.Use
kubectl apply
para atualizar o recurso.
Quando o ajuste de desempenho é pausado, o controlador do operador de ajuste de desempenho interrompe todas as operações. A pausa evita o risco de que as operações do controlador do operador de ajuste de desempenho entrem em conflito com as operações do controlador do Google Distributed Cloud.
PerformanceTuningProfile
referência do recurso
Nesta seção, descrevemos cada um dos campos no
recurso personalizado PerformanceTuningProfile
. Esse recurso é usado para criar um perfil de ajuste para um ou
mais dos nós do cluster. Todos os campos no recurso são mutáveis após
a criação do perfil. Os perfis precisam estar no namespace kube-system
.
O manifesto de amostra de perfil numa
a seguir para nós com oito núcleos de CPU
especifica as seguintes alocações de recursos:
Quatro núcleos de CPU (
0-3
) são reservados para a sobrecarga do sistema do Kubernetes.Quatro núcleos de CPU (
4-7
) são reservados apenas para cargas de trabalho.A memória do nó é dividida em páginas de 2 MiB por padrão, em vez das páginas padrão de 4Ki.
10 páginas de memória de 1 GiB são reservadas para uso pelo nó NUMA 0.
Cinco páginas de memória com tamanho de 2 MiB são reservadas para uso pelo nó NUMA 1.
O Topology Manager usa a política de melhor esforço para programar cargas de trabalho.
apiVersion: anthos.gke.io/v1alpha1
kind: PerformanceTuningProfile
metadata:
name: numa
namespace: kube-system
spec:
cpu:
isolatedCPUs: 4-7
reservedCPUs: 0-3
defaultHugepagesSize: 2M
nodeSelector:
app: database
node-role.kubernetes.io/worker: ""
pages:
- count: 10
numaNode: 0
size: 1G
- count: 5
numaNode: 1
size: 2M
topologyManagerPolicy: best-effort
É possível recuperar a definição do recurso personalizado PerformanceTuningProfile
relacionado do grupo anthos.gke.io
no cluster. A definição do recurso
personalizado é instalada depois que a anotação do recurso de visualização é adicionada ao
recurso de cluster autogerenciado.
Configuração de CPU
Propriedade | Descrição |
---|---|
cpu.reservedCPUs |
Obrigatório. Mutável. String. Esse campo define um conjunto de núcleos de CPU a serem reservados para daemons do sistema Kubernetes, como o kubelet, o ambiente de execução do contêiner e o detector de problemas do nó. Esses núcleos de CPU também são usados para daemons do sistema operacional (SO), como sshd e udev .
O campo |
cpu.isolatedCPUs |
Opcional. Mutável. String. O campo cpu.isolatedCPUs
define um conjunto de CPUs usadas exclusivamente para aplicativos
sensíveis ao desempenho. O gerenciador de CPU programa contêineres apenas nas CPUs não reservadas,
de acordo com as
classes de Qualidade de Serviço (QoS) do Kubernetes.
Para garantir que as cargas de trabalho sejam executadas nas CPUs isoladas,
configure os pods com a classe QoS garantida e
atribua um recurso de CPU ao pod ou contêiner.
Para garantir a programação de pods, é preciso especificar unidades de CPU com números inteiros, não
recursos parciais de CPU (cpu: "0.5" ).
apiVersion: v1 kind: Pod ... spec: containers: ... resources: limits: cpu: "1" requests: cpu: "1" ... A maximização de CPUs isoladas para cargas de trabalho oferece o melhor benefício de
desempenho. Esse campo usa uma lista de números de CPU ou intervalos de números de CPU.
Verifique se a lista de CPUs não se sobrepõe à lista especificada com
|
cpu.balanceIsolated |
Opcional. Mutável. Booleano. Padrão: true . Esse campo
especifica se o conjunto de CPUs isoladas está qualificado para o balanceamento
de carga automático de cargas de trabalho nas CPUs. Quando você define esse campo como
false , suas cargas de trabalho precisam atribuir cada linha de execução explicitamente
a uma CPU específica para distribuir a carga entre as CPUs. Com atribuições de CPU explícitas, você consegue o desempenho mais previsível para cargas de trabalho garantidas, mas isso aumenta a complexidade das cargas de trabalho. |
cpu.globallyEnableIRQLoadBalancing |
Obrigatório. Mutável. Booleano. Padrão: true . Esse campo especifica se o balanceamento de carga de solicitação de interrupção (IRQ, na sigla em inglês) é ativado para o conjunto de CPUs isoladas. |
Configuração de memória
Propriedade | Descrição |
---|---|
defaultHugePageSize |
Opcional. Mutável. Enumeração: 1G ou 2M .
Esse campo define o tamanho padrão de um enormepage nos parâmetros de inicialização do kernel.
Grandes páginas são alocadas no momento da inicialização, antes que a memória fique fragmentada.
É importante notar que definir o tamanho padrão de páginas enormes como 1G remove todos os 2 milhões de pastas relacionadas do nó. Um tamanho de página enorme padrão de 1G impede a configuração de 2 milhões de páginas enormes no nó.
|
pages |
Opcional. Mutável. Número inteiro. Esse campo especifica o número de páginas enormes a serem criadas durante a inicialização. Esse campo aceita uma matriz de páginas. Verifique a memória disponível para os nós antes de especificar páginas enormes. Não solicite mais páginas enormes do que o necessário nem reserve toda a memória para páginas enormes. Suas cargas de trabalho também precisam de memória padrão. |
Seleção de nó
Propriedade | Descrição |
---|---|
nodeSelector |
Obrigatório. Mutável. Esse campo sempre requer o rótulo do nó de trabalho
do Kubernetes, node-role.kubernetes.io/worker:"" , que garante
que o ajuste de desempenho seja feito apenas nos nós de trabalho. Esse campo usa um rótulo de nó opcional como par de chave-valor. Os identificadores de pares de chave-valor são
usados para selecionar nós de trabalho específicos com rótulos correspondentes. Quando os rótulos nodeSelector correspondem aos rótulos em um nó de trabalho, o perfil de desempenho é aplicado a esse nó. Se você não especificar um rótulo de chave-valor no perfil, ele será aplicado a todos os nós de trabalho no cluster.
Por exemplo, o ... spec: nodeSelector: app: database node-role.kubernetes.io/worker: "" ... |
Configuração do Kubelet
Propriedade | Descrição |
---|---|
topologyManagerPolicy |
Opcional. Mutável. Enumeração: none , best-effort ,
restricted ou single-numa-node . Padrão: best-effort .
Este campo especifica a
política do gerenciador de topologia
do Kubernetes usada para alocar recursos para suas cargas de trabalho com base na classe de Qualidade
de serviço (QoS) atribuída. Para mais informações sobre como as classes de QoS são
atribuídas, consulte
Configurar a qualidade de serviço para pods.
|
Operações de perfil
Propriedade | Descrição |
---|---|
paused |
Opcional. Mutável. Booleano. Defina paused como true para impedir temporariamente que os controladores de DaemonSet ajustem os nós selecionados. |
updateStrategy |
Opcional. Mutável. Especifica a estratégia para aplicar mudanças de configuração de ajuste aos nós selecionados. |
updateStrategy.rollingUpdateMaxUnavailalble |
Opcional. Mutável. Número inteiro. Padrão: 1 . Especifica o
número máximo de nós que podem ser ajustados ao mesmo tempo. Esse campo só é aplicado quando type está definido como rolling . |
updateStrategy.type |
Opcional. Mutável. Enumeração: batch ou rolling .
Padrão: rolling . Especifica como aplicar atualizações de perfil
aos nós selecionados. Se você quiser aplicar a atualização a todos os nós selecionados
ao mesmo tempo, defina type como batch . Por padrão, as atualizações são lançadas sequencialmente para nós individuais, uma após a outra. |
Verificar status
Depois que o recurso personalizado PerformanceTuningProfile
é criado ou atualizado, um
controlador ajusta os nós selecionados com base na configuração fornecida no
recurso. Para verificar o status de PerformanceTuningProfile
, estamos expondo
o seguinte campo em Status
:
Propriedade | Descrição |
---|---|
conditions |
A condição representa as observações mais recentes disponíveis do estado atual do recurso de perfil. |
conditions.lastTransitionTime |
Sempre devolvido. String (no formato data-hora). Mostra a última vez que a condição passou de um status para outro. Esse tempo geralmente indica quando a condição subjacente mudou. Se essa hora não for conhecida, a hora indicará quando o campo da API foi alterado. |
conditions.message |
Opcional. String. Uma mensagem legível indicando detalhes sobre a transição. Este campo pode estar vazio. |
conditions.observedGeneration |
Opcional. Número inteiro. Se definido, esse campo representa a metadata.generation
em que a condição foi definida. Por exemplo, se metadata.generation
for 12 , mas status.condition[x].observedGeneration
for 9 , a condição estará desatualizada em relação ao estado
atual da instância. |
conditions.reason |
Obrigatório. String. O motivo da última transição de condição. |
conditions.status |
Obrigatório. Status da condição: True , False ou Unknown . |
conditions.type |
Obrigatório. O tipo é o tipo de condição: Stalled ou Reconciling . |
readyNodes |
O número de nós em que o perfil de ajuste foi aplicado com sucesso. |
reconcilingNodes |
O número de nós selecionados (ou selecionados anteriormente) que estão em
processo de reconciliação com o perfil de ajuste mais recente pelo
DaemonSet nodeconfig-controller-manager . |
selectedNodes |
O número de notas selecionadas. Ou seja, o número de nós que correspondem ao seletor de nós para esse recurso personalizado PerformanceTuningProfile . |