1. Olá
Obrigado por participar do codelab Istio Multi Cloud Burst do Google.Ele exige experiência prática de nível iniciante com Kubernetes, Node e Go. O que é preciso
|
|
O que você aprenderá
- Como criar um cluster do Kubernetes no GKE
- Como instalar o Istio em um cluster do Kubernetes com o Helm
- Como instalar o Istio Multicluster com o Helm
- Como implantar um aplicativo da Web da origem para o Kubernetes
- Como gravar e aplicar regras de roteamento de tráfego ao Istio
- Métricas do Prometheus
- Criar e enviar imagens de contêiner em um cluster do Kubernetes
2. Etapas da configuração
Você pode seguir este codelab em:
- Google Cloud Shell (recomendado): shell no navegador, vem com ferramentas instaladas
- seu laptop (siga as instruções abaixo)
Começar a usar o Google Cloud Platform
- Retire seu cartão de conta de usuário sem custo financeiro com o instrutor se você não tiver uma conta do GCP.
- Acesse o Console do Google Cloud e clique em "Selecionar um projeto":

- Anote o "ID" do projeto em algum lugar e clique nele para escolher:

Opção 1: usar o Google Cloud Shell (recomendado)
O Cloud Shell oferece um shell de linha de comando no navegador com as ferramentas necessárias instaladas e autenticadas automaticamente na sua conta do Google Cloud Platform. Se você não quiser fazer este exercício no Cloud Shell, pule para a próxima seção.
Acesse o console do Cloud e clique em "Ativar o Cloud Shell" na barra de ferramentas no canto superior direito:

Adicionar ferramentas ao Cloud Shell
- Instale
kubectx****: faça o download dos scripts bash aqui em um local em $PATH. - Instale
helm**** seguindo estas instruções.
Como alternativa, execute estes comandos para instalar os dois em ~/.bin e adicionar ao $PATH:
mkdir -p ~/.bin && \
cd ~/.bin && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubectx && \
chmod +x kubectx && \
curl -LO https://raw.githubusercontent.com/ahmetb/kubectx/master/kubens && \
chmod +x kubens && \
curl -LO https://storage.googleapis.com/kubernetes-helm/helm-v2.12.0-linux-amd64.tar.gz && \
tar xzf helm-v2.12.0-linux-amd64.tar.gz && \
rm helm-v2.12.0-linux-amd64.tar.gz && \
mv linux-amd64/helm ./helm && \
rm -r linux-amd64 && \
export PATH=${HOME}/.bin:${PATH}
Algumas dicas rápidas para facilitar o uso do Cloud Shell:
1. Desanexe o shell em uma nova janela: |
|
2. Usando o editor de arquivos: clique no ícone de lápis no canto superior direito para abrir um editor de arquivos no navegador. Isso será útil porque vamos copiar snippets de código para arquivos. |
|
3. Iniciar novas guias:se você precisar de mais de um comando de terminal. |
|
4. Aumente o texto: o tamanho padrão da fonte no Cloud Shell pode ser muito pequeno para leitura. | Ctrl-+ no Linux/Windows⌘-+ no macOS. |
Opção 2: configurar o laptop (não recomendado)
Se você preferir usar seu próprio ambiente de estação de trabalho em vez do Cloud Shell, configure as seguintes ferramentas:
- Instale
gcloud:(pré-instalado no Cloud Shell). Siga as instruções para instalar ogcloudna sua plataforma. Vamos usar isso para criar um cluster do Kubernetes. - Instale
kubectl:(pré-instalado no Cloud Shell). Execute o comando a seguir para instalar:
gcloud components install kubectl
Execute o seguinte comando para autenticar o gcloud. Ele vai pedir para você fazer login com sua Conta do Google. Em seguida, escolha o projeto pré-criado (mostrado acima) como padrão. (Você pode pular a configuração de uma zona do Compute):
gcloud init
- Instale o
curl:, que já vem instalado na maioria dos sistemas Linux/macOS. Você provavelmente já tem. Caso contrário, pesquise na Internet como fazer isso. - Instale
kubectx****: faça o download dos scripts bash aqui em um local em $PATH. - Instale
helm**** seguindo estas instruções.
3. Configurar projeto do GCP
Ative as APIs do GKE (Google Kubernetes Engine), GCR (Google Container Registry) e GCB (Google Cloud Build) no seu projeto:
gcloud services enable \ cloudapis.googleapis.com \ container.googleapis.com \ containerregistry.googleapis.com \ cloudbuild.googleapis.com
Configurar variáveis de ambiente
Vamos trabalhar muito com nosso projeto do Google Cloud durante a configuração. Por isso, vamos definir uma variável de ambiente para referência rápida.
export GCLOUD_PROJECT=$(gcloud config get-value project)
Vamos criar alguns arquivos de código e de configuração durante este workshop. Por isso, crie um diretório de projeto e mude para ele.
mkdir -p src/istio-burst && \ cd src/istio-burst && \ export proj=$(pwd)
4. Criar o cluster do Kubernetes "primary"
É fácil criar um cluster gerenciado do Kubernetes com o Google Kubernetes Engine (GKE).
O comando a seguir cria um cluster do Kubernetes:
- chamado "primary",
- na zona us-west1-a,
- A versão mais recente disponível do Kubernetes,
- com quatro nós iniciais
export cluster=primary
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "4" --network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias
Isso pode levar cerca de 5 minutos. É possível acompanhar a criação do cluster no Console do Cloud.
Depois que o cluster do Kubernetes for criado, o gcloud vai configurar o kubectl com as credenciais que apontam para o cluster.
gcloud container clusters get-credentials $cluster --zone=$zone
Agora você pode usar kubectl com seu novo cluster.
Execute o seguinte comando para listar os nós do Kubernetes do cluster (eles precisam mostrar o status "Pronto"):
kubectl get nodes
Modificar nomes do Kubeconfig para facilitar o uso
Vamos alternar entre contextos com frequência, então ter um alias curto para nossos clusters é útil.
Esse comando vai renomear a entrada kubeconfig que você acabou de criar para primary.
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
Definir permissões:
Para implantar o Istio, é preciso ser um administrador de cluster. Esse comando vai definir o e-mail associado à sua conta do Google Cloud como administrador do cluster.
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
5. Criar cluster de "burst"
O comando a seguir cria um cluster do Kubernetes:
- chamado "burst",
- na zona us-west1-a,
- A versão mais recente disponível do Kubernetes,
- Com um nó inicial
- Escalonamento automático ativado para até cinco nós
export cluster=burst
export zone=us-west1-a
gcloud container clusters create $cluster --zone $zone --username "admin" \
--cluster-version latest --machine-type "n1-standard-2" \
--image-type "COS" --disk-size "100" \
--scopes "https://www.googleapis.com/auth/compute",\
"https://www.googleapis.com/auth/devstorage.read_only",\
"https://www.googleapis.com/auth/logging.write",\
"https://www.googleapis.com/auth/monitoring",\
"https://www.googleapis.com/auth/servicecontrol",\
"https://www.googleapis.com/auth/service.management.readonly",\
"https://www.googleapis.com/auth/trace.append" \
--num-nodes "1" --enable-autoscaling --min-nodes=1 --max-nodes=5 \
--network "default" \
--enable-cloud-logging --enable-cloud-monitoring --enable-ip-alias
Isso pode levar cerca de 5 minutos. É possível acompanhar a criação do cluster no Console do Cloud.
Depois que o cluster do Kubernetes for criado, o gcloud vai configurar o kubectl com as credenciais que apontam para o cluster.
gcloud container clusters get-credentials $cluster --zone=$zone
Agora você pode usar kubectl com seu novo cluster.
Execute o seguinte comando para listar os nós do Kubernetes do cluster (eles precisam mostrar o status "Pronto"):
kubectl get nodes
Modificar nomes do Kubeconfig para facilitar o uso
Esse comando vai modificar a entrada kubeconfig que você acabou de fazer para burst.
kubectx ${cluster}=gke_${GCLOUD_PROJECT}_${zone}_${cluster}
Definir permissões:
Para implantar o Istio Remote, é necessário ser um administrador de cluster. Esse comando vai definir o e-mail associado à sua conta do Google Cloud como administrador do cluster.
kubectl create clusterrolebinding cluster-admin-binding \
--clusterrole=cluster-admin \
--user=$(gcloud config get-value core/account)
6. Aplicar regras de firewall
Para que os dois clusters se comuniquem entre si, é necessário criar uma regra de firewall.
Execute os comandos a seguir para criar uma regra de firewall no Google Cloud Platform que permita a comunicação dos nossos clusters.
function join_by { local IFS="$1"; shift; echo "$*"; }
ALL_CLUSTER_CIDRS=$(gcloud container clusters list \
--filter="(name=burst OR name=primary) AND zone=$zone" \
--format='value(clusterIpv4Cidr)' | sort | uniq)
ALL_CLUSTER_CIDRS=$(join_by , $(echo "${ALL_CLUSTER_CIDRS}"))
ALL_CLUSTER_NETTAGS=$(gcloud compute instances list \
--filter="(metadata.cluster-name=burst OR metadata.cluster-name=primary) AND metadata.cluster-location=us-west1-a" \
--format='value(tags.items.[0])' | sort | uniq)
ALL_CLUSTER_NETTAGS=$(join_by , $(echo "${ALL_CLUSTER_NETTAGS}"))
gcloud compute firewall-rules create istio-multicluster-test-pods \
--allow=tcp,udp,icmp,esp,ah,sctp \
--direction=INGRESS \
--priority=900 \
--source-ranges="${ALL_CLUSTER_CIDRS}" \
--target-tags="${ALL_CLUSTER_NETTAGS}" --quiet
Os dois clusters estão configurados e prontos para a implantação do aplicativo e do Istio.
7. Introdução ao Istio
O que é o Istio?
O Istio é um plano de controle de malha de serviço que visa "conectar, proteger, controlar e observar serviços". Isso é feito de várias maneiras, mas principalmente usando um contêiner proxy ( Envoy) em cada um dos pods do Kubernetes implantados. O contêiner de proxy controla toda a comunicação de rede entre microsserviços em conjunto com uma política de uso geral e um hub de telemetria ( Mixer).

