Neste tutorial, você também aprenderá a combinar o kpt com outras soluções do Google, como o Config Sync e os blueprints de segurança do GKE Enterprise. Independentemente de você ser um desenvolvedor que trabalha com o Kubernetes ou um engenheiro de plataforma que gerencia uma plataforma baseada no Kubernetes, este tutorial permite que você aprenda a usar o kpt nos seus próprios fluxos de trabalho relacionados ao Kubernetes. Neste tutorial, presumimos que você esteja familiarizado com o Kubernetes e o Google Cloud.
A configuração declarativa da infraestrutura de nuvem é uma prática bem estabelecida no setor de TI. Ela traz uma grande abstração dos sistemas subjacentes. Essa abstração libera o trabalho de gerenciar detalhes e dependências de configuração de baixo nível. Portanto, a configuração declarativa tem uma vantagem em comparação com abordagens imperativas, como operações realizadas em interfaces gráficas e de linha de comando.
O modelo de recursos do Kubernetes (em inglês) tem influenciado na criação abordagens de configuração declarativas convencionais. Como a API Kubernetes é totalmente declarativa por natureza, você apenas informa ao Kubernetes o que quer, e não como conseguir o que quer. A API Kubernetes permite separar de maneira simples a configuração (desejada ou real) das operações na configuração (adição, remoção e modificação de objetos). Em outras palavras, no modelo de recurso do Kubernetes, a configuração é data e não código.
Essa separação de configurações e operações tem muitas vantagens: pessoas e sistemas automatizados podem entender e trabalhar na configuração, e o software que modifica a configuração é facilmente reutilizável. Essa separação também facilita a implementação de uma metodologia GitOps (conforme definido no tutorial Entrega contínua no estilo GitOps com o Cloud Build).
Neste tutorial, você conhecerá essa separação da declaração de configuração das operações de configuração usando o kpt. Neste tutorial, destacamos os seguintes recursos do kpt:
- Gerenciamento de pacotes: fazer o download e atualizar os pacotes de configuração do Kubernetes.
- Funções: executar partes de código arbitrárias para modificar ou validar as configurações.
- Pipeline de função: um conjunto de funções que o autor do pacote incluiu com o pacote.
- Gerenciamento de recursos: aplicar, atualizar e excluir os recursos que correspondem às suas configurações em um cluster do Kubernetes.
Objetivos
- Criar um cluster do Google Kubernetes Engine (GKE).
- Usar o kpt para fazer o download de um conjunto atual de configurações do Kubernetes.
- Use as funções kpt para personalizar as configurações.
- Aplicar a configuração ao cluster do GKE.
- Usar o kpt para receber algumas alterações upstream para a configuração.
- Usar o kpt em um cenário real para fortalecer seu cluster do GKE.
Custos
Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:
- Google Kubernetes Engine
Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços.
Antes de começar
- Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
-
No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.
-
Verifique se a cobrança está ativada para o seu projeto do Google Cloud.
-
No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.
-
Verifique se a cobrança está ativada para o seu projeto do Google Cloud.
-
No Console do Google Cloud, ative o Cloud Shell.
Na parte inferior do Console do Google Cloud, uma sessão do Cloud Shell é iniciada e exibe um prompt de linha de comando. O Cloud Shell é um ambiente shell com a CLI do Google Cloud já instalada e com valores já definidos para o projeto atual. A inicialização da sessão pode levar alguns segundos.
Configure o Cloud Shell para usar seu projeto:
gcloud config set project PROJECT_ID
-
No Cloud Shell, ative as APIs do Google Kubernetes Engine e do Cloud Source Repositories:
gcloud services enable container.googleapis.com \ sourcerepo.googleapis.com
Ao concluir o tutorial, exclua os recursos criados para evitar a continuidade do faturamento. Para mais detalhes, consulte Limpeza.
crie um cluster do GKE;
Nesta seção, você cria o cluster do GKE em que as configurações são implantadas mais adiante no tutorial.
No Cloud Shell, crie um cluster do GKE:
gcloud container clusters create kpt-tutorial \ --num-nodes=1 --machine-type=n1-standard-4 \ --zone=us-central1-a --enable-network-policy
Verifique se você tem acesso ao cluster. O comando a seguir retorna informações sobre o nó ou os nós que estão no cluster.
kubectl get nodes
Como aplicar um pacote kpt
Nesta seção, você usará o kpt para fazer o download de um conjunto de configurações, personalizá-las
e aplicá-las ao cluster criado na seção anterior.
O kpt
precisa ser instalado no ambiente do Cloud Shell. Se
não estiver, instale-o com os seguintes comandos:
No Cloud Shell, instale o kpt:
sudo apt update && sudo apt-get install google-cloud-sdk-kpt
Faça o download de um conjunto de configurações de exemplo. Para ver mais informações, consulte
kpt pkg get
.kpt pkg get https://github.com/GoogleContainerTools/kpt.git/package-examples/wordpress@v0.9
O comando anterior faz o download do pacote de amostra
wordpress
, que está disponível no repositório kpt do GitHub (em inglês), na versão marcada comv0.9
.Analise o conteúdo do pacote:
kpt pkg tree
.kpt pkg tree wordpress
A saída será assim:
Package "wordpress" ├── [Kptfile] Kptfile wordpress ├── [service.yaml] Service wordpress ├── deployment │ ├── [deployment.yaml] Deployment wordpress │ └── [volume.yaml] PersistentVolumeClaim wp-pv-claim └── Package "mysql" ├── [Kptfile] Kptfile mysql ├── [deployment.yaml] PersistentVolumeClaim mysql-pv-claim ├── [deployment.yaml] Deployment wordpress-mysql └── [deployment.yaml] Service wordpress-mysql
O pacote contém dois pacotes, um de nível superior
wordpress
e um subpacotewordpress/mysql
, ambos contêm um arquivo de metadadosKptfile
.Kptfile
é consumido apenas pelo kpt e tem dados sobre a origem, a personalização e a validação do pacote upstream.Atualizar o rótulo do pacote
O autor do pacote adicionou um pipeline de renderização que é frequentemente usado para transmitir as personalizações esperadas.
less wordpress/Kptfile
O conteúdo deve ser semelhante a isto:
apiVersion: kpt.dev/v1 kind: Kptfile metadata: name: wordpress upstream: type: git git: repo: https://github.com/GoogleContainerTools/kpt directory: /package-examples/wordpress ref: v0.9 updateStrategy: resource-merge upstreamLock: type: git git: repo: https://github.com/GoogleContainerTools/kpt directory: /package-examples/wordpress ref: package-examples/wordpress/v0.9 commit: b9ea0bca019dafa9f9f91fd428385597c708518c info: emails: - kpt-team@google.com description: This is an example wordpress package with mysql subpackage. pipeline: mutators: - image: gcr.io/kpt-fn/set-labels:v0.1 configMap: app: wordpress validators: - image: gcr.io/kpt-fn/kubeval:v0.3
Use seu editor favorito para alterar os parâmetros da função de definição de rótulo de
app: wordpress
paraapp: my-wordpress
.Edite a implantação
wordpress/mysql/deployment.yaml
do MySQL usando seu editor de código favorito para alterar a versão do MySQL. Além disso, para aumentar ainda mais a segurança, mude a variávelMYSQL_ROOT_PASSWORD
paraMYSQL_PASSWORD
e adicione as seguintes variáveis:MYSQL_USER
MYSQL_RANDOM_ROOT_PASSWORD
MYSQL_DATABASE
Antes:
[...] containers: - name: mysql image: mysql:5.6 ports: - name: mysql protocol: TCP containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password [...]
Depois:
[...] containers: - name: mysql image: mysql:8.0 ports: - name: mysql protocol: TCP containerPort: 3306 env: - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password - name: MYSQL_RANDOM_ROOT_PASSWORD value: '1' - name: MYSQL_USER value: wordpress - name: MYSQL_DATABASE value: wordpress [...]
Edite a implantação
wordpress/deployment/deployment.yaml
do WordPress usando seu editor de código favorito para alterar a versão do Wordpress e adicionar uma variávelWORDPRESS_DB_USER
.Antes:
[...] containers: - name: wordpress image: wordpress:6.1-apache ports: - name: wordpress protocol: TCP containerPort: 80 env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password [...]
Depois:
[...] containers: - name: wordpress image: wordpress:4.8-apache ports: - name: wordpress protocol: TCP containerPort: 80 env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password - name: WORDPRESS_DB_USER value: wordpress [...]
Ao contrário das ferramentas que operam apenas via parâmetros kpt, você pode editar arquivos no local usando um editor e ainda mesclar as atualizações upstream. É possível editar
deployment.yaml
diretamente sem precisar criar um patch ou uma função no pipeline.Anote a configuração com
sample-annotation: sample-value
.kpt fn eval wordpress --image gcr.io/kpt-fn/set-annotations:v0.1 \ -- sample-annotation=sample-value
A resposta será semelhante a esta:
[RUNNING] "gcr.io/kpt-fn/set-annotations:v0.1" [PASS] "gcr.io/kpt-fn/set-annotations:v0.1"
Para ver a nova anotação, é possível examinar qualquer valor de configuração, uma simples de se ver é
wordpress/service.yaml
Neste exemplo, fizemos uma personalização usando uma função de uma maneira que o autor do pacote não planejou. O kpt é compatível com a execução de funções declarativas e imperativas para permitir uma ampla variedade de cenários.
Se este pacote foi desenvolvido usando infraestrutura como código, precisamos acessar a origem do pacote e editar o código nela.
Execute o pipeline e valide as alterações usando o kubeval pelo kpt.
kpt fn render wordpress
O autor do pacote incluiu uma etapa de validação no pipeline:
... validators: - image: gcr.io/kpt-fn/kubeval:v0.3
A saída desse pipeline de renderização é assim:
Package "wordpress/mysql": [RUNNING] "gcr.io/kpt-fn/set-labels:v0.1" [PASS] "gcr.io/kpt-fn/set-labels:v0.1" in 1.3s Package "wordpress": [RUNNING] "gcr.io/kpt-fn/set-labels:v0.1" [PASS] "gcr.io/kpt-fn/set-labels:v0.1" in 1.3s [RUNNING] "gcr.io/kpt-fn/kubeval:v0.3" [PASS] "gcr.io/kpt-fn/kubeval:v0.3" in 3.7s Successfully executed 3 function(s) in 2 package(s).
Esta etapa é um exemplo dos benefícios do modelo de recursos do Kubernetes. Como as configurações são representadas nesse modelo conhecido, é possível usar as ferramentas atuais do Kubernetes, como o kubeval.
Examine as diferenças entre a versão local das configurações e a configuração upstream:
kpt pkg diff wordpress
Inicialize o pacote para implantação:
kpt live init wordpress
O comando anterior cria um inventário das configurações que estão no pacote. Entre outras coisas, o kpt usa o inventário para remover as configurações quando você as remove do pacote. Para mais informações, consulte estes tópicos
kpt live
.Crie um secret que contenha a senha do MySQL:
kubectl create secret generic mysql-pass --from-literal=password=foobar
Aplique as configurações ao cluster do GKE:
kpt live apply wordpress
A saída será assim:
installing inventory ResourceGroup CRD. inventory update started inventory update finished apply phase started service/wordpress apply successful service/wordpress-mysql apply successful deployment.apps/wordpress apply successful deployment.apps/wordpress-mysql apply successful persistentvolumeclaim/mysql-pv-claim apply successful persistentvolumeclaim/wp-pv-claim apply successful apply phase finished reconcile phase started service/wordpress reconcile successful service/wordpress-mysql reconcile successful deployment.apps/wordpress reconcile pending deployment.apps/wordpress-mysql reconcile pending persistentvolumeclaim/mysql-pv-claim reconcile pending persistentvolumeclaim/wp-pv-claim reconcile pending persistentvolumeclaim/wp-pv-claim reconcile successful persistentvolumeclaim/mysql-pv-claim reconcile successful deployment.apps/wordpress-mysql reconcile successful deployment.apps/wordpress reconcile successful reconcile phase finished inventory update started inventory update finished apply result: 6 attempted, 6 successful, 0 skipped, 0 failed reconcile result: 6 attempted, 6 successful, 0 skipped, 0 failed, 0 timed out
Aguarde alguns minutos e verifique se tudo está funcionando conforme o esperado:
kpt live status wordpress
A saída será assim:
inventory-88521939/deployment.apps/default/wordpress is Current: Deployment is available. Replicas: 1 inventory-88521939/persistentvolumeclaim/default/wp-pv-claim is Current: PVC is Bound inventory-88521939/service/default/wordpress-mysql is Current: Service is ready inventory-88521939/persistentvolumeclaim/default/mysql-pv-claim is Current: PVC is Bound inventory-88521939/deployment.apps/default/wordpress-mysql is Current: Deployment is available. Replicas: 1 inventory-88521939/service/default/wordpress is Current: Service is ready
Como atualizar o pacote local
Nesta seção, você atualizará a versão local do pacote com algumas alterações do pacote upstream.
Crie um repositório Git para suas configurações e configure seu e-mail e nome. Você precisa de um repositório Git local para atualizar o pacote. Substitua
YOUR_EMAIL
pelo seu endereço de e-mail eYOUR_NAME
pelo seu nome.cd wordpress/ git init -b main git config user.email "YOUR_EMAIL" git config user.name "YOUR_NAME"
Confirme as configurações:
git add . git commit -m "First version of Wordpress package" cd ..
Atualize seu pacote local. Nesta etapa, você extrai a versão
v0.10
do upstream.kpt pkg update wordpress@v0.10
Observe que as atualizações de upstream são aplicadas ao seu pacote local:
cd wordpress/ git diff
Nesse caso, a atualização alterou o volume de implantação do wordpress de 3Gi para 4Gi. Você também pode ver as alterações que você fez.
Confirme as mudanças:
git commit -am "Update to package version v0.10"
Aplique a nova versão do pacote:
kpt live apply .
Como remover um recurso e um pacote
Como o kpt rastreia os recursos criados, ele pode remover recursos do cluster quando você exclui recursos do pacote. Ele também pode remover um pacote do cluster completamente. Nesta seção, você removerá um recurso do pacote e, em seguida, o pacote.
Remova o arquivo
service.yaml
do pacote:git rm service.yaml git commit -m "Remove service"
Aplique a alteração e verifique se o kpt removeu o serviço do WordPress:
kpt live apply . kubectl get svc
Remova o restante do pacote do cluster e, em seguida, verifique se você não tem nada mais no cluster:
kpt live destroy . kubectl get deployment
Como usar o kpt para aumentar a proteção do GKE
O comando kpt live
não é a única maneira de aplicar um pacote a um
cluster do Kubernetes. Nesta seção, você usa o kpt com o
Config Sync
em um cenário básico, mas realista. A ferramenta Config Sync permite gerenciar sua
configuração de maneira centralizada, uniforme e declarativa para todos os clusters do
Kubernetes a partir de um repositório Git. O GKE Enterprise (que você usa
neste tutorial) inclui o
Config Sync.
Os
Blues de segurança do GKE Enterprise
fornecem várias configurações de segurança predefinidas para suas
cargas de trabalho baseadas no GKE Enterprise. Nesta seção, você usará o
blueprint
tráfego restrito
e o
diretório dele no repositório do GitHub (em inglês).
Use o kpt para fazer o download do pacote default-deny
. O pacote usa políticas de rede
do Kubernetes
para negar qualquer tráfego no cluster do GKE por padrão (exceto
na resolução de DNS). Para aplicar as configurações, você precisa confirmá-las
no repositório Git do Config Sync.
Instalar o Config Sync
Nesta seção, você criará o repositório Git que o Config Sync precisa e, em seguida, instalará o Config Sync no cluster do GKE.
No Cloud Shell, use o Cloud Source Repositories para criar um repositório Git para o Config Sync:
cd ~ gcloud source repos create config-management
Gere um par de chaves SSH para autenticação no repositório Git:
cd ~ ssh-keygen -t rsa -b 4096 -N '' \ -f cloud_source_repositories_key
Crie o secret do Kubernetes que contém a chave privada SSH para acessar o repositório Git:
kubectl create ns config-management-system && \ kubectl create secret generic git-creds \ --namespace=config-management-system \ --from-file=ssh=cloud_source_repositories_key
Exiba a chave pública e copie-a:
cat cloud_source_repositories_key.pub
Acessar o Cloud Source Repositories
Página Gerenciar chaves SSH.
Na caixa de diálogo Registrar chave SSH exibida, insira os seguintes valores:
- No campo Nome da chave, digite
config-management
. - No campo Chave, cole a chave pública.
- Clique em Registrar.
- No campo Nome da chave, digite
Clone o repositório do Git no Cloud Shell:
gcloud source repos clone config-management cd config-management git checkout -b main
Faça o download da ferramenta de linha de comando do Config Sync chamada
nomos
.nomos
precisa ser instalado no ambiente do Cloud Shell. Se não estiver, instale-o com os seguintes comandos:sudo apt update && sudo apt-get install google-cloud-sdk-nomos
Inicialize o repositório do Config Sync:
nomos init git add . git commit -m "Config Management directory structure" git push -u origin main
Implante o Config Sync Operator:
gsutil cp gs://config-management-release/released/latest/config-management-operator.yaml /tmp/config-management-operator.yaml kubectl apply -f /tmp/config-management-operator.yaml
Configure o Config Sync
Crie um recurso personalizado do ConfigManagement para configurar o Config Sync:
PROJECT=$(gcloud config get-value project) EMAIL=$(gcloud config get-value account) cat <<EOF > /tmp/config-management.yaml apiVersion: configmanagement.gke.io/v1 kind: ConfigManagement metadata: name: config-management spec: clusterName: kpt-tutorial git: syncRepo: ssh://${EMAIL}@source.developers.google.com:2022/p/${PROJECT}/r/config-management syncBranch: main secretType: ssh EOF kubectl -n config-management-system \ apply -f /tmp/config-management.yaml
Para mais opções de instalação, consulte a documentação de instalação do Config Sync.
No Cloud Shell, verifique se o Config Sync está funcionando corretamente:
nomos status --contexts=$(kubectl config current-context)
Esse comando retorna o status como
SYNCED
. O Config Sync pode levar algum tempo para ser inicializado. Se o status não for atualizado, aguarde alguns minutos e execute o comando novamente.
Aplique o blueprint de segurança do GKE Enterprise
Nesta seção, você usa o kpt para fazer o download do pacote default-deny
do
print de segurança de tráfego restrito do GKE Enterprise. Em seguida, use
o Config Sync para aplicar o pacote somente ao namespace default
.
Faça o download do pacote
default-deny
:cd ~ kpt pkg get https://github.com/GoogleCloudPlatform/anthos-security-blueprints.git/restricting-traffic/default-deny ./
É possível explorar o conteúdo do pacote: o arquivo
default-deny/Kptfile
contém os metadados do pacote, e o arquivodefault-deny/default-deny.yaml
contém uma NetworkPolicy do Kubernetes, que é a única configuração deste blueprint.Use o kpt para copiar o conteúdo do pacote no repositório do Config Sync e, em seguida, adicione rótulos para personalizá-lo:
kpt fn source default-deny/ | \ kpt fn eval - --image=gcr.io/kpt-fn/set-annotations:v0.1 -- \ anthos-security-blueprint=restricting-traffic | \ kpt fn sink ~/config-management/namespaces/default/
Como mostrado neste exemplo, é possível usar tubos para encadear comandos
kpt fn
. Ao encadear os comandoskpt fn
, você conseguirá ler configurações, modificá-las conforme necessário e gravar o resultado. Encadeie a quantidade de comandoskpt fn
que quiser.Crie o arquivo
namespace.yaml
no repositório do Config Sync:cat >> ~/config-management/namespaces/default/namespace.yaml <<EOF apiVersion: v1 kind: Namespace metadata: name: default EOF
O namespace
default
existe no cluster do GKE, mas o Config Sync não o gerencia. Ao criar o diretório e o arquivo nesta etapa, você fará o Config Sync gerenciar o namespace. Para aplicar o pacote a vários namespaces de uma só vez, crie um namespace abstrato.Verifique se as NetworkPolicies do Kubernetes foram gravadas no repositório do Config Sync e se estão anotadas com
anthos-security-blueprint: restricting-traffic
:cat config-management/namespaces/default/default-deny.yaml
A saída será assim:
kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: # kpt-merge: /default-deny name: default-deny annotations: internal.kpt.dev/upstream-identifier: 'networking.k8s.io|NetworkPolicy|default|default-deny' anthos-security-blueprint: restricting-traffic spec: policyTypes: - Ingress - Egress podSelector: {} egress: - to: - namespaceSelector: matchLabels: k8s-namespace: kube-system podSelector: matchExpressions: - key: k8s-app operator: In values: ["kube-dns", "node-local-dns"] ports: - protocol: TCP port: 53 - protocol: UDP port: 53
Confirme e envie as alterações:
cd ~/config-management/ git add namespaces/default/ git commit -m "Default deny" git push
Verifique se a nova política foi aplicada:
kubectl get networkpolicies
Se a nova política não estiver presente, aguarde alguns segundos e execute o comando novamente. O Config Sync atualiza as configurações a cada 15 segundos, por padrão. Se você precisar solucionar mais algum problema, execute o seguinte comando para ver informações sobre possíveis erros do Config Sync:
nomos status --contexts=$(kubectl config current-context)
Para testar a nova política, receba um shell em um pod em execução dentro do namespace
default
:kubectl -n default run -i --tty --rm test \ --image=busybox --restart=Never -- sh
Tente dar um ping no
8.8.8.8
e veja que ele não funciona, como esperado:ping -c 3 -W 1 8.8.8.8
A saída será assim:
PING 8.8.8.8 (8.8.8.8): 56 data bytes --- 8.8.8.8 ping statistics --- 3 packets transmitted, 0 packets received, 100% packet loss
Tente consultar o servidor da API Kubernetes e veja se ele não funciona, como esperado:
wget --timeout=3 https://${KUBERNETES_SERVICE_HOST}
A saída será assim:
Connecting to 10.3.240.1 (10.3.240.1:443) wget: download timed out
Saia do pod:
exit
Limpeza
Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.
Exclua o projeto
- No Console do Google Cloud, acesse a página Gerenciar recursos.
- Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
- Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.
Excluir os recursos
Se você quiser manter o projeto do Google Cloud usado neste tutorial, exclua o repositório Git e o cluster do GKE. No Cloud Shell, execute os seguintes comandos:
gcloud source repos delete config-management --quiet
gcloud container clusters delete kpt-tutorial \
--async --quiet --zone=us-central1-a
A seguir
- Saiba mais sobre o Config Sync e os componentes dele.
- Saiba mais sobre o Policy Controller para validar a configuração de implantação do aplicativo.
- Confira arquiteturas de referência, diagramas, tutoriais e práticas recomendadas do Google Cloud. Confira o Centro de arquitetura do Cloud.