Usando Scripts de Inicialização Cloud-init Personalizados para Configurar Nós Gerenciados

Descubra como gravar scripts cloud-init personalizados para execução em nós de trabalho em clusters que você criou usando o Kubernetes Engine (OKE).

Cloud-init é o método padrão do setor para inicialização de instâncias em nuvem, sistemas de provisionamento para infraestrutura de nuvem privada e instalações bare-metal. Ele é suportado em todos os principais provedores de nuvem pública, incluindo o Oracle Cloud Infrastructure (consulte Dados do Usuário). O Cloud-init executa scripts para inicializar e configurar instâncias. Para obter mais informações sobre o cloud-init, consulte a documentação do cloud-init.

O Kubernetes Engine usa cloud-init para configurar as instâncias de computação que hospedam nós gerenciados. O Kubernetes Engine instala um script de inicialização padrão em cada instância que hospeda um nó gerenciado. Quando a instância é inicializada pela primeira vez, o cloud-init executa o script de inicialização padrão. O script de inicialização padrão contém a seguinte lógica fornecida pelo Kubernetes Engine:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh

Você pode personalizar o script de inicialização padrão adicionando sua própria lógica ao script, antes ou depois da lógica padrão. A personalização do script de inicialização padrão permite que você, por exemplo:

  • configurar uma política SELinux em todos os hosts do nó de trabalho para fins de segurança e conformidade
  • cancelar a designação do IP público efêmero de uma instância na inicialização e, em vez disso, designar novamente à instância um IP público reservado
  • configurar um proxy corporativo
  • configurar proxies yum personalizados
  • instalar software antivírus obrigatório e outras ferramentas de segurança

Se você personalizar o script de inicialização padrão, não modifique a lógica fornecida pelo Kubernetes Engine.

Você pode personalizar o script de inicialização padrão ao criar um novo cluster, criar novos pools de nós e modificar pools de nós existentes:

  • usando a Console (ao criar um novo cluster, use o workflow 'Criação Personalizada')
  • usando a CLI
  • usando a API

O script de inicialização personalizado é executado quando uma instância que hospeda um nó de trabalho é inicializada pela primeira vez. Depois de personalizar o script de inicialização padrão, é uma boa ideia executar o script Node Doctor para confirmar se os nós de trabalho em instâncias recém-iniciadas estão funcionando conforme esperado (consulte Diagnosticando e Solucionando Problemas de Nó para Clusters do Kubernetes Usando o Script Node Doctor).

Exemplos de Casos de Uso para Scripts Cloud-init Personalizados

Exemplo 1: Usando um Script Cloud-init Personalizado para Configurar SELinux (Linux Aprimorado para Segurança) em Nós Gerenciados

Você pode usar um script cloud-init personalizado para configurar SELinux em nós gerenciados. SELinux é um aprimoramento de segurança para o Linux que permite aos administradores restringir quais usuários e aplicativos podem acessar quais recursos com base em regras em uma política. SELinux também adiciona granularidade mais fina aos controles de acesso.

SELinux pode estar em um dos dois estados, ativado ou desativado. Quando ele está ativado, SELinux pode ser executado em um dos dois modos, impondo ou permissivo.

Por padrão, SELinux é ativado e definido para ser executado no modo permissivo nos nós de trabalho. Quando executado no modo permissivo, SELinux não impõe regras de acesso e só executa o registro em log.

Se quiser que SELinux imponha regras de acesso, você poderá defini-lo para ser executado no modo de imposição. Ao executar no modo de imposição, SELinux bloqueia ações contrárias à política e registra um evento correspondente no log de auditoria.

Para definir SELinux para execução no modo de imposição, use o seguinte script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh
setenforce 1
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config 

Para confirmar o status e o modo de SELinux que está sendo executado em um nó de trabalho, conecte-se ao nó de trabalho e use o comando getenforce. Quando o script cloud-init acima tiver sido executado nos nós de trabalho, o comando getenforce retornará Enforcing.

Exemplo 2: Usando um Script Cloud-init Personalizado para Definir NodeLocal DNSCache em Nós Gerenciados

Você pode usar um script cloud-init personalizado para configurar NodeLocal DNSCache em nós gerenciados. NodeLocal DNSCache melhora o desempenho do Cluster DNS executando um agente de armazenamento em cache DNS nos nós de trabalho como um conjunto de daemons.