Essas políticas podem ser aplicadas de forma independente das suas implantações e serviços do Kubernetes. Isso significa que o operador de rede pode observar a atividade de rede, restringir, redirecionar ou reescrever políticas de rede sem reimplantar os aplicativos associados.
Alguns dos recursos de gerenciamento de tráfego compatíveis com o Istio são:
- Disjuntores
- Divisão de tráfego baseada em porcentagem
- Regravação de URL
- término de TLS
- Verificações de integridade
- Balanceamento de carga
Para este workshop, vamos nos concentrar na divisão de tráfego com base em porcentagens.
Termos do Istio que vamos usar
VirtualService
Um VirtualService define um conjunto de regras de roteamento de tráfego a serem aplicadas quando um host é resolvido.
Gateway
Um gateway é um balanceador de carga que opera na borda da malha e recebe conexões HTTP/TCP de entrada ou saída. Os gateways podem especificar portas, configurações de SNI etc.
DestinationRule (em inglês)
Uma DestinationRule define políticas que se aplicam ao tráfego destinado a um serviço após o roteamento. Eles especificam a configuração para balanceamento de carga, tamanho do pool de conexões do sidecar e configurações de detecção de outliers.
Istio Multicluster
Você deve ter notado que, ao criar os dois clusters, o primary tinha quatro nós sem escalonamento automático, e o burst tinha um nó com escalonamento automático de até cinco nós.
Há dois motivos para essa configuração.
Primeiro, vamos simular um cenário "no local" para a nuvem. Em um ambiente no local, você não tem acesso a clusters de escalonamento automático porque tem uma infraestrutura fixa.
Em segundo lugar, uma configuração de quatro nós (conforme definido acima) é o requisito mínimo para executar o Istio. Isso levanta a questão: se o Istio exige um mínimo de quatro nós, como nosso cluster burst pode executar o Istio com um nó? A resposta é que o Istio Multicluster instala um conjunto muito menor de serviços do Istio e se comunica com a instalação do Istio no cluster principal para recuperar as regras de política e publicar informações de telemetria.
8. Visão geral da arquitetura de aplicativos
Visão geral dos componentes
Vamos implantar um aplicativo de três níveis usando NodeJS e Redis.
Worker
O aplicativo de worker é escrito em NodeJS e detecta solicitações HTTP POST de entrada, realiza uma operação de hash nelas e, se uma variável de ambiente chamada PREFIX estiver definida, vai adicionar esse valor ao hash. Depois que o hash é calculado, o aplicativo envia o resultado no canal "calculation" no servidor Redis especificado.
Vamos usar a variável de ambiente PREFIX mais tarde para demonstrar a funcionalidade multicluster.
Para referência, estes são os pacotes usados pelo aplicativo.
body-parser:Permite analisar nossas solicitações HTTP.cors:Permite o uso do compartilhamento de recursos entre origens.dotenv:Análise fácil de variáveis de ambienteexpress:Hospedagem fácil de sites- Biblioteca de cliente
ioredis:para se comunicar com bancos de dados do Redis morgan:Fornece um registro estruturado adequado
Front-end
Nosso front-end também é um aplicativo NodeJS que hospeda uma página da Web usando o express. Ele usa uma frequência inserida pelo usuário e envia solicitações ao nosso aplicativo worker nessa taxa. Esse aplicativo também se inscreve em mensagens em um canal do Redis chamado "calculation" e mostra os resultados em uma página da Web.
O aplicativo usa as seguintes dependências.
body-parser:Permite analisar nossas solicitações HTTP.dotenv:Análise fácil de variáveis de ambienteexpress:Hospedagem fácil de sites- Biblioteca de cliente
ioredis:para se comunicar com bancos de dados do Redis morgan:Fornece registros estruturadosrequest:Permite fazer solicitações HTTP.socket.io:Permite a comunicação bidirecional da página da Web com o servidor
Esta página da Web usa o Bootstrap para estilização e, quando executada, tem esta aparência:

Diagrama de arquitetura

Diagrama de implantação
Vamos implantar nosso aplicativo final nos dois clusters que criamos. O cluster primary terá todos os componentes (frontend, worker e Redis) implantados nele, mas o cluster burst terá apenas o aplicativo worker implantado.
Confira um diagrama que descreve os dois clusters. As caixas em vermelho são serviços do Kubernetes, e as em azul são implantações do Kubernetes. As caixas amarelas significam nossa instalação do Istio.
Observe como o cluster burst ainda tem um serviço para o Redis implantado nele, mesmo que não haja uma implantação para o Redis no cluster. Precisamos ter esse serviço no cluster para que o DNS do Kubernetes possa resolver a solicitação. No entanto, quando a solicitação é feita, o proxy do Istio redireciona a solicitação para a implantação do Redis no cluster primary.
O aplicativo final terá uma implantação adicional em execução no cluster primary chamado istiowatcher.. Isso vai permitir que redirecionemos dinamicamente o tráfego para o burst automaticamente quando ele ultrapassar um determinado limite.

9. Criar arquivos de implantação de aplicativos
Precisamos criar um conjunto de manifestos do Kubernetes para implantar nosso aplicativo.
Mude para o diretório raiz do projeto e crie uma pasta chamada kubernetes.
mkdir ${proj}/kubernetes && cd ${proj}/kubernetes
Escrever frontend.yaml
Isso vai criar uma implantação e um serviço do Kubernetes para acessar nossa imagem de front-end.
Insira o seguinte em frontend.yaml.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: frontend-deployment
labels:
app: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: gcr.io/istio-burst-workshop/frontend
ports:
- containerPort: 8080
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8080
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8080
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8080"
- name: PROCESSOR_URL
value: "http://worker-service"
- name: REDIS_URL
value: "redis-cache-service:6379"
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: ClusterIP
selector:
app: frontend
ports:
- name: http
port: 80
targetPort: 8080
Principais pontos a serem observados no Deployment
- Especificamos que a porta em que o aplicativo será executado é
8080. - Definimos o endereço do worker como "
http://worker-service" e vamos usar o recurso DNS integrado do Kubernetes para resolver o serviço resultante. - Definimos o endereço do nosso
REDIS_URLcomo "redis-cache-service:6379" e vamos usar o recurso DNS integrado do Kubernetes para resolver os endereços IP resultantes. - Também definimos sondagens
livenessereadinesspara o contêiner, ajudando a informar ao Kubernetes quando ele está em execução.
Escrever worker-service.yaml
Estamos escrevendo a definição de serviço do Kubernetes em um arquivo separado da definição de implantação, já que vamos reutilizar esse serviço em vários clusters, mas vamos escrever uma implantação diferente para cada cluster.
Insira o seguinte em worker-service.yaml
apiVersion: v1
kind: Service
metadata:
name: worker-service
spec:
type: ClusterIP
selector:
app: worker
ports:
- name: http
port: 80
targetPort: 8081
Escrever worker-primary.yaml
Essa será a implantação de worker que vamos enviar para o cluster principal.
Insira o seguinte em worker-primary.yaml.
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: worker-deployment
labels:
app: worker
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
cluster-type: primary-cluster
spec:
containers:
- name: worker
image: gcr.io/istio-burst-workshop/worker
imagePullPolicy: Always
ports:
- containerPort: 8081
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
Note que estamos seguindo o mesmo padrão de fornecer sondas liveness e readiness, além de especificar as variáveis de ambiente PORT e REDIS_URL para uso no aplicativo.
Outra coisa a ser observada nessa implantação é a falta da variável de ambiente PREFIX. Isso significa que os resultados do cálculo serão hashes brutos (sem prefixo).
O último ponto importante dessa implantação é o rótulo cluster-type: primary-cluster. Vamos usar isso mais tarde ao fazer o roteamento de tráfego no Istio Multicluster.
Escrever redis.yaml
A comunicação do worker com o front-end é feita por um canal do Redis. Por isso, precisamos implantar um aplicativo do Redis no cluster.
Insira o seguinte em redis.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: redis-cache
spec:
template:
metadata:
labels:
app: redis-cache
spec:
containers:
- name: redis
image: redis:alpine
ports:
- containerPort: 6379
readinessProbe:
periodSeconds: 5
tcpSocket:
port: 6379
livenessProbe:
periodSeconds: 5
tcpSocket:
port: 6379
volumeMounts:
- mountPath: /data
name: redis-data
resources:
limits:
memory: 256Mi
cpu: 125m
requests:
cpu: 70m
memory: 200Mi
volumes:
- name: redis-data
emptyDir: {}
Esta é uma implantação semi-padrão de um aplicativo Redis. Ele cria um contêiner com base na imagem redis:alpine, expõe as portas adequadas e define limites de recursos razoáveis.
Escrever redis-service.yaml
Precisamos de um serviço do Kubernetes para se comunicar com nosso aplicativo Redis.
Insira o seguinte em redis-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-cache-service
spec:
type: ClusterIP
selector:
app: redis-cache
ports:
- port: 6379
targetPort: 6379
Isso fornece um serviço chamado redis-cache-service para acessar nossa implantação do Redis.
10. Implantar o aplicativo
Com as imagens enviadas por push para o GCR e os manifestos do Kubernetes gravados, este é um bom momento para implantar o aplicativo e ver como ele funciona.
Execute os comandos a seguir para implantar o aplicativo:
- Verificar se estamos no cluster certo
kubectx primary
- Implantar o cache do Redis
kubectl apply -f redis.yaml
- Implantar o serviço do Redis
kubectl apply -f redis-service.yaml
- Implantar o front-end
kubectl apply -f frontend.yaml
- Implantar trabalhador
kubectl apply -f worker-primary.yaml
- Implantar o serviço de worker
kubectl apply -f worker-service.yaml
Você implantou o aplicativo no GKE. Parabéns!
Teste
Aguarde até que os pods fiquem on-line.
kubectl get pods -w
Quando todos os pods estiverem "Em execução", pressione Ctrl + C.
NAME READY STATUS RESTARTS AGE frontend-deployment-695d95fbf7-76sd8 1/1 Running 0 2m redis-cache-7475999bf5-nxj8x 1/1 Running 0 2m worker-deployment-5b9cf9956d-g975p 1/1 Running 0 2m
Você vai notar que não expusemos nosso front-end por um LoadBalancer. Isso porque mais tarde vamos acessar o aplicativo pelo Istio. Para testar se tudo está funcionando, vamos usar kubectl port-forward.. Execute o comando a seguir para encaminhar a porta 8080 na sua máquina local (ou do Cloud Shell) para a porta 8080 que executa a implantação frontend.
kubectl port-forward \
$(kubectl get pods -l app=frontend -o jsonpath='{.items[0].metadata.name}') \
8080:8080
Se você estiver executando localmente: abra um navegador da Web e acesse http://localhost:8080.
Se você estiver executando no Cloud Shell:clique no botão "Visualização na Web" e selecione "Visualizar na porta 8080".

