Workshop do Anthos Service Mesh: guia do laboratório

1. WORKSHOP ALPHA

Link para o codelab do workshop: bit.ly/asm-workshop

2. Visão geral

Diagrama da arquitetura

9a033157f44308f3.png

Este workshop é uma experiência prática e imersiva que mostra como configurar serviços distribuídos globalmente no GCP em produção. As principais tecnologias usadas são o Google Kubernetes Engine (GKE) para computação e a malha de serviço do Istio para criar conectividade segura, observabilidade e ajuste da programação. Todas as práticas e ferramentas usadas neste workshop são as mesmas que você usaria em produção.

Tópicos

  • Módulo 0: introdução e configuração da plataforma
  • Introdução e arquitetura
  • Introdução à malha de serviço e ao Istio/ASM
  • Laboratório: configuração da infraestrutura: fluxo de trabalho do usuário
  • Intervalo
  • QnA
  • Módulo 1: instalar, proteger e monitorar aplicativos com o ASM
  • Modelo de repositório: explicação dos repositórios de infraestrutura e do Kubernetes
  • Laboratório: implantar um aplicativo de amostra
  • Serviços distribuídos e observabilidade
  • Almoço
  • Laboratório: capacidade de observação com o Stackdriver
  • QNA
  • Módulo 2: DevOps: implantações canário, política/RBAC
  • Descoberta de serviços e segurança/política de vários clusters
  • Laboratório: TLS mútuo
  • Implantações canário
  • Laboratório: implantações canário
  • Balanceamento de carga global de vários clusters seguro
  • Intervalo
  • Laboratório: política de autorização
  • QNA
  • Módulo 3: operações de infraestrutura: upgrades de plataforma
  • Elementos básicos de serviços distribuídos
  • Laboratório: escalonamento de infraestrutura
  • Próximas etapas

Apresentações

Os slides deste workshop estão disponíveis neste link:

Slides do workshop do ASM

Pré-requisitos

Os seguintes itens são necessários antes de prosseguir com este workshop:

  1. Um nó da organização do GCP
  2. Um ID da conta de faturamento. Seu usuário precisa ser um administrador de faturamento nessa conta.
  3. Papel do IAM de administrador da organização no nível da organização para seu usuário

3. Configuração da infraestrutura: fluxo de trabalho do administrador

Explicação do script do workshop de inicialização

Um script chamado bootstrap_workshop.sh é usado para configurar o ambiente inicial do workshop. Você pode usar esse script para configurar um único ambiente para você ou vários ambientes para vários usuários, caso esteja oferecendo este workshop como treinamento para várias pessoas.

O script do workshop de bootstrap requer o seguinte como entradas:

  • Nome da organização (por exemplo, yourcompany.com): é a organização em que você cria ambientes para o workshop.
  • ID de faturamento (por exemplo, 12345-12345-12345): usado para faturar todos os recursos usados durante o workshop.
  • Número do workshop (por exemplo, 01): um número de dois dígitos. Isso é usado caso você esteja fazendo vários workshops em um dia e queira acompanhar cada um separadamente. Os números do workshop também são usados para derivar IDs de projeto. Ter números de workshop separados facilita a garantia de que você vai receber IDs de projetos exclusivos a cada vez. Além do número do workshop, a data atual (formatada como YYMMDD) também é usada para IDs de projetos. A combinação de data e número do workshop fornece IDs de projeto exclusivos.
  • Número do usuário inicial (por exemplo, 1): significa o primeiro usuário do workshop. Por exemplo, se você quiser criar um workshop para 10 usuários, poderá ter um número de usuário inicial de 1 e um número de usuário final de 10.
  • Número do usuário final (por exemplo, 10): significa o último usuário no workshop. Por exemplo, se você quiser criar um workshop para 10 usuários, poderá ter um número de usuário inicial de 1 e um número de usuário final de 10. Se você estiver configurando um único ambiente (para você, por exemplo), defina o número de usuários inicial e final como o mesmo. Isso vai criar um único ambiente.
  • Bucket do GCS do administrador (por exemplo, my-gcs-bucket-name): um bucket do GCS é usado para armazenar informações relacionadas ao workshop. Essas informações são usadas pelo script cleanup_workshop.sh para excluir todos os recursos criados durante o script do workshop de bootstrap. Os administradores que criam workshops precisam ter permissões de leitura/gravação nesse bucket.

O script do workshop de bootstrap usa os valores fornecidos acima e atua como um script wrapper que chama o script setup-terraform-admin-project.sh. O script setup-terraform-admin-project.sh cria o ambiente do workshop para um único usuário.

Permissões de administrador necessárias para inicializar o workshop

Há dois tipos de usuários neste workshop. Um ADMIN_USER, que cria e exclui recursos para este workshop. O segundo é MY_USER, que realiza as etapas do workshop. MY_USER só tem acesso aos próprios recursos. ADMIN_USER tem acesso a todas as configurações de usuário. Se você estiver criando essa configuração para si mesmo, ADMIN_USER e MY_USER serão iguais. Se você for um instrutor criando este workshop para vários estudantes, seu ADMIN_USER e MY_USER serão diferentes.

As seguintes permissões no nível da organização são necessárias para o ADMIN_USER:

  • Proprietário: permissão de proprietário do projeto para todos os projetos na organização.
  • Administrador de pastas: capacidade de criar e excluir pastas na organização. Cada usuário recebe uma única pasta com todos os recursos dentro do projeto.
  • Administrador da organização
  • Criador de projetos: capacidade de criar projetos na organização.
  • Excluidor de projetos: capacidade de excluir projetos na organização.
  • Administrador do IAM do projeto: capacidade de criar regras do IAM em todos os projetos da organização.

Além disso, ADMIN_USER também precisa ser o administrador de faturamento do ID de faturamento usado no workshop.

Esquema e permissões do usuário que está fazendo o workshop

Se você planeja criar este workshop para usuários (além de você) na sua organização, siga um esquema específico de nomenclatura de usuário para MY_USERs. Durante o script bootstrap_workshop.sh, você fornece um número de usuário inicial e final. Esses números são usados para criar os seguintes nomes de usuário:

  • user<3 digit user number>@<organization_name>

Por exemplo, se você executar o script do workshop de bootstrap com o número de usuário inicial 1 e o número de usuário final 3, na sua organização chamada suaempresa.com.br, os ambientes do workshop para os seguintes usuários serão criados:

  • user001@yourcompany.com
  • user002@yourcompany.com
  • user003@yourcompany.com

Esses nomes de usuário recebem papéis de proprietário do projeto para os projetos específicos criados durante o script setup_terraform_admin_project.sh. É necessário seguir esse esquema de nomenclatura de usuário ao usar o script de bootstrap. Consulte como adicionar vários usuários de uma vez no GSuite.

Ferramentas necessárias para o workshop

Este workshop foi criado para ser inicializado no Cloud Shell. As seguintes ferramentas são necessárias para este workshop.

  • gcloud (ver >= 270)
  • kubectl
  • sed (funciona com sed no Cloud Shell/Linux e não no Mac OS)
  • git (verifique se você está atualizado)
  • sudo apt update
  • sudo apt install git
  • jq
  • envsubst
  • kustomize

Configurar o workshop para você (configuração de usuário único)

  1. Abra o Cloud Shell e execute todas as ações abaixo nele. Clique no link abaixo.

CLOUD SHELL

  1. Verifique se você fez login na gcloud com o usuário administrador pretendido.
gcloud config list
 
  1. Crie um WORKDIR e clone o repositório do workshop.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. Defina o nome da organização, o ID de faturamento, o número do workshop e um bucket do GCS de administrador para usar no workshop. Revise as permissões necessárias para configurar o workshop nas seções acima.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<ADMIN_BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. Execute o script bootstrap_workshop.sh. Est script leva alguns minutos para ser concluído.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --set-up-for-admin 
 

Depois que o script bootstrap_workshop.sh for concluído, uma pasta do GCP será criada para cada usuário na organização. Dentro da pasta, um projeto de administrador do Terraform é criado. O projeto de administrador do Terraform é usado para criar o restante dos recursos do GCP necessários para este workshop. Você ativa as APIs necessárias no projeto de administrador do Terraform. Você usa o Cloud Build para aplicar planos do Terraform e concede à conta de serviço do Cloud Build os papéis adequados do IAM para que ela possa criar recursos no GCP. Por fim, configure um back-end remoto em um bucket do Google Cloud Storage (GCS) para armazenar os estados do Terraform de todos os recursos do GCP.

Para ver as tarefas do Cloud Build no projeto de administrador do Terraform, você precisa do ID do projeto de administrador do Terraform. Ele é armazenado no arquivo vars/vars.sh no diretório asm. Esse diretório só será mantido se você estiver configurando o workshop para si mesmo como administrador.

  1. Execute o arquivo de variáveis para definir as variáveis de ambiente
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
source $WORKDIR/asm/vars/vars.sh 
 

Configurar um workshop para vários usuários (configuração para vários usuários)

  1. Abra o Cloud Shell e execute todas as ações abaixo nele. Clique no link abaixo.

CLOUD SHELL

  1. Verifique se você fez login na gcloud com o usuário administrador pretendido.
gcloud config list
 
  1. Crie um WORKDIR e clone o repositório do workshop.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. Defina o nome da organização, o ID de faturamento, o número do workshop, o número de usuários iniciais e finais e um bucket do GCS de administrador para usar no workshop. Revise as permissões necessárias para configurar o workshop nas seções acima.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export START_USER_NUMBER=<number for example 1>

export END_USER_NUMBER=<number greater or equal to START_USER_NUM>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. Execute o script bootstrap_workshop.sh. Est script leva alguns minutos para ser concluído.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --start-user-num ${START_USER_NUMBER} --end-user-num ${END_USER_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET}
 
  1. Extraia o arquivo workshop.txt do bucket do GCS do administrador para recuperar os IDs do projeto do Terraform.
export WORKSHOP_ID="$(date '+%y%m%d')-${WORKSHOP_NUMBER}"
gsutil cp gs://${ADMIN_STORAGE_BUCKET}/${ORGANIZATION_NAME}/${WORKSHOP_ID}/workshop.txt .
 

4. Configuração e preparação do laboratório

Escolha seu programa de laboratório

Os laboratórios deste workshop podem ser realizados de duas maneiras:

  • A maneira fácil e rápida de criar scripts interativos
  • A maneira de copiar e colar manualmente cada instrução

O método de scripts de faixa rápida permite executar um único script interativo para cada laboratório, que orienta você pelo laboratório executando automaticamente os comandos dele. Os comandos são executados em lotes com explicações concisas de cada etapa e o que elas realizam. Depois de cada lote, você vai receber uma solicitação para passar para o próximo lote de comandos. Assim, você pode fazer os laboratórios no seu ritmo. Os scripts de faixa rápida são idempotentes, ou seja, você pode executá-los várias vezes e ter o mesmo resultado.

Os scripts de acesso rápido vão aparecer na parte de cima de cada laboratório em uma caixa verde, conforme mostrado abaixo.

O método de copiar e colar é a maneira tradicional de copiar e colar blocos de comandos individuais com explicações. Esse método só pode ser executado uma vez. Não há garantia de que a nova execução de comandos nesse método vai gerar os mesmos resultados.

Ao fazer os laboratórios, escolha um dos dois métodos.

Configuração rápida de script

Receber informações do usuário

Este workshop é realizado usando uma conta de usuário temporária (ou uma conta de laboratório) criada pelo administrador do workshop. A conta do laboratório é proprietária de todos os projetos do workshop. O administrador do workshop fornece as credenciais da conta do laboratório (nome de usuário e senha) ao usuário que está fazendo o workshop. Todos os projetos do usuário têm o prefixo do nome de usuário da conta do laboratório. Por exemplo, para a conta do laboratório user001@yourcompany.com, o ID do projeto de administrador do Terraform seria user001-200131-01-tf-abcde, e assim por diante para o restante dos projetos. Cada usuário precisa fazer login com a conta do laboratório fornecida pelo administrador do workshop e realizar o workshop usando essa conta.

  1. Clique no link abaixo para abrir o Cloud Shell.

CLOUD SHELL

  1. Faça login com as credenciais da conta do laboratório (não faça login com sua conta corporativa ou pessoal). A conta de laboratório tem esta aparência: userXYZ@<workshop_domain>.com. 3101eca1fd3722bf.png
  2. Como esta é uma conta nova, você precisa aceitar os Termos de Serviço do Google. Clique em "Aceitar".

fb0219a89ece5168.png 4. Na próxima tela, marque a caixa de seleção para concordar com os Termos de Serviço do Google e clique em Start Cloud Shell.

7b198cf2e32cb457.png

Esta etapa provisiona uma pequena VM Linux Debian para você usar e acessar os recursos do GCP. Cada conta recebe uma VM do Cloud Shell. Fazer login com a conta do laboratório provisiona e faz login usando as credenciais dela. Além do Cloud Shell, um editor de código também é provisionado, facilitando a edição de arquivos de configuração (Terraform, YAML etc.). Por padrão, a tela do Cloud Shell é dividida entre o ambiente shell do Cloud Shell (na parte de baixo) e o editor do Cloud Code (na parte de cima). 5643bb4ebeafd00a.png Os ícones de lápis 8bca25ef1421c17e.png e de solicitação de shell eaeb4ac333783ba8.png no canto superior direito permitem alternar entre os dois (shell e editor de código). Você também pode arrastar a barra separadora do meio (para cima ou para baixo) e mudar o tamanho de cada janela manualmente. 5. Crie um WORKDIR para este workshop. O WORKDIR é uma pasta em que você realiza todos os laboratórios deste workshop. Execute os comandos a seguir no Cloud Shell para criar o WORKDIR.

mkdir -p ${HOME}/asm-workshop
cd ${HOME}/asm-workshop
export WORKDIR=`pwd` 
 
  1. Exporte o usuário da conta do laboratório como uma variável para usar neste workshop. É a mesma conta que você usou para fazer login no Cloud Shell.
export MY_USER=<LAB ACCOUNT EMAIL PROVIDED BY THE WORKSHOP ADMIN>
# For example export MY_USER=user001@gcpworkshops.com 
 
  1. Execute os comandos abaixo para mostrar as variáveis WORKDIR e MY_USER e garantir que ambas estejam definidas corretamente.
echo "WORKDIR set to ${WORKDIR}" && echo "MY_USER set to ${MY_USER}"
 
  1. Clone o repositório do workshop.
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git ${WORKDIR}/asm
 

5. Configuração da infraestrutura: fluxo de trabalho do usuário

Objetivo: verificar a infraestrutura e a instalação do Istio

  • Instalar ferramentas de workshop
  • Clonar o repositório do workshop
  • Verificar a instalação do Infrastructure
  • Verificar a instalação do k8s-repo
  • Verificar a instalação do Istio

Instruções do laboratório sobre o método de copiar e colar

Receber informações do usuário

O administrador que configura o workshop precisa fornecer as informações de nome de usuário e senha ao usuário. Todos os projetos do usuário terão o prefixo do nome de usuário. Por exemplo, para o usuário user001@yourcompany.com, o ID do projeto de administrador do Terraform seria user001-200131-01-tf-abcde, e assim por diante para o restante dos projetos. Cada usuário tem acesso apenas ao próprio ambiente de workshop.

Ferramentas necessárias para o workshop

Este workshop foi criado para ser inicializado no Cloud Shell. As seguintes ferramentas são necessárias para este workshop.

Acessar o projeto de administrador do Terraform

Depois que o script bootstrap_workshop.sh for concluído, uma pasta do GCP será criada para cada usuário na organização. Dentro da pasta, um projeto de administrador do Terraform é criado. O projeto de administrador do Terraform é usado para criar o restante dos recursos do GCP necessários para este workshop. O script setup-terraform-admin-project.sh ativa as APIs necessárias no projeto de administrador do Terraform. O Cloud Build é usado para aplicar planos do Terraform. Com o script, você concede à conta de serviço do Cloud Build os papéis adequados do IAM para que ela possa criar recursos no GCP. Por fim, um back-end remoto é configurado em um bucket do Google Cloud Storage (GCS) para armazenar os estados do Terraform de todos os recursos do GCP.

Para ver as tarefas do Cloud Build no projeto de administrador do Terraform, você precisa do ID do projeto de administrador do Terraform. Ele é armazenado no bucket do GCS de administrador especificado no script de inicialização. Se você executar o script de bootstrap para vários usuários, todos os IDs de projeto de administrador do Terraform estarão no bucket do GCS.

  1. Clique no link abaixo para abrir o Cloud Shell, caso ele ainda não esteja aberto na seção "Configuração e preparação do laboratório".

CLOUD SHELL

  1. Instale o kustomize (se ainda não estiver instalado) na pasta $HOME/bin e adicione a pasta $HOME/bin a $PATH.
mkdir -p $HOME/bin
cd $HOME/bin
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
cd $HOME
export PATH=$PATH:${HOME}/bin
echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
 
  1. Instale o pv e mova-o para $HOME/bin/pv.
sudo apt-get update && sudo apt-get -y install pv
sudo mv /usr/bin/pv ${HOME}/bin/pv
 
  1. Atualize o prompt do bash.
cp $WORKDIR/asm/scripts/krompt.bash $HOME/.krompt.bash
echo "export PATH=\$PATH:\$HOME/bin" >> $HOME/.asm-workshop.bash
echo "source $HOME/.krompt.bash" >> $HOME/.asm-workshop.bash

alias asm-init='source $HOME/.asm-workshop.bash' >> $HOME/.bashrc
echo "source $HOME/.asm-workshop.bash" >> $HOME/.bashrc
source $HOME/.bashrc
 
  1. Verifique se você fez login na gcloud com a conta de usuário desejada.
echo "Check logged in user output from the next command is $MY_USER"
gcloud config list account --format=json | jq -r .core.account
 
  1. Para receber o ID do projeto de administrador do Terraform, execute o seguinte comando:
export TF_ADMIN=$(gcloud projects list | grep tf- | awk '{ print $1 }')
echo $TF_ADMIN
 
  1. Todos os recursos associados ao workshop são armazenados como variáveis em um arquivo vars.sh em um bucket do GCS no projeto de administrador do Terraform. Extraia o arquivo vars.sh do seu projeto de administrador do Terraform.
mkdir $WORKDIR/asm/vars
gsutil cp gs://$TF_ADMIN/vars/vars.sh $WORKDIR/asm/vars/vars.sh
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
 
  1. Clique no link exibido para abrir a página do Cloud Build do projeto de administrador do Terraform e verifique se a build foi concluída com êxito.
source $WORKDIR/asm/vars/vars.sh
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

Se você estiver acessando o console do Cloud pela primeira vez, aceite os Termos de Serviço do Google.

  1. Agora que você está na página Cloud Build, clique no link History na navegação à esquerda e clique na versão mais recente para conferir os detalhes da aplicação inicial do Terraform. Os recursos a seguir são criados como parte do script do Terraform. Consulte também o diagrama de arquitetura acima.
  • 4 projetos do GCP na organização. A conta de faturamento fornecida está associada a cada projeto.
  • Um projeto é o network host project da VPC compartilhada. Nenhum outro recurso é criado neste projeto.
  • Um projeto é o ops project usado para clusters do GKE do plano de controle do Istio.
  • Dois projetos representam duas equipes de desenvolvimento diferentes trabalhando nos respectivos serviços.
  • Dois clusters do GKE são criados em cada um dos três projetos ops, dev1 e dev2.
  • Um repositório de CSR chamado k8s-repo é criado e contém seis pastas para arquivos de manifestos do Kubernetes. Uma pasta por cluster do GKE. Esse repositório é usado para implantar manifestos do Kubernetes nos clusters de maneira GitOps.
  • Um gatilho de build do Cloud Build é criado para que, sempre que houver um commit na ramificação principal do k8s-repo, ele implante os manifestos do Kubernetes nos clusters do GKE das respectivas pastas.
  1. Quando o build for concluído no terraform admin project, outro build será iniciado no projeto de operações. Clique no link exibido para abrir a página do Cloud Build para ops project e verifique se o Cloud Build do k8s-repo foi concluído com êxito.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 

Confirme a instalação

  1. Crie arquivos kubeconfig para todos os clusters. Execute o script a seguir.
$WORKDIR/asm/scripts/setup-gke-vars-kubeconfig.sh
 

Esse script cria um novo arquivo kubeconfig na pasta gke chamado kubemesh.

  1. Mude a variável KUBECONFIG para apontar para o novo arquivo kubeconfig.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. Adicione as variáveis vars.sh e KUBECONFIG ao .bashrc no Cloud Shell para que elas sejam usadas sempre que o Cloud Shell for reiniciado.
echo "source ${WORKDIR}/asm/vars/vars.sh" >> $HOME/.bashrc
echo "export KUBECONFIG=${WORKDIR}/asm/gke/kubemesh" >> $HOME/.bashrc
 
  1. Liste os contextos de cluster. Seis clusters vão aparecer.
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_tf05-01-ops_us-central1_gke-asm-2-r2-prod
gke_tf05-01-ops_us-west1_gke-asm-1-r1-prod
gke_tf05-02-dev1_us-west1-a_gke-1-apps-r1a-prod
gke_tf05-02-dev1_us-west1-b_gke-2-apps-r1b-prod
gke_tf05-03-dev2_us-central1-a_gke-3-apps-r2a-prod
gke_tf05-03-dev2_us-central1-b_gke-4-apps-r2b-prod

Verificar a instalação do Istio

  1. Verifique se o Istio está instalado nos dois clusters. Para isso, confira se todos os pods estão em execução e se os jobs foram concluídos.