Se NodeLocal DNSCache não estiver ativado, os pods no modo DNS ClusterFirst entrarão em contato com um serviceIP kube-dns para consultas DNS. Usando regras do iptables, essa solicitação é convertida em um ponto final kube-dns/CoreDNS adicionado por kube-proxy. Para obter mais informações, consulte DNS para Serviços e Pods na documentação do Kubernetes.

Se NodeLocal DNSCache estiver ativado, os pods entrarão em contato com um agente de cache de DNS em execução no mesmo nó de trabalho, o que permite ignorar as regras DNAT do iptables e o rastreamento de conexão. O agente de armazenamento em cache local consulta o serviço kube-dns/CoreDNS quanto a ausências de cache dos nomes de host do cluster (sufixo cluster.local por padrão).

Para configurar NodeLocal DNSCache, use o script cloud-init a seguir. Substitua CLUSTER DNS por um endereço IP de listening local que não colida com nada no cluster. Há uma faixa local de link recomendada de 169.254.0.0/16 para IPv4 ou da faixa de Endereços Locais Exclusivos de fd00::/8 para IPv6.

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --cluster-dns "[CLUSTER DNS]"

Para confirmar se NodeLocal DNSCache foi implantado com sucesso, conecte-se a um nó de trabalho e use o comando sudo systemctl status -l kubelet. Quando o script cloud-init acima tiver sido executado nos nós de trabalho, o comando sudo systemctl status -l kubelet retornará --cluster-dns como um dos sinalizadores kubelet, definido como um endereço de link local padrão (por exemplo, 169.254.20.10).

Depois de criar nós usando o script cloud-init acima, implante o agente de armazenamento em cache do DNS seguindo as etapas em Usando NodeLocal DNSCache em clusters do Kubernetes na documentação do Kubernetes. Uma vez ativado, um pod node-local-dns é executado no namespace kube-system em cada um dos nós do cluster. O pod node-local-dns executa CoreDNS no modo de cache, portanto, todas as métricas CoreDNS expostas pelos diferentes plug-ins estão disponíveis por nó.

Para testar a resolução de DNS, use um ou mais dos comandos a seguir (consulte Depurando a Resolução de DNS na documentação do Kubernetes). Os comandos devem funcionar e também gerar o endereço IP definido pelo flag --cluster-dns no script cloud-init personalizado:

kubectl apply -f https://k8s.io/examples/admin/dns/dnsutils.yaml
kubectl exec -it dnsutils – nslookup kubernetes.default
kubectl exec -it dnsutils – cat /etc/resolv.conf

Você pode desativar NodeLocal DNSCache removendo o daemonset e excluindo o manifesto nodelocaldns. Você também deve reverter as alterações feitas na configuração do kubelet.

Exemplo 3: Usando um Script Cloud-init Personalizado para Definir kubelet-extra-args em Nós Gerenciados

Você pode usar um script cloud-init personalizado para configurar várias opções extras no kubelet (o agente do nó principal) nos nós gerenciados. Essas opções extras às vezes são chamadas de kubelet-extra-args. Uma dessas opções kubelet-extra-args é a opção para configurar o detalhamento do log no nível da depuração.

Para configurar o nível de detalhamento do log de depuração, use o seguinte script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --kubelet-extra-args "--v=4"

Para confirmar a definição da verbosidade do log no nível de depuração, conecte-se a um nó de trabalho e use o comando sudo systemctl status -l kubelet. Quando o script cloud-init acima tiver sido executado nos nós de trabalho, o comando sudo systemctl status -l kubelet retornará o nível de verbosidade como 4. Os logs do kubelet também contêm mais detalhes.

Exemplo 4: Usando um Script Cloud-init Personalizado para Reservar Recursos para Daemons do Sistema Kubernetes e SO

Você pode usar um script personalizado cloud-init para reservar recursos de CPU e memória para daemons do sistema Kubernetes (como kubelet e container runtime) e daemons do sistema operacional (como sshd e systemd). Para reservar recursos para OS daemons do sistema operacional e do Kubernetes, inclua OS sinalizadores kubelet --kube-reserved e --system-reserved, respectivamente, como opções kubelet-extra-args em um script personalizado cloud-init.

