Preparando o Aplicativo para Istio


O Istio é uma ferramenta conveniente para conectar, proteger e monitorar aplicativos distribuídos. O Istio usa uma variedade de tecnologias para iniciar e gerenciar software em larga escala, incluindo contêineres para empacotar código de aplicativo e dependências para implantação e o Kubernetes para gerenciar esses contêineres. Portanto, para trabalhar com o Istio, você deve saber como um aplicativo com vários serviços baseados nessas tecnologias funciona sem o Istio. Se você já conhece essas ferramentas e conceitos, sinta-se à vontade para pular este guia e ir direto para Instalação do Istio no Google Kubernetes Engine (GKE) ou instalação da extensão Istio on GKE .


Este é um guia passo a passo, onde examinaremos todo o processo, do código-fonte até um contêiner no GKE, para que você tenha uma idéia básica dessas tecnologias usando um exemplo. Você também verá como o Istio tira proveito dessas tecnologias. Supõe-se que você não saiba nada sobre contêineres, Kubernetes, malha de serviço ou Istio.


As tarefas


Neste guia, você concluirá as seguintes tarefas:


  1. Explorando um aplicativo simples olá mundo com vários serviços.
  2. Executando o aplicativo a partir do código fonte.
  3. Empacotar o aplicativo em recipientes.
  4. Criando um cluster Kubernetes
  5. Implante contêineres em um cluster.

Antes de começar


Siga as instruções para ativar a API do Kubernetes Engine:


  1. Vá para a página do Kubernetes Engine no console do Google Cloud Platform.
  2. Crie ou selecione um projeto.
  3. Aguarde a API e os serviços relacionados serem ativados. Isso pode levar alguns minutos.
  4. Verifique se o faturamento está configurado para o projeto do Google Cloud Platform. Saiba como ativar o faturamento .

Neste guia, você pode usar o Cloud Shell, que prepara a máquina virtual g1-small no Google Compute Engine com Linux baseado no Debian ou em um computador Linux ou macOS.


Opção A: Usando o Cloud Shell


Benefícios do uso do Cloud Shell:


  • Os ambientes de desenvolvimento Python 2 e Python 3 (incluindo virtualenv ) são totalmente personalizados.
  • As ferramentas de linha de comando gcloud , docker , git e kubectl que usaremos já estão instaladas.
  • Você tem vários editores de texto para escolher:
    1. O editor de código que é aberto com o ícone de edição na parte superior da janela do Cloud Shell.
    2. Emacs, Vim ou Nano que são abertos na linha de comando no Cloud Shell.

Para usar o Cloud Shell :


  1. Vá para o console do GCP.
  2. Clique no botão Ativar Shell da Nuvem na parte superior da janela do console do GCP.


Na parte inferior do console do GCP, em uma nova janela, uma sessão do Cloud Shell é aberta com uma linha de comando.



Opção B: usando ferramentas de linha de comando localmente


Se você estiver trabalhando em um computador com Linux ou macOS, precisará configurar e instalar os seguintes componentes:


  1. Configure seu ambiente de desenvolvimento Python 3 e Python 2 .


  2. Instale o Cloud SDK com a ferramenta de linha de comando gcloud .


  3. Instale o kubectl , uma ferramenta de linha de comando para trabalhar com o Kubernetes .


    gcloud components install kubectl 

  4. Instale o Docker Community Edition (CE) . Você usará a ferramenta de linha de comando do docker para criar imagens de contêiner para um aplicativo de amostra.


  5. Instale a ferramenta de controle de versão do Git para obter um aplicativo de amostra com o GitHub.



Faça o download do código de exemplo


  1. Faça o download do código fonte do helloserver :


     git clone https://github.com/GoogleCloudPlatform/istio-samples 

  2. Vá para o diretório de código de amostra:


     cd istio-samples/sample-apps/helloserver 


Explorando um Aplicativo Multisserviço


