{"id":97982,"date":"2020-10-23T14:42:15","date_gmt":"2020-10-23T12:42:15","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/devyat-sovetov-po-povysheniyu-proizvoditelnosti-kubernetes"},"modified":"2020-11-18T00:58:47","modified_gmt":"2020-11-17T22:58:47","slug":"devyat-sovetov-po-povysheniyu-proizvoditelnosti-kubernetes","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/devyat-sovetov-po-povysheniyu-proizvoditelnosti-kubernetes","title":{"rendered":"Nove dicas para melhorar o desempenho do Kubernetes","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/92dc510aa9d785a31d310816b18bf854.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Ol\u00e1 a todos! Meu nome \u00e9 Oleg Sidorenkov, sou o l\u00edder da equipe de infraestrutura na empresa DomClick. J\u00e1 utilizamos o \"Cubo\" na produ\u00e7\u00e3o por mais de tr\u00eas anos, e ao longo desse tempo vivenciamos muitos momentos interessantes com ele. Hoje, vou contar como, com a abordagem correta, voc\u00ea pode extrair ainda mais desempenho do Kubernetes \"vanilla\" para o seu cluster. Pronto, vai! <\/p>\n<p>Todos voc\u00eas sabem que Kubernetes \u00e9 um sistema escal\u00e1vel de c\u00f3digo aberto para orquestra\u00e7\u00e3o de containers; ou melhor, 5 bin\u00e1rios que fazem m\u00e1gica ao gerenciar o ciclo de vida dos seus microsservi\u00e7os no ambiente de servidor. Al\u00e9m disso, \u00e9 uma ferramenta bastante flex\u00edvel, que pode ser montada como um brinquedo de Lego, para m\u00e1xima personaliza\u00e7\u00e3o para diferentes tarefas.<\/p>\n<p>E parece que est\u00e1 tudo bem: jogue servidores no cluster como lenha na lareira e n\u00e3o se preocupe. Mas se voc\u00ea se preocupa com o meio ambiente, vai pensar: \"Como posso manter o fogo na lareira e ainda preservar a floresta?\" Em outras palavras, como encontrar maneiras de melhorar a infraestrutura e reduzir custos.<\/p>\n<h2>1. Monitore os recursos das equipes e aplica\u00e7\u00f5es<\/h2>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/91e2e60b47ee985b024532c8b685230c.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Um dos m\u00e9todos mais simples, mas eficazes, \u00e9 a implementa\u00e7\u00e3o de requests\/limits. Separe as aplica\u00e7\u00f5es por namespaces e os namespaces pelas equipes de desenvolvimento. Defina os valores de consumo de tempo de CPU, mem\u00f3ria e armazenamento ef\u00eamero para cada aplica\u00e7\u00e3o antes do deployment.<\/p>\n<pre><code>resources:\n   requests:\n     memory: 2Gi\n     cpu: 250m\n   limits:\n     memory: 4Gi\n     cpu: 500m<\/code><\/pre>\n<p>Por experi\u00eancia, chegamos \u00e0 conclus\u00e3o de que n\u00e3o devemos inflacionar os requests em rela\u00e7\u00e3o aos limits em mais de duas vezes. O volume do cluster \u00e9 calculado com base nos requests, e se voc\u00ea definir para as aplica\u00e7\u00f5es uma diferen\u00e7a de recursos, por exemplo, de 5 a 10 vezes, imagine o que acontecer\u00e1 com o seu n\u00f3 quando ele estiver cheio de pods e de repente receber uma carga. Nada bom. No m\u00ednimo, throttling, e no m\u00e1ximo, voc\u00ea dir\u00e1 adeus ao worker e enfrentar\u00e1 uma carga c\u00edclica nos outros n\u00f3s ap\u00f3s os pods come\u00e7arem a migrar.<\/p>\n<p>Al\u00e9m disso, com o <code>limitranges<\/code> voc\u00ea pode definir valores de recursos para o container no in\u00edcio \u2014 m\u00ednimos, m\u00e1ximos e padr\u00e3o:<\/p>\n<pre><code>\u279c  ~ kubectl describe limitranges --namespace ops\nNome:       limit-range\nNamespace:  ops\nTipo        Recurso           M\u00edn   M\u00e1x   Solicita\u00e7\u00e3o Padr\u00e3o  Limite Padr\u00e3o  Raz\u00e3o M\u00e1x Limite\/Solicita\u00e7\u00e3o\n----        --------           ---   ---   -------------------  -------------  -----------------------\nContainer   cpu                50m   10    100m                 100m           2\nContainer   ephemeral-storage  12Mi  8Gi   128Mi              4Gi            -\nContainer   memory             64Mi  40Gi  128Mi              128Mi          2<\/code><\/pre>\n<p>N\u00e3o se esque\u00e7a de limitar os recursos do namespace para que um \u00fanico time n\u00e3o consuma todos os recursos do cluster:<\/p>\n<pre><code>\u279c  ~ kubectl describe resourcequotas --namespace ops\nNome:                   resource-quota\nNamespace:              ops\nRecurso                Usado          Limitado\n--------                ----          ----\nlimits.cpu              77250m        80\nlimits.memory           124814367488  150Gi\npods                    31            45\nrequests.cpu            53850m        80\nrequests.memory         75613234944   150Gi\nservices                26            50\nservices.loadbalancers  0             0\nservices.nodeports      0             0<\/code><\/pre>\n<p>Como pode ser visto na descri\u00e7\u00e3o <code>resourcequotas<\/code>, se o time ops tentar implantar pods que consumir\u00e3o 10 cpu a mais, o agendador n\u00e3o permitir\u00e1 e retornar\u00e1 um erro:<\/p>\n<pre><code>Error creating: pods \"nginx-proxy-9967d8d78-nh4fs\" is forbidden: exceeded quota: resource-quota, requested: limits.cpu=5,requests.cpu=5, used: limits.cpu=77250m,requests.cpu=53850m, limited: limits.cpu=10,requests.cpu=10<\/code><\/pre>\n<p>Para resolver um problema como esse, voc\u00ea pode escrever uma ferramenta, como <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/pauljamm\/team-operator\">este<\/a><\/noindex>, que \u00e9 capaz de armazenar e commitar o estado dos recursos dos times.<\/p>\n<h2>2. Escolha um armazenamento de arquivos ideal<\/h2>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/c7f8bdbf5490acc9061695a6d608015e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Aqui gostaria de abordar o tema de volumes persistentes e subsistemas de disco nos n\u00f3s worker do Kubernetes. Espero que ningu\u00e9m esteja usando \"Kub\" em HDD em produ\u00e7\u00e3o, mas \u00e0s vezes mesmo um SSD comum j\u00e1 n\u00e3o \u00e9 suficiente. Enfrentamos um problema em que os logs estavam sobrecarregando o disco com opera\u00e7\u00f5es de entrada e sa\u00edda, e aqui as op\u00e7\u00f5es de solu\u00e7\u00e3o s\u00e3o limitadas: <\/p>\n<ul>\n<li>\n<p>Usar SSDs de alto desempenho ou migrar para NVMe (se voc\u00ea gerencia seu pr\u00f3prio hardware).<\/p>\n<\/li>\n<li>\n<p>Reduzir o n\u00edvel de log.<\/p>\n<\/li>\n<li>\n<p>Fazer um balanceamento \"inteligente\" dos pods que est\u00e3o sobrecarregando o disco (<code>podAntiAffinity<\/code>).<\/p>\n<\/li>\n<\/ul>\n<p>A captura acima mostra o que acontece com o nginx-ingress-controller no disco, quando o log de access_logs est\u00e1 ativo (~12 mil logs\/segundo). Essa situa\u00e7\u00e3o, certamente, pode levar \u00e0 degrada\u00e7\u00e3o de todos os aplicativos nesse n\u00f3.<\/p>\n<p>Quanto aos PVs, infelizmente, n\u00e3o experimentei todos <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/storage\/persistent-volumes\/#types-of-persistent-volumes\">os tipos<\/a><\/noindex> Volumes Persistentes. Utilize a melhor op\u00e7\u00e3o que se adapte a voc\u00ea. Historicamente, uma pequena parte dos servi\u00e7os necessita de volumes RWX, e h\u00e1 muito tempo usamos armazenamento NFS para essa finalidade. \u00c9 barato e... \u00e9 suficiente. Claro, j\u00e1 tivemos problemas com isso \u2014 por favor, me entenda, mas aprendemos a otimizar e agora j\u00e1 n\u00e3o temos mais dores de cabe\u00e7a. E, se poss\u00edvel, migre para o armazenamento de objetos S3.<\/p>\n<h2>3. Colete imagens otimizadas<\/h2>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/c25ce405d1eb4c01f031e18b0bfa4836.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>O ideal \u00e9 usar imagens otimizadas para cont\u00eaineres, para que o Kubernetes possa acess\u00e1-las mais rapidamente e execut\u00e1-las de forma mais eficiente.&nbsp;<\/p>\n<p>A otimiza\u00e7\u00e3o significa que as imagens:<\/p>\n<ul>\n<li>\n<p>cont\u00eam apenas um aplicativo ou executam apenas uma fun\u00e7\u00e3o;<\/p>\n<\/li>\n<li>\n<p>s\u00e3o de tamanho reduzido, pois imagens grandes t\u00eam pior desempenho na transmiss\u00e3o pela rede;<\/p>\n<\/li>\n<li>\n<p>t\u00eam endpoints para verificar a sa\u00fade e a prontid\u00e3o, permitindo que o Kubernetes tome medidas em caso de falhas;<\/p>\n<\/li>\n<li>\n<p>utilizam sistemas operacionais que s\u00e3o amig\u00e1veis a cont\u00eaineres (como Alpine ou CoreOS), que s\u00e3o mais resistentes a erros de configura\u00e7\u00e3o;<\/p>\n<\/li>\n<li>\n<p>aplicam montagens em v\u00e1rias etapas, permitindo que voc\u00ea fa\u00e7a implementa\u00e7\u00f5es apenas com aplicativos compilados, e n\u00e3o com o c\u00f3digo fonte associado.<\/p>\n<\/li>\n<\/ul>\n<p>Existem muitas ferramentas e servi\u00e7os que permitem verificar e otimizar imagens dinamicamente. \u00c9 crucial mant\u00ea-las sempre atualizadas e verificadas quanto \u00e0 seguran\u00e7a. Como resultado, voc\u00ea obter\u00e1: <\/p>\n<ol>\n<li>\n<p>Redu\u00e7\u00e3o da carga de rede em todo o cluster.<\/p>\n<\/li>\n<li>\n<p>Diminui\u00e7\u00e3o do tempo de inicializa\u00e7\u00e3o do cont\u00eainer.<\/p>\n<\/li>\n<li>\n<p>Menor volume em todo o seu registro Docker.<\/p>\n<\/li>\n<\/ol>\n<h2>4. Utilize o cache DNS<\/h2>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/9f4384462a77dc528d7911c56f684f2d.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Quando se trata de altas cargas, viver sem a otimiza\u00e7\u00e3o do sistema DNS do cluster \u00e9 bastante complicado. H\u00e1 muito tempo, os desenvolvedores do Kubernetes mantinham sua solu\u00e7\u00e3o kube-dns. Ela foi implementada por n\u00f3s, mas esse software n\u00e3o foi muito ajustado e n\u00e3o entregou a performance desejada, embora a tarefa parecesse simples. Depois surgiu o coredns, que adotamos e que funcionou bem, posteriormente tornando-se o servi\u00e7o DNS padr\u00e3o no K8s. Em um determinado momento, chegamos a 40 mil rps para o sistema DNS, e essa solu\u00e7\u00e3o tamb\u00e9m se tornou insuficiente. Mas, por sorte, surgiu o Nodelocaldns, tamb\u00e9m conhecido como cache local de n\u00f3, que \u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/administer-cluster\/nodelocaldns\/\">NodeLocal DNSCache<\/a><\/noindex>.<\/p>\n<p>Por que usamos isso? H\u00e1 um bug no n\u00facleo do Linux que, quando h\u00e1 m\u00faltiplas solicita\u00e7\u00f5es atrav\u00e9s do conntrack NAT por UDP, leva a uma condi\u00e7\u00e3o de corrida para grava\u00e7\u00f5es nas tabelas de conntrack, resultando na perda de parte do tr\u00e1fego atrav\u00e9s do NAT (cada acesso atrav\u00e9s do Service \u00e9 um NAT). O nodelocaldns resolve esse problema eliminando o NAT e atualizando a conex\u00e3o para TCP com os DNS upstream, al\u00e9m de caching local das solicita\u00e7\u00f5es DNS para upstreams (incluindo um pequeno cache negativo de 5 segundos).<\/p>\n<h2>5. Escale os pods horizontal e verticalmente de forma autom\u00e1tica<\/h2>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/3804a14685a55160fa7d9f3226eab1fa.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Voc\u00ea pode afirmar com confian\u00e7a que todos os seus microsservi\u00e7os est\u00e3o prontos para um aumento de carga de duas a tr\u00eas vezes? Como alocar recursos corretamente para suas aplica\u00e7\u00f5es? Manter alguns pods em execu\u00e7\u00e3o al\u00e9m da carga de trabalho pode ser excessivo, e manter na carga m\u00e1xima pode resultar em inatividade devido a um aumento repentino do tr\u00e1fego no servi\u00e7o. Servi\u00e7os como os de escalonamento autom\u00e1tico ajudam a encontrar o meio termo, como <noindex><a rel=\"nofollow\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/run-application\/horizontal-pod-autoscale\/\">Horizontal Pod Autoscaler<\/a><\/noindex> e <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes\/autoscaler\/tree\/master\/vertical-pod-autoscaler\">Vertical Pod Autoscaler<\/a><\/noindex>. <\/p>\n<p><strong>VPA<\/strong> permite aumentar automaticamente os requests\/limits dos seus cont\u00eaineres no pod com base no uso real. Como isso pode ser \u00fatil? Se voc\u00ea tiver pods que n\u00e3o podem ser escalonados horizontalmente por algum motivo (o que n\u00e3o \u00e9 muito confi\u00e1vel), pode tentar confiar ao VPA a altera\u00e7\u00e3o de seus recursos. Sua caracter\u00edstica est\u00e1 no sistema de recomenda\u00e7\u00f5es baseado em dados hist\u00f3ricos e atuais do metric-server, portanto, se voc\u00ea n\u00e3o quiser alterar automaticamente os requests\/limits, pode apenas monitorar os recursos recomendados para seus cont\u00eaineres e otimizar as configura\u00e7\u00f5es para economizar CPU e mem\u00f3ria no cluster. <\/p>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/3965950aa3315faa4bb3e3ff5bd61955.png\" style=\"display:block;margin: 0 auto;\" \/>A imagem foi retirada de https:\/\/levelup.gitconnected.com\/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231<\/p>\n<p>O agendador no Kubernetes sempre se baseia nos requests. Qualquer que seja o valor que voc\u00ea definir, o agendador procurar\u00e1 um n\u00f3 apropriado com base nisso. Os valores limits s\u00e3o necess\u00e1rios para o kubelet entender quando restringir ou matar o pod. E como o \u00fanico par\u00e2metro importante \u00e9 o valor dos requests, o VPA ir\u00e1 trabalhar com isso. Sempre que voc\u00ea define o escalonamento vertical da aplica\u00e7\u00e3o, voc\u00ea determina quais devem ser os requests. E o que acontecer\u00e1 com os limits? Esse par\u00e2metro tamb\u00e9m ser\u00e1 escalonado proporcionalmente.<\/p>\n<p>Por exemplo, aqui est\u00e3o as configura\u00e7\u00f5es comuns de um pod:<\/p>\n<pre><code>recursos:\n   solicita\u00e7\u00f5es:\n     mem\u00f3ria: 250Mi\n     cpu: 200m\n   limites:\n     mem\u00f3ria: 500Mi\n     cpu: 350m<\/code><\/pre>\n<p>O mecanismo de recomenda\u00e7\u00e3o determina que sua aplica\u00e7\u00e3o requer 300m de CPU e 500Mi para funcionar normalmente. Voc\u00ea receber\u00e1 essas configura\u00e7\u00f5es:<\/p>\n<pre><code>recursos:\n   solicita\u00e7\u00f5es:\n     mem\u00f3ria: 500Mi\n     cpu: 300m\n   limites:\n     mem\u00f3ria: 1000Mi\n     cpu: 525m<\/code><\/pre>\n<p>Como mencionado acima, esse \u00e9 um dimensionamento proporcional baseado na rela\u00e7\u00e3o requests\/limits no manifesto:<\/p>\n<ul>\n<li>\n<p>CPU: 200m \u2192 300m: rela\u00e7\u00e3o 1:1.75;<\/p>\n<\/li>\n<li>\n<p>Mem\u00f3ria: 250Mi \u2192 500Mi: rela\u00e7\u00e3o 1:2.<\/p>\n<\/li>\n<\/ul>\n<p>Quanto \u00e0s <strong>HPA<\/strong>, aqui o mecanismo de funcionamento \u00e9 mais claro. Valores limites de m\u00e9tricas, como CPU e mem\u00f3ria, s\u00e3o definidos, e se a m\u00e9dia de todas as r\u00e9plicas ultrapassar o limite, a aplica\u00e7\u00e3o \u00e9 dimensionada para +1 pod at\u00e9 que o valor caia abaixo do limite ou at\u00e9 que o n\u00famero m\u00e1ximo de r\u00e9plicas seja alcan\u00e7ado.<\/p>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/f7a3fa28177d66be925867e38f5bbed6.png\" style=\"display:block;margin: 0 auto;\" \/>A imagem foi retirada de https:\/\/levelup.gitconnected.com\/kubernetes-autoscaling-101-cluster-autoscaler-horizontal-pod-autoscaler-and-vertical-pod-2a441d9ad231<\/p>\n<p>Al\u00e9m das m\u00e9tricas padr\u00e3o, como CPU e mem\u00f3ria, voc\u00ea pode configurar limites para suas m\u00e9tricas personalizadas a partir do Prometheus e trabalhar com elas, se achar que isso \u00e9 a defini\u00e7\u00e3o mais precisa de quando escalar sua aplica\u00e7\u00e3o. Ap\u00f3s a estabiliza\u00e7\u00e3o da aplica\u00e7\u00e3o abaixo do limite de m\u00e9trica estabelecido, o HPA come\u00e7ar\u00e1 a escalar os pods para baixo at\u00e9 o n\u00famero m\u00ednimo de r\u00e9plicas ou at\u00e9 que a carga atenda ao limite especificado.<\/p>\n<h2>6. N\u00e3o se esque\u00e7a da Afinidade de N\u00f3 e da Afinidade de Pod<\/h2>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/e718191d9e8ff25fd3b2d65cba9b3b73.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Nem todos os n\u00f3s operam com o mesmo hardware, nem todos os pods precisam executar aplica\u00e7\u00f5es que exigem computa\u00e7\u00e3o intensa. O Kubernetes permite definir especializa\u00e7\u00e3o de n\u00f3s e pods usando <strong>Node Affinity<\/strong> e <strong>Pod Affinity<\/strong>.<\/p>\n<p>Se voc\u00ea tiver n\u00f3s adequados para opera\u00e7\u00f5es intensivas em computa\u00e7\u00e3o, \u00e9 melhor vincular as aplica\u00e7\u00f5es aos n\u00f3s apropriados para m\u00e1xima efici\u00eancia. Para isso, use <code>nodeSelector<\/code> com o r\u00f3tulo do n\u00f3.<\/p>\n<p>Suponha que voc\u00ea tenha dois n\u00f3s: um com <code>CPUType=HIGHFREQ<\/code> e um grande n\u00famero de n\u00facleos r\u00e1pidos, e outro com <code>MemoryType=HIGHMEMORY<\/code> um grande volume de mem\u00f3ria e maior desempenho. O mais simples \u00e9 atribuir o deployment do pod ao n\u00f3 <code>HIGHFREQ<\/code>, adicionando na se\u00e7\u00e3o <code>spec<\/code> o seguinte seletor:<\/p>\n<pre><code>\u2026\nnodeSelector:\n\tCPUType: HIGHFREQ<\/code><\/pre>\n<p>Uma maneira mais custosa e espec\u00edfica de fazer isso \u00e9 usar <code>nodeAffinity<\/code> no campo <code>afinidade<\/code> da se\u00e7\u00e3o <code>spec<\/code>. Existem duas op\u00e7\u00f5es:<\/p>\n<ul>\n<li>\n<p><code>requiredDuringSchedulingIgnoredDuringExecution<\/code>: configura\u00e7\u00e3o r\u00edgida (o scheduler ir\u00e1 implantar pods apenas em n\u00f3s espec\u00edficos (e em nenhum outro lugar));<\/p>\n<\/li>\n<li>\n<p><code>preferredDuringSchedulingIgnoredDuringExecution<\/code>: configura\u00e7\u00e3o suave (o planejador tentar\u00e1 implantar em n\u00f3s espec\u00edficos, e se n\u00e3o conseguir, tentar\u00e1 implantar no pr\u00f3ximo n\u00f3 dispon\u00edvel).<\/p>\n<\/li>\n<\/ul>\n<p>Voc\u00ea pode especificar uma certa sintaxe para controlar as etiquetas dos n\u00f3s, como <code>Em<\/code>, <code>N\u00e3oEm<\/code>, <code>Existe<\/code>, <code>N\u00e3oExiste<\/code>, <code>Gt<\/code> ou <code>Lt<\/code>. No entanto, lembre-se de que m\u00e9todos complexos em listas longas de etiquetas atrasar\u00e3o a tomada de decis\u00f5es em situa\u00e7\u00f5es cr\u00edticas. Em outras palavras, n\u00e3o complique.<\/p>\n<p>Como mencionado anteriormente, o Kubernetes permite especificar a vincula\u00e7\u00e3o dos pods atuais. Ou seja, voc\u00ea pode fazer com que certos pods trabalhem junto com outros pods na mesma zona de disponibilidade (relevante para nuvens) ou n\u00f3s.<\/p>\n<p>Em <code>podAffinity<\/code> campos <code>afinidade<\/code> da se\u00e7\u00e3o <code>spec<\/code> os mesmos campos est\u00e3o dispon\u00edveis que no caso de <code>nodeAffinity<\/code>: <code>requiredDuringSchedulingIgnoredDuringExecution<\/code><strong> <\/strong>e <code>preferredDuringSchedulingIgnoredDuringExecution<\/code>. A \u00fanica diferen\u00e7a \u00e9 que <code>matchExpressions<\/code> vincular\u00e1 os pods ao n\u00f3 onde j\u00e1 est\u00e1 sendo executado um pod com essa etiqueta.<\/p>\n<p>Al\u00e9m disso, o Kubernetes oferece o campo <code>podAntiAffinity<\/code>, que, ao contr\u00e1rio, n\u00e3o vincula o pod a um n\u00f3 com determinados pods.<\/p>\n<p>Quanto \u00e0s express\u00f5es <code>nodeAffinity<\/code> pode-se dar o mesmo conselho: busque manter a simplicidade e a l\u00f3gica das regras, n\u00e3o tente sobrecarregar a especifica\u00e7\u00e3o dos pods com um conjunto complicado de regras. \u00c9 muito f\u00e1cil criar uma regra que n\u00e3o corresponda \u00e0s condi\u00e7\u00f5es do cluster, criando uma carga extra no planejador e reduzindo o desempenho geral.<\/p>\n<h2>7. Taints &amp; Tolerations<\/h2>\n<p>H\u00e1 mais uma maneira de gerenciar o planejador. Se voc\u00ea tiver um grande cluster com centenas de n\u00f3s e milhares de microsservi\u00e7os, \u00e9 muito dif\u00edcil impedir que certos pods sejam alocados em certos n\u00f3s.<\/p>\n<p>Isso \u00e9 ajudado pelo mecanismo de taints \u2014 regras proibitivas. Por exemplo, em certos cen\u00e1rios, pode-se proibir determinados n\u00f3s de executar pods. Para aplicar um taint a um n\u00f3 espec\u00edfico, voc\u00ea precisa usar a op\u00e7\u00e3o <code>taint<\/code> no kubectl. Especifique a chave e o valor, e depois o taint como <code>NoSchedule<\/code> ou <code>NoExecute<\/code>:<\/p>\n<pre><code>$ kubectl taint nodes node10 node-role.kubernetes.io\/ingress=true:NoSchedule<\/code><\/pre>\n<p>Vale ressaltar tamb\u00e9m que o mecanismo de taint suporta tr\u00eas efeitos principais: <code>NoSchedule<\/code>, <code>NoExecute<\/code> e <code>PreferNoSchedule<\/code><strong>. <\/strong><\/p>\n<ul>\n<li>\n<p><code>NoSchedule<\/code><strong> <\/strong>significa que, enquanto n\u00e3o houver um registro correspondente na especifica\u00e7\u00e3o do pod <code>tolerations<\/code>, ele n\u00e3o poder\u00e1 ser implantado em um n\u00f3 (neste exemplo <code>node10<\/code>).<\/p>\n<\/li>\n<li>\n<p><code>PreferNoSchedule <\/code>\u2014 uma vers\u00e3o simplificada <code>NoSchedule<\/code>. Nesse caso, o planejador tentar\u00e1 n\u00e3o alocar pods que n\u00e3o possuam um registro correspondente <code>tolerations<\/code> no n\u00f3, mas isso n\u00e3o \u00e9 uma restri\u00e7\u00e3o r\u00edgida. Se n\u00e3o houver recursos no cluster, os pods come\u00e7ar\u00e3o a ser implantados nesse n\u00f3.<\/p>\n<\/li>\n<li>\n<p><code>NoExecute<\/code><strong> <\/strong>\u2014 este efeito inicia a evacua\u00e7\u00e3o imediata de pods que n\u00e3o t\u00eam um registro correspondente <code>tolerations<\/code>.<\/p>\n<\/li>\n<\/ul>\n<p>Curiosamente, esse comportamento pode ser anulado por meio do mecanismo de toler\u00e2ncias. Isso \u00e9 \u00fatil quando h\u00e1 um n\u00f3 \"proibido\" e voc\u00ea precisa implantar nele apenas servi\u00e7os de infraestrutura. Como fazer isso? Permitir apenas os pods para os quais h\u00e1 uma toler\u00e2ncia adequada.<\/p>\n<p>Veja como ficar\u00e1 a especifica\u00e7\u00e3o do pod:<\/p>\n<pre><code>spec:\n   tolerations:\n     - key: \"node-role.kubernetes.io\/ingress\"\n        operator: \"Equal\"\n        value: \"true\"\n        effect: \"NoSchedule\"<\/code><\/pre>\n<p>Isso n\u00e3o significa que, na pr\u00f3xima reinicializa\u00e7\u00e3o do pod, ele ser\u00e1 implantado exatamente nesse n\u00f3, isso n\u00e3o \u00e9 um mecanismo de Affinity de N\u00f3 e <code>nodeSelector<\/code>. Mas, combinando v\u00e1rios recursos, voc\u00ea pode obter uma configura\u00e7\u00e3o de agendador muito flex\u00edvel.<\/p>\n<h2>8. Configure a prioridade de implanta\u00e7\u00e3o dos pods<\/h2>\n<p>O fato de voc\u00ea ter configurado a vincula\u00e7\u00e3o dos pods aos n\u00f3s n\u00e3o significa que todos os pods devem ser tratados com a mesma prioridade. Por exemplo, voc\u00ea pode querer implantar certos pods antes dos outros.<\/p>\n<p>O Kubernetes oferece diferentes maneiras de configurar a prioridade dos pods (Prioridade e Preemp\u00e7\u00e3o de Pods). A configura\u00e7\u00e3o consiste em v\u00e1rias partes: do objeto <code>PriorityClass<\/code><strong> <\/strong>e da descri\u00e7\u00e3o do campo <code>priorityClassName<\/code><strong> <\/strong>na especifica\u00e7\u00e3o do pod. Vamos ver um exemplo:<\/p>\n<pre><code>apiVersion: scheduling.k8s.io\/v1\nkind: PriorityClass\nmetadata:\n  name: high-priority\nvalue: 99999\nglobalDefault: false\ndescription: \"Esta classe de prioridade deve ser usada apenas para pods muito importantes\"<\/code><\/pre>\n<p>Estamos criando <code>PriorityClass<\/code>, definindo um nome, uma descri\u00e7\u00e3o e um valor.<strong> <\/strong>Quanto maior <code>valor<\/code>, maior a prioridade. O valor pode ser qualquer n\u00famero inteiro de 32 bits, menor ou igual a 1 000 000 000. Valores mais altos s\u00e3o reservados para pods de sistema cr\u00edticos, que geralmente n\u00e3o podem ser preemptados.<strong> <\/strong>A preemp\u00e7\u00e3o s\u00f3 ocorrer\u00e1 se n\u00e3o houver lugar para o pod de alta prioridade ser implantado, ent\u00e3o parte dos pods de um determinado n\u00f3 ser\u00e1 evacuada. Se esse mecanismo for muito r\u00edgido para voc\u00ea, pode-se adicionar a op\u00e7\u00e3o <code>preemptionPolicy: Never<\/code>, e ent\u00e3o n\u00e3o haver\u00e1 preemp\u00e7\u00e3o, o pod ficar\u00e1 em primeiro na fila esperando que o agendador encontre recursos livres para ele.<\/p>\n<p>Em seguida, criamos um pod, especificando o nome <code>priorityClassName<\/code>:<\/p>\n<pre><code>apiVersion: v1\nkind: Pod\nmetadata:\n  name: static-web\n  labels:\n    role: myrole\n spec:\n  containers:\n    - name: web\n      image: nginx\n      ports:\n        - name: web\n          containerPort: 80\n          protocol: TCP\n  priorityClassName: high-priority\n          <\/code><\/pre>\n<p>\u00c9 poss\u00edvel criar quantas classes de prioridade forem necess\u00e1rias, embora seja recomend\u00e1vel n\u00e3o exagerar (por exemplo, limitar-se a prioridade baixa, m\u00e9dia e alta). <\/p>\n<p>Dessa forma, se necess\u00e1rio, voc\u00ea poder\u00e1 aumentar a efici\u00eancia da implanta\u00e7\u00e3o de servi\u00e7os cr\u00edticos, como nginx-ingress-controller, coredns etc.<\/p>\n<h2>9. Otimize o cluster ETCD<\/h2>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/f5917adfa943c789b6c784f43305851b.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>O ETCD pode ser considerado o c\u00e9rebro de todo o cluster. \u00c9 muito importante manter o funcionamento desse banco de dados em um alto n\u00edvel, uma vez que a velocidade das opera\u00e7\u00f5es no 'Kube' depende dele. Uma solu\u00e7\u00e3o padr\u00e3o e ao mesmo tempo razo\u00e1vel seria manter o cluster ETCD em nodos mestres, para ter a menor lat\u00eancia poss\u00edvel at\u00e9 kube-apiserver. Se n\u00e3o for poss\u00edvel, posicione o ETCD o mais perto poss\u00edvel, garantindo uma boa largura de banda entre os participantes. Al\u00e9m disso, preste aten\u00e7\u00e3o em quantos n\u00f3s do ETCD podem falhar sem prejudicar o cluster.<\/p>\n<p><img decoding=\"async\" alt=\"Nove dicas para melhorar o desempenho do Kubernetes\" src=\"\/wp-content\/uploads\/2020\/10\/cdd2c32eefed253c6ff774899c367ccc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Lembre-se de que um aumento excessivo no n\u00famero de participantes do cluster pode aumentar a toler\u00e2ncia a falhas em detrimento do desempenho; tudo deve ser equilibrado.<\/p>\n<p>Falando sobre a configura\u00e7\u00e3o do servi\u00e7o, as recomenda\u00e7\u00f5es s\u00e3o poucas:<\/p>\n<ol>\n<li>\n<p>Tenha um bom hardware, levando em conta o tamanho do cluster (voc\u00ea pode ler sobre isso <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/etcd-io\/etcd\/blob\/master\/Documentation\/op-guide\/hardware.md\">aqui<\/a><\/noindex>).<\/p>\n<\/li>\n<li>\n<p>Ajuste alguns par\u00e2metros, se voc\u00ea espalhou o cluster entre alguns DCs ou se sua rede e discos deixam a desejar (voc\u00ea pode ler sobre isso <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/etcd-io\/etcd\/blob\/master\/Documentation\/tuning.md\">aqui<\/a><\/noindex>).<\/p>\n<\/li>\n<\/ol>\n<h2>Conclus\u00e3o<\/h2>\n<p>Neste artigo, descrevemos pontos que nossa equipe tenta seguir. Essa n\u00e3o \u00e9 uma descri\u00e7\u00e3o passo a passo das a\u00e7\u00f5es, mas op\u00e7\u00f5es que podem ser \u00fateis para otimizar os custos overhead do cluster. \u00c9 claro que cada cluster \u00e9 \u00fanico, e as solu\u00e7\u00f5es de configura\u00e7\u00e3o podem variar bastante, portanto, seria interessante receber seu feedback: como voc\u00ea monitora seu cluster Kubernetes e como melhora seu desempenho. Compartilhe sua experi\u00eancia nos coment\u00e1rios, ser\u00e1 interessante conhec\u00ea-la. <\/p>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/520968\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u041e\u043b\u0435\u0433 \u0421\u0438\u0434\u043e\u0440\u0435\u043d\u043a\u043e\u0432, \u044f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438 \u0414\u043e\u043c\u041a\u043b\u0438\u043a \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u041c\u044b \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0438\u0440\u0443\u0435\u043c \u00ab\u041a\u0443\u0431\u0438\u043a\u00bb \u0432 \u043f\u0440\u043e\u0434\u0435 \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0440\u0451\u0445 \u043b\u0435\u0442, \u0438 \u0437\u0430 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u0436\u0438\u043b\u0438 \u0441 \u043d\u0438\u043c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u044f \u043f\u043e\u0432\u0435\u0434\u0430\u044e \u0432\u0430\u043c, \u043a\u0430\u043a \u043f\u0440\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0436\u0430\u0442\u044c \u0438\u0437 \u00ab\u0432\u0430\u043d\u0438\u043b\u044c\u043d\u043e\u0433\u043e\u00bb Kubernetes \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430. Ready steady [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":97983,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-97982","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/devyat-sovetov-po-povysheniyu-proizvoditelnosti-kubernetes\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0414\u0435\u0432\u044f\u0442\u044c \u0441\u043e\u0432\u0435\u0442\u043e\u0432 \u043f\u043e \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 Kubernetes | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/devyat-sovetov-po-povysheniyu-proizvoditelnosti-kubernetes\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-10-23T12:42:15+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-11-17T22:58:47+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Nove dicas para melhorar o desempenho do Kubernetes | ProHoster","description":"Ol\u00e1 a todos!","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/devyat-sovetov-po-povysheniyu-proizvoditelnosti-kubernetes","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0414\u0435\u0432\u044f\u0442\u044c \u0441\u043e\u0432\u0435\u0442\u043e\u0432 \u043f\u043e \u043f\u043e\u0432\u044b\u0448\u0435\u043d\u0438\u044e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 Kubernetes | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442!","og:url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/devyat-sovetov-po-povysheniyu-proizvoditelnosti-kubernetes","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-10-23T12:42:15+00:00","article:modified_time":"2020-11-17T22:58:47+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"97982","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 10:08:27","updated":"2022-09-30 17:30:03","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/97982","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=97982"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/97982\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media\/97983"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=97982"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=97982"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=97982"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}