Use o ack-koordinator para priorizar a memória de contêineres sensíveis à latência e reduzir erros OOM durante contenção de recursos.
Antes de usar o QoS de memória, leia os seguintes tópicos na documentação do Kubernetes:
Pod Quality of Service Classes
e
Como funciona
O Kubernetes atribui a cada pod uma solicitação e um limite de memória. Sob pressão de memória, dois modos de falha podem ocorrer:
Pressão no nível do contêiner: Quando o uso de memória de um contêiner (incluindo page cache) se aproxima do limite, o sistema operacional aciona a recuperação direta no nível memcg e bloqueia processos. Se a alocação superar a recuperação, um erro OOM encerra o pod.
Pressão no nível do nó: Quando a soma dos limites de memória dos contêineres excede a memória física do nó, o kernel recupera memória entre os contêineres indiscriminadamente, degrada o desempenho e pode desencadear erros OOM.
O ack-koordinator resolve ambos os problemas ao configurar o grupo de controle de memória (memcg) por contêiner. Para isso, utiliza três recursos do kernel do Alibaba Cloud Linux (Alinux):
Memcg QoS: reserva uma quantidade mínima de memória para que contêineres de alta prioridade mantenham seu conjunto de trabalho.
Recuperação assíncrona de backend memcg: recupera memória proativamente antes que o limite seja atingido e evita o bloqueio da recuperação direta.
Classificação global de marca d'água mínima memcg: ajusta o limiar de recuperação por contêiner para que os contêineres sensíveis à latência (LS) sejam os últimos a ter memória recuperada.
Esses mecanismos resultam em uma distribuição de memória mais justa e menor latência durante cenários de overcommitment.
Vantagens sobre o QoS de memória do Kubernetes open-source
O recurso de QoS de memória nativo do Kubernetes (versão 1.22+) suporta apenas cgroup v2, exige configuração manual do kubelet e não oferece granularidade por pod ou namespace.
O ack-koordinator aprimora a implementação upstream de duas formas:
Maior compatibilidade de kernel: Suporta cgroup v1 e v2, com recursos do kernel Alinux como recuperação assíncrona de backend memcg e classificação de marca d'água mínima. Consulte Visão geral dos recursos e interfaces do kernel.
Configuração refinada: Permite configurar o QoS de memória por pod, namespace ou cluster por meio de anotações de pod ou ConfigMaps.
Mecanismo de configuração
O ack-koordinator utiliza quatro parâmetros de cgroup para o QoS de memória. Cada um corresponde às opções de configuração descritas em Parâmetros avançados:
|
Parâmetro de cgroup |
Função |
Configurado por |
|
|
Limite superior rígido para o contêiner |
Kubernetes (de |
|
|
Limiar de limitação — a recuperação começa aqui |
|
|
|
Gatilho de recuperação assíncrona |
|
|
|
Base de memória irrecuperável |
|
Prioridade de configuração
Quando múltiplas fontes de configuração se aplicam ao mesmo pod, o ack-koordinator segue esta ordem de prioridade (da maior para a menor):
Anotação do pod (
koordinator.sh/memoryQOS)ConfigMap no nível de namespace (
ack-slo-pod-config)ConfigMap no nível de cluster (
ack-slo-config)
Mapeamento de classes de QoS
Caso um pod não possua o rótulo koordinator.sh/qosClass, o ack-koordinator mapeia automaticamente as classes de QoS do Kubernetes:
|
Classe de QoS do Kubernetes |
Classe de QoS do koordinator |
|
Guaranteed |
Configurações padrão de QoS de memória |
|
Burstable |
LS (sensível à latência) |
|
BestEffort |
BE (melhor esforço) |
Pré-requisitos
Antes de começar, verifique se você possui:
Um cluster ACK executando Kubernetes 1.18 ou superior. Consulte Atualizar clusters ACK manualmente.
Alinux como sistema operacional dos nós. Alguns parâmetros avançados dependem de recursos do kernel Alinux. Consulte Parâmetros avançados.
ack-koordinator 0.8.0 ou superior instalado. Consulte ack-koordinator.
Ativar QoS de memória para um pod específico
Adicione a seguinte anotação à especificação do pod:
annotations:
# Enable memory QoS with recommended settings
koordinator.sh/memoryQOS: '{"policy": "auto"}'
# Disable memory QoS
# koordinator.sh/memoryQOS: '{"policy": "none"}'
Ativar QoS de memória para um cluster
Use o ConfigMap ack-slo-config para aplicar o QoS de memória a todos os pods do cluster.
-
Crie o arquivo
configmap.yamlcom o seguinte conteúdo:apiVersion: v1 kind: ConfigMap metadata: name: ack-slo-config namespace: kube-system data: resource-qos-config: |- { "clusterStrategy": { "lsClass": { "memoryQOS": { "enable": true } }, "beClass": { "memoryQOS": { "enable": true } } } } -
Defina a classe de QoS de cada pod com o rótulo
koordinator.sh/qosClass:apiVersion: v1 kind: Pod metadata: name: pod-demo labels: koordinator.sh/qosClass: 'LS' -
Aplique o ConfigMap:
Se o
ack-slo-configjá existir no namespacekube-system, atualize-o para preservar outras configurações: ``bash kubectl patch cm -n kube-system ack-slo-config --patch "$(cat configmap.yaml)"``Caso não exista, crie-o: ``
bash kubectl apply -f configmap.yaml``
(Opcional) Configure os parâmetros avançados.
Ativar QoS de memória para um namespace
Use o ConfigMap ack-slo-pod-config para ativar ou desativar o QoS de memória em pods de namespaces específicos.
-
Crie o arquivo
ack-slo-pod-config.yamlcom o seguinte conteúdo:apiVersion: v1 kind: ConfigMap metadata: name: ack-slo-pod-config namespace: kube-system data: memory-qos: | { "enabledNamespaces": ["allow-ns"], "disabledNamespaces": ["block-ns"] }Substitua
allow-nseblock-nspelos nomes reais dos namespaces. -
Aplique o ConfigMap:
kubectl patch cm -n kube-system ack-slo-pod-config --patch "$(cat ack-slo-pod-config.yaml)" (Opcional) Configure os parâmetros avançados.
Exemplo: Redis sob overcommitment de memória
Este exemplo demonstra como o QoS de memória reduz a latência do Redis e aumenta o throughput em cenários de overcommitment de memória. O teste utiliza:
Um cluster ACK Pro com dois nós (8 vCPUs e 32 GB cada)
Um nó dedicado ao Redis e outro para o teste de estresse
Executar o teste
-
Crie o arquivo
redis-demo.yaml:apiVersion: v1 kind: ConfigMap metadata: name: redis-demo-config data: redis-config: | appendonly yes appendfsync no --- apiVersion: v1 kind: Pod metadata: name: redis-demo labels: koordinator.sh/qosClass: 'LS' annotations: koordinator.sh/memoryQOS: '{"policy": "auto"}' spec: containers: - name: redis image: redis:5.0.4 command: - redis-server - "/redis-master/redis.conf" env: - name: MASTER value: "true" ports: - containerPort: 6379 resources: limits: cpu: "2" memory: "6Gi" requests: cpu: "2" memory: "2Gi" volumeMounts: - mountPath: /redis-master-data name: data - mountPath: /redis-master name: config volumes: - name: data emptyDir: {} - name: config configMap: name: redis-demo-config items: - key: redis-config path: redis.conf nodeName: # Set to the name of the node running Redis. --- apiVersion: v1 kind: Service metadata: name: redis-demo spec: ports: - name: redis-port port: 6379 protocol: TCP targetPort: 6379 selector: name: redis-demo type: ClusterIP -
Implante o Redis:
kubectl apply -f redis-demo.yaml -
Simule o overcommitment de memória com a ferramenta Stress. Crie o arquivo
stress-demo.yaml:apiVersion: v1 kind: Pod metadata: name: stress-demo labels: koordinator.sh/qosClass: 'BE' annotations: koordinator.sh/memoryQOS: '{"policy": "auto"}' spec: containers: - args: - '--vm' - '2' - '--vm-bytes' - 11G - '-c' - '2' - '--vm-hang' - '2' command: - stress image: polinux/stress imagePullPolicy: Always name: stress restartPolicy: Always nodeName: # Set to the same node as redis-demo. -
Implante a carga de trabalho de estresse:
kubectl apply -f stress-demo.yaml -
Verifique a marca d'água mínima global antes de executar o benchmark.
ImportanteEm cenários de overcommitment de memória, uma marca d'água mínima global baixa faz com que o OOM killer seja acionado antes da recuperação de memória. Para um nó de 32 GB, defina este valor como pelo menos 4.000.000 KB.
cat /proc/sys/vm/min_free_kbytesSaída esperada:
4000000 -
Implante o memtier-benchmark para enviar requisições ao pod do Redis:
apiVersion: v1 kind: Pod metadata: labels: name: memtier-demo name: memtier-demo spec: containers: - command: - memtier_benchmark - '-s' - 'redis-demo' - '--data-size' - '200000' - "--ratio" - "1:4" image: 'redislabs/memtier_benchmark:1.3.0' name: memtier restartPolicy: Never nodeName: # Set to the name of the node sending requests. -
Verifique os resultados do benchmark:
kubectl logs -f memtier-demo -
Para comparação, desative o QoS de memória em ambos os pods e repita o teste:
apiVersion: v1 kind: Pod metadata: name: redis-demo labels: koordinator.sh/qosClass: 'LS' annotations: koordinator.sh/memoryQOS: '{"policy": "none"}' spec: ... --- apiVersion: v1 kind: Pod metadata: name: stress-demo labels: koordinator.sh/qosClass: 'BE' annotations: koordinator.sh/memoryQOS: '{"policy": "none"}'
Resultados do teste
Os resultados servem apenas como referência. Os valores reais dependem da configuração do cluster e da carga de trabalho.
|
Métrica |
QoS de memória desativado |
QoS de memória ativado |
|
|
51,32 ms |
47,25 ms |
|
|
149,0 MB/s |
161,9 MB/s |
A ativação do QoS de memória reduziu a latência do Redis em 7,9% e aumentou o throughput em 8,7% sob condições de overcommitment de memória.
Parâmetros avançados
Configure estes parâmetros nas anotações do pod ou no ConfigMap ack-slo-config. As anotações do pod têm precedência.
As colunas
Anotação
e
ConfigMap
indicam se o parâmetro é configurável por meio de anotações e do ConfigMap.
![]()
indica suportado e
![]()
indica não suportado.
<table> <thead> <tr> <td><p><b>Parâmetro</b></p></td> <td><p><b>Tipo</b></p></td> <td><p><b>Faixa de valores</b></p></td> <td><p><b>Descrição</b></p></td> <td><p><b>Anotação do pod</b></p></td> <td><p><b>ConfigMap</b></p></td> </tr> </thead> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <colgroup></colgroup> <tbody> <tr> <td><p><code>enable</code></p></td> <td><p>Boolean</p></td> <td> <ul> <li><p><code>true</code></p></li> <li><p><code>false</code></p></li> </ul></td> <td> <ul> <li><p><code>true</code>: ativa o QoS de memória para todos os contêineres com as configurações recomendadas de memcg.</p></li> <li><p><code>false</code>: desativa o QoS de memória para todos os contêineres e restaura as configurações padrão de memcg.</p></li> </ul></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>policy</code></p></td> <td><p>String</p></td> <td> <ul> <li><p><code>auto</code></p></li> <li><p><code>default</code></p></li> <li><p><code>none</code></p></li> </ul></td> <td> <ul> <li><p><code>auto</code>: ativa o QoS de memória com configurações recomendadas e substitui o ConfigMap ack-slo-pod-config.</p></li> <li><p><code>default</code>: herda as configurações do ConfigMap ack-slo-pod-config.</p></li> <li><p><code>none</code>: desativa o QoS de memória, restaura as configurações padrão de memcg e substitui o ConfigMap ack-slo-pod-config.</p></li> </ul></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>minLimitPercent</code></p></td> <td><p>Int</p></td> <td><p>0\~100</p></td> <td><p>Unidade: %. Valor padrão: <code>0</code> (desativado). </p><p>Proporção irrecuperável da solicitação de memória do pod. Use este parâmetro para armazenar arquivos em cache para aplicações sensíveis a page-cache. Consulte <a href="https://www.alibabacloud.com/help/en/document_detail/169536.html#concept-2482889">Recurso Memcg QoS da interface cgroup v1</a>. </p><p>Fórmula: <code>Valor de memory.min = Solicitação de memória × Valor de minLimitPercent/100</code>. Por exemplo, com <code>Solicitação de memória=100MiB</code> e <code>minLimitPercent=100</code>, <code>o valor de memory.min é 104857600</code>. </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>lowLimitPercent</code></p></td> <td><p>Int</p></td> <td><p>0\~100</p></td> <td><p>Unidade: %. Valor padrão: <code>0</code> (desativado). </p><p>Proporção relativamente irrecuperável da solicitação de memória do pod. Consulte <a href="https://www.alibabacloud.com/help/en/document_detail/169536.html#concept-2482889">Recurso Memcg QoS da interface cgroup v1</a>. </p><p>Fórmula: <span><code>Valor de memory.low = Solicitação de memória × Valor de lowLimitPercent/100</code></span>. Por exemplo, com <span><code>Solicitação de memória=100MiB</code></span> e <span><code>lowLimitPercent=100</code></span>, <span><code>o valor de memory.low é 104857600</code></span>. </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>throttlingPercent</code></p></td> <td><p>Int</p></td> <td><p>0\~100</p></td> <td><p>Unidade: %. Valor padrão: <code>0</code> (desativado). </p><p>Limiar de limitação de memória como uma razão entre o uso do contêiner e o limite. Quando excedido, a memória é recuperada. Previne OOM no nível de cgroup em cenários de overcommitment. Consulte <a href="https://www.alibabacloud.com/help/en/document_detail/169536.html#concept-2482889">Recurso Memcg QoS da interface cgroup v1</a>. </p><p>Fórmula: <code>Valor de memory.high = Limite de memória × Valor de throttlingPercent/100</code>. Por exemplo, com <code>Limite de memória=100MiB</code> e <code>throttlingPercent=80</code>, <code>o valor de memory.high é 83886080 (80 MiB)</code>. </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>wmarkRatio</code></p></td> <td><p>Int</p></td> <td><p>0\~100</p></td> <td><p>Unidade: %. Valor padrão: <code>95</code>. <code>0</code> desativa este parâmetro. Quando o uso excede o limiar, a recuperação assíncrona de backend memcg é acionada. </p><p>Limiar de recuperação assíncrona: razão entre uso e limite, ou uso e <code>memory.high</code>. Consulte <a href="https://www.alibabacloud.com/help/en/document_detail/169535.html#task-2487938">Recuperação assíncrona de backend memcg</a>. </p><p>Se throttlingPercent estiver desativado, a fórmula é: Valor de memory.wmark_high = Limite de memória × wmarkRatio/100. Se throttlingPercent estiver ativado, a fórmula é: <code>Valor de memory.wmark_high = Valor de memory.high × wmarkRatio/100</code>. Por exemplo, com <code>Limite de memória=100MiB</code> e <code>wmarkRatio=95,throttlingPercent=80</code>: <code>memory.high é 83886080 (80 MiB)</code>, <code>memory.wmark_ratio é 95</code> e <code>memory.wmark_high é 79691776 (76 MiB)</code>. </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> <tr> <td><p><code>wmarkMinAdj</code></p></td> <td><p>Int</p></td> <td><p>-25\~50</p></td> <td><p>Unidade: %. O valor padrão é <code>-25</code> para a classe de QoS <code>LS</code> e <code>50</code> para a classe de QoS <code>BE</code>. <code>0</code> desativa este parâmetro. </p><p>Ajusta a marca d'água mínima global por contêiner. Valores negativos adiam a recuperação; valores positivos a aceleram. Consulte <a href="https://www.alibabacloud.com/help/en/document_detail/169537.html#task-2492619">Classificação global de marca d'água mínima memcg</a>. </p><p>Por exemplo, um pod LS tem como padrão <code>memory.wmark_min_adj=-25</code>, o que diminui a marca d'água mínima em 25%. </p></td> <td><p><img></p></td> <td><p><img></p></td> </tr> </tbody> </table>
Perguntas frequentes
A configuração de QoS de memória do ack-slo-manager ainda é válida após a atualização para o ack-koordinator?
Sim. O ack-koordinator mantém compatibilidade retroativa com o protocolo baseado em anotações usado no ack-slo-manager 0.8.0 e versões anteriores:
alibabacloud.com/qosClass— define a classe de QoSalibabacloud.com/memoryQOS— configura o QoS de memória
A tabela a seguir mostra quais protocolos cada versão suporta:
|
Versão do componente |
Protocolo alibabacloud.com |
Protocolo koordinator.sh |
|
≥ 0.3.0 e < 0.8.0 |
✓ |
× |
|
≥ 0.8.0 |
✓ |
✓ |
O suporte ao protocolo alibabacloud.com foi encerrado em 30 de julho de 2023. Migre para o protocolo koordinator.sh.
Faturamento
Não há cobrança pela instalação ou uso do componente ack-koordinator. No entanto, custos podem ser aplicados nos seguintes casos:
Uso de recursos do nó: O ack-koordinator é um componente não gerenciado que executa nos nós de trabalho. Configure as solicitações de recursos para cada módulo durante a instalação.
Métricas do Prometheus: Se você ativar as métricas do Prometheus para o ack-koordinator e usar o Managed Service for Prometheus, as métricas serão cobradas como métricas personalizadas. Antes de ativar este recurso, revise as regras de faturamento do Managed Service for Prometheus. Para monitorar o uso, consulte Consultar a quantidade de dados observáveis e faturas.
Próximos passos
Visão geral dos recursos e interfaces do kernel — recursos de kernel necessários para o QoS de memória do ACK
Ativar QoS de CPU para contêineres — limite e evite recursos recuperados para proteger cargas de trabalho sensíveis à latência