Preparando um aplicativo para Istio

Preparando um aplicativo para Istio

Istio é uma ferramenta conveniente para conectar, proteger e monitorar aplicativos distribuídos. O Istio usa uma variedade de tecnologias para executar e gerenciar software em escala, incluindo contêineres para empacotar código de aplicativo e dependências para implantação, e Kubernetes para gerenciar esses contêineres. Portanto, para trabalhar com Istio você deve saber como funciona uma aplicação com múltiplos serviços baseados nessas tecnologias sem Ístio. Se essas ferramentas e conceitos já são familiares para você, sinta-se à vontade para pular este tutorial e ir direto para a seção Instalando o Istio no Google Kubernetes Engine (GKE) ou instalando uma extensão Istio no GKE.

Este é um guia passo a passo onde percorreremos todo o processo, desde o código-fonte até o contêiner do GKE, para fornecer uma compreensão básica dessas tecnologias por meio de um exemplo. Você também verá como o Istio aproveita o poder dessas tecnologias. Isso pressupõe que você não saiba nada sobre contêineres, Kubernetes, service meshes ou Istio.

Tarefas

Neste tutorial, você concluirá as seguintes tarefas:

  1. Aprendendo um aplicativo simples de hello world com vários serviços.
  2. Execute o aplicativo a partir do código-fonte.
  3. Empacotar o aplicativo em contêineres.
  4. Criando um cluster Kubernetes.
  5. Implantando contêineres em um cluster.

Antes que você comece

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

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

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

Opção A: usar Cloud Shell

Benefícios de usar o Cloud Shell:

  • Ambientes de desenvolvimento Python 2 e Python 3 (incluindo virtualenv) estão totalmente configurados.
  • Ferramentas de linha de comando gcloud, docker, git и kubectl, que usaremos já estão instalados.
  • Você tem vários para escolher editores de texto:
    1. Editor de código, que abre com o ícone de edição na parte superior da janela do Cloud Shell.
    2. Emacs, Vim ou Nano, que abrem na linha de comando no Cloud Shell.

Usar Cloud Shell:

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

Preparando um aplicativo para Istio

Na parte inferior Console do GCP Uma sessão do Cloud Shell com linha de comando será aberta em uma nova janela.

Preparando um aplicativo para Istio

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

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

  1. Customizar Ambiente de desenvolvimento Python 3 e Python 2.

  2. Instalar o Cloud SDK com ferramenta de linha de comando gcloud.

  3. Conjunto kubectl - ferramenta de linha de comando para trabalhar com Kubernetes.

    gcloud components install kubectl

  4. Conjunto Edição da comunidade Docker (CE). Você usará a ferramenta de linha de comando dockerpara criar imagens de contêiner para o aplicativo de amostra.

  5. Instale a ferramenta Controle de versão Gitpara obter o aplicativo de exemplo do GitHub.

Baixe o código de exemplo

  1. Baixe o código fonte olá servidor:

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

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

    cd istio-samples/sample-apps/helloserver

Explorando um aplicativo com vários serviços

O aplicativo de exemplo é escrito em Python e consiste em dois componentes que interagem usando DESCANSO:

  • servidor: servidor simples com um endpoint PEGAR, /, que imprime "olá mundo" no console.
  • carregamento: script que envia tráfego para servidor, com um número configurável de solicitações por segundo.

Preparando um aplicativo para Istio

Executando um aplicativo a partir do código-fonte

Para explorar o aplicativo de exemplo, execute-o no Cloud Shell ou no seu computador.
1) No catálogo istio-samples/sample-apps/helloserver corre servidor:

python3 server/server.py

Quando você executa servidor o seguinte é exibido:

INFO:root:Starting server...

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

curl http://localhost:8080

respostas do servidor:

Hello World!

4) No diretório onde você baixou o código de amostra, vá para o diretório que contém carregamento:

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) Lançamento virtualenv:

virtualenv --python python3 env

7) Ative o ambiente virtual:

source env/bin/activate

8) Definir requisitos para carregamento:

pip3 install -r requirements.txt

9) Lançamento carregamento:

python3 loadgen.py

Quando você executa carregamento exibe algo como 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 servidor envia as seguintes mensagens para o 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, todo o aplicativo é executado em um único host (computador local ou máquina virtual Cloud Shell). Portanto você pode usar localhostpara enviar solicitações para servidor.
10) Parar carregamento и servidor, entrar Ctrl-c em todas as janelas do terminal.
11) Na janela do terminal carregamento desativar o ambiente virtual:

