Trabalhando com o Istio como um Programa Independente

Descubra como instalar o Istio como um programa independente em clusters que você criou com o Kubernetes Engine (OKE).

Este tópico fornece um exemplo de como instalar o Istio como um programa independente em clusters que você criou com o Kubernetes Engine (OKE). Além disso, são demonstrados os principais recursos do OKE e do Istio.

Os tópicos abordados incluem:

Observe que os produtos de malha de serviços (como Istio e Linkerd) são suportados ao usar o plug-in CNI de Rede de Pod Nativa da VCN do OCI para rede de pod. Observe que, com exceção do complemento Istio, o suporte está atualmente limitado ao Oracle Linux 7 (o suporte para Oracle Linux 8 está planejado). O complemento Istio é compatível com o Oracle Linux 7 e o Oracle Linux 8. Os nós de trabalho devem estar executando o Kubernetes 1.26 (ou posterior).

Observação

Você pode usar o Istio com pools de nós gerenciados, mas não com pools de nós virtuais.

Instalando o Istio como um Programa Independente

Para começar a usar o Istio, crie um cluster do OKE ou use um cluster existente do OKE e instale o Istio. As seções fornecidas a seguir descrevem as etapas para instalar e testar a configuração do Istio. Para obter uma lista completa das opções de instalação, veja aqui.

Criando um cluster do OKE

Criar um cluster do OKE.

  1. Se você ainda não tiver feito isso, crie um cluster do OKE na tenancy do OCI. Várias opções estão disponíveis para criar um cluster do OKE. A opção mais simples é o assistente de Criação Rápida na console Web.
  2. Para acessar o cluster do OKE na sua máquina local, instale kubectl e oci-cli .
  3. Acesse o cluster do OKE na linha de comando usando kubectl configurando o arquivo kubeconfig e certifique-se de que kubectl possa acessar o cluster.

Fazendo Download do Istio da Linha de Comando

Siga estas etapas para fazer download do Istio na linha de comando.

  1. Faça download do Istio executando o seguinte comando:
    curl -L https://istio.io/downloadIstio | sh -
  2. Mover para o diretório do pacote Istio. Por exemplo, se o pacote for istio-1.11.2:
    cd istio-1.11.2
  3. Adicione a ferramenta cliente istioctl ao PATH para sua estação de trabalho.
    export PATH=$PWD/bin:$PATH
  4. Valide se o cluster atende aos requisitos de instalação do Istio executando a pré-verificação:
    istioctl x precheck

Instalando o Istio com istioctl

Instale o Istio com istioctl usando o seguinte comando:
istioctl install

Executando o Aplicativo Bookinfo

O projeto Istio fornece o aplicativo Bookinfo como uma forma de demonstrar os recursos do Istio. O aplicativo exibe informações sobre um livro, semelhante a uma única entrada de catálogo de uma livraria on-line. Cada página do livro contém uma descrição do livro, detalhes sobre o livro (ISBN, número de páginas) e algumas resenhas de livros. Para obter mais informações sobre o aplicativo Bookinfo, consulte os documentos Bookinfo aqui.

Um diagrama do aplicativo Bookinfo

Como você pode ver no diagrama, o aplicativo Bookinfo é composto por quatro microsserviços.

  • Serviço de Página do Produto: Chama os serviços Detalhes e Revisões para criar uma página do produto.
  • Serviço de Detalhes: Retorna informações do livro.
  • Serviço de Avaliações: Retorna revisões de livros e chama o serviço Classificações.
  • Serviço de Classificações: Retorna informações de classificação para uma revisão do livro.

Para instalar e executar o aplicativo Bookinfo, siga estas etapas.

  1. Identifique o namespace que hospeda o aplicativo com istio-injection=enabled.
    kubectl label namespace default istio-injection=enabled
  2. Disponibilizar a aplicação Bookinfo de amostra.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  3. Verifique se todos os serviços e pods estão em execução.
    kubectl get services
    kubectl get pods
  4. Confirme se o aplicativo está em execução enviando um comando curl de um pod.
    kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
  5. Torne o aplicativo acessível de fora do cluster.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  6. Verifique se o aplicativo está usando o gateway. Determine INGRESS_HOST e INGRESS_PORT usando estas instruções.
    curl -s "http://${INGRESS_HOST}:${INGRESS_PORT}/productpage" | grep -o "<title>.*</title>"

Além disso, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um navegador para exibir a página da Web Bookinfo. Atualize a página várias vezes para ver diferentes versões de revisões mostradas na página do produto.

Adicionando Aplicativos de Integração do Istio

O Istio se integra bem a vários aplicativos populares relacionados ao Kubernetes.

Prometheus

O Istio fornece uma instalação básica de amostra para colocar o Prometheus em funcionamento rapidamente.

kubectl apply -f samples/addons/prometheus.yaml

Como alternativa, instale o prometheus e configure para raspar as métricas do Istio.

Para monitoramento em escala de produção usando Prometheus, consulte Usando Prometheus para monitoramento em escala de produção.

Grafana

O Istio fornece uma instalação básica de amostra para colocar o Grafana em funcionamento rapidamente. Todos os painéis do Istio estão incluídos na instalação.

kubectl apply -f samples/addons/grafana.yaml

Como alternativa, instale o Grafana separadamente. Além disso, os painéis pré-configurados do Istio podem ser importados.

Jaeger

O Istio fornece uma instalação básica de amostra para colocar o Jaeger em funcionamento rapidamente.

kubectl apply -f samples/addons/jaeger.yaml

Como alternativa, instale o Jaeger separadamente e configure o Istio para enviar rastreamentos para a implantação do Jaeger.

Zipkin

O Istio fornece uma instalação básica de amostra para ativar e executar rapidamente o zipkin.

kubectl apply -f samples/addons/extras/zipkin.yaml

Como alternativa, instale o zipkin separadamente e configure o Istio para enviar rastreamentos à implantação do zipkin.

Kiali

O Istio fornece uma instalação básica de amostra para colocar o Kiali rapidamente em funcionamento:

kubectl apply -f samples/addons/kiali.yaml
            

Como alternativa, instale e configure o Kiali separadamente.

Explorando a Observabilidade Istio

Nesta seção, explore as métricas de desempenho e os recursos de rastreamento fornecidos pelos aplicativos de integração do Istio.

Consultando Métricas do aplicativo Prometheus para Informações do Livro

Com Prometheus e Istio, os dados de desempenho da Bookinfo são analisados de várias maneiras.

Primeiro, verifique se o Prometheus está instalado.

kubectl -n istio-system get svc prometheus

Inicie a interface de usuário do Prometheus com o seguinte comando:

istioctl dashboard prometheus

Selecione Gráfico à direita de Prometheus no cabeçalho. Para ver alguns dados, gere tráfego para a página do produto usando um browser ou curl. O tráfego é refletido no painel Prometheus.

Visualizando Métricas para o Aplicativo Bookinfo com o Grafana

