Para que serve uma rede de serviços?
A malha de serviço, neste caso, Istio, é uma ligação para tudo o que é necessário para gerenciar e configurar a comunicação entre serviços: roteamento, autenticação, autorização, rastreamento, controle de acesso e muito mais. E embora existam inúmeras bibliotecas abertas para implementar essas funções diretamente no código de serviço, com o Istio você pode obter a mesma coisa sem adicionar nada ao serviço em si.
Componentes
Artigo escrito para istio 1.6
Sobre mudanças
O Istio é logicamente dividido em um plano de dados e um plano de controle.
O plano de dados é uma coleção de servidores proxy (Envoy) adicionados ao pod como sidecars. Esses proxies fornecem e controlam toda a comunicação de rede entre microsserviços e são configurados no plano de controle.
O plano de gerenciamento (istiod) fornece descoberta de serviços, configuração e gerenciamento de certificados. Ele converte objetos Istio em configurações que o Envoy entende e os distribui no plano de dados.
Componentes de malha de serviço Istio
Você pode adicionar o enviado ao pod do aplicativo manualmente ou configurando a adição automática usando o webhook Mutating Admission, que o Istio adiciona durante sua instalação. Para fazer isso, coloque a tag istio-injection = enabled no espaço para nome necessário.
Além do side-car proxy com enviado, o Istio adicionará um contêiner init especial ao pod que redirecionará o tráfego de combate para o contêiner com enviado. Mas como isso é alcançado? Nesse caso, não há mágica, e isso é implementado através da definição de regras adicionais de iptables no namespace de rede do pod.
Sobre o consumo de recursos
, 100 Istio ~2-3 , envoy 40 , CPU 5%-7% pod.
Vamos ver na prática como um carro lateral captura o tráfego de entrada e saída de um contêiner. Para fazer isso, dê uma olhada no espaço de rede de um pod com o sidio Istio adicionado em mais detalhes.
Suporte de demonstração
Kubernetes Istio.
Kubernetes minikube:
Istio demo :
: productpage details. Istio .
Kubernetes minikube:
Linux:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube
sudo mkdir -p /usr/local/bin/
sudo install minikube /usr/local/bin/
minikube start --driver=<driver_name> // --driver=none .
MacOS:
brew install minikube
minikube start --driver=<driver_name>
Istio demo :
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.6.3
export PATH=$PWD/bin:$PATH
istioctl install --set profile=demo
: productpage details. Istio .
kubectl label namespace default istio-injection=enabled
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
Vamos ver uma lista de contêineres para o aplicativo da página do produto:
kubectl -n default get pods productpage-v1-7df7cb7f86-ntwzz -o jsonpath="{.spec['containers','initContainers'][*].name}"
productpage
istio-proxy
istio-init
Além da própria página do produto, o sidecar istio-proxy (o mesmo enviado) e o init init istio-init funcionam no pod.
Você pode ver os nomes dos pods das regras do iptables configuradas no espaço usando o utilitário nsenter. Para fazer isso, precisamos descobrir o detalhe do processo do contêiner:
docker inspect k8s_productpage --format '{{ .State.Pid }}'
16286
Agora podemos ver as regras do iptables instaladas neste contêiner.
Você pode ver que quase todo o tráfego de entrada e saída agora é interceptado e redirecionado para portas nas quais o enviado já o espera.
Ativar criptografia de tráfego mútuo
Os objetos Policy e MeshPolicy foram removidos da versão 1.6. Em vez disso, é sugerido o uso do objeto PeerAuthentication
O Istio permite criptografar todo o tráfego entre contêineres, e os próprios aplicativos nem saberão que estão se comunicando via tls. Isso é feito pelo próprio Istio, pronto para uso, com literalmente um manifesto, pois os certificados do cliente já estão montados no side-car proxy.
O algoritmo é o seguinte:
- Os proxies enviados, no lado do cliente e no servidor, se autenticam antes de enviar solicitações;
- Se a verificação for bem-sucedida, o proxy do cliente criptografa o tráfego e o envia ao proxy do servidor;
- O lado do servidor proxy descriptografa o tráfego e o redireciona localmente para o serviço de destino real.
Você pode ativar o mTLS em diferentes níveis:
- No nível de toda a rede;
- No nível do espaço para nome;
- No nível de um pod específico.
Modos de operação:
- PERMISSIVO: o tráfego de texto criptografado e de texto sem formatação é permitido;
- STRICT: somente TLS permitido;
- DESATIVAR: somente texto sem formatação é permitido.
Vamos acessar o serviço de detalhes no pod da página do produto usando curl sem TLS ativado e ver o que vem com o tcpdump para obter detalhes:
Solicitação:
Despejo de tráfego:
todo o corpo e cabeçalhos são perfeitamente legíveis em texto sem formatação.
Vamos ativar tls. Para fazer isso, crie um objeto do tipo PeerAuthentication no espaço para nome com nossos pods.
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: default
spec:
mtls:
mode: STRICT
Vamos executar a solicitação na página do produto para obter detalhes novamente e ver o que obtemos: O
tráfego é criptografado
Conecte-se
Os objetos ClusterRbacConfig, ServiceRole e ServiceRoleBinding foram removidos junto com a implementação da nova política de autorização. Em vez disso, propõe-se usar o objeto AuthorizationPolicy.
Usando políticas de autorização, o Istio pode configurar um aplicativo para acessar outro. Além disso, diferentemente das políticas de rede Kubernetes, isso funciona no nível L7. Por exemplo, para o tráfego http, você pode controlar com precisão os métodos e caminhos da solicitação.
Como vimos no exemplo anterior, por padrão, o acesso é aberto a todos os pods em todo o cluster.
Agora vamos desativar todas as atividades no espaço para nome padrão usando o seguinte arquivo yaml:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: deny-all
namespace: default
spec:
{}
E vamos tentar alcançar o serviço de detalhes:
curl details:9080
RBAC: access denied
Ótimo, agora nosso pedido falha.
E agora vamos configurar o acesso para que apenas uma solicitação GET passe e somente ao longo do caminho / detalhes, e todas as outras solicitações sejam rejeitadas. Existem várias opções para isso:
- Pode ser configurado para passar solicitações com cabeçalhos específicos;
- Por conta de serviço do aplicativo;
- Pelo endereço IP de saída;
- Por namespace de saída;
- Por reivindicações no token JWT.
A coisa mais fácil de manter é configurar o acesso à conta de serviço do aplicativo, pois não é necessária nenhuma configuração preliminar, pois o aplicativo de demonstração bookinfo já vem com uma conta de serviço criada e monitorada.
Para usar políticas de autorização com base em contas de serviço, você deve habilitar a autenticação mútua TLS.
Configurando uma nova política de acesso:
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "details-viewer"
namespace: default
spec:
selector:
matchLabels:
app: details
rules:
- from:
- source:
principals: ["cluster.local/ns/default/sa/bookinfo-productpage"]
to:
- operation:
methods: ["GET"]
paths: ["/details/*"]
E tentamos entrar em contato novamente:
root@productpage-v1-6b64c44d7c-2fpkc:/# curl details:9080/details/0
{"id":0,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"}
Tudo está funcionando. Vamos tentar outros métodos e maneiras:
root@productpage-v1-6b64c44d7c-2fpkc:/# curl -XPOST details:9080/details/0
RBAC: access denied
root@productpage-v1-6b64c44d7c-2fpkc:/#
root@productpage-v1-6b64c44d7c-2fpkc:/# curl -XGET details:9080/ping
RBAC: access denied
Conclusão
Concluindo, observo que as oportunidades consideradas são apenas uma fração do que o Istio pode fazer. Pronto para uso, recebemos e configuramos a criptografia e a autorização de tráfego entre serviços, embora com o custo de adicionar componentes adicionais e, portanto, consumo adicional de recursos.
Obrigado a todos!