deactivate

Empacotando um aplicativo em contêineres

Para executar o aplicativo no GKE, você precisa empacotar o aplicativo de exemplo - servidor и carregamento - em contentores. Um contêiner é uma forma de empacotar um aplicativo para isolá-lo de seu ambiente.

Para empacotar um aplicativo em um contêiner, você precisa dockerfile. dockerfile é um arquivo de texto que define comandos para construir o código-fonte do aplicativo e suas dependências em Imagem do Docker. Depois de criada, você carrega a imagem em um registro de contêiner, como Docker Hub ou Registro de contêiner.

O exemplo já tem dockerfile para servidor и carregamento com todos os comandos necessários para coletar imagens. Abaixo - 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" ]

  • Equipe DE python:3-slim como base diz ao Docker para usar o mais recente Imagem Python 3 como base.
  • Equipe CÓPIA DE. . copia os arquivos fonte para o diretório de trabalho atual (apenas no nosso caso servidor.py) para o sistema de arquivos do contêiner.
  • PONTO DE ENTRADA define o comando usado para iniciar o contêiner. No nosso caso, este comando é quase o mesmo que você usou para executar servidor.py do código-fonte.
  • Equipe EXPOR indica que servidor espera por dados através da porta 8080. Esta equipe não é fornece portas. Este é algum tipo de documentação necessária para abrir a porta 8080 ao iniciar o contêiner.

Preparando-se para conteinerizar seu aplicativo

1) Defina as seguintes variáveis ​​de ambiente. Substituir PROJECT_ID ao ID do projeto do GCP.

export PROJECT_ID="PROJECT_ID"

export GCR_REPO="preparing-istio"

Usando valores PROJECT_ID и GCR_REPO você marca a imagem do Docker ao criá-la e envia-a para um Container Registry 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) Certifique-se de que o serviço Container Registry esteja habilitado no projeto GCP.

gcloud services enable containerregistry.googleapis.com

Servidor de conteinerização

  1. Vá para o diretório onde o exemplo está localizado servidor:

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

  2. Monte a imagem usando dockerfile e as variáveis ​​de ambiente que você definiu anteriormente:

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

Parâmetro -t representa a tag Docker. Este é o nome da imagem que você usa ao implantar o contêiner.

  1. Faça upload da imagem para o Container Registry:
    docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1

Conteinerização de loadgen

1) Vá até o diretório onde o exemplo está localizado carregamento:

cd ../loadgen

2) Colete a imagem:

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

3) Faça upload da imagem para o Container Registry:

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

Veja uma lista de imagens

Revise a lista de imagens no repositório e verifique se as imagens foram carregadas:

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

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

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

Criando um cluster do GKE.

Esses contêineres podem ser executados em uma máquina virtual Cloud Shell ou em um computador com o comando Docker Run. Mas em um ambiente de produção, você precisa de uma maneira de orquestrar contêineres centralmente. Por exemplo, você precisa de um sistema que garanta que os contêineres estejam sempre em execução e precisa de uma maneira de aumentar a escala e ativar instâncias de contêineres adicionais se o tráfego aumentar.

Para executar aplicativos em contêineres, você pode usar G.K.E.. GKE é uma plataforma de orquestração de contêineres que agrega máquinas virtuais em um cluster. Cada máquina virtual é chamada de nó. Os clusters do GKE são baseados no sistema de gerenciamento de cluster Kubernetes de código aberto. Kubernetes fornece mecanismos para interagir com o cluster.

Criando um cluster do GKE:

1) Crie um cluster:

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

Equipe gcloud cria um cluster istioready no projeto GCP e na zona padrão que você especificou. Para executar o Istio, recomendamos ter pelo menos quatro nós e uma máquina virtual n1-padrão-2.

A equipe cria o cluster em alguns minutos. Quando o cluster estiver pronto, o comando gerará algo assim сообщение.

2) Forneça credenciais na ferramenta de linha de comando kubectlpara usá-lo para gerenciar o cluster:

gcloud container clusters get-credentials istioready

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

kubectl get nodes

O comando produz 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 um aplicativo no GKE:

Preparando um aplicativo para Istio

