O que é ? Это так называемый Service mesh, технология, которая добавляет уровень абстракции над сетью. Мы перехватываем весь или часть трафика в кластере и производим определенный набор операций с ним. Какой именно? Например, делаем умный роутинг, или реализуем подход circuit breaker, можем организовывать «canary deployment», частично переключая трафик на новую версию сервиса, а можем ограничивать внешние взаимодействия и контролировать все походы из кластера во внешнюю сеть. Есть возможность задавать policy правила для контроля походов между разными микросервисами. Наконец, мы можем получить всю карту взаимодействия по сети и сделать унифицированный сбор метрик полностью прозрачно для приложений.
Você pode ler sobre o mecanismo de funcionamento na . O Istio é realmente uma ferramenta poderosa que permite resolver uma série de tarefas e problemas. Neste artigo, gostaria de responder às principais perguntas que geralmente surgem no início do trabalho com o Istio. Isso ajudará você a entender melhor.

Princípio de funcionamento
O Istio é composto por duas áreas principais — o control plane e o data plane. O control plane contém os componentes principais que garantem o funcionamento correto dos demais. Na versão atual (1.0), o control plane possui três componentes principais: Pilot, Mixer, Citadel. Não iremos abordar o Citadel, pois ele é necessário para a geração de certificados que garantem o funcionamento do mutual TLS entre os serviços. Vamos analisar mais detalhadamente a estrutura e o propósito do Pilot e do Mixer.

Pilot é o principal componente de gerenciamento, que distribui todas as informações sobre o que temos no cluster – serviços, seus endpoints e regras de roteamento (como, por exemplo, regras para Canary deployment ou regras de circuit breaker).
Mixer é um componente opcional do control plane, que fornece a capacidade de coletar métricas, logs e qualquer informação sobre a interação de rede. Ele também monitora a conformidade com as regras de Policy e limitações de taxa.
O data plane é implementado por meio de containers sidecar proxy. O poderoso . Ele pode ser substituído por outra implementação, como nginx (nginmesh).
Para que o Istio opere de forma totalmente transparente para as aplicações, há um sistema de injeção automática. A última implementação é adequada para versões do Kubernetes 1.9+ (mutational admission webhook). Para as versões 1.7 e 1.8 do Kubernetes, há a opção de usar o Initializer.
Os containers sidecar se conectam ao Pilot por meio do protocolo GRPC, que permite otimizar o modelo de push para as alterações que ocorrem no cluster. O GRPC começou a ser utilizado no Envoy a partir da versão 1.6 e no Istio é usado desde a versão 0.8, representando-se como pilot-agent — uma camada em golang sobre o envoy, que configura os parâmetros de inicialização.
Pilot e Mixer são componentes completamente stateless, mantendo todo o estado na memória. A configuração para eles é definida na forma de Recursos Customizados do Kubernetes, que são armazenados no etcd.
O Istio-agent obtém o endereço do Pilot e abre um stream GRPC para ele.
Como já mencionei, o Istio implementa toda a funcionalidade de forma completamente transparente para os aplicativos. Vamos entender como. O algoritmo é o seguinte:
- Implantamos uma nova versão do serviço.
- Dependendo da abordagem de injeção do contêiner sidecar, o contêiner istio-init e o contêiner istio-agent (envoy) são adicionados na fase de aplicação da configuração, ou podem já ter sido inseridos manualmente na descrição da entidade Pod do Kubernetes.
- O contêiner istio-init consiste em um script que aplica regras iptables ao pod. Existem duas opções para configurar o redirecionamento de tráfego para o contêiner istio-agent: usar regras de redirecionamento iptables ou . No momento da redação deste artigo, a abordagem com regras de redirecionamento é a usada por padrão. No istio-init, é possível configurar qual tráfego deve ser interceptado e direcionado para o istio-agent. Por exemplo, para interceptar todo o tráfego de entrada e saída, é necessário definir os parâmetros
-ie-bcomo valor*. É possível especificar portas específicas que devem ser interceptadas. Para evitar interceptar uma sub-rede específica, é possível indicá-la com a flag-x. - Após a execução dos contêineres init, os principais são iniciados, incluindo o pilot-agent (envoy). Ele se conecta ao Pilot já implementado via GRPC e obtém informações sobre todos os serviços existentes e políticas de roteamento no cluster. Com base nos dados recebidos, ele configura os clusters e define diretamente os endpoints dos nossos aplicativos no cluster Kubernetes. Também é importante notar um ponto fundamental: o envoy configura dinamicamente os listeners (pares IP, port) que começa a escutar. Portanto, quando as solicitações chegam ao pod, são redirecionadas por meio das regras de redirecionamento iptables para o sidecar, e o envoy já pode processar essas conexões com sucesso e entender para onde deve encaminhar o tráfego a seguir. Além disso, neste estágio, informações são enviadas ao Mixer, que examinaremos mais adiante, e são enviados spans de rastreamento.
No final, temos toda uma rede de proxies envoy que podemos configurar a partir de um único ponto (Pilot). Todas as requisições inbound e outbound passam pelo envoy. Além disso, apenas o tráfego TCP é interceptado. Isso significa que o IP do serviço Kubernetes é resolvido usando kube-dns via UDP sem alterações. Após a resolução, ocorre a interceptação da requisição de saída e o processamento pelo envoy, que decide para qual endpoint a requisição deve ser enviada (ou não, em caso de políticas de acesso ou ativação do algoritmo de circuit breaker).
Com o Pilot entendido, agora precisamos compreender como funciona o Mixer e para quê ele serve. Você pode ler a documentação oficial sobre ele. .
O Mixer, na sua forma atual, é composto por dois componentes: istio-telemetry e istio-policy (até a versão 0.8, era um único componente chamado istio-mixer). Ambos representam o mixer, cada um responsável por sua própria tarefa. O istio-telemetry recebe informações sobre quem está indo aonde e com quais parâmetros, enviadas via GRPC pelos contêineres sidecar. O istio-policy recebe requisições de verificação (Check) para validar se os requisitos da política estão sendo atendidos. As verificações de política são, claro, não feitas em cada requisição, mas são armazenadas em cache no cliente (no sidecar) por um tempo determinado. As verificações de relatório (Report) são enviadas em lotes. Vamos ver mais tarde como configurá-las e quais parâmetros exatamente precisam ser enviados.
O Mixer é projetado como um componente de alta disponibilidade, que garante o funcionamento contínuo da coleta e processamento de dados de telemetria. O sistema acaba se tornando um buffer em múltiplas camadas. Inicialmente, os dados são armazenados em buffer no lado dos contêineres sidecar, depois no lado do mixer e, em seguida, enviados para os chamados backends do mixer. Assim, se algum componente do sistema falhar, o buffer aumenta e, após a recuperação do sistema, é descarregado. Os backends do mixer atuam como os pontos finais de envio de dados de telemetria: statsd, newrelic, etc. É possível escrever seu próprio backend, o que é bastante simples, e ver como fazer isso.