O aplicativo de amostra é escrito em Python e consiste em dois componentes que interagem com o REST :


  • servidor : um servidor simples com um ponto de extremidade GET, / , que exibe "hello world" no console.
  • loadgen : um script que envia tráfego para o servidor , com um número configurável de solicitações por segundo.


Executando um Aplicativo da Origem


Para aprender um aplicativo de exemplo, execute-o no Cloud Shell ou em um computador.
1) No diretório istio-samples / sample-apps / helloserver , execute o servidor :


 python3 server/server.py 

Quando o servidor inicia, o seguinte é exibido:


 INFO:root:Starting server... 

2) Abra outra janela do terminal para enviar solicitações ao servidor . Se você estiver usando o Cloud Shell, clique no ícone Adicionar para abrir outra sessão.
3) Envie uma solicitação ao servidor :


 curl http://localhost:8080 

respostas do servidor:


 Hello World! 

4) No diretório em que você baixou o código de amostra, acesse o diretório que contém loadgen :


 cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/loadgen 

5) Crie as seguintes variáveis ​​de ambiente:


 export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5 

6) Execute virtualenv :


 virtualenv --python python3 env 

7) Ative o ambiente virtual:


 source env/bin/activate 

8) Defina os requisitos para o loadgen :


 pip3 install -r requirements.txt 

9) Execute o loadgen :


 python3 loadgen.py 

Quando iniciado, o loadgen exibe a seguinte mensagem:


 Starting loadgen: 2019-05-20 10:44:12.448415 5 request(s) complete to http://localhost:8080 

Em outra janela do terminal, o servidor exibe as seguintes mensagens no console:


 127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */* 

Do ponto de vista da rede, o aplicativo inteiro é executado no mesmo host (computador local ou máquina virtual do Cloud Shell). Portanto, você pode usar o host local para enviar solicitações ao servidor .
10) Para parar o loadgen e o servidor , digite Ctrl-c em cada janela do terminal.
11) Na janela do terminal loadgen, desative o ambiente virtual:


 deactivate 

Empacotando o aplicativo em contêineres


Para executar o aplicativo no GKE, você precisa empacotar o aplicativo de amostra - server e loadgen - em contêineres . Um contêiner é uma maneira de compactar um aplicativo para isolá-lo do ambiente.


Para compactar o aplicativo em um contêiner, você precisa de um Dockerfile . Um Dockerfile é um arquivo de texto que define comandos para criar o código-fonte de um aplicativo e suas dependências em uma imagem do Docker. Após a compilação, você carrega a imagem no registro de contêiner, por exemplo, no Docker Hub ou no Registro de Contêiner .


O exemplo já possui um Dockerfile para servidor e loadgen com todos os comandos necessários para montar as imagens. Abaixo está o Dockerfile para servidor :


 FROM python:3-slim as base FROM base as builder RUN apt-get -qq update \ && apt-get install -y --no-install-recommends \ g++ \ && rm -rf /var/lib/apt/lists/* # Enable unbuffered logging FROM base as final ENV PYTHONUNBUFFERED=1 RUN apt-get -qq update \ && apt-get install -y --no-install-recommends \ wget WORKDIR /helloserver # Grab packages from builder COPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/ # Add the application COPY . . EXPOSE 8080 ENTRYPOINT [ "python", "server.py" ] 

  • O comando FROM python: 3-slim as base informa ao Docker para usar a imagem mais recente do Python 3 como base.
  • Equipe de cópia. . copia os arquivos de origem para o diretório de trabalho atual (no nosso caso, apenas server.py ) no sistema de arquivos do contêiner.
  • ENTRYPOINT define o comando usado para iniciar o contêiner. No nosso caso, esse comando é quase o mesmo que você usou para executar o server.py a partir do código fonte.
  • O comando EXPOSE indica que o servidor está escutando na porta 8080 . Este comando não fornece portas . Esse é algum tipo de documentação necessária para abrir a porta 8080 quando o contêiner é iniciado.

Preparando para Contêiner de Aplicativos


1) Defina as seguintes variáveis ​​de ambiente. Substitua PROJECT_ID pelo seu identificador de projeto do GCP.


 export PROJECT_ID="PROJECT_ID" 

 export GCR_REPO="preparing-istio" 

Usando os valores PROJECT_ID e GCR_REPO, você marca a imagem do Docker quando a coleta e envia para o Registro de Contêiner privado.


2) Defina o projeto GCP padrão para a ferramenta de linha de comando gcloud .


 gcloud config set project $PROJECT_ID 

3) Defina a zona padrão para a ferramenta de linha de comando gcloud .


 gcloud config set compute/zone us-central1-b 

4) Verifique se o serviço Registro de Contêiner está incluído no projeto GCP.


 gcloud services enable containerregistry.googleapis.com 

Servidor de conteinerização


  1. Mude para o diretório em que o exemplo do servidor está localizado:


     cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/ 

  2. Crie a imagem usando o Dockerfile e as variáveis ​​de ambiente que você definiu anteriormente:


     docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 . 


A opção -t representa a marca do Docker. Este é o nome da imagem que você usa ao implantar o contêiner.


  1. Envie a imagem para o Registro do Contêiner:
     docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 

Containergen loadgen


1) Vá para o diretório em que o exemplo loadgen está localizado :


 cd ../loadgen 

2) Monte a imagem:


 docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 . 

3) Envie a imagem para o Registro de Contêiner:


 docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 

Ver uma lista de imagens


Navegue na lista de imagens no repositório e verifique se as imagens foram enviadas:


 gcloud container images list --repository gcr.io/$PROJECT_ID/preparing-istio 

O comando exibe os nomes das imagens recém-enviadas:


 NAME gcr.io/PROJECT_ID/preparing-istio/helloserver gcr.io/PROJECT_ID/preparing-istio/loadgen 

Criando um cluster GKE


Esses contêineres podem ser executados na máquina virtual do Cloud Shell ou no computador com o comando docker run . Mas em um ambiente de produção, você precisa de uma maneira de orquestrar centralmente os contêineres. Por exemplo, precisamos de um sistema que garanta que os contêineres sempre funcionem e precisamos de uma maneira de aumentar o zoom e lançar instâncias adicionais de contêineres se o tráfego aumentar.


Você pode usar o GKE para executar aplicativos de contêiner. O GKE é uma plataforma de orquestração de contêineres que agrupa máquinas virtuais. Cada máquina virtual é chamada de host. Os clusters GKE são baseados no sistema de gerenciamento de cluster de código aberto Kubernetes. O Kubernetes fornece mecanismos para interagir com o cluster.


Criando um cluster GKE:


1) Crie um cluster:


 gcloud container clusters create istioready \ --cluster-version latest \ --machine-type=n1-standard-2 \ --num-nodes 4 

O comando gcloud cria um cluster istioready no projeto GCP e a zona padrão que você especificou. Para iniciar o Istio, recomendamos que você tenha pelo menos 4 nós e uma máquina virtual n1-standard-2 .


A equipe cria um cluster por vários minutos. Quando o cluster está pronto, o comando emite uma mensagem semelhante.


2) Especifique as credenciais na ferramenta de linha de comando kubectl para usá-la para gerenciar o cluster:


 gcloud container clusters get-credentials istioready 

3) Agora você pode se comunicar com o Kubernetes através do kubectl . Por exemplo, com o seguinte comando, você pode descobrir o status dos nós:


 kubectl get nodes 

O comando exibe uma lista de nós:


 NAME STATUS ROLES AGE VERSION gke-istoready-default-pool-dbeb23dc-1vg0 Ready <none> 99s v1.13.6-gke.13 gke-istoready-default-pool-dbeb23dc-36z5 Ready <none> 100s v1.13.6-gke.13 gke-istoready-default-pool-dbeb23dc-fj7s Ready <none> 99s v1.13.6-gke.13 gke-istoready-default-pool-dbeb23dc-wbjw Ready <none> 99s v1.13.6-gke.13 

Principais conceitos do Kubernetes


O diagrama mostra a aplicação no GKE:



Antes de implantar contêineres no GKE, observe os principais conceitos do Kubernetes. Existem links no final, se você quiser saber mais.


  • Nós e clusters . No GKE, um nó é uma máquina virtual. Em outras plataformas Kubernetes, o host pode ser um computador ou máquina virtual. Um cluster é uma coleção de nós que podem ser considerados como um todo e onde você implementa um aplicativo em contêiner.
  • Pods . No Kubernetes, os contêineres são executados em cápsulas. Um pod em Kubernetes é uma unidade indivisível. Um pod contém um ou mais contêineres. Você implanta o servidor e carrega contêineres em pods separados. Quando existem vários contêineres em um pod (por exemplo, um servidor de aplicativos e um servidor proxy ), os contêineres são gerenciados como um único objeto e compartilham os recursos do pod.
  • Implantação . No Kubernetes, a implantação é um objeto que é uma coleção de pods idênticos. A implantação executa várias réplicas de pods distribuídos pelos nós do cluster. A implantação substitui automaticamente os pods que falham ou não respondem.
  • Serviço Kubernetes . Quando você executa o código do aplicativo no GKE, a conexão entre o loadgen e o servidor muda. Quando você iniciou os serviços na máquina virtual do Cloud Shell ou no computador, enviou solicitações ao servidor em localhost: 8080 . Após a implantação no GKE, os pods são executados nos nós disponíveis. Por padrão, você não pode controlar em que pod de host está sendo executado, para que os pods não tenham endereços IP permanentes.
    Para obter o endereço IP do servidor , você precisa definir a abstração da rede no topo dos pods. Este é o serviço Kubernetes . O serviço Kubernetes fornece um ponto final permanente para um conjunto de pods. Existem vários tipos de serviços . O servidor usa um LoadBalancer , que fornece um endereço IP externo para entrar em contato com o servidor de fora do cluster.
    O Kubernetes também possui um sistema DNS interno que atribui nomes DNS (por exemplo, helloserver.default.cluster.local ) aos serviços. Graças a isso, os pods dentro do cluster se comunicam com outros pods no cluster em um endereço fixo. O nome DNS não pode ser usado fora do cluster, como no Cloud Shell ou em um computador.

Manifests de Kubernetes


Quando você iniciou o aplicativo a partir do código-fonte, usou o comando imperativo python3


server.py


Imperativo implica o verbo: "faça".


Kubernetes usa um modelo declarativo . Isso significa que não informamos ao Kubernetes o que exatamente precisa ser feito, mas descrevemos o estado desejado. Por exemplo, o Kubernetes inicia e interrompe os pods conforme necessário, para que o estado real do sistema seja o desejado.


Você especifica o estado desejado em manifestos ou arquivos YAML . O arquivo YAML contém especificações para um ou mais objetos Kubernetes.


O exemplo contém o arquivo YAML para server e loadgen . Cada arquivo YAML indica o estado desejado do objeto de implantação e do serviço Kubernetes.


server.yaml


 apiVersion: apps/v1 kind: Deployment metadata: name: helloserver spec: selector: matchLabels: app: helloserver replicas: 1 template: metadata: labels: app: helloserver spec: terminationGracePeriodSeconds: 5 restartPolicy: Always containers: - name: main image: gcr.io/google-samples/istio/helloserver:v0.0.1 imagePullPolicy: Always 

  • tipo indica o tipo de objeto.
  • metadata.name indica o nome da implantação.
  • A primeira especificação do campo contém uma descrição do estado desejado.
  • spec.replicas indica o número desejado de pods.
  • A seção spec.template define o modelo do pod . Na especificação de pods, há um campo de imagem em que o nome da imagem a ser extraída do Registro de Contêiner é indicado.

O serviço é definido da seguinte maneira:


 apiVersion: v1 kind: Service metadata: name: hellosvc spec: type: LoadBalancer selector: app: helloserver ports: - name: http port: 80 targetPort: 8080 

  • LoadBalancer : os clientes enviam solicitações para o endereço IP do balanceador de carga, que possui um endereço IP fixo e acessível de fora do cluster.
  • targetPort : como você se lembra, o comando EXPOSE 8080 no Dockerfile não forneceu portas. Você fornece a porta 8080 para poder alcançar o contêiner do servidor de fora do cluster. No nosso caso, hellosvc.default.cluster.local: 80 (nome abreviado: hellosvc ) corresponde à porta 8080 do endereço IP do pod helloserver .
  • port : este é o número da porta para a qual outros serviços no cluster enviarão solicitações.

loadgen.yaml


O objeto de implementação no loadgen.yaml é semelhante ao server.yaml . A diferença é que o objeto de implantação contém uma seção env . Ele define as variáveis ​​de ambiente que o loadgen precisa e que você define quando iniciou o aplicativo a partir do código-fonte.


 apiVersion: apps/v1 kind: Deployment metadata: name: loadgenerator spec: selector: matchLabels: app: loadgenerator replicas: 1 template: metadata: labels: app: loadgenerator spec: terminationGracePeriodSeconds: 5 restartPolicy: Always containers: - name: main image: gcr.io/google-samples/istio/loadgen:v0.0.1 imagePullPolicy: Always env: - name: SERVER_ADDR value: "http://hellosvc:80/" - name: REQUESTS_PER_SECOND value: "10" resources: requests: cpu: 300m memory: 256Mi limits: cpu: 500m memory: 512Mi 

Como o loadgen não aceita solicitações de entrada, o ClusterIP é especificado para o campo de tipo . Esse tipo fornece um endereço IP fixo que os serviços no cluster podem usar, mas esse endereço IP não é fornecido para clientes externos.


 apiVersion: v1 kind: Service metadata: name: loadgensvc spec: type: ClusterIP selector: app: loadgenerator ports: - name: http port: 80 targetPort: 8080 

Implantar contêineres no GKE


1) Vá para o diretório em que o exemplo do servidor está localizado:


 cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/ 

2) Abra server.yaml em um editor de texto.
3) Substitua o nome no campo da imagem pelo nome da sua imagem do Docker.


 image: gcr.io/PROJECT_ID/preparing-istio/helloserver:v0.0.1 

Substitua PROJECT_ID pelo identificador do seu projeto GCP.
4) Salve e feche server.yaml .
5) Expanda o arquivo YAML no Kubernetes:


 kubectl apply -f server.yaml 

Após a conclusão bem-sucedida, o comando emite o seguinte código:


 deployment.apps/helloserver created service/hellosvc created 

6) Vá para o diretório em que o loadgen está localizado:


 cd ../loadgen 

7) Abra o loadgen.yaml em um editor de texto.
8) Substitua o nome no campo da imagem pelo nome da sua imagem do Docker.


 image: gcr.io/PROJECT_ID/preparing-istio/loadgenv0.0.1 

Substitua PROJECT_ID pelo identificador do seu projeto GCP.
9) Salve e feche o loadgen.yaml , feche o editor de texto.
10) Expanda o arquivo YAML no Kubernetes:


 kubectl apply -f loadgen.yaml 

Após a conclusão bem-sucedida, o comando emite o seguinte código:


 deployment.apps/loadgenerator created service/loadgensvc created 

11) Verifique o status das lareiras:


 kubectl get pods 

O comando mostra o status:


 NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s 

12) Extraia os logs do aplicativo do pod do loadgen . Substitua POD_ID pelo identificador da resposta anterior.


 kubectl logs loadgenerator-POD_ID 

13) Obtenha os IPs hellosvc externos:


 kubectl get service 

A resposta do comando é mais ou menos assim:


 NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m kubernetes ClusterIP 10.81.0.1 <none> 443/TCP 93m loadgensvc ClusterIP 10.81.15.155 <none> 80/TCP 4m52s 

14) Envie uma solicitação ao hellosvc : substitua EXTERNAL_IP pelo endereço IP externo do hellosvc .


 curl http://EXTERNAL_IP 

Enfrentar Istio


Você já possui um aplicativo implantado no GKE. O loadgen pode usar o DNS do Kubernetes ( hellosvc: 80 ) para enviar solicitações ao servidor e você pode enviar solicitações ao servidor em um endereço IP externo. Embora o Kubernetes tenha muitos recursos, faltam algumas informações sobre os serviços:


  • Como os serviços interagem? Qual é a relação entre os serviços? Como é o tráfego entre serviços? Você está ciente de que o loadgen envia solicitações ao servidor , mas imagine que você não sabe nada sobre o aplicativo. Para responder a essas perguntas, examinamos a lista de lares em funcionamento no GKE.
  • Métricas . Quanto tempo o servidor responde a uma solicitação de entrada? Quantas solicitações por segundo vão para o servidor? Dá mensagens de erro?
  • Informações de segurança . O tráfego entre o loadgen e o servidor é simplesmente via HTTP ou mTLS ?

Todas essas perguntas são respondidas por Istio. Para fazer isso, o Istio coloca um proxy lateral do Envoy em cada pod. O proxy Envoy intercepta todo o tráfego de entrada e saída para contêineres de aplicativos. Isso significa que o servidor e o loadgen recebem proxies laterais do Envoy, e todo o tráfego do loadgen para o servidor passa pelos proxies do Envoy.


As conexões entre os proxies Envoy formam uma malha de serviço. A arquitetura de malha de serviço fornece uma camada de controle sobre o Kubernetes.



Depois que os proxies Envoy são executados em seus contêineres, o Istio pode ser instalado na parte superior do cluster GKE, quase sem alterar o código do aplicativo. Mas você trabalhou para preparar o aplicativo para gerenciamento usando o Istio:


  • Serviços para todos os contêineres. As implantações de servidor e loadgen são vinculadas pelo serviço Kubernetes. Até o loadgen , que não recebe solicitações de entrada, possui um serviço.
  • As portas nos serviços devem ter nomes. Embora as portas de serviço possam ser deixadas sem nome no GKE, o Istio exige um nome de porta de acordo com seu protocolo. No arquivo YAML, a porta do servidor é chamada http porque o servidor usa o protocolo HTTP . Se o serviço usasse gRPC , você nomearia a porta grpc .
  • As implantações estão marcadas. Portanto, você pode usar os recursos de gerenciamento de tráfego do Istio, por exemplo, compartilhando o tráfego entre versões do mesmo serviço.

Instale o Istio


Existem duas maneiras de instalar o Istio. Você pode ativar a extensão Istio no GKE ou instalar a versão de código aberto do Istio em um cluster. Com o Istio no GKE, você pode gerenciar facilmente a instalação e a atualização do Istio como parte do ciclo de vida do cluster GKE. Se você precisar da versão mais recente do Istio ou de mais controle sobre a configuração do painel de controle do Istio, instale a versão de código aberto em vez da extensão Istio on GKE. Para decidir sobre a abordagem, leia o artigo Preciso de Istio no GKE? .


Selecione uma opção, estude o manual apropriado e siga as instruções para instalar o Istio no cluster. Se você deseja usar o Istio com seu aplicativo recém-implantado, ative a incorporação de side-car no espaço para nome padrão .


Limpeza


Para garantir que os recursos utilizados neste guia não sejam debitados da sua conta do Google Cloud Platform, remova o cluster de contêiner ao instalar o Istio e brincar com o aplicativo de amostra. Isso excluirá todos os recursos do cluster, como instâncias de computação, discos e recursos de rede.


O que vem a seguir?


Source: https://habr.com/ru/post/pt469515/


All Articles