A combinação do Prometheus com o Grafana fornece alguns painéis de desempenho interessantes para aplicativos. Para usar os painéis, primeiro verifique se o Prometheus e o Grafana estão instalados.

kubectl -n istio-system get svc prometheus
kubectl -n istio-system get svc grafana

Inicie o painel do Istio Grafana.

istioctl dashboard grafana

Gerenciamento de Dashboards do Grafana

A malha de serviços do Istio oferece seis painéis do Grafana. Os snapshots do painel do Grafana da malha de serviço do Istio são capturados aqui.

Observação

Gere tráfego para a página do produto usando um browser ou curl e veja isso refletido no painel de controle do Grafana.

Painel de Malha Istio

Instantâneo do Painel de Controle do Istio Mesh

Painel de Controle de Serviços Istio

Instantâneo do Painel de Controle do Serviço Istio

Painel da Carga de Trabalho Istio

Instantâneo do Painel de Controle da Carga de Trabalho do Istio

Istio - Painel de Desempenho

Instantâneo do Painel de Desempenho do Istio

Painel de Controle Istio

Instantâneo do Painel de Controle Istio

Para obter mais informações sobre como criar, configurar e editar painéis, consulte a documentação do Grafana.

Executar rastreamento distribuído usando Jaeger

Use a estrutura de código-fonte aberto Jaeger para executar o rastreamento de aplicativos com o Istio.

  1. Ative e configure o rastreamento usando istioctl:
    istioctl install --set meshConfig.enableTracing=true
  2. Com o aplicativo Bookinfo implantado, abra a interface do usuário do Jaeger usando istioctl.
    istioctl dashboard jaeger
  3. Para gerar rastreamentos, envie solicitações para a página do produto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Você vê que os traços refletidos no painel Jaeger.

Painel Jaeger

Instantâneo do Painel Istio Jaeger

Rastreamento de Aplicativo Jaeger

Instantâneo do rastreamento do aplicativo Istio Jaeger

Executar rastreamento distribuído usando zipkin

Use a estrutura de código aberto zipkin para executar o rastreamento de aplicativos com o Istio.

  1. Ative e configure o rastreamento usando istioctl.
    istioctl install --set meshConfig.enableTracing=true
  2. Com o aplicativo Bookinfo implantado, abra a IU do zipkin usando istioctl.
    istioctl dashboard zipkin
  3. Para gerar rastreamentos, envie solicitações para a página do produto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Você vê que os rastreamentos refletem no painel do zipkin.

Exemplo de Painel

Instantâneo do painel do Istio Zipkin

Executando o Rastreamento Distribuído com o OCI Application Performance Monitoring

O OCI Application Performance Monitoring (APM) se integra a ferramentas do sistema de rastreamento de código-fonte aberto, como Jaeger e zipkin. O APM permite fazer upload de dados de rastreamento no OCI. Para integração com o OCI APM, crie um domínio do APM seguindo as instruções mencionadas aqui. Um domínio do APM é um recurso do OCI que contém os sistemas monitorados pelo APM.

Depois que o domínio for criado, exiba os detalhes do domínio e obtenha o ponto final de upload de dados, a chave privada e a chave pública para construir o URL do Coletor do APM. O URL do coletor do APM é necessário ao configurar rastreadores de código-fonte aberto para comunicação com o serviço do APM. O formato do URL do Coletor requer um URL construído usando o ponto final de upload de dados como o URL base e gera o caminho com base em opções, incluindo valores de nossa chave privada ou pública. O formato está documentado aqui. Com o caminho de URL construído, conecte o URL à configuração do Istio.

Observação

Para obter informações mais detalhadas sobre como configurar políticas de serviço do APM, consulte:

Configurando o Istio para Enviar Rastreamentos para o APM

  1. Ative o rastreamento com istioctl.
    istioctl install --set meshConfig.defaultConfig.tracing.zipkin.address=aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com:443
    Observação

    O endereço do ponto final de aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com é um exemplo e não um ponto final real.
  2. Configure o Envoy para enviar os rastreamentos zipkin ao APM. Substitua o código em samples/custom-bootstrap/custom-bootstrap.yaml pelo bloco de código a seguir.
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: istio-custom-bootstrap-config
      namespace: default
    data:
      custom_bootstrap.json: |
        {
            "tracing": {
                "http": {
                    "name": "envoy.tracers.zipkin",
                    "typed_config": {
                        "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                        "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span]
                        "collectorEndpointVersion": "HTTP_JSON",
                        "trace_id_128bit": true,
                        "shared_span_context": false
                    }
                }
            },
            "static_resources": {
                "clusters": [{
                    "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443]
                    "type": "STRICT_DNS",
                    "lb_policy": "ROUND_ROBIN",
                    "load_assignment": {
                        "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "endpoints": [{
                            "lb_endpoints": [{
                                "endpoint": {
                                    "address": {
                                        "socket_address": {
                                            "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                                            "port_value": 443
                                        }
                                    }
                                }
                            }]
                        }]
                    },
                    "transport_socket": {
                        "name": "envoy.transport_sockets.tls",
                        "typed_config": {
                            "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
                            "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain]
                        }
                    }
                }]
            }
        }
    EOF
  3. Aplique a configuração personalizada.
    kubectl apply -f samples/custom-bootstrap/custom-bootstrap.yaml
  4. Para que todos os nossos serviços no Bookinfo usem essa configuração de bootstrap personalizada, adicione uma anotação sidecar.istio.io/bootstrapOverride com o nome ConfigMap personalizado como o valor. No exemplo a seguir, uma anotação é adicionada para a página do produto em samples/bookinfo/platform/kube/bookinfo.yaml. Adicione uma anotação semelhante a outros serviços.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: productpage-v1
      labels:
        app: productpage
        version: v1
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: productpage
          version: v1
      template:
        metadata:
          labels:
            app: productpage
            version: v1
          annotations:
            sidecar.istio.io/bootstrapOverride: "istio-custom-bootstrap-config" #[Name of custom configmap]
        spec:
          serviceAccountName: bookinfo-productpage
          containers:
            - name: productpage
              image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 9080
              volumeMounts:
                - name: tmp
                  mountPath: /tmp
              securityContext:
                runAsUser: 1000
          volumes:
            - name: tmp
              emptyDir: {}
    ---
  5. Aplique o yaml. Todos os pods reiniciados começam a enviar rastreamentos para o APM.
    kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
  6. Para permitir que um gateway de entrada envie rastreamentos, crie um configmap chamado custom-bootstrap.yaml no namespace istio-system:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: istio-custom-bootstrap-config
      namespace: istio-system
    data:
      custom_bootstrap.json: |
        {
            "tracing": {
                "http": {
                    "name": "envoy.tracers.zipkin",
                    "typed_config": {
                        "@type": "type.googleapis.com/envoy.config.trace.v3.ZipkinConfig",
                        "collector_cluster": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "collector_endpoint": "/20200101/observations/private-span?dataFormat=zipkin&dataFormatVersion=2&dataKey=2C6YOLQSUZ5Q7IGN", // [Replace with the private datakey of your apm domain. You can also use public datakey but change the observation type to public-span]
                        "collectorEndpointVersion": "HTTP_JSON",
                        "trace_id_128bit": true,
                        "shared_span_context": false
                    }
                }
            },
            "static_resources": {
                "clusters": [{
                    "name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain:443]
                    "type": "STRICT_DNS",
                    "lb_policy": "ROUND_ROBIN",
                    "load_assignment": {
                        "cluster_name": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                        "endpoints": [{
                            "lb_endpoints": [{
                                "endpoint": {
                                    "address": {
                                        "socket_address": {
                                            "address": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com", // [Replace this with data upload endpoint of your apm domain]
                                            "port_value": 443
                                        }
                                    }
                                }
                            }]
                        }]
                    },
                    "transport_socket": {
                        "name": "envoy.transport_sockets.tls",
                        "typed_config": {
                            "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext",
                            "sni": "aaaabbbb.apm-agt.us-ashburn-1.oci.oraclecloud.com" // [Replace this with data upload endpoint of your apm domain]
                        }
                    }
                }]
            }
        }
    EOF
  7. Crie um patch chamado gateway-patch.yaml para que o gateway de entrada comece a usar a configuração de inicialização personalizada:
    spec:
      template:
        spec:
          containers:
          - name: istio-proxy
            env:
            - name: ISTIO_BOOTSTRAP_OVERRIDE
              value: /etc/istio/custom-bootstrap/custom_bootstrap.json
            volumeMounts:
            - mountPath: /etc/istio/custom-bootstrap
              name: custom-bootstrap-volume
              readOnly: true
          volumes:
          - configMap:
              name: istio-custom-bootstrap-config
              defaultMode: 420
              optional: false
            name: custom-bootstrap-volume
  8. Aplique o patch anterior para o gateway de entrada:
    kubectl --namespace istio-system patch deployment istio-ingressgateway --patch "$(cat gateway-patch.yaml)"
  9. Para gerar rastreamentos, envie solicitações para a página do produto.
    for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Você vê que os rastreamentos refletem no painel do APM seguindo as etapas aqui.