Antes de implantar contêineres no GKE, conheça 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, um nó pode ser um computador ou uma máquina virtual. Um cluster é uma coleção de nós que pode ser considerada uma única unidade onde você implementa um aplicativo em contêiner.
  • Vagens. No Kubernetes, os contêineres são executados em pods. Um pod no Kubernetes é uma unidade indivisível. Um pod contém um ou mais contêineres. Você implanta contêineres de servidor e carregamento em vagens separadas. Quando há vários contêineres em um pod (por exemplo, um servidor de aplicativos e Servidor proxy), os contêineres são gerenciados como uma entidade única e compartilham recursos de pod.
  • Implantações. No Kubernetes, uma implantação é um objeto que é uma coleção de pods idênticos. A implantação inicia diversas réplicas de pods distribuídos entre nós do cluster. A implantação substitui automaticamente os pods que falharam ou não respondem.
  • Serviço Kubernetes. Ao executar o código do aplicativo no GKE, a conexão entre carregamento и servidor. Ao iniciar serviços em uma máquina virtual ou desktop do Cloud Shell, você enviou solicitações para servidor a localhost: 8080. Depois de implantados no GKE, os pods são executados nos nós disponíveis. Por padrão, você não tem controle sobre em qual nó o pod está sendo executado, então você vagens sem endereços IP permanentes.
    Para obter um endereço IP para servidor, você precisa definir uma abstração de rede na parte superior dos pods. É isso que é Serviço Kubernetes. O serviço Kubernetes fornece um endpoint persistente para um conjunto de pods. Existem alguns tipos de serviços. servidor usa Balanceador de carga, que fornece um endereço IP externo para entrar em contato servidor de fora do cluster.
    O Kubernetes também possui um sistema DNS integrado que atribui nomes DNS (por exemplo, helloserver.default.cluster.local) Serviços. Graças a isso, os pods dentro do cluster se comunicam com outros pods no cluster em um endereço permanente. O nome DNS não pode ser usado fora do cluster, como no Cloud Shell ou em um computador.

Manifestos do Kubernetes

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

servidor.py

O imperativo implica um verbo: “faça isto”.

Usos do Kubernetes modelo declarativo. Isso significa que não estamos dizendo exatamente ao Kubernetes o que fazer, mas sim descrevendo o estado desejado. Por exemplo, o Kubernetes inicia e interrompe os pods conforme necessário para garantir que o estado real do sistema corresponda ao estado desejado.

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

O exemplo contém um arquivo YAML para servidor и carregamento. Cada arquivo YAML especifica o estado desejado do objeto de implantação e do serviço Kubernetes.

servidor.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 do objeto.
  • metadados.nome especifica o nome da implantação.
  • Primeiro campo especulação contém uma descrição do estado desejado.
  • especificação.réplicas indica o número desejado de pods.
  • Seção especificação.template define um modelo de pod. Existe um campo na especificação do pod imagem, que especifica o nome da imagem que precisa ser extraída do Container Registry.

O serviço é definido da seguinte forma:

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

  • Balanceador de carga: os clientes enviam solicitações para o endereço IP do balanceador de carga, que possui um endereço IP persistente e pode ser acessado de fora do cluster.
  • targetPort: como você se lembra, a equipe EXPOR 8080 в dockerfile não forneceu portas. Você fornece a porta 8080para que você possa entrar em contato com o contêiner servidor fora do aglomerado. No nosso caso hellosvc.default.cluster.local:80 (nome curto: olávc) corresponde à porta 8080 Endereços IP de pods olá servidor.
  • porta: este é o número da porta para onde outros serviços no cluster enviarão solicitações.

carregargen.yaml

Objeto de implantação para carregargen.yaml parece servidor.yaml. A diferença é que o objeto de implantação contém uma seção env. Ele define as variáveis ​​de ambiente necessárias carregamento e que você instalou ao executar 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

Tempo carregamento não aceita solicitações recebidas, para o campo tipo indicado ClusterIP. Esse tipo fornece um endereço IP persistente que os serviços do cluster podem usar, mas esse endereço IP não é exposto a 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á até o diretório onde o exemplo está localizado servidor:

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

2) Aberto servidor.yaml em um editor de texto.
3) Substitua o nome no campo imagem ao nome da sua imagem Docker.

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