O front-end vai aparecer. Se você inserir um número na caixa "frequência", os hashes vão começar a aparecer.

Parabéns, está tudo funcionando!
Pressione Ctrl+C para interromper o encaminhamento da porta.
11. Limpar o aplicativo implantado
Vamos aplicar o Istio ao cluster e reimplantar o aplicativo. Primeiro, vamos limpar o aplicativo atual.
Execute os comandos a seguir para excluir todos os deployments e serviços que você acabou de criar:
- Excluir
redis-cache-service
kubectl delete -f redis-service.yaml
- Excluir
redis
kubectl delete -f redis.yaml
- Excluir
frontend
kubectl delete -f frontend.yaml
- Excluir
worker
kubectl delete -f worker-primary.yaml
- Excluir
worker-service
kubectl delete -f worker-service.yaml
12. Instalar o Istio no cluster principal
Fazer o download do Istio
As versões do Istio estão hospedadas no GitHub. Os comandos a seguir vão fazer o download e descompactar a versão 1.0.0 do istio.
- Mude para a raiz do projeto
cd ${proj}
- Baixar o arquivo
curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
- Extrair e remover o arquivo
tar xzf istio-1.0.0-linux.tar.gz && rm istio-1.0.0-linux.tar.gz
Criar modelo do Istio
Executar o comando Helm a seguir cria o modelo para instalar o Istio no cluster.
helm template istio-1.0.0/install/kubernetes/helm/istio \ --name istio --namespace istio-system \ --set prometheus.enabled=true \ --set servicegraph.enabled=true > istio-primary.yaml
Isso cria um arquivo chamado istio-primary.yaml no diretório atual que contém todas as definições e especificações necessárias para implantar e executar o Istio.
Observe os dois parâmetros --set. Eles adicionam suporte ao Prometheus e ao ServiceGraph ao sistema Istio. Vamos usar o serviço do Prometheus mais adiante no laboratório.
Implantar o Istio
Para implantar o Istio, primeiro precisamos criar um namespace chamado istio-system em que as implantações e os serviços do Istio possam ser executados.
kubectl create namespace istio-system
Por fim, aplique o arquivo istio-primary.yaml que criamos com o Helm.
kubectl apply -f istio-primary.yaml
Rotular o namespace padrão
O Istio injeta um serviço de proxy sidecar em cada uma das suas implantações. Isso é feito com base em uma opção de ativação. Portanto, precisamos rotular nosso namespace default com istio-injection=enabled para que o Istio possa injetar automaticamente o sidecar para nós.
kubectl label namespace default istio-injection=enabled
Parabéns! Temos um cluster em execução com o Istio pronto para implantar nosso aplicativo.
13. Implantar nosso aplicativo com o gerenciamento de tráfego do Istio
Criar arquivos de configuração de gerenciamento de tráfego do Istio
O Istio funciona de maneira semelhante ao Kubernetes, já que usa arquivos YAML para configuração. Nesse sentido, precisamos criar um conjunto de arquivos que informem ao Istio como expor e rotear nosso tráfego.
Crie um diretório chamado istio-manifests e mude para ele
mkdir ${proj}/istio-manifests && cd ${proj}/istio-manifests
Escrever frontend-gateway.yaml
Esse arquivo vai expor nosso cluster do Kubernetes de maneira semelhante a um LoadBalancer do GKE e vai rotear todo o tráfego de entrada para nosso serviço de front-end.
Crie um arquivo chamado frontend-gateway.yaml e insira o seguinte.
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: frontend-gateway
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: frontend-ingress-virtual-service
spec:
hosts:
- "*"
gateways:
- frontend-gateway
http:
- route:
- destination:
host: frontend-service
port:
number: 80
Escrever redis-virtualservice.yaml
Crie um arquivo chamado redis-virtualservice.yaml e insira o seguinte
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: redis-virtual-service
spec:
hosts:
- redis-cache-service
gateways:
- mesh
tcp:
- route:
- destination:
host: redis-cache-service.default.svc.cluster.local
Escrever worker-virtualservice.yaml
Crie um arquivo chamado worker-virtualservice.yaml e insira o seguinte
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
port:
number: 80
Implantar políticas de gerenciamento de tráfego do Istio
A implantação das políticas do Istio é feita da mesma maneira que outros recursos do Kubernetes, com kubectl apply.
- Usar nosso gateway
kubectl apply -f frontend-gateway.yaml
- Aplicar o VirtualService do Redis
kubectl apply -f redis-virtualservice.yaml
- Aplicar nosso Worker VirtualService
kubectl apply -f worker-virtualservice.yaml
Implantar o aplicativo
- Volte para o diretório
kubernetes
cd ${proj}/kubernetes
- Implantar o cache do Redis
kubectl apply -f redis.yaml
- Implantar o serviço do Redis
kubectl apply -f redis-service.yaml
- Implantar o front-end
kubectl apply -f frontend.yaml
- Implantar trabalhador
kubectl apply -f worker-primary.yaml
- Implantar o serviço de worker
kubectl apply -f worker-service.yaml
Verificar
Neste ponto, já reimplantamos o aplicativo em um cluster com políticas de gerenciamento de tráfego e do Istio.
Vamos esperar que todas as nossas cargas de trabalho fiquem on-line
Quando todos estiverem on-line, acesse o IngressGateway que configuramos em frontend-ingressgateway.yaml
$ kubectl -n istio-system get svc istio-ingressgateway NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE istio-ingressgateway LoadBalancer 10.36.3.112 35.199.158.10 80:31380/TCP,
Navegue até o endereço <EXTERNAL-IP> ou use curl para ver o front-end.
$ curl 35.199.158.10
<!doctype html>
<html>
<head>
<title>String Hashr</title>
<!-- Bootstrap -->
...
14. Instalar o Istio no cluster "burst"
Passamos muito tempo configurando e implantando no cluster primary, mas temos outro cluster inteiro para implantar.
Nesta seção, vamos precisar extrair variáveis de configuração dos dois clusters. Portanto, preste atenção a qual cluster estamos apontando para cada comando.
Criar o manifesto remoto do Istio
Assim como quando implantamos o Istio no cluster primary, vamos usar o Helm para criar um modelo da implantação do Istio remoto no cluster burst. Antes disso, precisamos coletar algumas informações sobre nosso cluster primary.
Coletar informações do cluster principal
Mudar para o cluster primary
kubectx primary
Os comandos a seguir recuperam os endereços IP de vários pods no cluster principal. Eles são usados pelo Istio Remote para se comunicar com o cluster principal.
export PILOT_POD_IP=$(kubectl -n istio-system get pod -l istio=pilot -o jsonpath='{.items[0].status.podIP}')
export POLICY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=policy -o jsonpath='{.items[0].status.podIP}')
export STATSD_POD_IP=$(kubectl -n istio-system get pod -l istio=statsd-prom-bridge -o jsonpath='{.items[0].status.podIP}')
export TELEMETRY_POD_IP=$(kubectl -n istio-system get pod -l istio-mixer-type=telemetry -o jsonpath='{.items[0].status.podIP}')
export ZIPKIN_POD_IP=$(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{range .items[*]}{.status.podIP}{end}')
Criar modelo remoto
Agora vamos usar helm para criar um arquivo chamado istio-remote-burst.yaml, que pode ser implantado no cluster burst.
Mudar para a raiz do projeto
cd $proj
helm template istio-1.0.0/install/kubernetes/helm/istio-remote --namespace istio-system \
--name istio-remote \
--set global.remotePilotAddress=${PILOT_POD_IP} \
--set global.remotePolicyAddress=${POLICY_POD_IP} \
--set global.remoteTelemetryAddress=${TELEMETRY_POD_IP} \
--set global.proxy.envoyStatsd.enabled=true \
--set global.proxy.envoyStatsd.host=${STATSD_POD_IP} \
--set global.remoteZipkinAddress=${ZIPKIN_POD_IP} > istio-remote-burst.yaml
Instalar o Istio Remote no cluster de burst
Para instalar o Istio no cluster burst, siga as mesmas etapas da instalação no cluster primary, mas use o arquivo istio-remote-burst.yaml.
Mudar o kubecontext para burst
kubectx burst
Criar namespace istio-system
kubectl create ns istio-system
Aplicar istio-burst.yaml
kubectl apply -f istio-remote-burst.yaml
Namespace padrão do rótulo
Mais uma vez, precisamos rotular o namespace default para que o proxy possa ser injetado automaticamente.
kubectl label namespace default istio-injection=enabled
Parabéns! Neste ponto, configuramos o Istio Remote no cluster burst. No entanto, nesse ponto, os clusters ainda não conseguem se comunicar. Precisamos gerar um arquivo kubeconfig para o cluster burst que pode ser implantado no cluster primary para vinculá-los.
Criar kubeconfig para o cluster "burst"
Mudar para o cluster de burst
kubectx burst
Configurar o ambiente
Precisamos coletar algumas informações sobre o cluster para criar um arquivo kubeconfig para ele.
- Consiga o nome do cluster
CLUSTER_NAME=$(kubectl config view --minify=true -o "jsonpath={.clusters[].name}")
- Extrair o nome do servidor do cluster
SERVER=$(kubectl config view --minify=true -o "jsonpath={.clusters[].cluster.server}")
- Consiga o nome do secret da autoridade certificadora da conta de serviço
istio-multi.
SECRET_NAME=$(kubectl get sa istio-multi -n istio-system -o jsonpath='{.secrets[].name}')
- Receber os dados da autoridade certificadora armazenados no secret anterior
CA_DATA=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['ca\.crt']}")
- Receber o token armazenado no secret anterior
TOKEN=$(kubectl get secret ${SECRET_NAME} -n istio-system -o "jsonpath={.data['token']}" | base64 --decode)
Criar arquivo kubeconfig
Com todas essas variáveis de ambiente definidas, precisamos criar nosso arquivo kubeconfig.
cat <<EOF > burst-kubeconfig
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ${CA_DATA}
server: ${SERVER}
name: ${CLUSTER_NAME}
contexts:
- context:
cluster: ${CLUSTER_NAME}
user: ${CLUSTER_NAME}
name: ${CLUSTER_NAME}
current-context: ${CLUSTER_NAME}
kind: Config
preferences: {}
users:
- name: ${CLUSTER_NAME}
user:
token: ${TOKEN}
EOF
Isso vai criar um arquivo chamado burst-kubeconfig no diretório atual, que pode ser usado pelo cluster primary para autenticar e gerenciar o cluster burst.
Voltar para o cluster principal
kubectx primary
Aplique o kubeconfig para "burst" criando um secret e rotulando-o
kubectl create secret generic burst-kubeconfig --from-file burst-kubeconfig -n istio-system
Adicione um rótulo ao secret para que o Istio saiba usá-lo na autenticação de vários clusters.
kubectl label secret burst-kubeconfig istio/multiCluster=true -n istio-system
Parabéns! Os dois clusters estão autenticados e se comunicando entre si pelo Istio Multicluster. Vamos implantar nosso aplicativo entre clusters
15. Implantar um aplicativo entre clusters
Criar implantações
Mude para o diretório kubernetes.
cd ${proj}/kubernetes
Criar uma implantação de worker para o cluster "burst": worker-burst.yaml
Crie um arquivo chamado worker-burst.yaml e insira o seguinte nele:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: worker-deployment
labels:
app: worker
spec:
replicas: 1
selector:
matchLabels:
app: worker
template:
metadata:
labels:
app: worker
cluster-type: burst-cluster
spec:
containers:
- name: worker
image: gcr.io/istio-burst-workshop/worker
imagePullPolicy: Always
ports:
- containerPort: 8081
readinessProbe:
initialDelaySeconds: 10
httpGet:
path: "/_healthz"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-readiness-probe"
livenessProbe:
initialDelaySeconds: 10
httpGet:
path: "/"
port: 8081
httpHeaders:
- name: "Cookie"
value: "istio_session-id=x-liveness-probe"
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
Observe como isso é quase idêntico ao worker-primary.yaml que criamos antes. Há duas diferenças principais.
A primeira diferença importante é que adicionamos a variável de ambiente PREFIX com o valor "bursty-".
env:
- name: PORT
value: "8081"
- name: REDIS_URL
value: "redis-cache-service:6379"
- name: PREFIX
value: "bursty-"
Isso significa que nosso worker no cluster burst vai prefixar todos os hashes enviados com "bursty-". Podemos usar isso para saber que nosso aplicativo é realmente entre clusters.
A segunda diferença importante é que mudamos o rótulo cluster-type nessa implantação de primary-cluster para burst-cluster.
labels:
app: worker
cluster-type: burst-cluster
Vamos usar esse rótulo mais tarde ao atualizar o VirtualService.
Modificar serviços do Istio
No momento, nossos serviços do Istio não estão aproveitando as duas implantações. 100% do nosso tráfego está sendo roteado para o cluster "primário". Vamos mudar isso.
Mude para o diretório istio-manifests.
cd ${proj}/istio-manifests
Edite worker-virtualservice.yaml para incluir DestinationRules
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 50
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: worker-destination-rule
spec:
host: worker-service
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: primary
labels:
cluster-type: primary-cluster
- name: burst
labels:
cluster-type: burst-cluster
Como você pode ver, adicionamos um segundo destino ao VirtualService. Ele ainda faz referência ao mesmo host (worker-service.default.svc.cluster.local)), mas 50% do tráfego estão sendo roteados para o subconjunto primary e os outros 50% para o subconjunto burst.
Definimos o subconjunto primary como as implantações que têm o rótulo cluster-type: primary-cluster e o subconjunto burst como as implantações que têm o rótulo cluster-type: burst-cluster.
Isso divide nosso tráfego 50/50 entre os dois clusters.
Implantar no cluster
Implante redis-service.yaml no cluster de burst
Mudar para o kubeconfig burst
kubectx burst
Mudar para a raiz do projeto
cd ${proj}
Em seguida, implante
Implante o redis-service.yaml no cluster de burst
kubectl apply -f kubernetes/redis-service.yaml
Implante worker-burst.yaml no cluster de burst
kubectl apply -f kubernetes/worker-burst.yaml
Implante worker-service.yaml no cluster de burst
kubectl apply -f kubernetes/worker-service.yaml
Aplicar VirtualServices do Istio
Mudar para o kubeconfig primary
kubectx primary
Em seguida, implante
kubectl apply -f istio-manifests/worker-virtualservice.yaml
Verificar se funciona
Para verificar se ele funciona, navegue até o ponto de entrada do Istio Ingress e observe como cerca de 50% dos hashes têm o prefixo "burst-".