Explorador de Rastreamento de Zipkin

Captura de tela do Zipkin Trace Explorer

Rastreamento de Zipkin

Captura de tela de um Rastreamento Zipkin

Intervalos de Zipkin

Para ver os intervalos, selecione Início na lista do APM.

Captura de tela de um intervalo Zipkin

Painel de aplicativos Zipkin

O APM fornece funcionalidade para criar painéis de controle e explorar os intervalos gerados com o tempo. Os painéis podem ser criados seguindo as etapas aqui.

Captura de tela de um painel do aplicativo Zipkin

Explorador de Métricas do Zipkin

O APM permite monitorar a integridade, a capacidade e o desempenho de seus aplicativos usando métricas, alarmes e notificações. Siga as etapas aqui para configurar métricas.

Captura de tela de um explorador de métricas Zipkin

Observando Logs com o OCI Logging

O OCI Logging é um componente central para analisar e pesquisar entradas de arquivo de log para tenancies no OCI. Os logs de contêiner do Kubernetes dos nós de trabalho do OKE podem ser publicados como logs personalizados no OCI Logging. Siga as etapas descritas aqui para configurar o OCI Logging para ingerir logs de contêiner.

  1. Ative o log de acesso do enviado no Istio com istioctl.
    istioctl install --set meshConfig.accessLogFile=/dev/stdout
  2. Acesse a página do produto Bookinfo usando um navegador ou curl. Os logs de acesso gerados podem ser exibidos usando o comando kubectl.
    kubectl logs -l app=productpage -c istio-proxy

Se o OCI Logging estiver configurado para o cluster, esses logs poderão ser consultados e analisados usando a página de pesquisa de log da console do OCI.

Pesquisa de Log do OCI

Captura de tela de uma pesquisa do OCI Logging

Pesquisa do OCI Logging Expandida

Captura de tela de uma pesquisa expandida do OCI Logging

Visualizando Malha Usando Kiali

Verifique se o Kiali está instalado.

kubectl -n istio-system get svc kiali

Abra a UI do Kiali no browser.

istioctl dashboard kiali

Envie algum tráfego para a página do produto.

for i in $(seq 1 100); do curl -s -o /dev/null "http://$INGRESS_HOST:$INGRESS_PORT/productpage"; done

Visualize sua malha em Kiali seguindo a etapa 5 a partir daqui.

Gerenciando o Tráfego

As regras de roteamento de tráfego do Istio permitem controlar o fluxo de tráfego entre serviços e simplifica a configuração de propriedades no nível de serviço, como disjuntores, tempos limite e novas tentativas. O Istio facilita a configuração de tarefas importantes, como testes A/B, implementações canárias e implementações preparadas com divisões de tráfego baseadas em porcentagem.

Recursos da API de gerenciamento de tráfego do Istio:

Para que o Istio controle o roteamento da versão do aplicativo Bookinfo, defina todas as versões disponíveis do seu serviço, chamadas subconjuntos, nas regras de destino. Crie regras de destino padrão para os serviços Bookinfo:
kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Mudança de tráfego

O Istio nos permite migrar o tráfego gradualmente de uma versão de um microsserviço para outra versão usando o recurso de roteamento ponderado do Istio. O exemplo a seguir mostra como configurar para enviar 50% do tráfego para reviews:v1 e 50% para reviews:v3. Depois disso, conclua a migração enviando 100% do tráfego para reviews:v3.

  1. Roteie todo o tráfego para a versão v1 de cada microsserviço.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

    Para exibir a página Web Bookinfo, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser. Observe que a parte de comentários da página é exibida sem estrelas de classificação, não importa quantas vezes você atualize. O Istio está configurado para rotear todo o tráfego do serviço de revisões para reviews:v1 e esta versão do serviço não acessa o serviço de classificações por estrelas.

  2. Transfira 50% do tráfego de reviews:v1 para reviews:v3 com o comando a seguir e aguarde a propagação das novas regras.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml

    Atualize o URL /productpage em seu navegador e veja as classificações por estrelas de cor vermelha aproximadamente 50% do tempo. O reviews:v3 acessa o serviço de classificações por estrelas, mas a versão do reviews:v1 não.

  3. Agora roteie 100% do tráfego para reviews:v3.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
  4. Atualize o URL /productpage em seu navegador e veja as classificações por estrelas de cor vermelha o tempo todo para cada revisão.

Gerenciando o Roteamento de Solicitações

Istio pode rotear o tráfego de várias maneiras. Para iniciar, configure o Istio para rotear todo o tráfego por meio do v1 de cada microsserviço.
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml

Para exibir a página Web Bookinfo, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser. Observe que a parte de comentários da página é exibida sem estrelas de classificação, não importa quantas vezes você atualize. Como o Istio está configurado para rotear todo o tráfego do serviço de revisões para a versão reviews:v1. Esta versão do serviço não acessa o serviço de classificação por estrelas.

Captura de tela de um livro Booinfo de amostra.

Roteamento com base na Identidade do Usuário