Para reservar recursos para OS daemons do sistema Kubernetes e SO, use o seguinte script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh --kubelet-extra-args "--kube-reserved=cpu=500m,memory=1Gi --system-reserved=cpu=100m,memory=100Mi"

Para obter mais informações e para valores recomendados para OS flags kubelet --kube-reserved e --system-reserved, consulte Melhores Práticas: Reservar recursos para daemons do sistema Kubernetes e SO.

Exemplo 5: Usando um Script Cloud-init Personalizado e oci-growfs para Aumentar o Tamanho da Partição do Volume de Inicialização

Você pode usar um script cloud-init personalizado para estender a partição para o volume de inicialização de nós gerenciados. Ao criar e atualizar clusters e pools de nós, você pode especificar um tamanho personalizado para volumes de inicialização do nó de trabalho. O tamanho do volume de inicialização personalizado especificado deve ser maior que o tamanho do volume de inicialização padrão da imagem selecionada. Quando você aumenta o tamanho do volume de inicialização, para aproveitar o tamanho do volume de inicialização maior, também é necessário estender a partição do volume de inicialização.

As imagens da plataforma Oracle Linux incluem o pacote oci-utils. Você pode usar o comando oci-growfs desse pacote em um script cloud-init para estender a partição raiz e, em seguida, aumentar o sistema de arquivos.

Para estender a partição do volume de inicialização, use o seguinte script cloud-init:

#!/bin/bash
curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
bash /var/run/oke-init.sh
bash /usr/libexec/oci-growfs -y

Para obter mais informações, consulte Estendendo a partição de um volume de inicialização.

Criando um Script Cloud-init Personalizado

Para personalizar o script de inicialização cloud-init padrão que o Kubernetes Engine fornece:

  1. Crie um novo arquivo de script contendo a lógica padrão fornecida pelo Kubernetes Engine. Isso pode ser feito de duas formas:
    • Selecionando a opção Fazer Download do Modelo de Script Cloud-Init Personalizado (na seção Opções Avançadas do pool de nós) ao usar a caixa de diálogo Criar Cluster Personalizado, Adicionar Pool de Nós ou Editar Pool de Nós. O arquivo baixado contém a lógica padrão.
    • Criando um novo arquivo do zero com um tipo de arquivo suportado pelo cloud-init (como .yaml) e adicionando a lógica padrão que o Kubernetes Engine fornece. Por exemplo:
      #!/bin/bash
      curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
      bash /var/run/oke-init.sh
  2. Antes ou depois da lógica padrão fornecida pelo Kubernetes Engine, adicione sua própria lógica personalizada ao arquivo de script. Não modifique a lógica padrão.

    Por exemplo, para configurar a verbosidade do log no nível de depuração, você pode adicionar --kubelet-extra-args "--v=4" para que o arquivo se pareça com:

    #!/bin/bash
    curl --fail -H "Authorization: Bearer Oracle" -L0 http://169.254.169.254/opc/v2/instance/metadata/oke_init_script | base64 --decode >/var/run/oke-init.sh
    bash /var/run/oke-init.sh --kubelet-extra-args "--v=4"

    Para obter outros exemplos, consulte Exemplo de Casos de Uso para Scripts Cloud-init Personalizados.

  3. Salve o arquivo de script cloud-init personalizado que você criou.
  4. Especifique o arquivo de script cloud-init personalizado ao criar um novo cluster, adicionar um novo pool de nós ou modificar um pool de nós existente:

Usando a Console