Isso significa que estamos conversando entre clusters. Tente mudar os pesos nos diferentes serviços e aplique o arquivo worker-virtualservice.yaml. Essa é uma ótima maneira de equilibrar o tráfego entre clusters, mas e se pudermos fazer isso automaticamente?
16. Como usar métricas do Prometheus
Introdução ao Prometheus
O Prometheus é um kit de ferramentas de monitoramento e alerta de sistemas de código aberto originalmente criado no SoundCloud. Ele mantém um modelo de dados multidimensional com dados de série temporal identificados por nome de métrica e pares de chave-valor.
Para referência, confira o diagrama da arquitetura do Prometheus:

Quando implantado com o Prometheus, o Istio envia automaticamente várias métricas ao servidor do Prometheus. Podemos usar essas métricas para gerenciar nossos clusters em tempo real.
Como explorar nossas métricas do Prometheus
Para começar, precisamos expor a implantação do Prometheus.
Navegue até a guia "Cargas de trabalho" no GKE e detalhe a carga de trabalho "prometheus".

Na página de detalhes da implantação, acesse "Ações" -> "Expor".

Escolha encaminhar para a porta 9090 e digite "Balanceador de carga".

e escolha "Expor".
Isso vai criar um serviço em um endereço IP acessível publicamente que podemos usar para explorar nossas métricas do Prometheus.
Aguarde o endpoint ficar operacional e clique no endereço IP ao lado de "Endpoints externos"
.
Agora você vai ver a interface do Prometheus.