Para rotear com base na identidade do usuário:

  1. Altere a configuração da rota para que todo o tráfego de um usuário específico chamado jason seja roteado para reviews:v2. O Istio não tem nenhuma compreensão especial e integrada da identidade do usuário. Neste exemplo, o serviço productpage adiciona um cabeçalho de usuário final personalizado a todas as solicitações HTTP de saída ao serviço de revisões.
    kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml
  2. Para exibir a página Web Bookinfo e fazer log-in como usuário jason, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser. Atualize o navegador para ver que as classificações por estrelas aparecem ao lado de cada avaliação.

    Captura de tela de um livro Booinfo de amostra com estrelas
  3. Abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser para exibir a página Web do Bookinfo e fazer log-in como usuário diferente de jason. Atualize o navegador para não ver estrelas para cada revisão.

    Captura de tela de um exemplo de livro Booinfo sem estrelas

Roteamento baseado na regravação de URL

Neste exemplo, as solicitações HTTP com um caminho que começa com /products ou /bookinfoproductpage são regravadas para /productpage. As solicitações HTTP são enviadas aos pods com productpage em execução na porta 9080. Para obter mais informações sobre a reescrita de URL do Istio, veja aqui.

  1. Aplique o seguinte yaml:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            prefix: /products
        - uri:
            prefix: /bookinfoproductpage
        rewrite:
          uri: /productpage
        route:
        - destination:
            host: productpage
            port:
              number: 9080
    EOF
  2. Para exibir a página Web Bookinfo, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/products e http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage em um browser. Em ambos os casos, uma reescrita é executada antes de encaminhar a solicitação.

    Reescrever /bookproductpage

    Captura de tela de um livro Booinfo de amostra com /bookproductpage

    Regravar/produtos

    Captura de tela de um livro Booinfo de amostra com /products
  3. Limpe o arquivo yaml para a versão original fornecida pelo Istio e aplique-o.
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
  4. Abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/bookinfoproductpage ou http://${INGRESS_HOST}:${INGRESS_PORT}/products para não ver a página do produto porque o yaml não reescreve a solicitação.

    404 Erro /produtos

    Captura de tela de um livro de amostra Booinfo com /products 404

    Erro 404 /booksproductpage

    Captura de tela de um exemplo de livro Booinfo com /booksproductpage 404

Testando a Resiliência da Rede

O Istio permite que você configure sua instalação para tempos limite de solicitação, injeção de falha e disjuntores. Essas definições permitem gerenciar e testar a tolerância a falhas de aplicativos implantados.

Definindo Time-outs de Solicitação

Tempo limite é o tempo que um proxy do Envoy aguarda respostas de um determinado serviço. O timeout garante que os serviços não aguardem respostas indefinidamente e garante que as chamadas sejam bem-sucedidas ou falhem dentro de um prazo previsível. Para obter mais informações sobre timeouts, veja aqui.

Um timeout para solicitações HTTP pode ser especificado usando o campo timeout da regra de roteamento. Por default, o timeout da solicitação é desativado.

  1. Inicialize o roteamento da versão do aplicativo executando o seguinte comando:
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Roteie solicitações para o serviço reviews:v2, na verdade, uma versão que chama o serviço de classificações:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v2
    EOF
  3. Adicione um atraso de 2 segundos às chamadas ao serviço de classificações:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - fault:
          delay:
            percent: 100
            fixedDelay: 2s
        route:
        - destination:
            host: ratings
            subset: v1
    EOF
  4. Para exibir a página web Bookinfo com estrelas de classificações exibidas, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um navegador. Um atraso de 2 segundos ocorre sempre que você atualiza a página.
    Captura de tela da página do produto do livro.
  5. Adicione meio segundo de timeout de solicitação para chamadas ao serviço de revisões:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
      - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v2
        timeout: 0.5s
    EOF
  6. Para exibir a página Web Bookinfo, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser. Observe que a página retorna em cerca de 1 segundo, em vez de 2, e as avaliações não estão disponíveis.
    Captura de tela da página do produto do livro.

O motivo pelo qual a resposta leva 1 segundo, mesmo que o timeout esteja configurado em meio segundo, é porque uma nova tentativa codificada no serviço productpage. O serviço chama o serviço de avaliações expiradas duas vezes antes de retornar.

Além de substituí-los em regras de roteamento, o timeout também poderá ser substituído por solicitação se o aplicativo adicionar um cabeçalho x-envoy-upstream-rq-timeout-ms em solicitações de saída.

Gerenciando a injeção de falha

A injeção de falhas é um método de teste que introduz erros em um sistema para garantir que o sistema resista e se recupere das condições de erro. O Istio permite a injeção de falhas na camada do aplicativo, como códigos de erro HTTP. O Istio injeta dois tipos de falhas, ambas configuradas usando um serviço virtual. Para obter mais informações sobre injeção de falhas, veja aqui.

  • Atrasos: Atrasos são falhas de tempo que imitam o aumento da latência da rede ou um serviço upstream sobrecarregado.
  • Abortos: abortos são falhas de falha que imitam falhas em serviços upstream. Aborta manifesto na forma de códigos de erro HTTP ou falhas de conexão TCP.

Para testar a injeção de falha, execute o seguinte comando para inicializar o roteamento da versão do aplicativo:

kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml

Injetando uma Falha de Atraso HTTP

Para injetar uma falha de atraso, siga estas etapas:

  • Crie uma regra de injeção de falha para atrasar o tráfego proveniente do usuário jason. O comando a seguir injeta um atraso de 7 segundos entre o reviews:v2 e os microsserviços de classificações para o usuário jason.
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
    Observação

    O serviço reviews:v2 tem um timeout de conexão com código fixo de 10 segundos para chamadas ao serviço de classificações. Com um atraso de 7 segundos, espere que o fluxo de ponta a ponta continue sem erros.
  • Para exibir a página Web Bookinfo, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser.
    Instantâneo da página Bookinfo mostrando erros de atraso

    A página inicial do Bookinfo é carregada sem erros em aproximadamente sete segundos. No entanto, a seção de revisões exibe uma mensagem de erro: Desculpe, as revisões de produtos estão indisponíveis no momento para este livro. Existe um bug no código do aplicativo. O timeout codificado entre o serviço productpage e o serviço reviews resulta em um atraso de 6 segundos, 3 segundos mais 1 repetição. Como resultado, a chamada productpage para reviews expira prematuramente e gera um erro após 6 segundos.

    Para corrigir o bug, aumente o timeout do serviço productpage para reviews ou diminua o timeout de reviews para ratings para menos de 3 segundos.

  • Vamos corrigir o bug adicionando um atraso de 2 segundos ao serviço ratings para o usuário jason.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: ratings
    spec:
      hosts:
      - ratings
      http:
      - match:
        - headers:
            end-user:
              exact: jason
        fault:
          delay:
            percentage:
              value: 100.0
            fixedDelay: 2s
        route:
        - destination:
            host: ratings
            subset: v1
      - route:
        - destination:
            host: ratings
            subset: v1
    EOF
  • Agora que o bug foi corrigido, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um navegador para ver a página do Bookinfo. Efetue sign-in como jason com estrelas de classificações exibidas.
    Instantâneo da página Bookinfo sem erros de eliminação

Injetando uma Falha de Aborto de HTTP

Siga estas etapas para injetar uma falha de aborto:

  1. Crie uma regra de injeção de falha para enviar uma resposta de cancelamento HTTP para o usuário jason:
    kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
  2. Para exibir a página Web Bookinfo, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser. Faça log-in como usuário jason. Uma mensagem indica que o serviço ratings está indisponível.
    Captura de tela da Página Bookinfo com Serviço de Classificação Indisponível

    Faça logout do usuário jason ou faça log-in com qualquer outro usuário para não ver nenhuma mensagem de erro.

    creenshot da Página Bookinfo sem erros

Criando Disjuntores

A quebra de circuito nos permite escrever aplicações que limitam o impacto de falhas, picos de latência e outros efeitos indesejáveis de peculiaridades de rede. Para obter mais informações sobre disjuntores, veja aqui.

  1. Crie uma regra de destino para aplicar definições de interrupção de circuito ao chamar o serviço do produto. A regra a seguir define o número máximo de conexões para não ser mais de uma e ter no máximo uma solicitação HTTP pendente. Além disso, as regras configuram hosts para serem verificados a cada 1 segundo. Qualquer host que falha uma vez com um código de erro 5XX é ejetado por 3 minutos. Além disso, 100% dos hosts no pool de balanceamento de carga para o serviço upstream são ejetados.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: productpage
    spec:
      host: productpage
      trafficPolicy:
        connectionPool:
          tcp:
            maxConnections: 1
          http:
            http1MaxPendingRequests: 1
            maxRequestsPerConnection: 1
        outlierDetection:
          consecutive5xxErrors: 1
          interval: 1s
          baseEjectionTime: 3m
          maxEjectionPercent: 100
      subsets:
      - name: v1
        labels:
          version: v1
    EOF
  2. Roteie todo o tráfego para a versão v1 de cada microsserviço.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  3. Crie um cliente para enviar tráfego ao serviço do produto. O Fortio permite que você controle o número de conexões, simultaneidade e atrasos para chamadas HTTP de saída. Se você tiver ativado a injeção automática de sidecar, implante o serviço fortio:
    kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml
    Como alternativa, injete manualmente o sidecar antes de implantar o aplicativo fortio.
    kubectl apply -f <(istioctl kube-inject -f samples/httpbin/sample-client/fortio-deploy.yaml)
  4. Faça log-in no pod do cliente e use a ferramenta fortio para chamar productpage e verificar se o código de status da resposta é 200 com os comandos a seguir.
    export FORTIO_POD=$(kubectl get pods -l app=fortio -o 'jsonpath={.items[0].metadata.name}')
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio curl http://productpage:9080
    
    É produzida a seguinte saída:
    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 1683
    server: envoy
    date: Tue, 07 Sep 2021 11:01:02 GMT
    x-envoy-upstream-service-time: 5
  5. Chame o serviço com 2 conexões simultâneas (-c 2) e envie 20 solicitações (-n 20). Curiosamente, 16 solicitações passam e 4 falham.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 2 -qps 0 -n 20 -loglevel Warning http://productpage:9080
    O comando produz resultados semelhantes a seguir.
    11:03:43 I logger.go:127> Log level is now 3 Warning (was 2 Info)
    Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 20 calls: http://productpage:9080
    Starting at max qps with 2 thread(s) [gomax 128] for exactly 20 calls (10 per thread + 0)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:03:43 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 51.340006ms : 20 calls. qps=389.56
    Aggregated Function Time : count 20 avg 0.0045031997 +/- 0.002036 min 0.000387421 max 0.007704444 sum 0.090063995
    # range, mid point, percentile, count
    >= 0.000387421 <= 0.001 , 0.000693711 , 15.00, 3
    > 0.003 <= 0.004 , 0.0035 , 20.00, 1
    > 0.004 <= 0.005 , 0.0045 , 65.00, 9
    > 0.005 <= 0.006 , 0.0055 , 75.00, 2
    > 0.006 <= 0.007 , 0.0065 , 95.00, 4
    > 0.007 <= 0.00770444 , 0.00735222 , 100.00, 1
    # target 50% 0.00466667
    # target 75% 0.006
    # target 90% 0.00675
    # target 99% 0.00756356
    # target 99.9% 0.00769036
    Sockets used: 5 (for perfect keepalive, would be 2)
    Jitter: false
    Code 200 : 16 (80.0 %)
    Code 503 : 4 (20.0 %)
    Response Header Sizes : count 20 avg 133.6 +/- 66.8 min 0 max 167 sum 2672
    Response Body/Total Sizes : count 20 avg 1528.2 +/- 643.6 min 241 max 1850 sum 30564
    All done 20 calls (plus 0 warmup) 4.503 ms avg, 389.6 qps
  6. Aumente o número de conexões simultâneas para 3.
    kubectl exec "$FORTIO_POD" -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 30 -loglevel Warning http://productpage:9080
    Apenas 26,7% das solicitações foram bem-sucedidas e a quebra de circuito prende o restante.
    11:10:19 I logger.go:127> Log level is now 3 Warning (was 2 Info)
    Fortio 1.11.3 running at 0 queries per second, 128->128 procs, for 30 calls: http://productpage:9080
    Starting at max qps with 3 thread(s) [gomax 128] for exactly 30 calls (10 per thread + 0)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    11:10:19 W http_client.go:693> Parsed non ok code 503 (HTTP/1.1 503)
    Ended after 28.105508ms : 30 calls. qps=1067.4
    Aggregated Function Time : count 30 avg 0.0024256753 +/- 0.003264 min 0.000261072 max 0.010510116 sum 0.07277026
    # range, mid point, percentile, count
    >= 0.000261072 <= 0.001 , 0.000630536 , 66.67, 20
    > 0.001 <= 0.002 , 0.0015 , 73.33, 2
    > 0.005 <= 0.006 , 0.0055 , 76.67, 1
    > 0.006 <= 0.007 , 0.0065 , 83.33, 2
    > 0.007 <= 0.008 , 0.0075 , 93.33, 3
    > 0.009 <= 0.01 , 0.0095 , 96.67, 1
    > 0.01 <= 0.0105101 , 0.0102551 , 100.00, 1
    # target 50% 0.000805545
    # target 75% 0.0055
    # target 90% 0.00766667
    # target 99% 0.0103571
    # target 99.9% 0.0104948
    Sockets used: 25 (for perfect keepalive, would be 3)
    Jitter: false
    Code 200 : 8 (26.7 %)
    Code 503 : 22 (73.3 %)
    Response Header Sizes : count 30 avg 44.533333 +/- 73.85 min 0 max 167 sum 1336
    Response Body/Total Sizes : count 30 avg 670.06667 +/- 711.5 min 241 max 1850 sum 20102
    All done 30 calls (plus 0 warmup) 2.426 ms avg, 1067.4 qps
  7. Consulte as estatísticas de istio-proxy para obter mais informações.
    kubectl exec "$FORTIO_POD" -c istio-proxy -- pilot-agent request GET stats | grep productpage | grep pending
    A quebra de circuito sinaliza 32 chamadas observando a métrica upstream_rq_pending_overflow.
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.remaining_pending: 1
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_active: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_failure_eject: 0
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_overflow: 32
    cluster.outbound|9080|v1|productpage.default.svc.cluster.local.upstream_rq_pending_total: 39
  8. Limpe o cliente.
    kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
    kubectl delete deploy fortio-deploy
    kubectl delete svc fortio

