Para acompanhar o Workshop, siga os passos a seguir:
$ git clone --recurse-submodules git@github.com:vcampitelli/workshop-kubernetes.git
docs/index.html
em seu navegador
scripts
e execute:
$ minikube start
A variant of the soa structural style – arranges an application as a collection of loosely-coupled services. In a microservices architecture, services are fine-grained and the protocols are lightweight.Wikipedia
Containers are an abstraction at the app layer that packages code and dependencies together. Multiple containers can run on the same machine and share the OS kernel with other containers, each running as isolated processes in user space. Containers take up less space than VMs (container images are typically tens of MBs in size), can handle more applications and require fewer VMs and Operating systems.Docker
Kubernetes, also known as K8s, is an open-source system for automating deployment, scaling, and management of containerized applications.kubernetes.io
Pods are the smallest deployable units of computing that you can create and manage in Kubernetes.
Pod is a group of one or more containers, with shared storage and network resources, and a specification for how to run the containers. A Pod's contents are always co-located and co-scheduled, and run in a shared context.kubernetes.io
A Deployment provides declarative updates for Pods and ReplicaSets.kubernetes.io
You describe a desired state in a Deployment, and the Deployment Controller changes the actual state to the desired state at a controlled rate. You can define Deployments to create new ReplicaSets, or to remove existing Deployments and adopt all their resources with new Deployments.
An abstract way to expose an application running on a set of Pods as a network service.
In Kubernetes, a Service is an abstraction which defines a logical set of Pods and a policy by which to access them (sometimes this pattern is called a micro-service).kubernetes.io
In Kubernetes, a HorizontalPodAutoscaler automatically updates a workload resource (such as a Deployment or StatefulSet), with the aim of automatically scaling the workload to match demand.kubernetes.io
Horizontal scaling means that the response to increased load is to deploy more Pods. This is different from vertical scaling, which for Kubernetes would mean assigning more resources (for example: memory or CPU) to the Pods that are already running for the workload.kubernetes.io
If the load decreases, and the number of Pods is above the configured minimum, the HorizontalPodAutoscaler instructs the workload resource (the Deployment, StatefulSet, or other similar resource) to scale back down. Horizontal pod autoscaling does not apply to objects that can't be scaled (for example: a DaemonSet.)kubernetes.io
É uma camada dedicada de infraestrutura para facilitar a comunicação entre serviços usando um proxyWikipedia
Propõe uma gestão mais eficaz das comunicações entre serviços, maior controle operacional e também o fornecimento de informações comportamentaisWikipedia
is an open source Service Mesh that layers transparently onto existing distributed applicationsistio.io
Siga a documentação oficial em
minikube.sigs.k8s.io
para instalar o minikube
de acordo com seu sistema operacional
Para ambientes Linux com arquitetura amd64, o comando é:
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
$ sudo install minikube-linux-amd64 /usr/local/bin/minikube
Clone ou atualize este repositório:
$ git clone --recurse-submodules git@github.com:vcampitelli/workshop-kubernetes.git
Entre na pasta scripts
e inicialize o
cluster com:
$ minikube start
Seguindo a documentação em istio.io:
$ curl -L https://istio.io/downloadIstio | sh -
$ cd istio-1.14.1
$ export PATH=$PWD/bin:$PATH
Isso irá adicionar a pasta istio-1.14.1/bin
em seu $PATH
temporariamente.
Para fazer de forma permanente, você pode colocar o último comando
(export ...
) em algum arquivo de seu sistema que seja sempre carregado,
como /etc/profile
, ~/.bashrc
, ~/.zshrc
, entre
outros.
Instalando com o perfil demo
(saiba mais sobre os outros
perfis na documentação)
$ istioctl install --set profile=demo -y
Adicionando a label istio-injection=enabled
no namespace
default, indicando que queremos injetá-lo automaticamente em nossas aplicações
$ minikube kubectl -- label namespace default istio-injection=enabled
O minikube cria um serviço separado do Docker, então sempre que iniciarmos um terminal e quisermos interagir diretamente com ele, devemos especificar que queremos executar os comandos nesse novo ambiente:
$ eval $(minikube -p minikube docker-env)
Execute os comandos abaixo para fazer o build das imagens do Docker:
$ docker build -t auth:latest auth
$ docker build -t comments:latest comments
$ docker build -t posts:latest posts
$ docker build -t users:latest users
Agora, vamos começar a subir a nossa aplicação:
$ minikube kubectl -- apply -f k8s/jwt_keys.yml
$ minikube kubectl -- apply -f k8s/auth.yml
$ minikube kubectl -- apply -f k8s/comments.yml
$ minikube kubectl -- apply -f k8s/posts.yml
$ minikube kubectl -- apply -f k8s/users.yml
Para acompanhar tudo que foi configurado:
$ minikube kubectl -- get pods
$ minikube kubectl -- get deployments
$ minikube kubectl -- get services
Como não há um serviço de Load Balancing no minikube
, devemos expor os
IPs dos serviços para eles serem acessados localmente
Execute o comando abaixo em um novo terminal e mantenha-o rodando:
$ minikube tunnel --cleanup
Volte ao terminal anterior e execute o comando a seguir até que os 4
EXTERNAL-IP
s estejam alocados:
$ minikube kubectl -- get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
auth-service LoadBalancer 10.106.141.164 <pending> 3000:32110/TCP 1h
comments-service LoadBalancer 10.107.141.217 <pending> 3000:31457/TCP 1h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
posts-service LoadBalancer 10.106.220.106 <pending> 3000:32532/TCP 1h
users-service LoadBalancer 10.102.133.17 <pending> 3000:30921/TCP 1h
Volte ao terminal anterior e execute o comando a seguir até que os 4
EXTERNAL-IP
s estejam alocados:
$ minikube kubectl -- get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
auth-service LoadBalancer 10.106.141.164 10.106.141.164 3000:32110/TCP 1h
comments-service LoadBalancer 10.107.141.217 10.107.141.217 3000:31457/TCP 1h
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1h
posts-service LoadBalancer 10.106.220.106 10.106.220.106 3000:32532/TCP 1h
users-service LoadBalancer 10.102.133.17 10.102.133.17 3000:30921/TCP 1h
Para facilitar, vamos guardar os 4 IPs com as portas em variáveis:
$ IP_AUTH=10.106.141.164:3000
$ IP_COMMENTS=10.107.141.217:3000
$ IP_POSTS=10.106.220.106:3000
$ IP_USERS=10.102.133.17:3000
Para iniciar, vamos nos autenticar em nossa aplicação, executando o comando abaixo:
$ curl -X POST \
-u "admin:admin" \
"http://${IP_AUTH}/auth"
Resultado:
{
"status": true,
"access_token": "eyJhbGciOiJFUzI1NiJ9.eyJzY29wZXMiOlsidXNlcnMiLCJwb3N0cyIsImNvbW..."
}
Salve o access_token
em uma variável para facilitar as próximas chamadas:
$ TOKEN="eyJhbGciOiJFUzI1NiJ9.eyJzY29wZXMiOlsidXNlcnMiLCJwb3N0cyIsImNvbW..."
Teste os outros serviços:
$ curl -H "Authorization: Bearer ${TOKEN}" "http://${IP_COMMENTS}/comments"
$ curl -H "Authorization: Bearer ${TOKEN}" "http://${IP_POSTS}/posts"
$ curl -H "Authorization: Bearer ${TOKEN}" "http://${IP_USERS}/users"
Vamos criar um API Gateway que irá fazer o roteamento dos nossos microsserviços:
$ minikube kubectl -- apply -f k8s/istio/gateway.yml
Descubra o IP do API Gateway:
$ minikube kubectl -- -n istio-system get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-egressgateway ClusterIP 10.107.106.220 <none> 80/TCP,443/TCP 1h
istio-ingressgateway LoadBalancer 10.101.22.8 10.101.22.8 15021:32023/TCP, ... 1h
istiod ClusterIP 10.111.73.255 <none> 15010/TCP, ... 1h
E mais uma vez, vamos salvar em uma variável para facilitar o uso:
$ IP_GATEWAY=10.101.22.8
Vamos testar o roteamento:
$ curl -H "Authorization: Bearer ${TOKEN}" "http://${IP_GATEWAY}/comments"
$ curl -H "Authorization: Bearer ${TOKEN}" "http://${IP_GATEWAY}/posts"
$ curl -H "Authorization: Bearer ${TOKEN}" "http://${IP_GATEWAY}/users"
Ative o plugin de Metrics para coletar dados do uso de recursos:
$ minikube addons enable metrics-server
Abra um novo terminal e aplique a regra de Autoscaling:
$ minikube kubectl -- apply -f k8s/hpa.yml
kubernetes.io/docs/tasks
Abra um novo terminal e execute o comando abaixo para acompanhar o status:
$ watch -n 1 "minikube kubectl -- get hpa"
Também é possível rodar este comando para visualizar o histórico de ações:
$ minikube kubectl -- describe hpa posts
Baixe o wrk para realizar requisições simultâneas e execute:
$ wrk -t8 -c400 -d30s \
-H "Authorization: Bearer ${TOKEN}" \
"http://${IP_POSTS}/posts"
PS: esse comando irá abrir 400 conexões distribuídas em 8 threads durante 30 segundos.
Ajuste esses números para atender às especificações de sua máquina.
Instalando o Kiali (dashboard), Prometheus (métricas), Grafana (monitoramento) e Jaeger (tracing distribuído):
$ minikube kubectl -- apply -f <caminho-para-o-istio>/samples/addons
serviceaccount/grafana configured
configmap/grafana configured
service/grafana configured
deployment.apps/grafana configured
...
Para abrir o Kiali no navegador, execute o comando abaixo e acesse o endereço informado:
$ istioctl dashboard kiali
http://localhost:20001/kiali
Aplique a regra abaixo:
$ minikube kubectl -- apply -f k8s/istio/gateway-delay.yml
E busque novamente os comentários, passando pelo API Gateway:
$ curl -H "Authorization: Bearer ${TOKEN}" "http://${IP_GATEWAY}/comments"
Fault Injection: Delay