O Prometheus fornece métricas suficientes para ser um workshop por si só. Por enquanto, vamos começar analisando a métrica istio_requests_total.
A execução dessa consulta retorna vários dados. São métricas de todas as solicitações que passam pela malha de serviço do Istio, e isso é muita coisa. Vamos mudar nossa expressão para filtrar o que realmente nos interessa:
Solicitações em que o serviço de destino é worker-service.default.svc.cluster.local e a origem é frontend-deployment, limitadas aos últimos 15 segundos
A consulta é assim:
istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s]
e nos dá um conjunto de dados muito mais gerenciável para trabalhar.

Mas ainda é um pouco denso. Queremos saber as solicitações por segundo, não todas as solicitações.
Para isso, podemos usar a função rate integrada.
rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])

Estamos chegando lá, mas precisamos reduzir um pouco mais essas métricas em um grupo lógico.
Para isso, podemos usar as palavras-chave sum e by para agrupar e somar nossos resultados.
sum(rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])) by (source_workload,
source_app, destination_service)

Perfeito! Podemos extrair do Prometheus as métricas exatas de que precisamos.
Nossa consulta final do Prometheus
Com tudo o que aprendemos, a consulta final que precisamos fazer ao Prometheus é
sum(rate(istio_requests_total{reporter="destination",
destination_service="worker-service.default.svc.cluster.local",
source_workload="frontend-deployment"}[15s])) by (source_workload,
source_app, destination_service)
Agora podemos usar a API HTTP para receber a métrica.
Podemos consultar a API deles com nossa consulta fazendo uma solicitação GET HTTP assim. Substitua <prometheus-ip-here>
curl http://<prometheus-ip-here>/api/v1/query?query=sum\(rate\(istio_requests_total%7Breporter%3D%22destination%22%2C%0Adestination_service%3D%22worker-service.default.svc.cluster.local%22%2C%0Asource_workload%3D%22frontend-deployment%22%7D%5B15s%5D\)\)%20by%20\(source_workload%2C%0Asource_app%2C%20destination_service\)
Confira um exemplo de resposta:
{
"status": "success",
"data": {
"resultType": "vector",
"result": [
{
"metric": {
"destination_service": "worker-service.default.svc.cluster.local",
"source_app": "frontend",
"source_workload": "frontend-deployment"
},
"value": [
1544404907.503,
"18.892886390062788"
]
}
]
}
}
Agora podemos extrair o valor da métrica do JSON.
Limpeza
Precisamos excluir o serviço que acabamos de usar para expor o Prometheus. No Console do Google Cloud, acesse a parte de cima do serviço que acabamos de criar e clique em "Excluir".