Resumindo, o esquema de operação com o istio-telemetry é o seguinte.
- O serviço 1 envia uma requisição para o serviço 2.
- Ao sair do serviço 1, a requisição é encapsulada em seu próprio sidecar.
- O sidecar envoy monitora como a requisição avança para o serviço 2 e prepara as informações necessárias.
- Em seguida, estas informações são enviadas ao istio-telemetry por meio de uma requisição de Report.
- O istio-telemetry determina se deve enviar este Report para os backends, quais especificamente e quais dados devem ser enviados.
- O Istio-telemetry envia dados de relatório para o backend se necessário.
Agora vamos ver como implantar o sistema Istio, composto apenas pelos componentes principais (Pilot e sidecar envoy).
Para começar, vamos olhar a configuração principal (mesh) que o Pilot lê:
apiVersion: v1
kind: ConfigMap
metadata:
name: istio
namespace: istio-system
labels:
app: istio
service: istio
data:
mesh: |-
# por enquanto não habilitamos o envio de informações de tracing (o pilot configurará os envoys de tal forma que o envio não ocorra)
enableTracing: false
# por enquanto não especificamos os endpoints do mixer, para que os contêineres sidecar não enviem informações para lá
#mixerCheckServer: istio-policy.istio-system:15004
#mixerReportServer: istio-telemetry.istio-system:15004
# definimos o intervalo de tempo com o qual o envoy fará novas consultas ao Pilot (isso é para a versão antiga do proxy envoy)
rdsRefreshDelay: 5s
# configuração padrão para o sidecar do envoy
defaultConfig:
# similar ao rdsRefreshDelay
discoveryRefreshDelay: 5s
# mantemos por padrão (caminho para a configuração e binário do envoy)
configPath: "/etc/istio/proxy"
binaryPath: "/usr/local/bin/envoy"
# nome padrão do contêiner sidecar em execução (usado, por exemplo, nos nomes de serviço ao enviar spans de tracing)
serviceCluster: istio-proxy
# tempo que o envoy esperará antes de forçar o fechamento de todas as conexões estabelecidas
drainDuration: 45s
parentShutdownDuration: 1m0s
# por padrão, são usadas regras de REDIRECT do iptables. Pode ser alterado para TPROXY.
#interceptionMode: REDIRECT
# Porta em que será iniciada a painel administrativo de cada contêiner sidecar (envoy)
proxyAdminPort: 15000
# endereço para onde os traces serão enviados via protocolo zipkin (no início desabilitamos o próprio envio, portanto este campo atualmente não será utilizado)
zipkinAddress: tracing-collector.tracing:9411
# endereço statsd para enviar métricas dos contêineres envoy (desabilitado)
# statsdUdpAddress: aggregator:8126
# desativamos o suporte à opção Mutual TLS
controlPlaneAuthPolicy: NONE
# endereço onde o istio-pilot escutará para relatar informações sobre descoberta de serviço a todos os contêineres sidecar
discoveryAddress: istio-pilot.istio-system:15007
Todos os principais componentes de controle (control plane) serão colocados no namespace istio-system no Kubernetes.
Minimamente, precisamos implantar apenas o Pilot. Para isso, usaremos
E configuraremos manualmente o injecting do contêiner sidecar.
Contêiner Init:
initContainers:
- name: istio-init
args:
- -p
- "15001"
- -u
- "1337"
- -m
- REDIRECT
- -i
- '*'
- -b
- '*'
- -d
- ""
image: istio/proxy_init:1.0.0
imagePullPolicy: IfNotPresent
resources:
limits:
memory: 128Mi
securityContext:
capabilities:
add:
- NET_ADMIN
E sidecar:
name: istio-proxy
args:
- "bash"
- "-c"
- |
exec /usr/local/bin/pilot-agent proxy sidecar
--configPath
/etc/istio/proxy
--binaryPath
/usr/local/bin/envoy
--serviceCluster
service-name
--drainDuration
45s
--parentShutdownDuration
1m0s
--discoveryAddress
istio-pilot.istio-system:15007
--discoveryRefreshDelay
1s
--connectTimeout
10s
--proxyAdminPort
"15000"
--controlPlaneAuthPolicy
NONE
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: ISTIO_META_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ISTIO_META_INTERCEPTION_MODE
value: REDIRECT
image: istio/proxyv2:1.0.0
imagePullPolicy: IfNotPresent
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 2048Mi
securityContext:
privileged: false
readOnlyRootFilesystem: true
runAsUser: 1337
volumeMounts:
- mountPath: /etc/istio/proxy
name: istio-envoy
Para que tudo funcione corretamente, é necessário criar um ServiceAccount, ClusterRole, ClusterRoleBinding e CRD para o Pilot, cujas descrições podem ser encontradas .
Em resumo, o serviço no qual injetamos o sidecar com o envoy deve ser iniciado com sucesso, obter todas as descobertas do piloto e processar as solicitações.
É importante entender que todos os componentes do controle de plano são aplicativos sem estado e podem ser escalonados horizontalmente sem problemas. Todos os dados estão armazenados no etcd na forma de descrições personalizadas de recursos do Kubernetes.
O Istio também (ainda de forma experimental) tem a capacidade de funcionar fora do cluster e de visualizar e compartilhar a descoberta de serviços entre vários clusters do Kubernetes. Mais detalhes podem ser encontrados aqui. .
Ao instalar em ambientes multicluster, é importante considerar as seguintes restrições:
- O Pod CIDR e o Service CIDR devem ser exclusivos em todos os clusters e não devem se sobrepor.
- Todos os Pod CIDR devem ser acessíveis a partir de qualquer Pod CIDR entre os clusters.
- Todos os servidores de API do Kubernetes devem ser acessíveis entre si.
Estas são informações iniciais que ajudarão você a começar a trabalhar com Istio. No entanto, há muitos desafios adicionais. Por exemplo, as particularidades do roteamento de tráfego externo (fora do cluster), abordagens para depuração de sidecars, perfilamento, configuração do mixer e desenvolvimento de um backend customizado para o mixer, além da configuração do mecanismo de rastreamento e sua operação com o envoy.
Vamos abordar tudo isso nas publicações futuras. Sinta-se à vontade para fazer suas perguntas, tentarei esclarecê-las.
Fonte: habr.com
