Preparação do Aplicativo para Istio

Preparação do Aplicativo para Istio

Istio é uma ferramenta conveniente para conectar, proteger e monitorar aplicativos distribuídos. O Istio utiliza várias tecnologias para executar e gerenciar software em grande escala, incluindo contêineres para empacotar o código do aplicativo e suas dependências para implantação e Kubernetes para gerenciar esses contêineres. Portanto, para trabalhar com o Istio, você deve entender como funciona um aplicativo com vários serviços baseado nessas tecnologias. sem Istio. Se você já estiver familiarizado com essas ferramentas e conceitos, fique à vontade para pular este guia e ir direto para a seção Instalação do Istio no Google Kubernetes Engine (GKE) ou instalação da extensão Istio no GKE.

Este é um guia passo a passo, onde vamos passar por todo o processo desde o código fonte até o contêiner no GKE, para que você tenha uma visão básica dessas tecnologias como exemplo. Você também verá como o Istio aproveita as funcionalidades dessas tecnologias. Supõe-se que você não saiba nada sobre contêineres, Kubernetes, service mesh ou Istio.

Tarefas

Neste guia, você realizará as seguintes tarefas:

  1. Explorar um simples aplicativo hello world com vários serviços.
  2. Executar o aplicativo a partir do código fonte.
  3. Empacotar o aplicativo em contêineres.
  4. Criar um cluster Kubernetes.
  5. Implantar contêineres no cluster.

Antes de começar

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

  1. Acesse a página do Kubernetes Engine no console do Google Cloud Platform.
  2. Crie ou selecione um projeto.
  3. Espere até que a API e os serviços relacionados sejam ativados. Isso pode levar alguns minutos.
  4. Certifique-se de que a cobrança está configurada para o projeto do Google Cloud Platform. Descubra como ativar a cobrança.

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

Opção A: usar o Cloud Shell

Vantagens de usar o Cloud Shell:

  • Ambientes de desenvolvimento Python 2 e Python 3 (incluindo virtualenv) totalmente configurados.
  • Ferramentas de linha de comando gcloud, docker, git e kubectl, que vamos usar, já estão instaladas.
  • Você tem várias opções de editores de texto:
    1. O editor de código, que é aberto pelo ícone de edição na parte superior da janela do Cloud Shell.
    2. Emacs, Vim ou Nano, que são abertos a partir da linha de comando no Cloud Shell.

Para usar Cloud Shell:

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

Preparação do Aplicativo para Istio

Na parte inferior do console GCP uma sessão do Cloud Shell com o terminal será aberta em uma nova janela.

Preparação do Aplicativo para Istio

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

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

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

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

  3. Instale kubectl — ferramenta de linha de comando para trabalhar com Kubernetes.

    gcloud components install kubectl

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

  5. Instale a ferramenta de controle de versão Git, para obter o exemplo do aplicativo do GitHub.

Baixando o exemplo de código

  1. Baixe o código-fonte helloserver:

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

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

    cd istio-samples/sample-apps/helloserver

Explorando o aplicativo com vários serviços

O exemplo do aplicativo é escrito em Python e consiste em dois componentes que interagem através de REST:

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

Preparação do Aplicativo para Istio

Executando o aplicativo a partir do código-fonte

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

python3 server/server.py

Ao iniciar servidor aproximadamente a seguinte saída:

INFO:root:Iniciando servidor...

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

curl http://localhost:8080

o servidor responde:

Hello World!

4) No diretório onde você baixou o exemplo de código, vá para 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) Instale as dependências para loadgen:

pip3 install -r requirements.txt

9) Execute loadgen:

python3 loadgen.py

Ao iniciar loadgen exibe aproximadamente a seguinte mensagem:

Iniciando loadgen: 2019-05-20 10:44:12.448415
5 solicitação(ões) completada(s) para http://localhost:8080

Em outra janela do terminal servidor exibe aproximadamente as seguintes mensagens:

127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 -
INFO:root:Solicitação GET,
Caminho: /
Cabeçalhos:
Host: localhost:8080
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*