Espelhamento

O espelhamento de tráfego, também chamado de sombreamento, permite que as equipes tragam mudanças para a produção com o mínimo de risco possível. O espelhamento envia uma cópia do tráfego ao vivo para um serviço espelhado. O tráfego espelhado ocorre fora do caminho de solicitação crítica para o serviço principal.

  1. Roteie todo o tráfego para a versão v1 de cada microsserviço.
    kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
  2. Altere a regra de roteamento para espelhar o tráfego para reviews:v2.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: reviews
    spec:
      hosts:
        - reviews
      http:
      - route:
        - destination:
            host: reviews
            subset: v1
          weight: 100
        mirror:
          host: reviews
          subset: v2
        mirrorPercentage:
          value: 100.0
    EOF

    A regra de roteamento anterior envia 100% do tráfego para reviews:v1 e espelha 100% do mesmo tráfego para o serviço reviews:v2.

    Quando o tráfego é espelhado, as solicitações são enviadas ao serviço espelhado com seus cabeçalhos de Host/Autoridade anexados a -shadow. Por exemplo, as revisões se tornam solicitações reviews-shadow.Mirrored consideradas como "disparar e esquecer". As respostas espelhadas são descartadas.

    Em vez de espelhar todas as solicitações, altere o campo de valor no campo mirrorPercentage para espelhar uma fração do tráfego. Se este campo estiver ausente, todo o tráfego será espelhado.

  3. Envie algum tráfego atualizando o url http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um browser.
  4. Logs do serviço reviews:v1. Observação: o serviço v1 não chama o serviço de classificações.
    Captura de tela do serviço reviews:v1
  5. Logs do serviço espelhado reviews:v2. Observação para o serviço v2, o cabeçalho é anexado a -shadow.
    Captura de tela do serviço reviews:v2 com -shadow

Gerenciando Gateways

O gateway descreve um balanceador de carga que opera na borda da malha que recebe conexões HTTP/TCP de entrada ou de saída. As configurações de gateway são aplicadas a proxies Envoy autônomos que estão sendo executados na borda da malha, em vez de proxies Envoy sidecar executados ao lado de suas cargas de trabalho de serviço. O Istio fornece algumas implantações de proxy de gateway pré-configuradas istio-ingressgateway e istio-egressgateway.

Se você não tiver configurado os gateways Istio como parte da instalação, execute o comando a seguir para instalá-los.
istioctl install

O comando implanta o Istio usando as configurações padrão que incluem um gateway. Para obter mais informações, consulte aqui.

Observação

Determine INGRESS_HOST e INGRESS_PORT usando estas instruções.

Configurando a Entrada usando o Istio Gateway

O gateway de entrada configura portas e protocolos expostos, mas, ao contrário dos Recursos de Entrada do Kubernetes, não inclui nenhuma configuração de roteamento de tráfego. O roteamento de tráfego para tráfego de entrada é configurado usando regras de roteamento Istio. Para obter mais informações sobre a entrada no Istio, veja aqui.

Observação

Se você já tiver implantado o aplicativo Bookinfo, as etapas a seguir não serão necessárias.
  1. Crie um gateway Istio que configura na porta 80 para tráfego HTTP.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: Gateway
    metadata:
      name: bookinfo-gateway
    spec:
      selector:
        istio: ingressgateway # use istio default controller
      servers:
        - port:
            number: 80
            name: http
            protocol: HTTP
          hosts:
            - "*"
    EOF
  2. Configure rotas para tráfego que entra pelo Gateway:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: bookinfo
    spec:
      hosts:
      - "*"
      gateways:
      - bookinfo-gateway
      http:
      - match:
        - uri:
            exact: /productpage
        - uri:
            prefix: /static
        - uri:
            exact: /login
        - uri:
            exact: /logout
        - uri:
            prefix: /api/v1/products
        route:
        - destination:
            host: productpage
            port:
              number: 9080
    EOF
  3. Para implantar o aplicativo Bookinfo, consulte a seção "Executando o Aplicativo Bookinfo" da Página Instalando o Istio e o OKE.
  4. Acesse o serviço productpage usando o curl:
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/productpage

    O comando produz a seguinte saída:

    HTTP/1.1 200 OK
    content-type: text/html; charset=utf-8
    content-length: 4183
    server: istio-envoy
    date: Tue, 07 Sep 2021 13:48:39 GMT
    x-envoy-upstream-service-time: 36
  5. Acesse qualquer outro URL que não tenha sido explicitamente exposto. Você verá um erro HTTP 404.
    curl -s -I http://$INGRESS_HOST:$INGRESS_PORT/any

    O comando produz a seguinte saída:

    HTTP/1.1 404 Not Found
    date: Tue, 07 Sep 2021 13:49:45 GMT
    server: istio-envoy
    transfer-encoding: chunked
  6. Para hosts explícitos em gateways, use o flag -H para definir o cabeçalho HTTP do Host. O flag é necessário porque o gateway de entrada e o serviço virtual estão configurados para tratar o host. Por exemplo, seu host é example.com e o nome é especificado nos gateways e no serviço virtual.
    curl -s -I -HHost:example.com http://$INGRESS_HOST:$INGRESS_PORT/productpage
  7. Além disso, abra o URL http://${INGRESS_HOST}:${INGRESS_PORT}/productpage em um navegador para exibir a página da Web Bookinfo.

Configurando a Entrada usando o Recurso de Entrada do Kubernetes

O leitor assume que o aplicativo Bookinfo é implantado no cluster. Para implantar o aplicativo Bookinfo, consulte a seção "Executando o Aplicativo Bookinfo" da Página Instalando o Istio e o OKE.

  1. Remova o gateway Istio se a configuração já estiver aplicada.
    kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
  2. Crie um recurso de Entrada na porta 80 para tráfego HTTP.
    kubectl apply -f - <<EOF
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: istio
      name: ingress
    spec:
      rules:
      - http:
         paths:
         - path: /productpage
           pathType: Prefix
           backend:
              service:
                name: productpage
                port:
                  number: 9080
    EOF

    A anotação kubernetes.io/ingress.class é necessária para informar ao controlador de gateway Istio para tratar esse Ingress.

  3. Verifique o acesso ao aplicativo Bookinfo seguindo as instruções da seção anterior.
  4. Exclua o recurso e ative o gateway Istio para tarefas adicionais.
    kubectl delete ingress ingress
    kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml

Acessando Serviços Externos com Saída

Por padrão, todo o tráfego de saída de um pod ativado pelo Istio é redirecionado para seu proxy sidecar e o Istio configura o proxy Envoy para passar por solicitações de serviços desconhecidos. O Istio configura o tratamento sidecar de serviços externos por meio de um campo de configuração meshConfig.outboundTrafficPolicy.mode. Se essa opção for definida como:

  • ALLOW_ANY (padrão): O proxy Istio permite que chamadas a serviços desconhecidos passem.
  • REGISTRY_ONLY: O proxy Istio bloqueia qualquer host sem um serviço HTTP ou uma entrada de serviço definida na malha.

O leitor assume que o aplicativo Bookinfo é implantado no cluster. Caso contrário, siga as etapas para implantar o aplicativo Bookinfo.

Gerenciando a Transferência do Envoy para Serviços Externos

Para ativar a transferência para serviços externos, siga estas etapas.

  1. Altere a opção meshConfig.outboundTrafficPolicy.mode para ALLOW_ANY com istioctl.
    istioctl install --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY
    Observação

    Esta etapa só será necessária se você tiver definido explicitamente a opção como REGISTRY_ONLY durante a instalação.
  2. Para confirmar 200 respostas bem-sucedidas, faça uma solicitação para serviços externos pelo SOURCE_POD:
    export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}')
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    O comando produz a seguinte saída:
    HTTP/1.1 200 OK

No entanto, a desvantagem com essa abordagem é que o monitoramento e o controle do Istio para o tráfego para serviços externos são perdidos.

Controlando o Acesso a Serviços Externos [Recomendado]

Para configurar o acesso controlado a serviços externos, siga estas etapas:

  1. Altere a opção meshConfig.outboundTrafficPolicy.mode para REGISTRY_ONLY. Esta etapa só será necessária se você não tiver definido explicitamente a opção como REGISTRY_ONLY durante a instalação.
  2. Siga apenas a etapa 1 da seção "Transferência do Envoy para Serviços Externos". A única alteração a ser feita aqui é substituir ALLOW_ANY por REGISTRY_ONLY.
  3. Para verificar se os serviços externos estão bloqueados, faça algumas solicitações para serviços HTTPS externos em SOURCE_POD. As alterações de configuração levam vários segundos para serem propagadas, de modo que conexões bem-sucedidas são possíveis. Aguarde alguns segundos e repita o último comando.
    export SOURCE_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items..metadata.name}')
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"

    O comando produz a seguinte saída:

    HTTP/1.1 502 Bad Gateway
  4. Crie um ServiceEntry para permitir o acesso a um serviço HTTP externo.
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: ServiceEntry
    metadata:
      name: httpbin-ext
    spec:
      hosts:
      - httpbin.org
      ports:
      - number: 80
        name: http
        protocol: HTTP
      resolution: DNS
      location: MESH_EXTERNAL
    EOF
  5. Faça uma solicitação para o serviço HTTP externo em SOURCE_POD. Observe que os cabeçalhos adicionados pelo proxy sidecar do Istio: X-Envoy-Decorator-Operation.
    kubectl exec $SOURCE_POD -c ratings -- curl -sI http://httpbin.org/headers | grep "HTTP"
    O comando produz a seguinte saída:
    HTTP/1.1 200 OK

    Remova o comando grep para ver todos os cabeçalhos.

    kubectl exec $SOURCE_POD -c ratings -- curl -sS http://httpbin.org/headers

    O comando produz a seguinte saída:

    {
      "headers": {
        "Accept": "*/*",
        "Host": "httpbin.org",
        "User-Agent": "curl/7.52.1",
        "X-Amzn-Trace-Id": "Root=1-61384b41-2d3cf8b5571ba7504ab9a834",
        "X-B3-Sampled": "0",
        "X-B3-Spanid": "6983ef0cec914f83",
        "X-B3-Traceid": "d510c4d190cb099d6983ef0cec914f83",
        "X-Envoy-Attempt-Count": "1",
        "X-Envoy-Decorator-Operation": "httpbin.org:80/*",
        "X-Envoy-Peer-Metadata": "ChsKDkFQUF9DT05UQUlORVJTEgkaB3JhdGluZ3MKGgoKQ0xVU1RFUl9JRBIMGgpLdWJlcm5ldGVzChkKDUlTVElPX1ZFUlNJT04SCBoGMS4xMS4xCtQBCgZMQUJFTFMSyQEqxgEKEAoDYXBwEgkaB3JhdGluZ3MKIAoRcG9kLXRlbXBsYXRlLWhhc2gSCxoJYzk5NDdiOTlmCiQKGXNlY3VyaXR5LmlzdGlvLmlvL3Rsc01vZGUSBxoFaXN0aW8KLAofc2VydmljZS5pc3Rpby5pby9jYW5vbmljYWwtbmFtZRIJGgdyYXRpbmdzCisKI3NlcnZpY2UuaXN0aW8uaW8vY2Fub25pY2FsLXJldmlzaW9uEgQaAnYxCg8KB3ZlcnNpb24SBBoCdjEKGgoHTUVTSF9JRBIPGg1jbHVzdGVyLmxvY2FsCiQKBE5BTUUSHBoacmF0aW5ncy12MS1jOTk0N2I5OWYtbGN4bHQKFgoJTkFNRVNQQUNFEgkaB2RlZmF1bHQKTgoFT1dORVISRRpDa3ViZXJuZXRlczovL2FwaXMvYXBwcy92MS9uYW1lc3BhY2VzL2RlZmF1bHQvZGVwbG95bWVudHMvcmF0aW5ncy12MQoXChFQTEFURk9STV9NRVRBREFUQRICKgAKHQoNV09SS0xPQURfTkFNRRIMGgpyYXRpbmdzLXYx",
        "X-Envoy-Peer-Metadata-Id": "sidecar~10.244.0.11~ratings-v1-c9947b99f-lcxlt.default~default.svc.cluster.local"
      }
    }
  6. Para acessar chamadas HTTPS, substitua a porta e o protocolo ao criar entradas de serviço.
  7. A abordagem adiciona recursos de gerenciamento de tráfego de serviço externo, como timeouts e injeção de falhas. A solicitação a seguir retorna 200 (OK) em aproximadamente cinco segundos.
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
    Use kubectl para definir um timeout de 3 segundos nas chamadas para o serviço externo httpbin.org:
    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: httpbin-ext
    spec:
      hosts:
        - httpbin.org
      http:
      - timeout: 3s
        route:
          - destination:
              host: httpbin.org
            weight: 100
    EOF
    Desta vez, um timeout aparece após 3 segundos. Embora httpbin.org estivesse aguardando cinco segundos, o Istio cortou a solicitação em 3 segundos:
    kubectl exec $SOURCE_POD -c ratings -- curl http://httpbin.org/delay/5
  8. Limpe os recursos para tarefas futuras.
    kubectl delete serviceentry httpbin-ext
    kubectl delete virtualservice httpbin-ext --ignore-not-found=true

