Uma forma de melhorar o desempenho das aplicações baseadas em contentores é aumentar os recursos do cluster adicionando nós ou recursos, como CPUs ou memória, aos nós. No entanto, esta abordagem pode tornar-se dispendiosa. Ajustar os nós do cluster para um melhor desempenho ajuda a otimizar a utilização de recursos para as suas cargas de trabalho de forma rentável. Este documento descreve como usar o operador de otimização do desempenho para otimizar os nós de trabalho de modo a otimizar o desempenho da carga de trabalho para o Google Distributed Cloud.
Para tirar o máximo partido do hardware e software subjacentes, diferentes tipos de aplicações, especialmente aplicações de alto desempenho, beneficiam da otimização das definições dos nós, como as seguintes:
- CPUs dedicadas para cargas de trabalho sensíveis ao desempenho
- CPUs reservadas para serviços e daemons padrão do Kubernetes
- Tamanhos de páginas de memória aumentados com páginas enormes de 1 GiB (gibibyte) ou 2 MiB (mebibyte)
- Distribuição da carga de trabalho com base na arquitetura do sistema, como processadores multinúcleos e NUMA
Com o operador de otimização do desempenho, configura as definições de desempenho ao nível do nó criando recursos personalizados do Kubernetes que aplicam configurações de desempenho. Seguem-se as vantagens:
Interface de configuração única e unificada: com o operador de otimização do desempenho, atualiza um ou mais manifestos que podem ser aplicados a nós de trabalho com seletores de nós.
PerformanceTuningProfile
Não precisa de configurar cada nó individualmente com várias definições de configuração e políticas. Esta abordagem permite-lhe gerir as configurações ao nível do nó e do contentor de forma única e unificada.Persistência e fiabilidade: também tem toda a fiabilidade que o Kubernetes oferece com a sua arquitetura de alta disponibilidade. Pode atualizar os recursos personalizados do
PerformanceTuningProfile
sempre que quiser, e as respetivas definições persistem nas principais operações de cluster, como as atualizações.
O operador de otimização do desempenho funciona orquestrando as seguintes funcionalidades e ferramentas do Kubernetes e do sistema operativo (SO) relacionadas com o desempenho:
Para evitar conflitos, quando usa o operador de otimização do desempenho, recomendamos que não use as ferramentas e as funcionalidades do Kubernetes e do SO mencionadas anteriormente de forma independente.
Pré-requisitos e limitações
Seguem-se os pré-requisitos e as limitações para usar o operador de otimização do desempenho:
Apenas Red Hat Enterprise Linux (RHEL): o operador de otimização do desempenho é suportado para nós que executam apenas versões suportadas do RHEL.
Cluster de utilizador ou híbrido com nós de trabalho: o operador de otimização do desempenho é suportado para utilização com nós de trabalho apenas em clusters de utilizador ou híbridos. A utilização do operador de otimização do desempenho para otimizar os nós do plano de controlo não é suportada. O operador de otimização do desempenho usa um seletor de nós para determinar como aplicar perfis de otimização. Para garantir que os perfis de otimização são aplicados apenas aos nós de trabalho, o
nodeSelector
em cada recurso personalizado do perfil tem de incluir a etiqueta de nó de trabalho padrãonode-role.kubernetes.io/worker: ""
. Se onodeSelector
num perfil de otimização corresponder às etiquetas num nó do plano de controlo, esse nó não é otimizado e é definida uma condição de erro. Para mais informações sobre as condições de erro, consulte o artigo Verificar estado. Certifique-se de que o cluster está a funcionar corretamente antes de instalar o Performance Tuning Operator e aplicar perfis de otimização.TuneD 2.22.0: o operador de otimização do desempenho requer a pré-instalação da versão 2.22.0 do TuneD nos nós de trabalho que quer otimizar. Para mais informações sobre o TuneD, incluindo instruções de instalação, consulte o artigo Introdução ao TuneD na documentação do Red Hat Enterprise Linux. O Performance Tuning Operator usa o TuneD com o perfil
cpu-partitioning
. Se não tiver este perfil, pode instalá-lo com o seguinte comando:dnf install -y tuned-profiles-cpu-partitioning
Requisitos de recursos da carga de trabalho: para tirar o máximo partido do ajuste de desempenho, deve compreender bem os requisitos de memória e CPU (pedidos e limites de recursos) das suas cargas de trabalho.
Recursos de nós disponíveis: encontre os recursos de CPU e memória para os seus nós. Pode obter informações detalhadas sobre a CPU e a memória do seu nó nos ficheiros
/proc/cpuinfo
e/proc/meminfo
, respetivamente. Também pode usarkubectl get nodes
para obter a quantidade de recursos de computação e memória (status.allocatable
) que um nó de trabalho tem disponíveis para Pods.Requer esgotamento: como parte do processo de otimização, o operador de otimização do desempenho esgota primeiro os nós e, em seguida, aplica um perfil de otimização. Como resultado, os nós podem comunicar um estado
NotReady
durante o ajuste do desempenho. Recomendamos que use a estratégia de atualização contínua (spec.updateStrategy.type: rolling
) em vez de uma atualização em lote para minimizar a indisponibilidade da carga de trabalho.Requer reinício: para que as alterações de otimização de nós entrem em vigor, o operador de otimização do desempenho reinicia o nó após aplicar o perfil de otimização.
Instale o operador de otimização do desempenho
O operador de otimização do desempenho consiste principalmente em dois controladores (uma implementação e um DaemonSet) que interagem entre si para otimizar os nós com base nas definições do seu perfil.
O operador de otimização do desempenho não está instalado com o Google Distributed Cloud por predefinição. Transfere os manifestos do operador de otimização do desempenho do Cloud Storage e usa kubectl apply
para criar recursos do operador de otimização do desempenho no cluster.
Para ativar o ajuste de desempenho com valores predefinidos para o cluster:
Crie um diretório
performance-tuning
na estação de trabalho do administrador.A partir do diretório
performance-tuning
, transfira o pacote do operador de otimização do desempenho mais recente a partir do contentor de lançamento do Cloud Storage:gcloud storage cp gs://anthos-baremetal-release/node-performance-tuning/0.1.0-gke.47 . --recursive
Os ficheiros transferidos incluem manifestos para a
performance-tuning-operator
implementação e onodeconfig-controller-manager
DaemonSet. Também estão incluídos manifestos para funções relacionadas, como o controlo de acesso baseado em funções (CABF) e o controlo de admissão dinâmico.Como utilizador raiz, aplique todos os manifestos do operador de otimização do desempenho recursivamente ao seu cluster de utilizador (ou híbrido):
kubectl apply -f performance-tuning --recursive –-kubeconfig USER_KUBECONFIG
Depois de o Deployment e o DaemonSet serem criados e estarem em execução, a sua única interação é editar e aplicar
PerformanceTuningProfile
manifestos.
Reveja os requisitos de recursos para as suas cargas de trabalho
Antes de poder otimizar os seus nós, tem de compreender os requisitos de recursos de computação e memória das suas cargas de trabalho. Se os nós de trabalho tiverem recursos suficientes, os nós podem ser otimizados para fornecer memória garantida (standard e hugepages) para as suas cargas de trabalho na classe de Qualidade de Serviço (QoS) garantida.
O Kubernetes atribui classes de QoS a cada um dos seus pods com base nas restrições de recursos que especificar para os contentores associados. Em seguida, o Kubernetes usa as classes de QoS para determinar como agendar os seus pods e contentores, e alocar recursos aos seus workloads. Para tirar o máximo partido da otimização de nós para as suas cargas de trabalho, estas têm de ter definições de pedidos ou limites de recursos de CPU ou memória.
Para lhe ser atribuída uma classe de QoS garantida, os seus pods têm de cumprir os seguintes requisitos:
- Para cada contentor no agrupamento:
- Especifique valores para pedidos de recursos de memória (
spec.containers[].resources.requests.memory
) e limites (spec.containers[].resources.limits.memory
). - O valor dos limites de memória tem de ser igual ao valor dos pedidos de memória.
- Especifique valores para os pedidos de recursos de CPU (
spec.containers[].resources.requests.cpu
) e os limites (spec.containers[].resources.limits.cpu
). - O valor dos limites de CPU tem de ser igual ao valor dos pedidos de CPU.
- Especifique valores para pedidos de recursos de memória (
O excerto da especificação do pod seguinte mostra as definições de recursos da CPU que cumprem os requisitos da classe de QoS garantida:
spec:
containers:
- name: sample-app
image: images.my-company.example/app:v4
resources:
requests:
memory: "128Mi"
cpu: "2"
limits:
memory: "128Mi"
cpu: "2"
...
Quando obtém detalhes do pod com kubectl get pods
, a secção status
deve incluir a classe de QoS atribuída, conforme mostrado no exemplo seguinte:
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 o artigo Classes de qualidade de serviço de pods na documentação do Kubernetes. Para obter instruções sobre como configurar os seus pods e contentores para que lhes seja atribuída uma classe de QoS, consulte o artigo Configure a qualidade de serviço para pods
Requisitos da CPU
Ao otimizar um nó, pode especificar um conjunto de núcleos da CPU reservados (spec.cpu.reservedCPUs
) para executar daemons do sistema Kubernetes, como o kubelet e o tempo de execução do contentor. Este mesmo conjunto de CPUs reservadas também executa os daemons do sistema operativo, como sshd
e udev
. Os restantes núcleos da CPU são
atribuídos como isolados. As CPUs isoladas destinam-se a aplicações limitadas pela CPU, que requerem tempo de CPU dedicado sem interferência de outras aplicações ou interrupções da rede ou de outros dispositivos.
Para agendar um Pod nas CPUs isoladas de um nó trabalhador:
Configure o Pod para uma qualidade de serviço (QoS) garantida.
Os requisitos e os limites da CPU têm de ser especificados em números inteiros. Se especificar recursos parciais da CPU na especificação do pod, como
cpu: 0.5
oucpu: 250m
(250 milicores), não é possível garantir o agendamento.
Requisitos de memória
Quando ajusta um nó com o operador de ajuste de desempenho, pode criar páginas grandes e associá-las aos nós de acesso à memória não uniforme (NUMA) na máquina. Com base nas definições de nós e pods, os pods podem ser agendados com afinidade de nós NUMA.
Crie um perfil de otimização do desempenho
Depois de instalar o Performance Tuning Operator, interage apenas com o cluster que executa as suas cargas de trabalho. Cria PerformanceTuningProfile
recursos personalizados diretamente
no cluster de utilizadores ou no cluster híbrido e 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 aos quais o perfil de otimização é aplicado. Para aplicar um perfil a um nó, coloca a etiqueta do par de chave-valor correspondente no nó. É aplicado um perfil de otimização aos nós que têm todas as etiquetas especificadas no campo nodeSelector
.
Pode criar vários recursos PerformanceTuningProfile
num cluster. Se mais do que um perfil corresponder a um determinado nó, é definida uma condição de erro no status
do recurso personalizado PerformanceTuningProfile
. Para mais
informações sobre a secção status
, consulte o artigo Verificar estado.
Defina o espaço de nomes do seu recurso personalizado como PerformanceTuningProfile
kube-system
.
Para otimizar um ou mais nós de trabalho:
Edite o
PerformanceTuningProfile
manifesto.Para ver informações sobre cada campo no manifesto e um manifesto de exemplo, consulte a
PerformanceTuningProfile
referência de recursos.(Opcional) Para os nós de trabalho aos quais está a aplicar um perfil, adicione etiquetas que correspondam ao par de chave-valor
spec.nodeSelector
.Se não for especificado nenhum par de chave-valor
spec.nodeSelector
no recurso personalizadoPerformanceTuningProfile
, o perfil é aplicado a todos os nós de trabalho.Aplique o manifesto ao seu cluster.
kubectl apply -f PROFILE_MANIFEST --kubeconfig KUBECONFIG
Substitua o seguinte:
PROFILE_MANIFEST
: o caminho do ficheiro do manifesto para o recursoPerformanceTuningProfile
personalizado.KUBECONFIG
: o caminho do ficheiro kubeconfig do cluster.
Remova um perfil de otimização
Para repor um nó para o estado original sem ajuste:
Elimine o recurso personalizado
PerformanceTuningProfile
do cluster.Atualize ou remova as etiquetas no nó para que não seja selecionado novamente pelo perfil de otimização.
Se tiver vários perfis de otimização associados ao nó, repita os passos anteriores, conforme necessário.
Pause um perfil de otimização
Se precisar de realizar manutenção no cluster, pode pausar temporariamente a otimização editando o recurso personalizado PerformanceTuningProfile
. Recomendamos que
pause a otimização antes de realizar operações de cluster críticas, como uma
atualização do cluster.
A aplicação de um perfil sem êxito é outro caso em que pode pausar a otimização. Se o processo de otimização não for bem-sucedido, o controlador pode continuar a tentar otimizar o nó, o que pode resultar no reinício repetido do nó. Se observar que o estado do nó alterna entre o estado pronto e não pronto, pause a otimização para poder recuperar do estado danificado.
Para pausar a otimização:
Edite o manifesto de recursos personalizados
PerformanceTuningProfile
para definirspec.paused
comotrue
.Use
kubectl apply
para atualizar o recurso.
Quando a otimização do desempenho está pausada, o controlador do operador de otimização do desempenho interrompe todas as respetivas operações. A pausa evita o risco de as operações do controlador do operador de otimização do desempenho entrarem em conflito com as operações do controlador do Google Distributed Cloud.
PerformanceTuningProfile
referência de recurso
Esta secção descreve cada um dos campos no recurso personalizado.PerformanceTuningProfile
Este recurso é usado para criar um perfil de otimização para um ou mais nós do cluster. Todos os campos no recurso são mutáveis após a criação do perfil. Os perfis têm de estar no espaço de nomes kube-system
.
O seguinte manifesto do perfil de exemplo numa
para nós com 8 núcleos de CPU
especifica as seguintes atribuições de recursos:
4 núcleos da CPU (
0-3
) estão reservados para a sobrecarga do sistema Kubernetes.4 núcleos de CPU (
4-7
) estão reservados apenas para cargas de trabalho.Por predefinição, a memória do nó é dividida em páginas de 2 MiB, em vez das páginas padrão de 4 KiB.
São reservadas 10 páginas de memória com um tamanho de 1 GiB para utilização pelo nó NUMA 0.
5 páginas de memória com um tamanho de 2 MiB são reservadas para utilização pelo nó NUMA 1.
O Topology Manager usa a política de melhor esforço para agendar 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
Pode obter a definição de recurso personalizado PerformanceTuningProfile
relacionada do grupo anthos.gke.io
no seu cluster. A definição do recurso personalizado é instalada assim que a anotação da funcionalidade de pré-visualização é adicionada ao recurso do cluster autogerido.
Configuração da CPU
Propriedade | Descrição |
---|---|
cpu.reservedCPUs |
Obrigatório. Mutável. String. Este campo define um conjunto de núcleos da CPU a reservar para os daemons do sistema Kubernetes, como o kubelet, o tempo de execução do contentor e o detetor de problemas do nó. Estes núcleos da CPU também são usados para os daemons do sistema operativo (SO), como o sshd e o udev .
O campo |
cpu.isolatedCPUs |
Opcional. Mutável. String. O campo cpu.isolatedCPUs define um conjunto de CPUs que são usadas exclusivamente para aplicações sensíveis ao desempenho. O CPU Manager agenda contentores 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 são executadas nas CPUs isoladas,
configure os pods com a classe de QoS garantida e
atribua um recurso de CPU ao pod ou ao contentor.
Para o agendamento de pods garantido, tem de especificar unidades de CPU inteiras e não
recursos de CPU parciais (cpu: "0.5" ).
apiVersion: v1 kind: Pod ... spec: containers: ... resources: limits: cpu: "1" requests: cpu: "1" ... A maximização das CPUs isoladas para cargas de trabalho oferece o melhor benefício de desempenho. Este campo aceita uma lista de números de CPU ou intervalos de números de CPU.
Certifique-se de que a lista de CPUs não se sobrepõe à lista especificada com
|
cpu.balanceIsolated |
Opcional. Mutável. Booleano. Predefinição: true . Este campo
especifica se o conjunto de CPUs isolado é elegível para o equilíbrio de carga automático
das cargas de trabalho nas CPUs. Quando define este campo como
false , as suas cargas de trabalho têm de atribuir cada thread explicitamente
a uma CPU específica para distribuir a carga pelas CPUs. Com as atribuições explícitas de CPU, obtém o desempenho mais previsível para cargas de trabalho garantidas, mas adiciona mais complexidade às suas cargas de trabalho. |
cpu.globallyEnableIRQLoadBalancing |
Obrigatório. Mutável. Booleano. Predefinição: true . Este campo
especifica se o balanceamento de carga do pedido de interrupção (IRQ) deve ser ativado ou não
para o conjunto de CPUs isolado. |
Configuração da memória
Propriedade | Descrição |
---|---|
defaultHugePageSize |
Opcional. Mutável. Enumeração: 1G ou 2M .
Este campo define o tamanho da página enorme predefinido nos parâmetros de arranque do kernel.
As páginas grandes são atribuídas no momento do arranque, antes de a memória ficar fragmentada.
É importante ter em atenção que a definição do tamanho predefinido das páginas enormes para 1G remove todas as pastas relacionadas com 2M do nó. Um tamanho de página enorme predefinido de 1 G impede a configuração de páginas enormes de 2 M no nó.
|
pages |
Opcional. Mutável. Número inteiro. Este campo especifica o número de páginas grandes a criar no momento do arranque. Este campo aceita uma matriz de páginas. Verifique a memória disponível para os seus nós antes de especificar páginas grandes. Não peça mais páginas grandes do que o necessário e não reserve toda a memória para páginas grandes. As suas cargas de trabalho também precisam de memória padrão. |
Seleção de nós
Propriedade | Descrição |
---|---|
nodeSelector |
Obrigatório. Mutável. Este campo requer sempre a etiqueta do nó trabalhador do Kubernetes, node-role.kubernetes.io/worker:"" , que garante que a otimização do desempenho é feita apenas nos nós trabalhadores. Este campo recebe uma etiqueta de nó opcional como um par de chave-valor. As etiquetas de pares de chave-valor são usadas para selecionar nós de trabalho específicos com etiquetas correspondentes. Quando as etiquetas nodeSelector correspondem às etiquetas num nó de trabalho, o perfil de desempenho é aplicado a esse nó. Se não especificar uma etiqueta de chave-valor no seu perfil, esta é aplicada a todos os nós de trabalho no cluster.
Por exemplo, o seguinte ... 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 . Predefinição: best-effort .
Este campo especifica a política do Topology Manager do Kubernetes usada para atribuir recursos aos seus 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 o artigo Configure a qualidade de serviço para pods.
|
Operações do perfil
Propriedade | Descrição |
---|---|
paused |
Opcional. Mutável. Booleano. Defina paused como
true para impedir temporariamente que os controladores DaemonSet ajustem os nós selecionados. |
updateStrategy |
Opcional. Mutável. Especifica a estratégia para aplicar alterações de configuração de otimização aos nós selecionados. |
updateStrategy.rollingUpdateMaxUnavailalble |
Opcional. Mutável. Número inteiro. Predefinição: 1 . Especifica o número máximo de nós que podem ser ajustados em simultâneo. Este campo
aplica-se apenas quando type está definido como rolling . |
updateStrategy.type |
Opcional. Mutável. Enumeração: batch ou rolling .
Predefinição: rolling . Especifica como aplicar atualizações de perfis
aos nós selecionados. Se quiser aplicar a atualização a todos os nós selecionados
em simultâneo, defina type como batch . Por predefinição,
as atualizações são implementadas sequencialmente em nós individuais, um após o outro. |
Verificar estado
Após a criação ou a atualização do recurso personalizado PerformanceTuningProfile
, um controlador ajusta os nós selecionados com base na configuração fornecida no recurso. Para verificar o estado do PerformanceTuningProfile
, estamos a expor o seguinte campo em Status
:
Propriedade | Descrição |
---|---|
conditions |
Condition representa as observações mais recentes disponíveis do estado atual do recurso de perfil. |
conditions.lastTransitionTime |
Sempre devolvido. String (no formato de data/hora). Última vez que a condição passou de um estado para outro. Normalmente, esta hora indica quando a condição subjacente foi alterada. Se essa hora não for conhecida, a hora indica quando o campo da API foi alterado. |
conditions.message |
Opcional. String. Uma mensagem legível que indica detalhes sobre a transição. Este campo pode estar vazio. |
conditions.observedGeneration |
Opcional. Número inteiro. Se estiver definido, este campo representa o metadata.generation
com base no qual a condição foi definida. Por exemplo, se metadata.generation
for 12 , mas status.condition[x].observedGeneration
for 9 , a condição está desatualizada relativamente ao estado atual
da instância. |
conditions.reason |
Obrigatório. String. O motivo da última transição de condição. |
conditions.status |
Obrigatório. Estado 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 aos quais o perfil de otimização foi aplicado com êxito. |
reconcilingNodes |
O número de nós selecionados (ou selecionados anteriormente) que estão em processo de conciliação com o perfil de otimização mais recente pelo DaemonSet nodeconfig-controller-manager . |
selectedNodes |
O número de notas que foram selecionadas. Ou seja, o número de nós que correspondem ao seletor de nós para este recurso personalizado PerformanceTuningProfile . |