Do ponto de vista da rede, todo o aplicativo funciona em um único host (computador local ou máquina virtual Cloud Shell). Portanto, você pode usar localhost, para enviar solicitações para servidor.
10) Para parar loadgen e 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 um exemplo de aplicativo — servidor e loadgen — em containers. Um contêiner é uma forma de empacotar um aplicativo, isolando-o do ambiente.

Para empacotar o aplicativo em um contêiner, você precisa Dockerfile. Dockerfile — é um arquivo de texto que define os comandos para construir o código-fonte do aplicativo e suas dependências em a imagem Docker. Após a construção, você envia a imagem para um registro de contêineres, como o Docker Hub ou Container Registry.

No exemplo, já há Dockerfile para servidor e loadgen com todos os comandos necessários para compilar as imagens. Abaixo está 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/*

# Ativar logging não bufferizado
FROM base as final
ENV PYTHONUNBUFFERED=1

RUN apt-get -qq update 
    && apt-get install -y --no-install-recommends 
        wget

WORKDIR /helloserver

# Obtenha pacotes do construtor
COPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/

# Adicione o aplicativo
COPY . .

EXPOSE 8080
ENTRYPOINT [ "python", "server.py" ]

  • Time FROM python:3-slim as base informa ao Docker para usar a última imagem do Python 3 como base.
  • Time COPY . . copia os arquivos-fonte para o diretório de trabalho atual (neste caso, apenas server.py) para o sistema de arquivos do contêiner.
  • ENTRYPOINT define o comando que é usado para executar o contêiner. Neste caso, este comando se assemelha muito ao que você usou para executar server.py a partir do código-fonte.
  • Time EXPOSE indica que servidor aguarda dados na porta 8080. Este comando não define portas. É algo como um documento que é necessário para abrir a porta 8080 ao iniciar o contêiner.

Preparação para a contêinerização do aplicativo

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

export PROJECT_ID="PROJECT_ID"

export GCR_REPO="preparing-istio"

Com os valores de PROJECT_ID e GCR_REPO você marca a imagem Docker ao compilá-la e enviá-la para o 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) Verifique se o serviço Container Registry está ativado no projeto GCP.

gcloud services enable containerregistry.googleapis.com

Containerização do servidor

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

    cd SEU_DIRETÓRIO_DE_TRABALHO/istio-samples/sample-apps/helloserver/server/

  2. Construa 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. É o nome da imagem que você usa ao implantar o container.

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

Containerização do loadgen

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

cd ../loadgen

2) Construa a imagem:

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

3) Envie a imagem para o Container Registry:

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

Visualizando a lista de imagens

Revise a 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 retorna os nomes das imagens que foram enviadas recentemente:

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

Criando um cluster GKE.

Esses containers poderiam ser executados em uma máquina virtual no Cloud Shell ou em um computador com o comando docker run. Mas em um ambiente de produção, é necessário ter uma maneira de orquestrar os containers de forma centralizada. Por exemplo, precisa haver um sistema que monitore para que os containers estejam sempre funcionando e uma maneira de escalar e iniciar instâncias adicionais de containers se o tráfego aumentar.

Para executar aplicativos em containers, você pode usar GKE. O GKE é uma plataforma de orquestração de containers que combina máquinas virtuais em um cluster. Cada máquina virtual é chamada de nó. Os clusters GKE são baseados no sistema de gerenciamento de clusters 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

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

O comando cria o cluster em alguns minutos. Quando o cluster estiver pronto, o comando retornará algo como a ocorrência.

2) Configure as credenciais na ferramenta de linha de comando kubectl, para gerenciar o cluster:

gcloud container clusters get-credentials istioready

3) Agora você pode interagir com o Kubernetes através de kubectl. Por exemplo, o seguinte comando pode ser usado para verificar o status dos nós:

kubectl get nodes

O comando retorna a lista de nós:

NOME                                       STATUS   FUNÇÕES    IDADE    VERSÃO
gke-istoready-default-pool-dbeb23dc-1vg0   Pronto       99s    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-36z5   Pronto       100s   v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-fj7s   Pronto       99s    v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-wbjw   Pronto       99s    v1.13.6-gke.13

Conceitos-chave do Kubernetes

O diagrama mostra um aplicativo no GKE:

Preparação do Aplicativo para Istio

Antes de implantar contêineres no GKE, familiarize-se com os conceitos-chave do Kubernetes. No final, há links se você quiser saber mais.

  • Nodos e clusters. No GKE, um nodo é uma máquina virtual. Em outras plataformas, um nodo do Kubernetes pode ser um computador ou uma máquina virtual. Um cluster é um conjunto de nodos que pode ser considerado um todo, onde você implanta um aplicativo empacotado em contêineres.
  • Pods. 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ê deve implantar os contêineres server e loadgen em pods separados. Quando há vários contêineres em um pod (por exemplo, servidor de aplicativos e proxy), os contêineres são gerenciados como um único objeto e compartilham os recursos do pod.
  • Implantações. No Kubernetes, uma implantação é um objeto que representa um conjunto de pods idênticos. A implantação inicia várias réplicas de pods distribuídas pelos nós do cluster. A implantação substitui automaticamente os pods que falharam ou não estão respondendo.
  • Serviço Kubernetes. Ao executar o código do aplicativo no GKE, a conexão entre loadgen e servidor. Quando você executou serviços em uma máquina virtual Cloud Shell ou em um computador, enviou solicitações para servidor no endereço 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 qual nodo um pod está em execução, portanto, não há pods endereços IP permanentes.
    Para obter um endereço IP para servidor, você precisa definir uma abstração de rede sobre os pods. Isso é o que serviço Kubernetes. O serviço Kubernetes fornece um ponto final permanente para um conjunto de pods. Existem vários tipos de serviços. servidor usa LoadBalancer, que fornecem um endereço IP externo, permitindo a comunicação com servidor de fora do cluster.
    Além disso, o Kubernetes 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 por meio de um endereço constante. O nome DNS não pode ser utilizado fora do cluster, por exemplo, no Cloud Shell ou em um computador.

Manifestos do Kubernetes

Quando você executou o aplicativo a partir do código-fonte, utilizou um comando imperativo python3

server.py

A imperatividade implica um verbo: "faça isso".

O Kubernetes utiliza um modelo declarativo. Isso significa que não dizemos ao Kubernetes o que exatamente fazer, mas descrevemos o estado desejado. Por exemplo, o Kubernetes inicia e para pods conforme necessário para que o estado real do sistema corresponda ao desejado.

O estado desejado é indicado em manifestos, ou arquivos YAML. O arquivo YAML contém especificações para um ou mais objetos do Kubernetes.

O exemplo contém um arquivo YAML para servidor e loadgen. Cada arquivo YAML indica o estado desejado do objeto de implantação e serviço do 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

  • kind indica o tipo de objeto.
  • metadata.name indica o nome da implantação.
  • O primeiro campo spec contém a descrição do estado desejado.
  • spec.replicas indica o número desejado de pods.
  • Seção spec.template define o template do pod. Na especificação dos pods, há um campo image, onde é indicado o nome da imagem que deve 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

  • LoadBalancer: os clientes enviam solicitações para o endereço IP do balanceador de carga, que possui um IP constante e que está disponível fora do cluster.
  • targetPort: como você se lembra, o comando EXPOSE 8080 em Dockerfile não forneceu portas. Você fornecerá a porta 8080, para que seja possível se comunicar com o contêiner servidor fora do cluster. No nosso caso hellosvc.default.cluster.local:80 (nome curto: hellosvc) corresponde à porta 8080 do endereço IP do pod helloserver.
  • port: este é o número da porta para onde os outros serviços no cluster enviarão solicitações.

loadgen.yaml

O objeto de implantação em loadgen.yaml é semelhante a server.yaml. A diferença é que o objeto de implantação contém a seção env. Ela define as variáveis de ambiente necessárias loadgen que você definiu 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

Um loadgen não aceita solicitações de entrada, para o campo tipo indicado ClusterIP. Este tipo fornece um endereço IP permanente que pode ser usado por serviços no cluster, mas esse endereço IP não é disponibilizado para clientes externos.

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

Implantando contêineres no GKE

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

cd SEU_DIRETÓRIO_DE_TRABALHO/istio-samples/sample-apps/helloserver/server/

2) Abra server.yaml em um editor de texto.
3) Substitua o nome no campo image pelo nome da sua imagem 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) Implante o arquivo YAML no Kubernetes:

kubectl apply -f server.yaml

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

deployment.apps/helloserver created
service/hellosvc created

6) Vá para o diretório onde está loadgen:

cd ../loadgen

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

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

Substitua PROJECT_ID pelo identificador do seu projeto GCP.
9) Salve e feche loadgen.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 retorna 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 loadgen. Substitua POD_ID pelo identificador da resposta anterior.

kubectl logs loadgenerator-POD_ID

13) Obtenha os endereços IP externos hellosvc:

kubectl get service

A resposta do comando se parece com isto:

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                443/TCP        93m
loadgensvc   ClusterIP      10.81.15.155             80/TCP         4m52s

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

curl http://EXTERNAL_IP

Vamos trabalhar com Istio

Você já tem um aplicativo implantado no GKE. loadgen pode usar o DNS do Kubernetes (hellosvc:80), para enviar solicitações para servidor, e você pode enviar solicitações para servidor pelo endereço IP externo. Embora o Kubernetes tenha muitas funcionalidades, falta 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 loadgen envia solicitações para servidor, mas imagine que você não sabe nada sobre o aplicativo. Para responder a essas perguntas, olhamos para a lista de pods em execução no GKE.
  • Métricas. Quanto tempo servidor responde a uma solicitação de entrada? Quantas solicitações por segundo chegam ao servidor? Ele gera mensagens de erro?
  • Informações sobre segurança. O tráfego entre loadgen e servidor flui diretamente por HTTP ou através de mTLS?

Todas essas perguntas são respondidas pelo Istio. Para isso, o Istio insere um proxy sidecar Envoy em cada pod. O proxy Envoy intercepta todo o tráfego de entrada e saída para os contêineres do aplicativo. Isso significa que servidor e loadgen recebem através do proxy sidecar Envoy, e todo o tráfego de loadgen para servidor passa pelo proxy Envoy.

As conexões entre os proxies Envoy formam uma service mesh. A arquitetura da service mesh fornece um nível de controle sobre o Kubernetes.

Preparação do Aplicativo para Istio

Como os proxies Envoy são executados em seus próprios contêineres, o Istio pode ser instalado sobre o cluster GKE, fazendo quase nenhuma alteração no código do aplicativo. Mas você fez algum trabalho para preparar o aplicativo para ser gerenciado pelo Istio:

  • Serviços para todos os contêineres. Está associado um serviço Kubernetes a cada implantação. servidor e loadgen Até mesmo aquele loadgen, que não recebe solicitações de entrada, tem um serviço.
  • As portas dos serviços devem ter nomes. Embora no GKE as portas dos serviços possam permanecer sem nome, o Istio exige que você especifique o nome da porta de acordo com seu protocolo. No arquivo YAML, a porta para servidor é chamada de http, porque o servidor utiliza o protocolo HTTP. Se o serviço utilizasse gRPC, você chamaria a porta grpc.
  • Implantações são rotuladas. Portanto, você pode usar os recursos de gerenciamento de tráfego do Istio, como dividir o tráfego entre versões de um mesmo serviço.

Instalação do Istio

O Istio pode ser instalado de duas maneiras. Você pode ativar a extensão Istio on GKE ou instalar a versão open source do Istio no cluster. Com o Istio on GKE, é fácil gerenciar a instalação e a atualização do Istio durante o ciclo de vida do cluster GKE. Se você precisa da versão mais recente do Istio ou de mais controle sobre a configuração do painel do Istio, instale a versão open source em vez da extensão Istio on GKE. Para decidir sobre o método, leia o artigo Preciso do Istio on GKE?.

Escolha uma opção, estude o guia correspondente e siga as instruções para instalar o Istio no cluster. Se você quiser usar o Istio com um aplicativo recém-implantado, ativar a injeção de sidecars para o espaço de nomes padrão.

Limpeza

Para evitar que sejam cobrados recursos da sua conta do Google Cloud Platform utilizados neste guia, exclua o cluster de contêineres quando instalar o Istio e brincar com o exemplo do aplicativo. Isso removerá todos os recursos do cluster, como instâncias de computação, discos e recursos de rede.

E agora?

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster