Acompanhe os novos blogs no site www.byiorio.com.br
Projeto Java
Para migrar meu projeto SpringBoot do 2.7.6 para a versão 3.0.7 foi bem trabalhosa, mas consegui fazer functionar 100% no modo JAR e uns 60% no modo NATIVO. Nesse caso não irei colocar muitods detalhes e sim que isso é necessário para entrar no universo nativo.
Instalação de Visual Studio
Essa parte é bem simples e precisamos somente escolher o WorkLoad do C++ para instalação, iremos utilizar o "X64 native tools command" para compilar o projeto no formato .EXE do Windows.
Abrindo o Native Tools, podemos executar o comando abaixo e verificar se tudo compila normalmente
mvn -Pnative native:compile
Instalação e configuração do Kubernetes
Primeira parte é instalar o Docker Desktop e na parte de configuração (Ícone de Engrenagem), tenho um video demonstrando como instala a primeira parte , veja nesse link
Após a instalação precisaremos configurar a plataforma, e para começar vamos instalar o Dashboard, uma interface para acompanhar tudo que está acontecendo no kubernetes.
Todos os comandos do KUBECTL devem ser executados no powershell ou gitbash.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
Vamos acionar o proxy para poder acessar o dashboard nesse momento
kubectl proxy
Como resultado teremos um serviço na porta 8001
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
Uma vez instalado poderemos acessar o Dashboard através do link
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
Para poder acessar no modo TOKEN teremos que configurar todo o acesso , e para isso vamos criar dois arquivos:
create-cluster-role-binding.yaml com o conteúdo
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
create-service-cccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
Uma vez criado vamos executar os seguintes comando no mesmno diretório dos arquivos
kubectl apply -f create-service-cccount.yaml
kubectl apply -f create-cluster-role-binding.yaml
Uma vez criado vamos solicitar a geração do Token atravbés do seguinte comando
kubectl -n kubernetes-dashboard create token admin-user
Como resultado do comando teremos o TOKEN que você pode colar no console de login do Dashboard
$ kubectl -n kubernetes-dashboard create token admin-user
eyJhbGciOiJSUzI1NiIsImtpZCI6InlYenVpSnNEVUlGTWMzZHlBTFpLQjduLWxUbU9wZWRkNGw5QnNrUXd3Q1kifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjg5MTA4MTMyLCJpYXQiOjE2ODkxMDQ1MzIsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJhZG1pbi11c2VyIiwidWlkIjoiOWUzYjgwZDctNGNjOC00MGQ0LTk5ZmMtOTk0OTQxMzI5NGJkIn19LCJuYmYiOjE2ODkxMDQ1MzIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbi11c2VyIn0.J9mX4CcOV4_oFQboyz-qBfffSddusWrHqndVdYuYO-6oB_e_2QM8OeigAOOK9TRGnAGhcCSfWiMuKgHX4OfVSZTxJI0RXrUjKIGlwX4dbiHM3eeqlUkT7TqNCE-yUAIgD7ioUUKaWcmDtNgp7InA8Nv3Gon0DCwtraxvd4-FH3LJ8nqU86RW5nutjcuXOQ7B1T06VS0akC-4xwn5EsQbTlc9kIB5kkFdwTpj5NsrChhA8uTOxI3Nsiv0_iZnhM7VAIEGD4CkEHUMFtqlUlDrIRkI16bn3ji63LRkw_EVAKjXqqQf_luK_ZItVE1cSsmSITgbvLQF3sDprRBgU71BVg
Agora vamos executar um comando para escolher o namespace padrão para instalar o nosso projeto
kubectl config set-context --current --namespace=default
Próximo passo é instalar o módulo que vai controlar as entradas nos nossos serviços e eu escolhi usar o ingress-nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.0/deploy/static/provider/cloud/deploy.yaml
Vamos gerar a imagem com o JAR e outra com o NATIVO
Para gerar uma imagem com o seu protejto compilado na forma nativa, vamos executar o comando
mvn -Pnative spring-boot:build-image
Para gerar uma imagem no formato JAR, vou usar o seguinte arquivo Dockerfile
FROM openjdk:17-jdk-slim
EXPOSE 8080
COPY target/*.jar byiorio.jar
ENTRYPOINT ["java","-jar","/byiorio.jar"]
Vou executar o comando no mesmo diretório que está o arquivo Dockerfile.
docker build -t byiorio-normal:0.1.7 -f ./Dockerfile .
Com isso eu fiquei com duas imagens no meu Docker, imagem do nativo e outra imagem com o JAR
byiorio-api:0.1.7
byiorio-normal:0.1.7
Agora basta instalarmos no Kubernetes e para isso criei dois arquivos de instalação
byiorio-normal.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: byiorio-normal-deployment
labels:
app: byiorio-normal
spec:
replicas: 1
selector:
matchLabels:
app: byiorio-normal
template:
metadata:
labels:
app: byiorio-normal
spec:
containers:
- name: byiorio-normal
image: byiorio-normal:0.1.7
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "500m"
byiorio-native.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: byiorio-native-deployment
labels:
app: byiorio-native
spec:
replicas: 1
selector:
matchLabels:
app: byiorio-native
template:
metadata:
labels:
app: byiorio-native
spec:
containers:
- name: byiorio-native
image: byiorio-api:0.1.7
ports:
- containerPort: 8080
resources:
requests:
memory: "512Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "500m"
Agora vamos executar a instalação das imagens no Kubernetes
kubectl apply -f byiorio-native.yaml
kubectl apply -f byiorio-normal.yaml
Nesse momento conseguiremos ver os PODS instalados no kubernetes. Lembrando que estou aqui passando os comandos mínimos, caso queira ver com mais detalhes me mande uma mensagem.
Chegou o momento de criar o serviço, é ele que dará acesso ao nosso projeto e também fazer o balanceamento das requisições:
kubectl expose deployment byiorio-native-deployment --name=byiorio-nativo-service --type=NodePort --port=8080 --target-port=8080
kubectl expose deployment byiorio-normal-deployment --name=byiorio-normal-service --type=NodePort --port=8080 --target-port=8080
Vamos agora criar as entradas externas para as duas instalações, e para isso vamos executar os comandos abaixo:
kubectl create ingress byiorio-nativo-ingress --class=nginx --rule="byiorio-native/*=byiorio-nativo-service:8080"
kubectl create ingress byiorio-normal-ingress --class=nginx --rule="byiorio-normal/*=byiorio-normal-service:8080"
Com esses comandos eu precisei colocar alguns endereços no arquivo HOST do windows
127.0.0.1 byiorio-normal
127.0.0.1 byiorio-native
Configurando Escala Automática
Para funcionar a escala automática precisaremos instalar um plugin para verificar as métricas do processador, para isso iremos criar 3 arquivos.
metrics.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: system:aggregated-metrics-reader
rules:
- apiGroups:
- metrics.k8s.io
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
verbs:
- get
- apiGroups:
- ""
resources:
- pods
- nodes
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server-auth-reader
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: extension-apiserver-authentication-reader
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: metrics-server:system:auth-delegator
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
k8s-app: metrics-server
name: system:metrics-server
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:metrics-server
subjects:
- kind: ServiceAccount
name: metrics-server
namespace: kube-system
---
apiVersion: v1
kind: Service
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
k8s-app: metrics-server
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
k8s-app: metrics-server
name: metrics-server
namespace: kube-system
spec:
selector:
matchLabels:
k8s-app: metrics-server
strategy:
rollingUpdate:
maxUnavailable: 0
template:
metadata:
labels:
k8s-app: metrics-server
spec:
containers:
- args:
- --cert-dir=/tmp
- --secure-port=4443
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
- --kubelet-use-node-status-port
- --metric-resolution=15s
- --kubelet-insecure-tls
image: registry.k8s.io/metrics-server/metrics-server:v0.6.3
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /livez
port: https
scheme: HTTPS
periodSeconds: 10
name: metrics-server
ports:
- containerPort: 4443
name: https
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /readyz
port: https
scheme: HTTPS
initialDelaySeconds: 20
periodSeconds: 10
resources:
requests:
cpu: 100m
memory: 200Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
volumeMounts:
- mountPath: /tmp
name: tmp-dir
nodeSelector:
kubernetes.io/os: linux
priorityClassName: system-cluster-critical
serviceAccountName: metrics-server
volumes:
- emptyDir: {}
name: tmp-dir
---
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
labels:
k8s-app: metrics-server
name: v1beta1.metrics.k8s.io
spec:
group: metrics.k8s.io
groupPriorityMinimum: 100
insecureSkipTLSVerify: true
service:
name: metrics-server
namespace: kube-system
version: v1beta1
versionPriority: 100
metrics-service.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: metrics-server
namespace: kube-system
labels:
k8s-app: metrics-server
spec:
selector:
matchLabels:
k8s-app: metrics-server
template:
metadata:
name: metrics-server
labels:
k8s-app: metrics-server
spec:
serviceAccountName: metrics-server
volumes:
# mount in tmp so we can safely use from-scratch images and/or read-only containers
- name: tmp-dir
emptyDir: {}
containers:
- command:
- /metrics-server
- --metric-resolution=30s
- --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP
name: metrics-server
image: k8s.gcr.io/metrics-server-amd64:v0.3.1
imagePullPolicy: Always
volumeMounts:
- name: tmp-dir
mountPath: /tmp
metrics-svc.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: metrics-server
namespace: kube-system
Agora vamos executar os 3 arquivos
kubectl apply -f metrics.yaml
kubectl apply -f metrics-service.yaml
kubectl apply -f metrics-svc.yaml
Estamos chegando ao fim de nossa configuração , agora vamos criar a escala automática para cada projeto, para subir automaticamente os PODS quando forem chamados:
kubectl autoscale deployment byiorio-native-deployment --cpu-percent=50 --min=1 --max=3
kubectl autoscale deployment byiorio-normal-deployment --cpu-percent=50 --min=1 --max=3
kubernetes; java ; problema; nuvem; cloud; escala;