Direcionando o Acesso a Serviços Externos

Essa abordagem ignora o proxy sidecar do Istio, dando aos serviços acesso direto a qualquer servidor externo. No entanto, configurar o proxy dessa forma requer conhecimento e configuração específicos do provedor de cluster. Semelhante à primeira abordagem, perdemos o monitoramento do acesso a serviços externos e não podemos aplicar os recursos do Istio no tráfego a serviços externos. Siga estas etapas para fornecer acesso direto a serviços externos.

Protegendo o Istio

Os recursos de segurança do Istio fornecem identidade forte, política avançada, criptografia TLS transparente e ferramentas de autenticação, autorização e auditoria (AAA) para proteger seus serviços e dados.

Configurando a Autenticação

O Istio oferece TLS mútuo como uma solução de pilha completa para autenticação de transporte, que é ativada sem exigir alterações no código de serviço.

Implante os serviços sleep e httpbin no namespace padrão.
kubectl apply -f samples/sleep/sleep.yaml
kubectl apply -f samples/httpbin/httpbin.yaml

Por padrão, o Istio executa várias tarefas. O Istio rastreia as cargas de trabalho do servidor migradas para os proxies do Istio. O Istio configura proxies clientes para enviar tráfego TLS mútuo para essas cargas de trabalho automaticamente. O Istio envia tráfego de texto sem formatação para cargas de trabalho sem sidecars.

Para verificar se os certificados são enviados, envie uma solicitação de um pod sleep para o pod httpbin e procure o cabeçalho X-Forwarded-Client-Cert.
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl -s http://httpbin.default:8000/headers -s | grep X-Forwarded-Client-Cert | sed 's/Hash=[a-z0-9]*;/Hash=<redacted>;/'
Implante outra instância dos serviços sleep e httpbin sem o sidecar ativado.
kubectl create ns legacy
kubectl apply -f samples/sleep/sleep.yaml -n legacy
kubectl apply -f samples/httpbin/httpbin.yaml -n legacy
A solicitação do pod sleep no namespace padrão para o pod httpbin no namespace legado é texto sem formatação porque o destino não está ativado para sidecar. Verifique se o texto sem formatação é enviado executando o comando a seguir.
kubectl exec "$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})" -c sleep -- curl http://httpbin.legacy:8000/headers -s | grep X-Forwarded-Client-Cert
A solicitação do pod sleep no namespace legado para httpbin no namespace padrão também é bem-sucedida com uma conexão de texto simples. O comando a seguir pode ser verificado.
kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
Para evitar tráfego TLS não mútuo para toda a malha, defina uma política de autenticação de mesmo nível em toda a malha com o modo TLS mútuo definido como STRICT.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: "default"
  namespace: "istio-system"
spec:
  mtls:
    mode: STRICT
EOF
A conexão de um pod sleep no namespace legado com httpbin no namespace padrão não funciona mais quando o modo TLS mútuo é definido como STRICT.
kubectl exec "$(kubectl get pod -l app=sleep -n legacy -o jsonpath={.items..metadata.name})" -n legacy -c sleep -- curl http://httpbin.default:8000/headers
Reverta a definição de autenticação de pareamento STRICT excluindo o CR.
kubectl delete peerauthentication -n istio-system default

Além da definição de TLS mútuo global, ela também pode ser definida em um namespace ou nível de carga de trabalho. Siga a documentação do Istio para obter configurações de autenticação detalhadas.

Configurando a Autorização

O Istio permite configurar políticas de autorização para seus aplicativos.

Primeiro, configure uma política allow-nothing simples que rejeite todas as solicitações para a carga de trabalho e, em seguida, conceda mais acesso à carga de trabalho de forma gradual e incremental.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
  namespace: default
spec:
  {}
EOF

Abra a página do produto Bookinfo no seu navegador. Ela mostra o erro "RBAC: access denied" confirmando que a política deny-all está funcionando conforme pretendido.

Crie uma política para conceder a todos os usuários e cargas de trabalho acesso à página do produto usando o comando a seguir.
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "productpage-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: productpage
  action: ALLOW
  rules:
  - to:
    - operation:
        methods: ["GET"]
EOF

Você vê a página "Bookinfo Sample", mas o serviço productpage não pode acessar a página de detalhes e revisões.

Adicione as políticas a seguir para conceder acesso à carga de trabalho productpage aos detalhes e verifica cargas de trabalho e verifica o acesso à carga de trabalho à carga de trabalho ratings.

Definir Visualizador de Detalhes

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "details-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: details
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

Definir Visualizador de Revisões

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "reviews-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: reviews
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
    to:
    - operation:
        methods: ["GET"]
EOF

Definir Visualizador de Classificações

kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: "ratings-viewer"
  namespace: default
spec:
  selector:
    matchLabels:
      app: ratings
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/default/sa/bookinfo-reviews"]
    to:
    - operation:
        methods: ["GET"]
EOF

Visualize a página do produto a partir de um navegador sem erros.

Para reverter as políticas aplicadas, informe os comandos a seguir.

kubectl delete authorizationpolicy.security.istio.io/allow-nothing
kubectl delete authorizationpolicy.security.istio.io/productpage-viewer
kubectl delete authorizationpolicy.security.istio.io/details-viewer
kubectl delete authorizationpolicy.security.istio.io/reviews-viewer
kubectl delete authorizationpolicy.security.istio.io/ratings-viewer

Protegendo Gateways com TLS

Podemos expor o aplicativo Bookinfo como um serviço HTTPS seguro usando TLS simples ou mútuo. Para assinar os certificados de seus serviços, crie um certificado raiz e uma chave privada:

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt

Crie um certificado e uma chave privada para productpage.bookinfo.com.

openssl req -out bookinfo.example.com.csr -newkey rsa:2048 -nodes -keyout bookinfo.example.com.key -subj "/CN=bookinfo.example.com/O=bookinfo organization"
openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in bookinfo.example.com.csr -out bookinfo.example.com.crt

Certifique-se de ter implantado o aplicativo Bookinfo. Crie um segredo para os certificados do gateway de entrada.

kubectl create -n istio-system secret tls bookinfo-credential --key=bookinfo.example.com.key --cert=bookinfo.example.com.crt

Atualize o gateway Bookinfo para incluir uma porta segura.

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: bookinfo-gateway-https
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      credentialName: bookinfo-credential
    hosts:
    - bookinfo.example.com
EOF

Criar regras de destino Bookinfo se ainda não tiverem sido criadas.

kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml

Crie um serviço virtual vinculado ao gateway.

kubectl apply -f - <<EOF
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: bookinfo-https
spec:
  hosts:
  - "bookinfo.example.com"
  gateways:
  - bookinfo-gateway-https
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
EOF

Você pode verificar a conexão TLS com o gateway com o seguinte comando curl.

curl -v -HHost:bookinfo.example.com --resolve "bookinfo.example.com:443:$INGRESS_HOST" --cacert example.com.crt "https://bookinfo.example.com/productpage"