Para usar a Console para fornecer um script cloud-init personalizado para instâncias que hospedam nós gerenciados em um novo cluster, um novo pool de nós ou um pool de nós existente:

  1. Crie um arquivo cloud-init válido, em um dos formatos (por exemplo, cloud-config) e tipos de arquivos (por exemplo, um arquivo .yaml) suportados pelo cloud-init. Consulte Criando um Script Cloud-init Personalizado.
  2. Abra o menu de navegação e clique em Serviços ao Desenvolvedor. Em Contêineres e Artefatos, clique em Clusters do Kubernetes (OKE).
  3. Escolha um Compartimento no qual você tem permissão para trabalhar.
  4. Crie um novo cluster usando o workflow 'Criação Personalizada', adicione um novo pool de nós a um cluster existente ou modifique um pool de nós existente.
  5. Na seção Opções Avançadas do pool de nós da caixa de diálogo Criar Cluster Personalizado, Adicionar Pool de Nós ou Editar Pool de Nós (conforme apropriado), especifique:
    • Script de Inicialização: (Opcional) Um script para cloud-init ser executado em cada instância que hospeda nós de trabalho quando a instância é inicializada pela primeira vez. O script especificado deve ser gravado em um dos formatos suportados pelo cloud-init (por exemplo, cloud-config) e deve ser um tipo de arquivo suportado (por exemplo, .yaml). Especifique o script como segue:
      • Escolher Script Cloud-Init: Selecione um arquivo que contenha o script cloud-init ou arraste e solte o arquivo na caixa.
      • Colar Script Cloud-Init: Copie o conteúdo de um script cloud-init e cole-o na caixa.

      Se você ainda não tiver gravado scripts cloud-init para inicializar nós de trabalho em clusters criados pelo Kubernetes Engine, talvez seja útil clicar em Fazer Download do Modelo de Script Cloud-Init Personalizado. O arquivo baixado contém a lógica padrão fornecida pelo Kubernetes Engine. É possível adicionar sua própria lógica personalizada antes ou depois da lógica padrão, mas não modifique a lógica padrão. Para obter exemplos, consulte Exemplo de Casos de Uso para Scripts Cloud-init Personalizados.

Usando a CLI

Para obter informações sobre como usar a CLI, consulte Interface de Linha de Comando (CLI). Para obter uma lista completa de flags e opções disponíveis para comandos da CLI, consulte a Referência da Linha de Comando.

Para usar a CLI a fim de fornecer um script cloud-init personalizado para instâncias que hospedam nós de trabalho em um novo pool de nós ou em um pool de nós existente:

  1. Crie um arquivo cloud-init válido, em um dos formatos (por exemplo, cloud-config) e tipos de arquivos (por exemplo, um arquivo .yaml) suportados pelo cloud-init. Consulte Criando um Script Cloud-init Personalizado.
  2. Abra um prompt de comando e insira um dos seguintes comandos para criar um novo pool de nós ou atualizar um pool de nós existente, conforme apropriado:
    • oci ce node-pool create
    • oci ce node-pool update
  3. Assim como os parâmetros obrigatórios exigidos pelo comando que você está usando:
    1. Inclua o parâmetro --node-image-id, mesmo que você não queira especificar uma imagem personalizada.
    2. Inclua o parâmetro opcional --node-metadata no formato:
      --node-metadata '{"user_data": "'$(cat <cloud-init-file> | base64)'"}'
      em que:
      • <cloud-init-file> é o nome do arquivo cloud-init criado
      • base64 especifica que o arquivo deve ser codificado em base64

      Por exemplo:

      --node-metadata '{"user_data": "'$(cat my-custom-cloud-init.yaml | base64)'"}'

Exemplo

Este comando de exemplo cria um novo pool de nós chamado my-cloud-init-test-nodepool para um cluster existente, com um único nó do Kubernetes 1.18.10 que tem uma forma de VM 2.1 executando o Oracle Linux. Quando a instância que hospeda o nó de trabalho no novo pool de nós for inicializada pela primeira vez, ela executará um script cloud-init personalizado chamado my-custom-cloud-init.yaml:

oci ce node-pool create \
--cluster-id ocid1.cluster.oc1.iad.aaaa______m4w \
--name my-cloud-init-test-nodepool \
--node-image-id ocid1.image.oc1.iad.aaaa______zpq \
--compartment-id ocid1.tenancy.oc1..aaa______q4a \
--kubernetes-version v1.18.10 \
--node-shape VM.Standard2.1 \
--placement-configs "[   { \"availabilityDomain\": \"PKGK:US-ASHBURN-AD-1\", \"subnetId\": \"ocid1.subnet.oc1.iad.aaaa______kfa\"   }   ]" \
--size 1 \
--region us-ashburn-1 \
--node-metadata '{"user_data": "'$(cat my-custom-cloud-init.yaml | base64)'"}'