Próximas etapas:
Depois de descobrir como o tráfego está se movendo pelo cluster e em qual taxa, a próxima etapa é gravar um pequeno binário que consulta o Prometheus periodicamente. Se as solicitações por segundo para worker ficarem acima de um determinado limite, aplique pesos de destino diferentes no serviço virtual de trabalho para enviar todo o tráfego ao cluster burst. Quando as solicitações por segundo ficarem abaixo de um limite inferior, envie todo o tráfego de volta para primary.
17. Criar um burst entre clusters
Configuração
Definir todo o tráfego para o serviço de worker no cluster principal
Vamos considerar todo o tráfego destinado a worker-service sendo roteado para o cluster primary como o estado "padrão" do nosso aplicativo.
Edite $proj/istio-manifests/worker-virtualservice.yaml para que fique assim:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 100
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: worker-destination-rule
spec:
host: worker-service
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: primary
labels:
cluster-type: primary-cluster
- name: burst
labels:
cluster-type: burst-cluster
Verifique se você está conectado ao cluster primary.
kubectx primary
Aplicar istio-manifests/worker-virtualservice.yaml
kubectl apply -f istio-manifests/worker-virtualservice.yaml
Escrever o daemon do istiowatcher
Vamos usar Go para escrever esse serviço devido à velocidade e portabilidade. O fluxo geral do aplicativo será iniciar e, a cada segundo, consultar o Prometheus.
Crie um novo diretório em src chamado istiowatcher
mkdir -p ${proj}/src/istiowatcher && cd ${proj}/src/istiowatcher
Vamos chamar istioctl de dentro do contêiner para manipular o plano de controle do Istio no cluster.
Escrever istiowatcher.go
Crie um arquivo nesse diretório chamado istiowatcher.go e insira o seguinte nele:
package main
import (
"github.com/tidwall/gjson"
"io/ioutil"
"log"
"net/http"
"os/exec"
"time"
)
func main() {
//These are in requests per second
var targetLow float64 = 10
var targetHigh float64 = 15
// This is for the ticker in milliseconds
ticker := time.NewTicker(1000 * time.Millisecond)
isBurst := false
// Our prometheus query
reqQuery := `/api/v1/query?query=sum(rate(istio_requests_total{reporter="destination",destination_service="worker-service.default.svc.cluster.local",source_workload="frontend-deployment"}[15s]))by(source_workload,source_app,destination_service)`
for t := range ticker.C {
log.Printf("Checking Prometheus at %v", t)
// Check prometheus
// Note that b/c we are querying over the past 5 minutes, we are getting a very SLOW ramp of our reqs/second
// If we wanted this to be a little "snappier" we can scale it down to say 30s
resp, err := http.Get("http://prometheus.istio-system.svc.cluster.local:9090" + reqQuery)
if err != nil {
log.Printf("Error: %v", err)
continue
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
val := gjson.Get(string(body), "data.result.0.value.1")
log.Printf("Value: %v", val)
currentReqPerSecond := val.Float()
log.Printf("Reqs per second %f", currentReqPerSecond)
if currentReqPerSecond > targetHigh && !isBurst {
applyIstio("burst.yaml")
log.Println("Entering burst mode")
isBurst = true
} else if currentReqPerSecond < targetLow && isBurst {
applyIstio("natural.yaml")
log.Println("Returning to natural state.")
isBurst = false
}
}
}
func applyIstio(filename string) {
cmd := exec.Command("istioctl", "replace", "-f", filename)
if err := cmd.Run(); err != nil {
log.Printf("Error hit applying istio manifests: %v", err)
}
}
Gravar Dockerfile
Crie um arquivo chamado Dockerfile e insira o seguinte nele.
FROM golang:1.11.2-stretch as base
FROM base as builder
WORKDIR /workdir
RUN curl -LO https://github.com/istio/istio/releases/download/1.0.0/istio-1.0.0-linux.tar.gz
RUN tar xzf istio-1.0.0-linux.tar.gz
RUN cp istio-1.0.0/bin/istioctl ./istioctl
FROM base
WORKDIR /go/src/istiowatcher
COPY . .
COPY --from=builder /workdir/istioctl /usr/local/bin/istioctl
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["istiowatcher"]
Esse Dockerfile de vários estágios faz o download e extrai a versão 1.0.0 do Istio no primeiro estágio. A segunda etapa copia tudo do nosso diretório para a imagem, depois copia istioctl da etapa de build para /usr/local/bin (para que possa ser chamado pelo nosso aplicativo), recebe as dependências, compila o código e define o CMD como "istiowatcher".
Escrever burst.yaml
Esse é o arquivo que istiowatcher vai aplicar quando as solicitações/segundo para worker de frontend excederem 15.
Crie um arquivo chamado burst.yaml e insira o seguinte nele.
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 0
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 100
Escrever natural.yaml
Consideramos esse o estado "natural" a que retornamos quando as solicitações/segundo de frontend para worker caem abaixo de 10. Nesse estado, 100% do tráfego são roteados para o cluster primary.
Crie um arquivo chamado natural.yaml e insira o seguinte nele:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: worker-virtual-service
spec:
hosts:
- worker-service
gateways:
- mesh
http:
- route:
- destination:
host: worker-service.default.svc.cluster.local
subset: primary
port:
number: 80
weight: 100
- destination:
host: worker-service.default.svc.cluster.local
subset: burst
port:
number: 80
weight: 0
Criar e enviar istiowatcher
Execute o comando a seguir para enviar o diretório atual ao Google Cloud Build (GCB), que vai criar e marcar a imagem no GCR.
gcloud builds submit -t gcr.io/${GCLOUD_PROJECT}/istiowatcher
Implantar o istiowatcher
Mude para o diretório kubernetes.
cd ${proj}/kubernetes/
Escrever um arquivo de implantação: istiowatcher.yaml
Crie um arquivo chamado istiowatcher.yaml e insira o seguinte (substitua <your-project-id>).
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: istiowatcher-deployment
labels:
app: istiowatcher
spec:
replicas: 1
selector:
matchLabels:
app: istiowatcher
template:
metadata:
labels:
app: istiowatcher
spec:
serviceAccountName: istio-pilot-service-account
automountServiceAccountToken: true
containers:
- name: istiowatcher
image: gcr.io/<your-project-id>/istiowatcher
imagePullPolicy: Always
Implantar
Verifique se estamos executando no cluster principal
kubectx primary
Implante istiowatcher.yaml no namespace istio-system
kubectl apply -n istio-system -f istiowatcher.yaml
É importante observar as diretivas serviceAccountName e automountServiceAccountToken no yaml. Isso nos dá as credenciais necessárias para executar istioctl no cluster.
Também precisamos fazer a implantação no namespace istio-system para garantir que temos as credenciais do istio-pilot-service-account. Ele não existe no namespace default.
Assista a troca automática de tráfego!
Agora, o momento mágico! Vamos ao front-end e aumentar a solicitação/segundo para 20.
Perceba que leva alguns segundos, mas ele aumenta e todos os nossos hashes têm o prefixo "bursty-".
Isso acontece porque estamos fazendo amostragem do Prometheus no intervalo 15s, o que atrasa um pouco nosso tempo de resposta. Se quisermos uma faixa muito mais estreita, podemos mudar nossa consulta para o Prometheus para 5s.
18. A seguir
Limpeza
Não é necessário fazer limpeza se você estiver usando uma conta temporária fornecida para este workshop.
Você pode excluir os clusters do Kubernetes, a regra de firewall e as imagens no GCR.
gcloud container clusters delete primary --zone=us-west1-a
gcloud container clusters delete burst --zone=us-west1-a
gcloud compute firewall-rules delete istio-multicluster-test-pods
gcloud container images delete gcr.io/$GCLOUD_PROJECT/istiowatcher
O futuro
- Participe de algumas Istio Talks!
- Receba o certificado: crie seu próximo app com Kubernetes e Istio
- Keynote: Kubernetes, Istio, Knative: The New Open Cloud Stack - Aparna Sinha, Group Product Manager for Kubernetes, Google (em inglês)
- Tutorial: como usar o Istio – Lee Calcote e Girish Ranganathan, SolarWinds
- Istio - The Packet's-Eye View - Matt Turner, Tetrate (em inglês)
- O Istio é o firewall de última geração mais avançado já criado? - John Morello, Twistlock
- Leia a documentação do Istio.
- Participe dos grupos de trabalho do Istio
- Siga @IstioMesh no Twitter