Substituir PROJECT_ID ao ID do projeto do GCP.
4) Salve e feche servidor.yaml.
5) Implante o arquivo YAML no Kubernetes:

kubectl apply -f server.yaml

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

deployment.apps/helloserver created
service/hellosvc created

6) Vá para o diretório onde carregamento:

cd ../loadgen

7) Aberto carregargen.yaml em um editor de texto.
8) Substitua o nome no campo imagem ao nome da sua imagem Docker.

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

Substituir PROJECT_ID ao ID do projeto do GCP.
9) Salve e feche carregargen.yaml, feche o editor de texto.
10) Implante o arquivo YAML no Kubernetes:

kubectl apply -f loadgen.yaml

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

deployment.apps/loadgenerator created
service/loadgensvc created

11) Verifique o status dos pods:

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 carregamento. Substituir POD_ID ao identificador da resposta anterior.

kubectl logs loadgenerator-POD_ID

13) Obtenha endereços IP externos olávc:

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 para olávc: substituir EXTERNAL_IP para endereço IP externo olávc.

curl http://EXTERNAL_IP

Vamos enfrentar o Istio

Você já tem um aplicativo implantado no GKE. carregamento pode usar DNS do Kubernetes (Olávc:80) para enviar solicitações para servidore você pode enviar solicitações para servidor por endereço IP externo. Embora o Kubernetes tenha muitos recursos, faltam algumas informações sobre os serviços:

  • Como os serviços interagem? Quais são as relações entre os serviços? Como o tráfego flui entre os serviços? Você está ciente de que carregamento envia solicitações para servidor, mas imagine que você não sabe nada sobre o aplicativo. Para responder a essas perguntas, vejamos a lista de pods em execução no GKE.
  • Métricas. Quanto tempo servidor responde a uma solicitação recebida? Quantas solicitações por segundo são recebidas pelo servidor? Dá mensagens de erro?
  • informação segura. Tráfego entre carregamento и servidor apenas passa HTTP ou por mTLS?

O Istio responde a todas essas perguntas. Para fazer isso, o Istio coloca um proxy sidecar Enviado em cada vagem. O proxy Envoy intercepta todo o tráfego de entrada e saída para contêineres de aplicativos. Significa que servidor и carregamento receber via proxy sidecar Envoy e todo o tráfego de carregamento к servidor passa pelo proxy 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.

Preparando um aplicativo para Istio

Como os proxies Envoy são executados em seus próprios contêineres, o Istio pode ser instalado em um cluster do GKE quase sem alterações no código do aplicativo. Mas você trabalhou um pouco para deixar seu aplicativo pronto para ser gerenciado pelo Istio:

  • Serviços para todos os contêineres. Para implantações servidor и carregamento vinculado ao serviço Kubernetes. Até carregamento, que não recebe solicitações recebidas, existe um serviço.
  • As portas nos serviços devem ter nomes. Embora as portas de serviço possam ficar sem nome no GKE, o Istio exige que você especifique nome da porta de acordo com seu protocolo. No arquivo YAML a porta para servidor chamado httpporque o servidor usa o protocolo HTTP. Se serviço usado gRPC, você nomearia a porta grpc.
  • As implantações são sinalizadas. Portanto, você pode usar os recursos de gerenciamento de tráfego do Istio, como dividir o tráfego entre versões do mesmo serviço.

Instalando o Istio

Existem duas maneiras de instalar o Istio. Pode ativar o Istio na extensão GKE ou instale a versão de código aberto do Istio no cluster. Com o Istio no GKE, você pode gerenciar facilmente instalações e upgrades do Istio durante todo o ciclo de vida do cluster do GKE. Se você quiser a versão mais recente do Istio ou 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 no GKE. Para decidir sobre a abordagem, leia o artigo Eu preciso do Istio no GKE?.

Selecione uma opção, revise o guia apropriado e siga as instruções para instalar o Istio em seu cluster. Se você quiser usar o Istio com seu aplicativo recém-implantado, habilitar implementação de sidecar para espaço para nome omissão.

Очистка

Para evitar a cobrança em sua conta do Google Cloud Platform pelos recursos usados ​​neste tutorial, exclua o cluster de contêiner depois de instalar o Istio e testar o aplicativo de amostra. Isto removerá todos os recursos do cluster, como instâncias de computação, discos e recursos de rede.

Qual é o próximo?

Fonte: habr.com

Adicionar um comentário