kubectl --context ${OPS_GKE_1} get pods -n istio-system
kubectl --context ${OPS_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-z9f98                  1/1     Running   0          6m21s
istio-citadel-568747d88-qdw64             1/1     Running   0          6m26s
istio-egressgateway-8f454cf58-ckw7n       1/1     Running   0          6m25s
istio-galley-6b9495645d-m996v             2/2     Running   0          6m25s
istio-ingressgateway-5df799fdbd-8nqhj     1/1     Running   0          2m57s
istio-pilot-67fd786f65-nwmcb              2/2     Running   0          6m24s
istio-policy-74cf89cb66-4wrpl             2/2     Running   1          6m25s
istio-sidecar-injector-759bf6b4bc-mw4vf   1/1     Running   0          6m25s
istio-telemetry-77b6dfb4ff-zqxzz          2/2     Running   1          6m24s
istio-tracing-cd67ddf8-n4d7k              1/1     Running   0          6m25s
istiocoredns-5f7546c6f4-g7b5c             2/2     Running   0          6m39s
kiali-7964898d8c-5twln                    1/1     Running   0          6m23s
prometheus-586d4445c7-xhn8d               1/1     Running   0          6m25s
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-2s8k4                  1/1     Running   0          59m
istio-citadel-568747d88-87kdj             1/1     Running   0          59m
istio-egressgateway-8f454cf58-zj9fs       1/1     Running   0          60m
istio-galley-6b9495645d-qfdr6             2/2     Running   0          59m
istio-ingressgateway-5df799fdbd-2c9rc     1/1     Running   0          60m
istio-pilot-67fd786f65-nzhx4              2/2     Running   0          59m
istio-policy-74cf89cb66-4bc7f             2/2     Running   3          59m
istio-sidecar-injector-759bf6b4bc-grk24   1/1     Running   0          59m
istio-telemetry-77b6dfb4ff-6zr94          2/2     Running   4          60m
istio-tracing-cd67ddf8-grs9g              1/1     Running   0          60m
istiocoredns-5f7546c6f4-gxd66             2/2     Running   0          60m
kiali-7964898d8c-nhn52                    1/1     Running   0          59m
prometheus-586d4445c7-xr44v               1/1     Running   0          59m
  1. Verifique se o Istio está instalado nos dois clusters dev1. Somente o Citadel, o sidecar-injector e o coredns são executados nos clusters dev1. Eles compartilham um plano de controle do Istio em execução no cluster ops-1.
kubectl --context ${DEV1_GKE_1} get pods -n istio-system
kubectl --context ${DEV1_GKE_2} get pods -n istio-system
 
  1. Verifique se o Istio está instalado nos dois clusters dev2. Somente o Citadel, o sidecar-injector e o coredns são executados nos clusters dev2. Eles compartilham um plano de controle do Istio em execução no cluster ops-2.
kubectl --context ${DEV2_GKE_1} get pods -n istio-system
kubectl --context ${DEV2_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

Verificar a descoberta de serviços para planos de controle compartilhados

  1. Como opção, verifique se os secrets foram implantados.
kubectl --context ${OPS_GKE_1} get secrets -l istio/multiCluster=true -n istio-system
kubectl --context ${OPS_GKE_2} get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
For OPS_GKE_1:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      8m7s
gke-2-apps-r1b-prod   Opaque   1      8m7s
gke-3-apps-r2a-prod   Opaque   1      44s
gke-4-apps-r2b-prod   Opaque   1      43s

For OPS_GKE_2:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      40s
gke-2-apps-r1b-prod   Opaque   1      40s
gke-3-apps-r2a-prod   Opaque   1      8m4s
gke-4-apps-r2b-prod   Opaque   1      8m4s

Neste workshop, você vai usar uma única VPC compartilhada em que todos os clusters do GKE são criados. Para descobrir serviços em clusters, use os arquivos kubeconfig (para cada um dos clusters de aplicativos) criados como secrets nos clusters de operações. O Pilot usa esses segredos para descobrir serviços consultando o servidor da API Kube dos clusters de aplicativos (autenticados pelos segredos acima). Você pode ver que os dois clusters de operações podem se autenticar em todos os clusters de apps usando secrets criados com kubeconfig. Os clusters de operações podem descobrir serviços automaticamente usando os arquivos kubeconfig como um método secreto. Isso exige que o Pilot nos clusters de operações tenha acesso ao servidor da API Kube de todos os outros clusters. Se o Pilot não conseguir acessar os servidores da API Kube, adicione manualmente os serviços remotos como ServiceEntries. É possível pensar nas ServiceEntries como entradas DNS no registro de serviço. As ServiceEntries definem um serviço usando um nome DNS totalmente qualificado ( FQDN) e um endereço IP em que ele pode ser acessado. Consulte a documentação do Istio Multicluster para mais informações.

6. Explicação sobre o repositório de infraestrutura

Cloud Build de infraestrutura

Os recursos do GCP para o workshop são criados usando o Cloud Build e um infrastructure repositório do CSR. Você acabou de executar um script de bootstrap (localizado em scripts/bootstrap_workshop.sh) no terminal local. O script de inicialização cria uma pasta do GCP, um projeto de administrador do Terraform e as permissões adequadas do IAM para a conta de serviço do Cloud Build. O projeto de administrador do Terraform é usado para armazenar estados, registros e scripts diversos do Terraform. Ele contém os repositórios infrastructure e k8s_repo do CSR. Esses repositórios são explicados em detalhes na próxima seção. Nenhum outro recurso do workshop é criado no projeto de administrador do Terraform. A conta de serviço do Cloud Build no projeto de administrador do Terraform é usada para criar recursos para o workshop.

Um arquivo cloudbuild.yaml localizado na pasta infrastructure é usado para criar recursos do GCP para o workshop. Ele cria uma imagem de builder personalizada com todas as ferramentas necessárias para criar recursos do GCP. Essas ferramentas incluem o SDK gcloud, o Terraform e outros utilitários, como Python, Git, jq etc. A imagem do builder personalizado executa terraform plan e apply para cada recurso. Os arquivos do Terraform de cada recurso estão localizados em pastas separadas (detalhes na próxima seção). Os recursos são criados um de cada vez e na ordem em que normalmente seriam criados. Por exemplo, um projeto do GCP é criado antes dos recursos no projeto. Consulte o arquivo cloudbuild.yaml para mais detalhes.

O Cloud Build é acionado sempre que há um commit no repositório infrastructure. Qualquer mudança feita na infraestrutura é armazenada como infraestrutura como código (IaC) e confirmada no repositório. O estado do workshop é sempre armazenado nesse repositório.

Estrutura de pastas: equipes, ambientes e recursos

O repositório de infraestrutura configura os recursos de infraestrutura do GCP para o workshop. Ele é estruturado em pastas e subpastas. As pastas de base no repositório representam as team que possuem recursos específicos do GCP. A próxima camada de pastas representa o environment específico da equipe (por exemplo, dev, stage, prod). A próxima camada de pastas no ambiente representa o resource específico (por exemplo, host_project, gke_clusters etc.). Os scripts e arquivos do Terraform necessários estão nas pastas de recursos.

434fc1769bb49b8c.png

Os quatro tipos de equipes a seguir são representados neste workshop:

  1. infraestrutura: representa a equipe de infraestrutura em nuvem. Eles são responsáveis por criar os recursos do GCP para todas as outras equipes. Eles usam o projeto de administrador do Terraform para os recursos. O repositório de infraestrutura está no projeto de administrador do Terraform, assim como os arquivos de estado do Terraform (explicados abaixo). Esses recursos são criados por um script bash durante o processo de inicialização (consulte o módulo 0: fluxo de trabalho do administrador para mais detalhes).
  2. network: representa a equipe de rede. Eles são responsáveis pelos recursos de rede e VPC. Eles são proprietários dos seguintes recursos do GCP:
  3. host project: representa o projeto host da VPC compartilhada.
  4. shared VPC: representa a VPC compartilhada, as sub-redes, os intervalos de IP secundários, as rotas e as regras de firewall.
  5. ops: representa a equipe de operações/DevOps. Eles são proprietários dos seguintes recursos:
  6. ops project: representa um projeto para todos os recursos de operações.
  7. gke clusters: um cluster do GKE de operações por região. O plano de controle do Istio é instalado em cada um dos clusters do GKE de operações.
  8. k8s-repo: um repositório de CSR que contém manifestos do GKE para todos os clusters do GKE.
  9. apps: representa as equipes de aplicativos. Este workshop simula duas equipes, app1 e app2. Eles são proprietários dos seguintes recursos:
  10. app projects: cada equipe de app recebe um conjunto de projetos. Isso permite que eles controlem o faturamento e o IAM do projeto específico.
  11. gke clusters: são clusters de aplicativos em que os contêineres/pods de aplicativos são executados.
  12. gce instances: opcionalmente, se eles tiverem aplicativos executados em instâncias do GCE. Neste workshop, o app1 tem algumas instâncias do GCE em que parte do aplicativo é executada.

Neste workshop, o mesmo app (Hipster Shop) representa app1 e app2.

Provedor, estados e saídas: back-ends e estados compartilhados

Os provedores google e google-beta estão localizados em gcp/[environment]/gcp/provider.tf. O arquivo provider.tf é symlinked em todas as pastas de recursos. Assim, você muda o provedor em um só lugar, em vez de gerenciar individualmente os provedores de cada recurso.

Cada recurso contém um arquivo backend.tf que define o local do arquivo tfstate do recurso. Esse arquivo backend.tf é gerado de um modelo (localizado em templates/backend.tf_tmpl) usando um script (localizado em scripts/setup_terraform_admin_project) e colocado na pasta de recursos respectiva. Os buckets do Google Cloud Storage (GCS) são usados para back-ends. O nome da pasta do bucket do GCS corresponde ao nome do recurso. Todos os back-ends de recursos residem no projeto de administrador do Terraform.

Recursos com valores interdependentes contêm um arquivo output.tf. Os valores de saída necessários são armazenados no arquivo tfstate definido no back-end para esse recurso específico. Por exemplo, para criar um cluster do GKE em um projeto, é necessário saber o ID do projeto. O ID do projeto é gerado via output.tf para o arquivo tfstate, que pode ser usado com uma fonte de dados terraform_remote_state no recurso de cluster do GKE.

O arquivo shared_state é uma fonte de dados terraform_remote_state que aponta para o arquivo tfstate de um recurso. Um ou mais arquivos shared_state_[resource_name].tf existem nas pastas de recursos que exigem saídas de outros recursos. Por exemplo, na pasta de recursos ops_gke, há arquivos shared_state dos recursos ops_project e shared_vpc, porque você precisa do ID do projeto e dos detalhes da VPC para criar clusters do GKE no projeto de operações. Os arquivos shared_state são gerados de um modelo (localizado em templates/shared_state.tf_tmpl) usando um script (localizado em scripts/setup_terraform_admin_project). Todos os arquivos shared_state dos recursos são colocados na pasta gcp/[environment]/shared_states. Os arquivos shared_state necessários são vinculados por symlink nas respectivas pastas de recursos. Colocar todos os arquivos shared_state em uma pasta e criar links simbólicos para eles nas pastas de recursos apropriadas facilita o gerenciamento de todos os arquivos de estado em um só lugar.

Variáveis

Todos os valores de recursos são armazenados como variáveis de ambiente. Essas variáveis são armazenadas (como instruções de exportação) em um arquivo chamado vars.sh localizado em um bucket do GCS no projeto de administrador do Terraform. Ele contém ID da organização, conta de faturamento, IDs de projetos, detalhes do cluster do GKE etc. É possível fazer o download e extrair o vars.sh de qualquer terminal para receber os valores da sua configuração.

As variáveis do Terraform são armazenadas em vars.sh como TF_VAR_[variable name]. Essas variáveis são usadas para gerar um arquivo variables.tfvars na pasta de recursos respectiva. O arquivo variables.tfvars contém todas as variáveis com os respectivos valores. O arquivo variables.tfvars é gerado de um arquivo de modelo na mesma pasta usando um script (localizado em scripts/setup_terraform_admin_project).

Explicação do repositório do K8s

k8s_repo é um repositório do CSR (separado do repositório de infraestrutura) localizado no projeto de administrador do Terraform. Ele é usado para armazenar e aplicar manifestos do GKE a todos os clusters do GKE. k8s_repo é criado pelo Cloud Build de infraestrutura. Consulte a seção anterior para mais detalhes. Durante o processo inicial de build da infraestrutura do Cloud Build, um total de seis clusters do GKE são criados. No k8s_repo, seis pastas são criadas. Cada pasta (nome correspondente ao nome do cluster do GKE) corresponde a um cluster do GKE que contém os respectivos arquivos de manifesto de recursos. Assim como na criação de infraestrutura, o Cloud Build é usado para aplicar os manifestos do Kubernetes a todos os clusters do GKE usando o k8s_repo. O Cloud Build é acionado sempre que há um commit no repositório k8s_repo. Assim como a infraestrutura, todos os manifestos do Kubernetes são armazenados como código no repositório k8s_repo, e o estado de cada cluster do GKE é sempre armazenado na respectiva pasta.

Como parte da criação inicial da infraestrutura, o k8s_repo é criado e o Istio é instalado em todos os clusters.

Projetos, clusters do GKE e namespaces

Os recursos deste workshop são divididos em diferentes projetos do GCP. Os projetos precisam corresponder à estrutura organizacional (ou de equipe) da sua empresa. Equipes (na sua organização) responsáveis por diferentes projetos/produtos/recursos usam projetos diferentes do GCP. Com projetos separados, é possível criar conjuntos separados de permissões do IAM e gerenciar o faturamento no nível do projeto. Além disso, as cotas também são gerenciadas no nível do projeto.

Cinco equipes estão representadas neste workshop, cada uma com um projeto próprio.

  1. A equipe de infraestrutura que cria recursos do GCP usa o Terraform admin project. Eles gerenciam a infraestrutura como código em um repositório CSR (chamado infrastructure) e armazenam todas as informações de estado do Terraform relacionadas aos recursos criados no GCP em buckets do GCS. Eles controlam o acesso ao repositório de CSR e aos buckets do GCS de estado do Terraform.
  2. A equipe de rede que cria a VPC compartilhada usa o host project. Esse projeto contém a VPC, as sub-redes, as rotas e as regras de firewall. Com uma VPC compartilhada, é possível gerenciar centralmente a rede para recursos do GCP. Todos os projetos usavam essa única VPC compartilhada para rede.
  3. A equipe de operações/plataforma que cria clusters do GKE e planos de controle do ASM/Istio usa o ops project. Eles gerenciam o ciclo de vida dos clusters do GKE e da malha de serviço. Eles são responsáveis pelo reforço da proteção dos clusters e por gerenciar a resiliência e o escalonamento da plataforma Kubernetes. Neste workshop, você vai usar o método gitops para implantar recursos no Kubernetes. Um repositório do CSR (chamado de k8s_repo) existe no projeto de operações.
  4. Por fim, as equipes dev1 e dev2 (representam duas equipes de desenvolvimento) que criam aplicativos usam os próprios dev1 e dev2 projects. São os aplicativos e serviços que você oferece aos seus clientes. Elas são criadas na plataforma gerenciada pela equipe de operações. Os recursos (implantações, serviços etc.) são enviados para o k8s_repo e implantados nos clusters adequados. É importante observar que este workshop não se concentra nas práticas recomendadas e ferramentas de CI/CD. Você usa o Cloud Build para automatizar a implantação de recursos do Kubernetes diretamente nos clusters do GKE. Em cenários de produção reais, você usaria uma solução de CI/CD adequada para implantar aplicativos em clusters do GKE.

Há dois tipos de clusters do GKE neste workshop.

  1. Clusters de operações: usados pela equipe de operações para executar ferramentas de DevOps. Neste workshop, eles executam o plano de controle do ASM/Istio para gerenciar a malha de serviço.
  2. Clusters de aplicativos: usados pelas equipes de desenvolvimento para executar aplicativos. Neste workshop, usamos o app Hipster Shop.

Ao separar as ferramentas de operações/administração dos clusters que executam o aplicativo, é possível gerenciar o ciclo de vida de cada recurso de forma independente. Os dois tipos de clusters também existem em projetos diferentes relacionados à equipe/produto que os usa, o que facilita o gerenciamento das permissões do IAM.

Há um total de seis clusters do GKE. Dois clusters operacionais regionais são criados no projeto de operações. O plano de controle do ASM/Istio está instalado nos dois clusters de operações. Cada cluster de operações está em uma região diferente. Além disso, há quatro clusters de aplicativos zonais. Eles são criados nos próprios projetos. Este workshop simula duas equipes de desenvolvimento, cada uma com seus próprios projetos. Cada projeto contém dois clusters de apps. Os clusters de apps são zonais em zonas diferentes. Os quatro clusters de apps estão localizados em duas regiões e quatro zonas. Assim, você tem redundância regional e zonal.

O aplicativo usado neste workshop, o Hipster Shop, é implantado em todos os quatro clusters de aplicativos. Cada microsserviço fica no próprio namespace em todos os clusters de apps. As implantações (pods) do app Hipster Shop não são implantadas nos clusters de operações. No entanto, os namespaces e recursos de serviço para todos os microsserviços também são criados nos clusters de operações. O plano de controle do ASM/Istio usa os registros de serviço do Kubernetes para descoberta de serviços. Na ausência de serviços (nos clusters de operações), você precisaria criar manualmente ServiceEntries para cada serviço em execução no cluster de apps.

Neste workshop, você vai implantar um aplicativo de microsserviços de 10 níveis. O aplicativo é um e-commerce baseado na Web chamado Hipster Shop, em que os usuários podem procurar itens, adicioná-los ao carrinho e fazer compras.

Manifestos do Kubernetes e k8s_repo

Use o k8s_repo para adicionar recursos do Kubernetes a todos os clusters do GKE. Para isso, copie os manifestos do Kubernetes e faça commit no k8s_repo. Todos os commits no k8s_repo acionam um job do Cloud Build que implanta os manifestos do Kubernetes no cluster respectivo. O manifesto de cada cluster está localizado em uma pasta separada com o mesmo nome do cluster.

Os seis nomes de cluster são:

  1. gke-asm-1-r1-prod: o cluster de operações regional na região 1
  2. gke-asm-2-r2-prod: o cluster regional de operações na região 2
  3. gke-1-apps-r1a-prod: o cluster de apps na zona a da região 1
  4. gke-2-apps-r1b-prod: o cluster de apps na zona b da região 1
  5. gke-3-apps-r2a-prod: o cluster de apps na zona a da região 2
  6. gke-4-apps-r2b-prod: o cluster de apps na zona b da região 2

O k8s_repo tem pastas correspondentes a esses clusters. Qualquer manifesto colocado nessas pastas é aplicado ao cluster do GKE correspondente. Os manifestos de cada cluster são colocados em subpastas (na pasta principal do cluster) para facilitar o gerenciamento. Neste workshop, você vai usar o Kustomize para acompanhar os recursos implantados. Consulte a documentação oficial do Kustomize para mais detalhes.

7. Implantar o app de exemplo

Objetivo: implantar o app Hipster Shop em clusters de apps

  • k8s-repo (clone)
  • Copiar manifestos da Hipster Shop para todos os clusters de apps
  • Criar serviços para o app Hipster Shop nos clusters de operações
  • Configurar o loadgenerators nos clusters de operações para testar a conectividade global
  • Verificar a conectividade segura com o app Hipster Shop

Instruções do laboratório sobre o método de copiar e colar

Clonar o repositório de origem do projeto de operações

Como parte do build inicial da infraestrutura do Terraform, o k8s-repo já é criado no projeto de operações.

  1. Crie um diretório vazio para o repositório Git:
mkdir $WORKDIR/k8s-repo
 
  1. Inicialize o repositório Git, adicione o repositório remoto e extraia o master do repositório remoto:
cd $WORKDIR/k8s-repo
git init && git remote add origin \
https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
 
  1. Defina a configuração local do Git.
git config --local user.email $MY_USER
git config --local user.name "K8s repo user"
git config --local \
credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master

Copiar manifestos, fazer commit e enviar

  1. Copie os namespaces e serviços do Hipster Shop para o repositório de origem de todos os clusters.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.

cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
 
  1. Copie o arquivo kustomization.yaml da pasta do app para todos os clusters.
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/
 
  1. Copie as implantações, o RBAC e a PodSecurityPolicy do Hipster Shop para o repositório de origem dos clusters de apps.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/

cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
  1. Remova a implantação do cartservice, o RBAC e o podsecuritypolicy de todos os clusters de desenvolvimento, exceto um. A Hipstershop não foi criada para implantação em vários clusters. Por isso, para evitar resultados inconsistentes, estamos usando apenas um cartservice.
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
 
  1. Adicione a implantação do cartservice, o RBAC e a podsecuritypolicy ao kustomization.yaml apenas no primeiro cluster de desenvolvimento.
cd ${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app
cd deployments && kustomize edit add resource app-cart-service.yaml
cd ../podsecuritypolicies && kustomize edit add resource cart-psp.yaml
cd ../rbac && kustomize edit add resource cart-rbac.yaml
cd ${WORKDIR}/asm
 
  1. Remova podsecuritypolicies, implantações e diretórios rbac de ops clusters kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/kustomization.yaml
  1. Substitua o PROJECT_ID nos manifestos do RBAC.
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_2_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_2_CLUSTER}/app/rbac/*
  
  1. Copie os manifestos IngressGateway e VirtualService para o repositório de origem dos clusters de operações.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-ingress/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-ingress/
 
  1. Copie os recursos do Config Connector para um dos clusters em cada projeto.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/
 
  1. Substitua o PROJECT_ID nos manifestos do Config Connector.
sed -i 's/${PROJECT_ID}/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev1_project_name'/g' \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev2_project_name'/g' \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/*
 
  1. Copie os manifestos loadgenerator (implantação, PodSecurityPolicy e RBAC) para os clusters de operações. O app Hipster Shop é exposto usando um balanceador de carga global do Google Cloud (GCLB). O GCLB recebe o tráfego do cliente (destinado a frontend) e o envia para a instância mais próxima do serviço. Colocar loadgenerator nos dois clusters de operações garante que o tráfego seja enviado aos dois gateways de entrada do Istio em execução nos clusters de operações. O balanceamento de carga é explicado em detalhes na seção a seguir.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/. 
 
  1. Substitua o ID do projeto de operações nos manifestos loadgenerator para os dois clusters de operações.
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g'  \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
 

  1. Adicione os recursos loadgenerator a kustomization.yaml para os dois clusters de operações.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
 

  1. Criar confirmação para k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "create app namespaces and install hipster shop"
git push --set-upstream origin master 
 
  1. Confira o status do projeto de operações do Cloud Build em uma guia aberta anteriormente ou clicando no link a seguir:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
  

Verificar a implantação do aplicativo

  1. Verifique se os pods em todos os namespaces de aplicativos, exceto "cart", estão no estado "Running" em todos os clusters de desenvolvimento.
for ns in ad checkout currency email frontend payment product-catalog recommendation shipping; do
  kubectl --context $DEV1_GKE_1 get pods -n $ns;
  kubectl --context $DEV1_GKE_2 get pods -n $ns;
  kubectl --context $DEV2_GKE_1 get pods -n $ns;
  kubectl --context $DEV2_GKE_2 get pods -n $ns;
done;
 

Output (do not copy)

NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-pvc6s   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-xlkl9   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-zdjkg   2/2     Running   0          115s
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-l748q   2/2     Running   0          82s

NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-gk92n   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-rvzk9   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-mt925   2/2     Running   0          117s
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-klqn7   2/2     Running   0          84s

NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-kkq7d   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-lwskf   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-zz7xs   2/2     Running   0          118s
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-2vtw5   2/2     Running   0          85s

NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-df8ml   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-bdcvg   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-jqf28   2/2     Running   0          117s
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-95x2m   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-q5g9p   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-n6lp8   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-gf9xl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-v7cbr   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-2ltrk   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-dqd55   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-jghcl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-kkspz   2/2     Running   0          87s

NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-qqd9n   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-xczg5   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-wfgfr   2/2     Running   0          2m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-r6t8v   2/2     Running   0          88s
  1. Verifique se os pods no namespace do carrinho estão no estado "Em execução" apenas no primeiro cluster de desenvolvimento.
kubectl --context $DEV1_GKE_1 get pods -n cart;
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
cartservice-659c9749b4-vqnrd   2/2     Running   0          17m

Acessar o aplicativo Hipster Shop

Balanceamento de carga global

Agora o app Hipster Shop está implantado em todos os quatro clusters de apps. Esses clusters estão em duas regiões e quatro zonas. Os clientes podem acessar o app Hipster Shop acessando o serviço frontend. O serviço frontend é executado em todos os quatro clusters de apps. Um balanceador de carga do Google Cloud ( GCLB) é usado para direcionar o tráfego do cliente a todas as quatro instâncias do serviço frontend.

Os gateways de entrada do Istio são executados apenas nos clusters de operações e atuam como um balanceador de carga regional para os dois clusters de aplicativos zonais na região. O GCLB usa os dois gateways de entrada do Istio (executados nos dois clusters de operações) como back-ends para o serviço de front-end global. Os gateways de entrada do Istio recebem o tráfego do cliente do GCLB e o enviam para os pods de front-end em execução nos clusters de aplicativos.

4c618df35cb928ee.png

Como alternativa, coloque os gateways de entrada do Istio diretamente nos clusters de aplicativos. Assim, o GCLB pode usá-los como back-ends.

Controlador Autoneg do GKE

O serviço do Kubernetes do gateway de entrada do Istio se registra como um back-end no GCLB usando grupos de endpoints de rede (NEGs). As NEGs permitem o balanceamento de carga nativo de contêiner usando GCLBs. Os NEGs são criados por uma anotação especial em um serviço do Kubernetes, para que ele possa se registrar no controlador de NEG. O controlador Autoneg é um controlador especial do GKE que automatiza a criação de NEGs e a atribuição deles como back-ends a um GCLB usando anotações de serviço. Os planos de controle do Istio, incluindo os gateways de entrada do Istio, são implantados durante o Cloud Build inicial da infraestrutura do Terraform. A configuração do GCLB e do autoneg é feita como parte do Cloud Build inicial da infraestrutura do Terraform.

Ingress seguro usando o Cloud Endpoints e certificados gerenciados

Os certificados gerenciados pelo GCP são usados para proteger o tráfego do cliente para o serviço frontend do GCLB. O GCLB usa certificados gerenciados para o serviço global frontend, e o certificado é encerrado no GCLB. Neste workshop, você vai usar o Cloud Endpoints como o domínio do certificado gerenciado. Como alternativa, use seu domínio e um nome DNS para o frontend e crie certificados gerenciados pelo GCP.

  1. Para acessar a loja Hipster, clique no link de saída do seguinte comando:
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 
  1. Para verificar se o certificado é válido, clique no símbolo de bloqueio na barra de URL da guia do Chrome.

6c403a63caa06c84.png

Verificar o balanceamento de carga global

Como parte da implantação do aplicativo, os geradores de carga foram implantados nos dois clusters de operações que geram tráfego de teste para o link do Cloud Endpoints da loja Hipster do GCLB. Verifique se o GCLB está recebendo tráfego e enviando para os dois gateways de entrada do Istio.

  1. Acesse o link GCLB > Monitoring do projeto de operações em que o GCLB da loja Hipster foi criado.
echo "https://console.cloud.google.com/net-services/loadbalancing/details/http/istio-ingressgateway?project=$TF_VAR_ops_project_name&cloudshell=false&tab=monitoring&duration=PT1H" 
 
  1. Mude de Todos os back-ends para istio-ingressgateway no menu suspenso "Back-end", conforme mostrado abaixo.

6697c9eb67998d27.png

  1. Observe o tráfego para istio-ingressgateways.

ff8126e44cfd7f5e.png

Há três NEGs criadas por istio-ingressgateway. Como os clusters de operações são regionais, um NEG é criado para cada zona na região. No entanto, os pods istio-ingressgateway são executados em uma única zona por região. O tráfego é mostrado indo para os pods istio-ingressgateway.

Os geradores de carga estão sendo executados nos dois clusters de operações, simulando o tráfego de clientes das duas regiões em que estão. A carga gerada na região 1 do cluster de operações está sendo enviada para istio-ingressgateway na região 2. Da mesma forma, a carga gerada na região 2 do cluster de operações está sendo enviada para istio-ingressgateway na região 2.

8. Observabilidade com o Stackdriver

Objetivo: conectar a telemetria do Istio ao Stackdriver e validar.

  • Instalar recursos istio-telemetry
  • Criar/atualizar painéis de serviços do Istio
  • Ver registros de contêineres
  • Ver rastreamento distribuído no Stackdriver

Instruções do laboratório sobre o método de copiar e colar

Um dos principais recursos do Istio é a observabilidade integrada ("o11y"). Isso significa que, mesmo com contêineres de caixa preta não instrumentados, os operadores ainda podem observar o tráfego entrando e saindo desses contêineres, fornecendo serviços aos clientes. Essa observação assume a forma de alguns métodos diferentes: métricas, registros e rastreamentos.

Também vamos usar o sistema de geração de carga integrado no Hipster Shop. A capacidade de observação não funciona muito bem em um sistema estático sem tráfego. Por isso, a geração de carga ajuda a entender como ela funciona. Essa carga já está sendo executada, agora só vamos poder vê-la.

  1. Instale o arquivo de configuração do Istio para o Stackdriver.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
 
  1. Faça commit em k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "Install istio to stackdriver configuration"
git push 
 
  1. Confira o status do projeto de operações do Cloud Build em uma guia aberta anteriormente ou clicando no link a seguir:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. Verifique a integração do Istio com o Stackdriver. Receba o CRD do manipulador do Stackdriver.
kubectl --context $OPS_GKE_1 get handler -n istio-system
 

A saída vai mostrar um manipulador chamado stackdriver:

NAME            AGE
kubernetesenv   12d
prometheus      12d
stackdriver     69s      # <== NEW!
  1. Verifique se a exportação de métricas do Istio para o Stackdriver está funcionando. Clique no link gerado por este comando:
echo "https://console.cloud.google.com/monitoring/metrics-explorer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

Você vai precisar criar um espaço de trabalho com o nome do projeto de operações. Basta clicar em "OK". Se aparecer uma mensagem sobre a nova interface, basta dispensar a caixa de diálogo.

No Metrics Explorer, em "Encontrar tipo de recurso e métrica", digite "istio" para ver que há opções como "Contagem de solicitações do servidor" no tipo de recurso "Contêiner do Kubernetes". Isso mostra que as métricas estão fluindo da malha para o Stackdriver.

(Você precisará agrupar por rótulo destination_service_name se quiser ver as linhas abaixo.)

b9b59432ee68e695.png

Visualizar métricas com painéis:

Agora que nossas métricas estão no sistema APM do Stackdriver, queremos uma maneira de visualizá-las. Nesta seção, vamos instalar um painel predefinido que mostra três dos quatro "Indicadores de ouro" de métricas: Tráfego (solicitações por segundo), Latência (neste caso, percentis 99 e 50) e Erros (excluímos Saturação neste exemplo).

O proxy Envoy do Istio oferece várias métricas, mas este é um bom conjunto para começar. A lista completa está aqui. Cada métrica tem um conjunto de rótulos que podem ser usados para filtragem e agregação, como: destination_service, source_workload_namespace, response_code, istio_tcp_received_bytes_total etc.

  1. Agora vamos adicionar nosso painel de métricas predefinidas. Vamos usar a API Dashboard diretamente. Isso é algo que você normalmente não faria gerando chamadas de API manualmente. Ele faria parte de um sistema de automação, ou você criaria o painel manualmente na interface da Web. Isso vai nos ajudar a começar rapidamente:
sed -i 's/OPS_PROJECT/'${TF_VAR_ops_project_name}'/g' \
$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
OAUTH_TOKEN=$(gcloud auth application-default print-access-token)
curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards \
 -d @$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
 
  1. Navegue até o link de saída abaixo para conferir o "Painel de serviços" recém-adicionado.
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
 

Podemos editar o painel no local usando a UX, mas, no nosso caso, vamos adicionar rapidamente um novo gráfico usando a API. Para isso, puxe a versão mais recente do painel, aplique as edições e envie de volta usando o método HTTP PATCH.

  1. É possível consultar a API Monitoring para acessar um painel. Receba o painel que acabou de ser adicionado:
curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash > /tmp/services-dashboard.json
 
  1. Adicionar um novo gráfico (latência do 50º percentil): [ Referência da API] Agora podemos adicionar um novo widget de gráfico ao nosso painel no código. Essa mudança pode ser revisada por colegas e verificada no controle de versões. Aqui está um widget para adicionar que mostra a latência do 50º percentil (latência mediana).

Tente editar o painel que você acabou de receber e adicione uma nova estrofe:

NEW_CHART=${WORKDIR}/asm/k8s_manifests/prod/app-telemetry/new-chart.json
jq --argjson newChart "$(<$NEW_CHART)" '.gridLayout.widgets += [$newChart]' /tmp/services-dashboard.json > /tmp/patched-services-dashboard.json
 
  1. Atualize o painel de serviços atual:
curl -X PATCH -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash \
 -d @/tmp/patched-services-dashboard.json
 
  1. Para conferir o painel atualizado, acesse o seguinte link de saída:
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
  1. Faça uma análise de registros simples.

O Istio oferece um conjunto de registros estruturados para todo o tráfego de rede na malha e faz upload deles para o Stackdriver Logging, permitindo a análise entre clusters em uma ferramenta eficiente. Os registros são anotados com metadados no nível do serviço, como cluster, contêiner, app, connection_id etc.

Um exemplo de entrada de registro (neste caso, o accesslog do proxy Envoy) pode ter esta aparência (cortado):

*** DO NOT PASTE *** 
 logName: "projects/PROJECTNAME-11932-01-ops/logs/server-tcp-accesslog-stackdriver.instance.istio-system" 
labels: {
  connection_id: "fbb46826-96fd-476c-ac98-68a9bd6e585d-1517191"   
  destination_app: "redis-cart"   
  destination_ip: "10.16.1.7"   
  destination_name: "redis-cart-6448dcbdcc-cj52v"   
  destination_namespace: "cart"   
  destination_owner: "kubernetes://apis/apps/v1/namespaces/cart/deployments/redis-cart"   
  destination_workload: "redis-cart"   
  source_ip: "10.16.2.8"   
  total_received_bytes: "539"   
  total_sent_bytes: "569" 
...  
 }

Acesse seus registros aqui:

echo "https://console.cloud.google.com/logs/viewer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

Para ver os registros do plano de controle do Istio, selecione Recurso > Contêiner do Kubernetes e pesquise "pilot":

6f93b2aec6c4f520.png

Aqui, podemos ver o plano de controle do Istio enviando a configuração de proxy para os proxies sidecar de cada serviço de app de exemplo. "CDS", "LDS" e "RDS" representam diferentes APIs do Envoy ( mais informações).

Além dos registros do Istio, você também pode encontrar registros de contêineres, infraestrutura ou outros serviços do GCP na mesma interface. Confira algumas consultas de registros de exemplo para o GKE. O visualizador de registros também permite criar métricas com base em registros (por exemplo, "contar todos os erros que correspondem a alguma string"), que podem ser usadas em um painel ou como parte de um alerta. Os registros também podem ser transmitidos para outras ferramentas de análise, como o BigQuery.

Alguns exemplos de filtros para uma loja hipster:

resource.type="k8s_container" labels.destination_app="productcatalogservice"

resource.type="k8s_container" resource.labels.namespace_name="cart"

  1. Confira os rastreamentos distribuídos.

Agora que você está trabalhando com um sistema distribuído, a depuração precisa de uma nova ferramenta: o rastreamento distribuído. Com essa ferramenta, você pode descobrir estatísticas sobre como seus serviços estão interagindo (como encontrar eventos lentos atípicos na imagem abaixo), além de analisar rastreamentos de amostra brutos para investigar os detalhes do que está acontecendo.

A visualização da linha do tempo mostra todas as solicitações ao longo do tempo, representadas graficamente pela latência ou pelo tempo gasto entre a solicitação inicial, passando pela pilha Hipster e, finalmente, respondendo ao usuário final. Quanto mais acima os pontos estiverem, mais lenta (e menos feliz!) será a experiência do usuário.

Clique em um ponto para encontrar a visualização em cascata detalhada dessa solicitação específica. Essa capacidade de encontrar os detalhes brutos de uma solicitação específica (não apenas estatísticas agregadas) é vital para entender a interação entre os serviços, especialmente ao procurar interações raras, mas ruins, entre eles.

A visualização em cascata é familiar para quem já usou um depurador. No entanto, em vez de mostrar o tempo gasto em diferentes processos de um único aplicativo, ela mostra o tempo gasto percorrendo nossa malha, entre serviços, executados em contêineres separados.

Aqui você encontra seus rastreamentos:

echo "https://console.cloud.google.com/traces/overview?cloudshell=false&project=$TF_VAR_ops_project_name"
 

Exemplo de captura de tela da ferramenta:

5ee238836dc9047f.png

9. Autenticação TLS mútua

Objetivo: conectividade segura entre microsserviços (AuthN).

  • Ativar o mTLS em toda a malha
  • Verificar o mTLS inspecionando registros

Instruções do laboratório sobre o método de copiar e colar

Agora que os apps estão instalados e a observabilidade está configurada, podemos começar a proteger as conexões entre os serviços e garantir que tudo continue funcionando.

Por exemplo, podemos ver no painel do Kiali que nossos serviços não estão usando o MTLS (sem ícone de "bloqueio"). Mas o trânsito está fluindo e o sistema está funcionando bem. Nosso painel de métricas de ouro do StackDriver nos dá a tranquilidade de que as coisas estão funcionando, no geral.

  1. Verifique a MeshPolicy nos clusters de operações. O mTLS é PERMISSIVE, permitindo tráfego criptografado e não mTLS.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq '.items[].spec'
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq '.items[].spec'
 
    `Output (do not copy)`
{
  "peers": [
    {
      "mtls": {
        "mode": "PERMISSIVE"
      }
    }
  ]
}

O Istio é configurado em todos os clusters usando o operador do Istio, que usa o recurso personalizado (CR) IstioControlPlane. Vamos configurar o mTLS em todos os clusters atualizando o CR do IstioControlPlane e o k8s-repo. Definir global > mTLS > enabled: true no CR IstioControlPlane resulta nas seguintes duas mudanças no plano de controle do Istio:

  • A MeshPolicy está definida para ativar o mTLS em toda a malha para todos os serviços em execução em todos os clusters.
  • Uma DestinationRule é criada para permitir o tráfego ISTIO_MUTUAL entre os serviços executados em todos os clusters.
  1. Vamos aplicar um patch do kustomize ao CR istioControlPlane para ativar o mTLS em todo o cluster. Copie o patch para o diretório relevante de todos os clusters e adicione um patch do kustomize.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
 
  1. Faça commit em k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "turn mTLS on"
git push
 
  1. Confira o status do projeto de operações do Cloud Build em uma guia aberta anteriormente ou clicando no link a seguir:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"

 

Verificar mTLS

  1. Verifique o MeshPolicy mais uma vez nos clusters de operações. Observação: o mTLS não é mais PERMISSIVE e só permite tráfego mTLS.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq .items[].spec
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq .items[].spec
 

Resposta (não copie):

{
  "peers": [
    {
      "mtls": {}
    }
  ]
}
  1. Descreva a DestinationRule criada pelo controlador do operador do Istio.
kubectl --context $OPS_GKE_1 get DestinationRule default -n istio-system -o json | jq '.spec'
kubectl --context $OPS_GKE_2 get DestinationRule default -n istio-system -o json | jq '.spec'

Resposta (não copie):

{
    host: '*.local',
    trafficPolicy: {
      tls: {
        mode: ISTIO_MUTUAL
      }
   }
}

Também podemos ver a mudança de HTTP para HTTPS nos registros.

Podemos expor esse campo específico dos registros na interface clicando em uma entrada de registro e depois no valor do campo que você quer mostrar. No nosso caso, clique em "http" ao lado de "protocol":

d92e0c88cd5b2132.png

Isso resulta em uma boa maneira de visualizar a mudança:

ea3d0240fa6fed81.png

10. Implantações canário

Objetivo: lançar uma nova versão do serviço de front-end.

  • Lançamento do serviço frontend-v2 (próxima versão de produção) em uma região
  • Use DestinationRules e VirtualServices para direcionar o tráfego lentamente para frontend-v2
  • Verifique o pipeline de implantação do GitOps inspecionando uma série de commits no k8s-repo

Instruções do laboratório sobre o método de copiar e colar

Uma implantação canário é um lançamento progressivo de um novo serviço. Em uma implantação canário, você envia uma quantidade crescente de tráfego para a nova versão, enquanto ainda envia a porcentagem restante para a versão atual. Um padrão comum é realizar uma análise de teste canário em cada estágio da divisão de tráfego e comparar os "sinais de ouro" da nova versão (latência, taxa de erros, saturação) com um valor de referência. Isso ajuda a evitar interrupções e garante a estabilidade do novo serviço "v2" em todas as etapas da divisão de tráfego.

Nesta seção, você vai aprender a usar o Cloud Build e as políticas de tráfego do Istio para criar uma implantação canário básica de uma nova versão do serviço frontend.

Primeiro, vamos executar o pipeline canário na região DEV1 (us-west1) e implantar o front-end v2 nos dois clusters dessa região. Em seguida, vamos executar o pipeline de Canary na região DEV2 (us-central) e implantar a v2 nos dois clusters dessa região. Executar o pipeline em regiões em ordem, em vez de em paralelo em todas as regiões, ajuda a evitar interrupções globais causadas por configuração incorreta ou por bugs no próprio app v2.

Observação: vamos acionar manualmente o pipeline Canary nas duas regiões, mas, em produção, você usaria um gatilho automatizado, por exemplo, com base em uma nova tag de imagem Docker enviada para um registro.

  1. No Cloud Shell, defina algumas variáveis de ambiente para simplificar a execução do restante dos comandos.
CANARY_DIR="$WORKDIR/asm/k8s_manifests/prod/app-canary/"
K8S_REPO="$WORKDIR/k8s-repo"
 
  1. Execute o script repo_setup.sh para copiar os manifestos de base no k8s-repo.
$CANARY_DIR/repo-setup.sh 
 

Os seguintes manifestos são copiados:

  • Implantação frontend-v2
  • Patch frontend-v1 (para incluir o rótulo "v1" e uma imagem com um endpoint "/version")
  • respy, um pequeno pod que vai imprimir a distribuição de respostas HTTP e ajudar a visualizar a implantação canário em tempo real.
  • DestinationRule do Istio de front-end: divide o serviço do Kubernetes de front-end em dois subconjuntos, v1 e v2, com base no rótulo de implantação "version".
  • VirtualService do Istio de front-end: roteia 100% do tráfego para o front-end v1. Isso substitui o comportamento padrão de rotação do serviço do Kubernetes, que enviaria imediatamente 50% de todo o tráfego regional do Dev1 para o front-end v2.
  1. Confirmar mudanças em k8s_repo:
cd $K8S_REPO 
git add . && git commit -am "frontend canary setup"
git push
 
  1. Confira o status do projeto de operações do Cloud Build em uma guia aberta anteriormente ou clicando no link a seguir:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}" 
 
  1. Navegue até o Cloud Build no console do projeto OPS1. Aguarde a conclusão do pipeline do Cloud Build e extraia os pods no namespace do front-end nos dois clusters DEV1. Você verá o seguinte:
watch -n 1 kubectl --context $DEV1_GKE_1 get pods -n frontend 
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
frontend-578b5c5db6-h9567      2/2     Running   0          59m
frontend-v2-54b74fc75b-fbxhc   2/2     Running   0          2m26s
respy-5f4664b5f6-ff22r         2/2     Running   0          2m26s

Vamos usar o tmux para dividir a janela do Cloud Shell em dois painéis:

  • O painel de baixo vai executar o comando "watch" para observar a distribuição de respostas HTTP do serviço de front-end.
  • O painel superior vai executar o script real do pipeline de teste canário.
  1. Execute o comando para dividir a janela do Cloud Shell e execute o comando "watch" no painel de baixo.
RESPY_POD=$(kubectl --context $DEV1_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV1_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

Resposta (não copie)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Execute o pipeline canário na região Dev1. Fornecemos um script que atualiza as porcentagens de tráfego do frontend-v2 no VirtualService (atualizando os pesos para 20%, 50%, 80% e 100%). Entre as atualizações, o script aguarda a conclusão do pipeline do Cloud Build. Execute o script de implantação canário para a região Dev1. Observação: a execução desse script leva cerca de 10 minutos.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_1_CLUSTER OPS_CONTEXT=$OPS_GKE_1 \
${CANARY_DIR}/auto-canary.sh
 

É possível conferir a divisão de tráfego em tempo real na janela da parte de baixo em que você está executando o comando respy. Por exemplo, na marca de 20%:

Resposta (não copie)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 79.4%             |
|          |                   |
| v2       | 20.6%             |
|          |                   |
+----------+-------------------+
  1. Quando o lançamento do Dev2 for concluído para frontend-v2, você vai ver uma mensagem de sucesso no final do script:
     Output (do not copy) 
    
✅ 100% successfully deployed
🌈 frontend-v2 Canary Complete for gke-asm-1-r1-prod
  1. Todo o tráfego de front-end de um pod Dev2 precisa ir para frontend-v2:
     Output (do not copy) 
    
500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Feche o painel dividido.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
 
  1. Navegue até o Cloud Source Repos no link gerado.
echo https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo

Você vai encontrar um commit separado para cada porcentagem de tráfego, com o mais recente no topo da lista:

b87b85f52fd2ff0f.png

Agora, repita o mesmo processo para a região Dev2. A região Dev2 ainda está "bloqueada" na v1. Isso ocorre porque, no script baseline repo_setup, enviamos um VirtualService para enviar explicitamente todo o tráfego para a v1. Assim, pudemos fazer um canário regional seguro no Dev1 e garantir que ele fosse executado com sucesso antes de lançar a nova versão globalmente.

  1. Execute o comando para dividir a janela do Cloud Shell e execute o comando "watch" no painel de baixo.
RESPY_POD=$(kubectl --context $DEV2_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV2_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

Resposta (não copie)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Execute o pipeline canário na região Dev2. Fornecemos um script que atualiza as porcentagens de tráfego do frontend-v2 no VirtualService (atualizando os pesos para 20%, 50%, 80% e 100%). Entre as atualizações, o script aguarda a conclusão do pipeline do Cloud Build. Execute o script de implantação canário para a região Dev1. Observação: a execução desse script leva cerca de 10 minutos.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_2_CLUSTER OPS_CONTEXT=$OPS_GKE_2 \
${CANARY_DIR}/auto-canary.sh
 

Resposta (não copie)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. No pod Respy em Dev2, observe o tráfego dos pods Dev2 se mover progressivamente do front-end v1 para v2. Quando o script for concluído, você verá:

Resposta (não copie)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Feche o painel dividido.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'

Nesta seção, mostramos como usar o Istio para implantações canário regionais. Em produção, em vez de um script manual, você pode acionar automaticamente esse script canary como um pipeline do Cloud Build, usando um gatilho, como uma nova imagem marcada enviada para um registro de contêiner. Também é recomendável adicionar uma análise de teste canário entre cada etapa, analisando a latência e a taxa de erros da v2 em relação a um limite de segurança predefinido, antes de enviar mais tráfego.

11. Políticas de autorização

Objetivo: configurar o RBAC entre microsserviços (AuthZ).

  • Criar AuthorizationPolicy para NEGAR o acesso a um microsserviço
  • Criar AuthorizationPolicy para PERMITIR acesso específico a um microsserviço

Instruções do laboratório sobre o método de copiar e colar

Ao contrário de um aplicativo monolítico que pode estar em execução em um só lugar, os aplicativos de microsserviços distribuídos globalmente fazem chamadas além dos limites da rede. Isso significa mais pontos de entrada nos seus aplicativos e mais oportunidades de ataques mal-intencionados. Como os pods do Kubernetes têm IPs temporários, as regras de firewall tradicionais baseadas em IP não são mais adequadas para proteger o acesso entre as cargas de trabalho. Em uma arquitetura de microsserviços, é necessária uma nova abordagem de segurança. Com base em blocos de construção de segurança do Kubernetes, como contas de serviço, o Istio oferece um conjunto flexível de políticas de segurança para seus aplicativos.

As políticas do Istio abrangem autenticação e autorização. A autenticação verifica a identidade (este servidor é quem diz ser?), e a autorização verifica as permissões (este cliente tem permissão para fazer isso?). Abordamos a autenticação do Istio na seção de TLS mútuo do Módulo 1 (MeshPolicy). Nesta seção, vamos aprender a usar as políticas de autorização do Istio para controlar o acesso a uma das cargas de trabalho do aplicativo, o currencyservice.

Primeiro, vamos implantar uma AuthorizationPolicy em todos os quatro clusters de desenvolvimento, fechando todo o acesso ao currencyservice e acionando um erro no front-end. Em seguida, vamos permitir que apenas o serviço de front-end acesse o currencyservice.

  1. Inspecione o conteúdo de currency-deny-all.yaml. Essa política usa seletores de rótulo de implantação para restringir o acesso ao currencyservice. Não há um campo spec. Isso significa que a política vai negar todo o acesso ao serviço selecionado.
cat $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml
 

Resposta (não copie)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  1. Copie a política de moeda para k8s-repo, para os clusters de operações nas duas regiões.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
  1. Envie as mudanças por push.
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: deny all"
git push 
  1. Verifique o status do Cloud Build do projeto de operações em uma guia aberta anteriormente ou clicando no seguinte link:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name 
 
  1. Depois que o build for concluído, tente acessar o front-end da hipstershop em um navegador no seguinte link:
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 

Você vai receber um erro de autorização do currencyservice:

f120f3d30d6ee9f.png

  1. Vamos investigar como o serviço de moeda está aplicando essa AuthorizationPolicy. Primeiro, ative os registros no nível do trace no proxy Envoy para um dos pods de moeda, já que as chamadas de autorização bloqueadas não são registradas por padrão.
CURRENCY_POD=$(kubectl --context $DEV1_GKE_2 get pod -n currency | grep currency| awk '{ print $1 }')
kubectl --context $DEV1_GKE_2 exec -it $CURRENCY_POD -n \
currency -c istio-proxy -- curl -X POST \
"http://localhost:15000/logging?level=trace"
 
  1. Receba os registros do RBAC (autorização) do proxy sidecar do serviço de moeda. Você vai ver uma mensagem "Aplicação negada", indicando que o currencyservice está definido para bloquear todas as solicitações de entrada.
kubectl --context $DEV1_GKE_2 logs -n currency $CURRENCY_POD \
-c istio-proxy | grep -m 3 rbac
 

Resposta (não copie)

[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:67] checking request: remoteAddress: 10.16.5.15:37310, localAddress: 10.16.3.8:7000, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/frontend/sa/frontend, subjectPeerCertificate: , headers: ':method', 'POST'
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:118] enforced denied
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][http] [external/envoy/source/common/http/conn_manager_impl.cc:1354] [C115][S17310331589050212978] Sending local reply with details rbac_access_denied
  1. Agora, vamos permitir que o front-end, mas não os outros serviços de back-end, acesse o currencyservice. Abra currency-allow-frontend.yaml e inspecione o conteúdo. Adicionamos a seguinte regra:
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml

Resposta (não copie)

rules:
 - from:
   - source:
       principals: ["cluster.local/ns/frontend/sa/frontend"]

Aqui, estamos adicionando à lista de permissões um source.principal (cliente) específico para acessar o serviço de moeda. Esse source.principal é definido pela conta de serviço do Kubernetes. Nesse caso, a conta de serviço que estamos adicionando à lista de permissões é a conta de serviço de front-end no namespace de front-end.

Observação:ao usar contas de serviço do Kubernetes em AuthorizationPolicies do Istio, primeiro ative o TLS mútuo em todo o cluster, como fizemos no módulo 1. Isso garante que as credenciais da conta de serviço sejam incluídas nas solicitações.

  1. Copie a política de moeda atualizada
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. Envie as mudanças por push.
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend"
git push
 
  1. Confira o status do projeto de operações do Cloud Build em uma guia aberta anteriormente ou clicando no link a seguir:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
  1. Depois que o build for concluído, abra o front-end da Hipstershop novamente. Desta vez, não deve haver erros na página inicial, porque o front-end tem permissão explícita para acessar o serviço atual.
  2. Agora, tente fazer uma finalização de compra. Para isso, adicione itens ao carrinho e clique em "Fazer pedido". Desta vez, você vai encontrar um erro de conversão de preço do serviço de moeda. Isso acontece porque só adicionamos o front-end à lista de permissões. Portanto, o checkoutservice ainda não consegue acessar o currencyservice.

7e30813d693675fe.png

  1. Por fim, vamos permitir que o serviço de finalização de compra acesse a moeda adicionando outra regra à AuthorizationPolicy do currencyservice. Estamos abrindo o acesso à moeda apenas para os dois serviços que precisam dela: front-end e finalização da compra. Os outros back-ends ainda serão bloqueados.
  2. Abra currency-allow-frontend-checkout.yaml e inspecione o conteúdo. A lista de regras funciona como um OR lógico. A moeda aceita apenas solicitações de cargas de trabalho com uma dessas duas contas de serviço.
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml
 

Resposta (não copie)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/frontend/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/checkout/sa/checkout"]
  1. Copie a política de autorização final para k8s-repo.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. Enviar mudanças
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend and checkout"
git push
 
  1. Confira o status do projeto de operações do Cloud Build em uma guia aberta anteriormente ou clicando no link a seguir:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
 
  1. Depois que o build for concluído, tente fazer um pagamento. Ele deve funcionar.

Esta seção mostrou como usar as políticas de autorização do Istio para aplicar o controle de acesso granular no nível de cada serviço. Em produção, é possível criar uma AuthorizationPolicy por serviço e, por exemplo, usar uma política de permissão total para permitir que todas as cargas de trabalho no mesmo namespace acessem umas às outras.

12. Escalonamento de infraestrutura

Objetivo: escalonar a infraestrutura adicionando novas regiões, projetos e clusters.

  • Clone o repositório infrastructure
  • Atualizar os arquivos do Terraform para criar novos recursos
  • Duas sub-redes na nova região (uma para o projeto de operações e outra para o novo projeto)
  • Novo cluster de operações em uma nova região (na nova sub-rede)
  • Novo plano de controle do Istio para a nova região
  • Dois clusters de apps no novo projeto na nova região
  • Fazer commit no repositório infrastructure
  • Confirme a instalação

Instruções do laboratório sobre o método de copiar e colar

Há várias maneiras de escalonar uma plataforma. Para adicionar mais capacidade de computação, adicione nós aos clusters atuais. É possível adicionar mais clusters em uma região. Ou você pode adicionar mais regiões à plataforma. A decisão sobre qual aspecto da plataforma dimensionar depende dos requisitos. Por exemplo, se você tiver clusters em todas as três zonas de uma região, talvez seja suficiente adicionar mais nós (ou pools de nós) ao cluster atual. No entanto, se você tiver clusters em duas das três zonas em uma única região, adicionar um novo cluster na terceira zona vai oferecer escalonamento e um domínio de falha adicional (ou seja, uma nova zona). Outro motivo para adicionar um novo cluster em uma região pode ser a necessidade de criar um cluster de locatário único por motivos regulatórios ou de compliance (por exemplo, PCI ou um cluster de banco de dados que armazena informações de identificação pessoal). À medida que sua empresa e seus serviços se expandem, adicionar novas regiões se torna inevitável para oferecer serviços mais próximos aos clientes.

A plataforma atual consiste em duas regiões e clusters em duas zonas por região. É possível pensar no escalonamento da plataforma de duas maneiras:

  • Verticalmente: em cada região, adicionando mais computação. Isso é feito adicionando mais nós (ou pools de nós) aos clusters atuais ou adicionando novos clusters na região. Isso é feito pelo repositório infrastructure. A maneira mais simples é adicionar nós aos clusters atuais. Não é preciso fazer nenhuma configuração adicional. A adição de novos clusters pode exigir sub-redes (e intervalos secundários) adicionais, a inclusão de regras de firewall adequadas, a adição dos novos clusters ao plano de controle regional da malha de serviço do ASM/Istio e a implantação de recursos de aplicativos nos novos clusters.
  • Horizontalmente: adicionando mais regiões. A plataforma atual oferece um modelo regional. Ele consiste em um cluster de operações regional em que o plano de controle do ASM/Istio reside e dois (ou mais) clusters de aplicativos zonais em que os recursos do aplicativo são implantados.

Neste workshop, você vai escalonar a plataforma "horizontalmente", já que ela também abrange as etapas do caso de uso vertical. Para escalonar horizontalmente a plataforma adicionando uma nova região (r3), os seguintes recursos precisam ser adicionados:

  1. Sub-redes na VPC compartilhada do projeto host na região r3 para os novos clusters de operações e aplicativos.
  2. Um cluster de operações regional na região r3 em que reside o plano de controle do ASM/Istio.
  3. Dois clusters de aplicativos zonais em duas zonas na região r3.
  4. Atualize para o k8s-repo:
  5. Implante recursos do plano de controle do ASM/Istio no cluster de operações na região r3.
  6. Implante recursos compartilhados do plano de controle do ASM/Istio nos clusters de apps na região r3.
  7. Embora não seja necessário criar um novo projeto, as etapas do workshop mostram como adicionar um novo projeto dev3 para abranger o caso de uso de adição de uma nova equipe à plataforma.

O repositório de infraestrutura é usado para adicionar os novos recursos mencionados acima.

  1. No Cloud Shell, navegue até WORKDIR e clone o repositório infrastructure.
mkdir -p $WORKDIR/infra-repo
cd $WORKDIR/infra-repo
git init && git remote add origin https://source.developers.google.com/p/${TF_ADMIN}/r/infrastructure
git config --local user.email ${MY_USER}
git config --local user.name "infra repo user"
git config --local credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
  1. Clone a ramificação add-proj do repositório de origem do workshop no diretório add-proj-repo.
cd $WORKDIR
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git add-proj-repo -b add-proj

 
  1. Copie os arquivos da ramificação add-proj no repositório do workshop de origem. O branch add-proj contém as mudanças desta seção.
cp -r $WORKDIR/add-proj-repo/infrastructure/* $WORKDIR/infra-repo/
 
  1. Substitua o diretório infrastructure no diretório do repositório add-proj por um link simbólico para o diretório infra-repo para permitir que os scripts na ramificação sejam executados.
rm -rf $WORKDIR/add-proj-repo/infrastructure
ln -s $WORKDIR/infra-repo $WORKDIR/add-proj-repo/infrastructure
 
  1. Execute o script add-project.sh para copiar os estados e as variáveis compartilhados para a nova estrutura de diretório do projeto.
$WORKDIR/add-proj-repo/scripts/add-project.sh app3 $WORKDIR/asm $WORKDIR/infra-repo
  1. Confirmar e enviar mudanças para criar um novo projeto
cd $WORKDIR/infra-repo
git add .
git status
git commit -m "add new project" && git push origin master
 

  1. O commit aciona o repositório infrastructure para implantar a infraestrutura com os novos recursos. Para conferir o progresso do Cloud Build, clique na saída do link a seguir e navegue até o build mais recente na parte de cima.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

A última etapa do infrastructure Cloud Build cria novos recursos do Kubernetes no k8s-repo. Isso aciona o Cloud Build no k8s-repo (no projeto de operações). Os novos recursos do Kubernetes são para os três novos clusters adicionados na etapa anterior. O plano de controle do ASM/Istio e os recursos do plano de controle compartilhado são adicionados aos novos clusters com o k8s-repo do Cloud Build.

  1. Depois que o Cloud Build da infraestrutura for concluído, navegue até a k8s-repo execução mais recente do Cloud Build clicando no seguinte link de saída.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. Execute o script a seguir para adicionar os novos clusters ao arquivo vars e kubeconfig.
$WORKDIR/add-proj-repo/scripts/setup-gke-vars-kubeconfig-add-proj.sh $WORKDIR/asm
 
  1. Mude a variável KUBECONFIG para apontar para o novo arquivo kubeconfig.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. Liste os contextos de cluster. Oito clusters vão aparecer.
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_user001-200204-05-dev1-49tqc4_us-west1-a_gke-1-apps-r1a-prod
gke_user001-200204-05-dev1-49tqc4_us-west1-b_gke-2-apps-r1b-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-a_gke-3-apps-r2a-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-b_gke-4-apps-r2b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-b_gke-5-apps-r3b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-c_gke-6-apps-r3c-prod
gke_user001-200204-05-ops-49tqc4_us-central1_gke-asm-2-r2-prod
gke_user001-200204-05-ops-49tqc4_us-east1_gke-asm-3-r3-prod
gke_user001-200204-05-ops-49tqc4_us-west1_gke-asm-1-r1-prod

Verificar a instalação do Istio

  1. Verifique se o Istio está instalado no novo cluster de operações. Para isso, confira se todos os pods estão em execução e se os jobs foram concluídos.
kubectl --context $OPS_GKE_3 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-72g6w                  1/1     Running   0          5h12m
istio-citadel-7d8595845-hmmvj             1/1     Running   0          5h12m
istio-egressgateway-779b87c464-rw8bg      1/1     Running   0          5h12m
istio-galley-844ddfc788-zzpkl             2/2     Running   0          5h12m
istio-ingressgateway-59ccd6574b-xfj98     1/1     Running   0          5h12m
istio-pilot-7c8989f5cf-5plsg              2/2     Running   0          5h12m
istio-policy-6674bc7678-2shrk             2/2     Running   3          5h12m
istio-sidecar-injector-7795bb5888-kbl5p   1/1     Running   0          5h12m
istio-telemetry-5fd7cbbb47-c4q7b          2/2     Running   2          5h12m
istio-tracing-cd67ddf8-2qwkd              1/1     Running   0          5h12m
istiocoredns-5f7546c6f4-qhj9k             2/2     Running   0          5h12m
kiali-7964898d8c-l74ww                    1/1     Running   0          5h12m
prometheus-586d4445c7-x9ln6               1/1     Running   0          5h12m
  1. Verifique se o Istio está instalado nos dois clusters dev3. Somente o Citadel, o sidecar-injector e o coredns são executados nos clusters dev3. Eles compartilham um plano de controle do Istio em execução no cluster ops-3.
kubectl --context $DEV3_GKE_1 get pods -n istio-system
kubectl --context $DEV3_GKE_2 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

Verificar a descoberta de serviços para planos de controle compartilhados

  1. Verifique se os secrets estão implantados em todos os clusters de operações para todos os seis clusters de aplicativos.
kubectl --context $OPS_GKE_1 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_2 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_3 get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      14h
gke-2-apps-r1b-prod   Opaque   1      14h
gke-3-apps-r2a-prod   Opaque   1      14h
gke-4-apps-r2b-prod   Opaque   1      14h
gke-5-apps-r3b-prod   Opaque   1      5h12m
gke-6-apps-r3c-prod   Opaque   1      5h12m

13. Quebra de circuito

Objetivo: implementar um disjuntor para o serviço de frete.

  • Crie um DestinationRule para o serviço shipping implementar um disjuntor.
  • Use fortio (um utilitário de geração de carga) para validar o disjuntor do serviço shipping acionando o circuito

Instruções do laboratório de programação do Fast Track

O Fast Track Script Lab vai chegar em breve!

Instruções do laboratório sobre o método de copiar e colar

Agora que aprendemos algumas estratégias básicas de monitoramento e solução de problemas para serviços habilitados para Istio, vamos ver como o Istio ajuda a melhorar a resiliência dos seus serviços, reduzindo a quantidade de solução de problemas que você terá que fazer.

Uma arquitetura de microsserviços introduz o risco de falhas em cascata, em que a falha de um serviço pode se propagar para as dependências dele e as dependências dessas dependências, causando uma interrupção de "efeito cascata" que pode afetar os usuários finais. O Istio oferece uma política de tráfego de disjuntor para ajudar você a isolar serviços, protegendo os serviços downstream (do lado do cliente) contra a espera por serviços com falha e protegendo os serviços upstream (do lado do servidor) contra um fluxo repentino de tráfego downstream quando eles voltam a ficar on-line. No geral, usar disjuntores pode ajudar você a evitar que todos os serviços falhem nos SLOs devido a um serviço de back-end travado.

O padrão de disjuntor recebe esse nome por causa de um interruptor elétrico que pode "disparar" quando há um fluxo excessivo de eletricidade, protegendo os dispositivos contra sobrecarga. Em uma configuração do Istio, isso significa que o Envoy é o disjuntor, acompanhando o número de solicitações pendentes de um serviço. Nesse estado fechado padrão, as solicitações fluem pelo Envoy sem interrupção.

No entanto, quando o número de solicitações pendentes excede o limite definido, o disjuntor é acionado (abre), e o Envoy retorna um erro imediatamente. Isso permite que o servidor falhe rapidamente para o cliente e impede que o código do aplicativo do servidor receba a solicitação do cliente quando estiver sobrecarregado.

Depois do tempo limite definido, o Envoy passa para um estado semiaberto, em que o servidor pode começar a receber solicitações novamente de maneira provisória. Se ele conseguir responder às solicitações, o disjuntor será fechado novamente, e as solicitações para o servidor começarão a fluir novamente.

Este diagrama resume o padrão de disjuntor do Istio. Os retângulos azuis representam o Envoy, o círculo azul representa o cliente, e os círculos brancos representam o contêiner do servidor:

2127a0a172ff4802.png

É possível definir políticas de interruptor de circuito usando DestinationRules do Istio. Nesta seção, vamos aplicar a seguinte política para impor um disjuntor ao serviço de frete:

Output (do not copy)

apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "shippingservice-shipping-destrule"
  namespace: "shipping"
spec:
  host: "shippingservice.shipping.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutiveErrors: 1
      interval: 1s
      baseEjectionTime: 10s
      maxEjectionPercent: 100

Há dois campos DestinationRule a serem observados aqui. connectionPool define o número de conexões que esse serviço vai permitir. O campo "outlierDetection" é onde configuramos como o Envoy vai determinar o limite para abrir o disjuntor. Aqui, a cada segundo (intervalo), o Envoy conta o número de erros recebidos do contêiner do servidor. Se ele exceder o limite de consecutiveErrors, o disjuntor do Envoy será aberto, e 100% dos pods do productcatalog serão protegidos contra novas solicitações de clientes por 10 segundos. Quando o disjuntor do Envoy estiver aberto (ou seja, ativo), os clientes vão receber erros 503 (Serviço indisponível). Vamos ver tudo funcionando.

  1. Defina variáveis de ambiente para os diretórios k8s-repo e asm para simplificar os comandos.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm" 
 
  1. Atualizar o k8s-repo
cd $WORKDIR/k8s-repo
git pull
cd $WORKDIR
  1. Atualize a DestinationRule do serviço de frete nos dois clusters de operações.
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml

cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
 
  1. Copie um pod gerador de carga Fortio para o cluster GKE_1 na região Dev1. Esse é o pod cliente que vamos usar para "acionar" o disjuntor do shippingservice.
cp $ASM/k8s_manifests/prod/app/deployments/app-fortio.yaml ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments/
cd ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments; kustomize edit add resource app-fortio.yaml
 
  1. Faça commit das mudanças.
cd $K8S_REPO 
git add . && git commit -am "Circuit Breaker: shippingservice"
git push
cd $ASM
 
  1. Aguarde a conclusão do Cloud Build.
  2. De volta ao Cloud Shell, use o pod do Fortio para enviar tráfego gRPC para o shippingservice com uma conexão simultânea e um total de 1.000 solicitações. Isso não vai acionar o disjuntor porque ainda não excedemos as configurações de connectionPool.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 1 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

Resposta (não copie)

Health SERVING : 1000
All done 1000 calls (plus 0 warmup) 4.968 ms avg, 201.2 qps
  1. Agora execute o fortio novamente, aumentando o número de conexões simultâneas para 2, mas mantendo o número total de solicitações constante. Até dois terços das solicitações vão retornar um erro"overflow", porque o disjuntor foi acionado:na política que definimos, apenas uma conexão simultânea é permitida em um intervalo de um segundo.
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 2 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

Resposta (não copie)

18:46:16 W grpcrunner.go:107> Error making grpc call: rpc error: code = Unavailable desc = upstream connect error or disconnect/reset before headers. reset reason: overflow
...

Health ERROR : 625
Health SERVING : 375
All done 1000 calls (plus 0 warmup) 12.118 ms avg, 96.1 qps
  1. O Envoy acompanha o número de conexões descartadas quando o disjuntor está ativo, com a métrica upstream_rq_pending_overflow. Vamos encontrar isso no pod do fortio:
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c istio-proxy  -- sh -c 'curl localhost:15000/stats' | grep shipping | grep pending
 

Resposta (não copie)

cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_failure_eject: 9
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_overflow: 565
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_total: 1433
  1. Faça a limpeza removendo a política de disjuntor das duas regiões.
kubectl --context ${OPS_GKE_1} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
 

kubectl --context ${OPS_GKE_2} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
cd $K8S_REPO; git add .; git commit -m "Circuit Breaker: cleanup"; git push origin master
 

Esta seção mostrou como configurar uma única política de disjuntor para um serviço. Uma prática recomendada é configurar um disjuntor para qualquer serviço de back-end (back-end) que possa ficar travado. Ao aplicar políticas de disjuntor do Istio, você ajuda a isolar seus microsserviços, cria tolerância a falhas na sua arquitetura e reduz o risco de falhas em cascata sob alta carga.

14. Injeção de falha

Objetivo: testar a resiliência do serviço de recomendação introduzindo atrasos (antes de ser enviado para produção).

  • Crie um VirtualService para o serviço recommendation e introduza um atraso de 5 segundos.
  • Testar o atraso usando o gerador de carga fortio
  • Remova o atraso no VirtualService e valide

Instruções do laboratório de programação do Fast Track

O Fast Track Script Lab vai chegar em breve!

Instruções do laboratório sobre o método de copiar e colar

Adicionar políticas de disjuntor aos seus serviços é uma maneira de criar resiliência contra serviços em produção. No entanto, a interrupção do circuito resulta em falhas, potencialmente erros voltados ao usuário, o que não é o ideal. Para evitar esses casos de erro e prever melhor como seus serviços downstream podem responder quando os back-ends retornam erros, adote o teste de caos em um ambiente de staging. O teste de caos é a prática de quebrar deliberadamente seus serviços para analisar pontos fracos no sistema e melhorar a tolerância a falhas. Também é possível usar testes de caos para identificar maneiras de reduzir erros que afetam o usuário quando os back-ends falham. Por exemplo, mostrando um resultado em cache em um front-end.

Usar o Istio para injeção de falhas é útil porque você pode usar as imagens de lançamento de produção e adicionar a falha na camada de rede, em vez de modificar o código-fonte. Em produção, você pode usar uma ferramenta de teste de caos completa para testar a resiliência na camada de computação/Kubernetes, além da camada de rede.

É possível usar o Istio para testes de caos aplicando um VirtualService com o campo "fault". O Istio oferece suporte a dois tipos de falhas: falhas de atraso (injetam um tempo limite) e falhas de interrupção (injetam erros HTTP). Neste exemplo, vamos injetar uma falha de atraso de 5 segundos no serviço de recomendações. Mas, desta vez, em vez de usar um disjuntor para "falhar rapidamente" contra esse serviço travado, vamos forçar os serviços downstream a suportar o tempo limite total.

  1. Navegue até o diretório de injeção de falhas.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm/" 
cd $ASM
 
  1. Abra k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml para inspecionar o conteúdo. O Istio tem uma opção para injetar a falha em uma porcentagem das solicitações. Aqui, vamos introduzir um tempo limite em todas as solicitações do "recommendationservice".

Resposta (não copie)

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation-delay-fault
spec:
  hosts:
  - recommendationservice.recommendation.svc.cluster.local
  http:
  - route:
    - destination:
        host: recommendationservice.recommendation.svc.cluster.local
    fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 5s
  1. Copie o VirtualService para k8s_repo. Vamos injetar a falha globalmente, nas duas regiões.
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml

cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
 
  1. Enviar mudanças
cd $K8S_REPO 
git add . && git commit -am "Fault Injection: recommendationservice"
git push
cd $ASM
 
  1. Aguarde a conclusão do Cloud Build.
  2. Execute o comando exec no pod do fortio implantado na seção de disjuntor e envie tráfego para o recommendationservice.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 100 -n 100 -qps 0 recommendationservice.recommendation.svc.cluster.local:8080
 
    Once the fortio command is complete, you should see responses averaging 5s:

Resposta (não copie)

Ended after 5.181367359s : 100 calls. qps=19.3
Aggregated Function Time : count 100 avg 5.0996506 +/- 0.03831 min 5.040237641 max 5.177559818 sum 509.965055
  1. Outra maneira de ver a falha injetada em ação é abrir o front-end em um navegador da Web e clicar em qualquer produto. Uma página de produto leva 5 segundos a mais para carregar, já que busca as recomendações exibidas na parte de baixo da página.
  2. Para fazer a limpeza, remova o serviço de injeção de falhas dos dois clusters do Ops.
kubectl --context ${OPS_GKE_1} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml

kubectl --context ${OPS_GKE_2} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
 
  1. Enviar mudanças:
cd $K8S_REPO 
git add . && git commit -am "Fault Injection cleanup / restore"
git push
cd $ASM
 

15. Como monitorar o plano de controle do Istio

O ASM instala quatro componentes importantes do plano de controle: Pilot, Mixer, Galley e Citadel. Cada um envia as métricas de monitoramento relevantes para o Prometheus, e o ASM vem com painéis do Grafana que permitem aos operadores visualizar esses dados de monitoramento e avaliar a integridade e o desempenho do plano de controle.

Como ver os painéis

  1. Encaminhar portas do serviço do Grafana instalado com o Istio
kubectl --context ${OPS_GKE_1} -n istio-system port-forward svc/grafana 3000:3000 >> /dev/null
 
  1. Abra o Grafana no navegador
  2. Clique no ícone "Visualização na Web" no canto superior direito da janela do Cloud Shell.
  3. Clique em "Visualizar na porta 3000". Observação: se a porta não for 3000, clique em "Alterar porta" e selecione a porta 3000.
  4. Isso vai abrir uma guia no navegador com um URL semelhante a " BASE_URL/?orgId=1&authuser=0&environment_id=default"
  5. Ver os painéis disponíveis
  6. Modifique o URL para " BASE_URL/dashboard"
  7. Clique na pasta "istio" para ver os painéis disponíveis.
  8. Clique em qualquer um desses painéis para conferir a performance do componente. Vamos analisar as métricas importantes de cada componente nas seções a seguir.

Piloto de monitoramento

O Pilot é o componente do plano de controle que distribui a configuração de rede e de política para o plano de dados (os proxies Envoy). O Pilot tende a ser dimensionado com o número de cargas de trabalho e implantações, embora não necessariamente com a quantidade de tráfego para essas cargas de trabalho. Um piloto não íntegro pode:

  • consumir mais recursos do que o necessário (CPU e/ou RAM)
  • resultar em atrasos no envio de informações de configuração atualizadas para os envoys.

Observação: se o Pilot estiver inativo ou houver atrasos, suas cargas de trabalho ainda vão veicular tráfego.

  1. Navegue até "BASE_URL/dashboard/db/istio-pilot-dashboard" no navegador para conferir as métricas do Pilot.

Métricas monitoradas importantes

Uso de recursos

Use a página de desempenho e escalonabilidade do Istio como guia para números de uso aceitáveis. Entre em contato com o suporte do GCP se você notar um uso de recursos muito maior do que isso.

5f1969f8e2c8b137.png

Informações sobre o envio de notificações push do programa piloto

Esta seção monitora os pushs de configuração do Pilot para seus proxies Envoy.

  • Envios de piloto mostra o tipo de configuração enviada em um determinado momento.
  • O monitoramento do ADS mostra o número de serviços virtuais, serviços e endpoints conectados no sistema.
  • Clusters sem endpoints conhecidos mostra endpoints que foram configurados, mas não têm instâncias em execução, o que pode indicar serviços externos, como *.googleapis.com.
  • Erros de piloto mostram o número de erros encontrados ao longo do tempo.
  • Conflitos mostra o número de conflitos, que são configurações ambíguas em listeners.

Se você tiver erros ou conflitos, a configuração de um ou mais serviços está incorreta ou inconsistente. Consulte "Solução de problemas do plano de dados" para mais informações.

Informações do Envoy

Esta seção contém informações sobre os proxies do Envoy que entram em contato com o plano de controle. Entre em contato com o suporte do GCP se você encontrar falhas repetidas na conexão XDS.

Mesa de monitoramento

O Mixer é o componente que canaliza a telemetria dos proxies do Envoy para back-ends de telemetria (geralmente Prometheus, Stackdriver etc.). Nessa capacidade, ele não está no plano de dados. Ele é implantado como dois jobs do Kubernetes (chamados Mixer) com dois nomes de serviço diferentes (istio-telemetry e istio-policy).

O Mixer também pode ser usado para integrar com sistemas de políticas. Nessa capacidade, o Mixer afeta o plano de dados, já que as verificações de política que falham bloqueiam o acesso aos seus serviços.

O Mixer tende a ser dimensionado com o volume de tráfego.

  1. Acesse " BASE_URL/dashboard/db/istio-mixer-dashboard" no navegador para conferir as métricas do Mixer.

Métricas monitoradas importantes

Uso de recursos

Use a página de desempenho e escalonabilidade do Istio como guia para números de uso aceitáveis. Entre em contato com o suporte do GCP se você notar um uso de recursos muito maior do que isso.

87ed83238f9addd8.png

Visão geral do Mixer

  • A duração da resposta é uma métrica importante. Embora os relatórios para a telemetria do Mixer não estejam no caminho de dados, se essas latências forem altas, o desempenho do proxy sidecar será afetado. O 90º percentil deve estar em milissegundos de um único dígito, e o 99º percentil deve ser inferior a 100 ms.

e07bdf5fde4bfe87.png

  • A duração do envio do adaptador indica a latência que o Mixer está enfrentando ao chamar adaptadores (pelos quais ele envia informações para sistemas de telemetria e geração de registros). Latências altas aqui vão afetar o desempenho na malha. Novamente, as latências p90 precisam ser menores que 10 ms.

1c2ee56202b32bd9.png

Galeria de monitoramento

O Galley é o componente de validação, ingestão, processamento e distribuição da configuração do Istio. Ele transmite a configuração do servidor da API Kubernetes para o Pilot. Assim como o Pilot, ele tende a escalonar com o número de serviços e endpoints no sistema.

  1. Navegue até " BASE_URL/dashboard/db/istio-galley-dashboard" no navegador para conferir as métricas do Galley.

Métricas monitoradas importantes

Validação de recursos

A métrica mais importante a ser seguida, que indica o número de recursos de vários tipos, como regras de destino, gateways e entradas de serviço que estão passando ou falhando na validação.

Clientes conectados

Indica quantos clientes estão conectados ao Galley. Normalmente, são três (piloto, istio-telemetry, istio-policy), e esse número aumenta conforme esses componentes são escalonados.

16. Solução de problemas do Istio

Solução de problemas do plano de dados

Se o painel do Pilot indicar que você tem problemas de configuração, examine os registros do Pilot ou use o istioctl para encontrar problemas de configuração.

Para examinar os registros do Pilot, execute kubectl -n istio-system logs istio-pilot-69db46c598-45m44 discovery, substituindo istio-pilot-... pelo identificador do pod da instância do Pilot que você quer resolver.

No registro resultante, procure uma mensagem de Status do push. Exemplo:

2019-11-07T01:16:20.451967Z        info        ads        Push Status: {
    "ProxyStatus": {
        "pilot_conflict_outbound_listener_tcp_over_current_tcp": {
            "0.0.0.0:443": {
                "proxy": "cartservice-7555f749f-k44dg.hipster",
                "message": "Listener=0.0.0.0:443 AcceptedTCP=accounts.google.com,*.googleapis.com RejectedTCP=edition.cnn.com TCPServices=2"
            }
        },
        "pilot_duplicate_envoy_clusters": {
            "outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            }
        },
        "pilot_eds_no_instances": {
            "outbound_.80_._.frontend-external.hipster.svc.cluster.local": {},
            "outbound|443||*.googleapis.com": {},
            "outbound|443||accounts.google.com": {},
            "outbound|443||metadata.google.internal": {},
            "outbound|80||*.googleapis.com": {},
            "outbound|80||accounts.google.com": {},
            "outbound|80||frontend-external.hipster.svc.cluster.local": {},
            "outbound|80||metadata.google.internal": {}
        },
        "pilot_no_ip": {
            "loadgenerator-778c8489d6-bc65d.hipster": {
                "proxy": "loadgenerator-778c8489d6-bc65d.hipster"
            }
        }
    },
    "Version": "o1HFhx32U4s="
}

O status do push indica problemas que ocorreram ao tentar enviar a configuração para proxies do Envoy. Nesse caso, vemos várias mensagens "Duplicate cluster", que indicam destinos upstream duplicados.

Para receber ajuda no diagnóstico de problemas, entre em contato com o suporte do Google Cloud.

Encontrar erros de configuração

Para usar o istioctl e analisar sua configuração, execute istioctl experimental analyze -k --context $OPS_GKE_1. Isso vai realizar uma análise da configuração no seu sistema, indicar problemas e sugerir mudanças. Consulte a documentação para ver uma lista completa de erros de configuração que esse comando pode detectar.

17. Limpeza

Um administrador executa o script cleanup_workshop.sh para excluir os recursos criados pelo script bootstrap_workshop.sh. Você precisa das seguintes informações para executar o script de limpeza.

  • Nome da organização, por exemplo, yourcompany.com
  • ID do workshop: no formato YYMMDD-NN, por exemplo, 200131-01
  • Bucket do GCS do administrador: definido no script de inicialização.
  1. Abra o Cloud Shell e execute todas as ações abaixo nele. Clique no link abaixo.

CLOUD SHELL

  1. Verifique se você fez login na gcloud com o usuário administrador pretendido.
gcloud config list
 
  1. Navegue até a pasta asm.
cd ${WORKDIR}/asm
 
  1. Defina o nome da organização e o ID do workshop a ser excluído.
export ORGANIZATION_NAME=<ORGANIZATION NAME>
export ASM_WORKSHOP_ID=<WORKSHOP ID>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. Execute o script de limpeza da seguinte maneira.
./scripts/cleanup_workshop.sh --workshop-id ${ASM_WORKSHOP_ID} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --org-name ${ORGANIZATION_NAME}