top of page

Manipulação do componente Service do Kubernetes

  • Foto do escritor: Rodrigo Saito
    Rodrigo Saito
  • há 5 horas
  • 7 min de leitura

Fala pessoal. Tudo bem?


Sabe para que serve o Service do K8s?


Service é um tipo de recurso como os outros do K8s. Ele é um recurso que expõe o nosso aplicativo para fora do cluster.


As nossas aplicações podem ser acessadas fora do cluster. Isso pode ser feito com diferentes tipos de serviços.


O tráfego externo (que vem da internet) precisa de permissão para chegar ao servidor dentro do cluster.


K8s oferece um serviço de DNS exposto ao PODs que executa ao cluster, ou seja, o serviço de DNS que tem dentro do K8s que possibilita a comunicação com os nossos pods. Este serviço de DNS é responsável por resolver todos os nomes (o caminho para que se chegue até os PODs onde se encontra as aplicações executadas dentro de containers)


O serviço de DNS é instalado como um componente de sistema quando o cluster é criado. (vimos anteriormente que temos um serviço de DNS funcionando dentro do k8s)


Usando o namespace que já vimos, basta usar um nome de serviço para se conectar com um POD identificado por um serviço. O K8s vai utilizar o namespace para encontrar o serviço e o serviço vai encontrar os nossos PODs onde estão as nossas aplicações.


O DNS do cluster nada mais é do que um servidor DSNS real. Ele faz parte de toda a infraestrutra d rede virtualizada que temos dentro de um clustrer kubernetes.


Disponibilização dos serviços


Os serviços podem ser consumidos basicamente de 2 formas:

  • Pelo próprio cluster (as aplicações do próprio cluster consomem este recurso)

  • Por fora do meu cluster, através da internet (chegando até as aplicações através desses serviços)



ClusterIP


O ClusterIP Default Service é o serviço padrão do Kubernetes


O ClusterIp torna o serviço acessível apenas dentro do cluster, sendo sendo possível alcançar este serviço de fora do cluster




O clusterIP não pode ser acessado diretamente. Somente de fora para dentro tem que ser através acesso a um proxy.


As portas (port) é um dos atributos mais importantes a serem definidos. É um atributo obrigatório, a qual o serviço é disponibilizado.


Outro atributo é o TargetPort, é onde a aplicação foi disponibilizada dentro do container. (É um atributo opcional. Caso seja omitido, é assumido o mesmo valor que Port)


Pods não tem IP´s staticos. Quando são reiniciados ou criados ou recriados, podem ter novos IP´s. É onde que entrarm os serviços. O cliente da aplicação acessam os serviços e não se preocupa mais com os endereços IPs dos Pods, o qual o Kube-DNS se encarrega de resolver o caminho até os Pods. Os serviços é que vão resolver todo o novo endereçamento IP que um Pod tem na hora que ele é recriado, deletado, reiniciado. O Kube-DNS faz todo esse serviço para que voce não se preocupe com toda a complexidade.


Podemos ter multiplos containers dentro de um POD, porém utilizando portas diferentes. Essas portas são chamadas de target-port.





Criação do ClusterIP Service


Vamos criar um novo arquivo chamado my-clusterIP-service.yaml em Downloads, e mais 2 terminais:


O conteúdo do arquivo é:


apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  labels:
    type: web-app
spec:
  containers:
    - name: web-server-apache
      image: httpd
      ports:
        - containerPort: 80
    - name: web-server-tomcat
      image: tomcat
      ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-service
spec:
  type: ClusterIP
  selector:
    type: web-app
  ports:
    - name: http
      port: 80
      targetPort: 80

Aqui temos 2 serviços definidos utilizando o mesmo arquivo. Não costuma ser uma boa prática, mas é possível fazer dessa maneira separandos os serviços por ---


Teremos a seguinte arquitetura:



O fato de simplesmente mudarmos as portas dos serviços no arquivo, não quer dizer que o serviço irá responder por ela. (Necessário entrar no container e alterar as configurações dos serviços)


Veja se o minikube está iniciado no terminal 1:

minikube start
minikube status

Veja se tem algum serviço ativo:

kubectl get services

Temos 1 serviço apenas criado pelo próprio k8s.


Entre dentro da pasta Downloads (ou na pasta em que voce salvou) para acessar o arquivo criado my-clusterIP-service.yaml.


Aplique o arquivo criado

kubectl apply -f my-clusterIP-service.yaml

Vamos verificar quais são os serviços, de modo abreviado:


kubectl get svc

Veja todos os objetos com o comando:

kubectl get all

Abra um novo terminal, para criarmos de modo interativo uma nova Pod, com um servidor debian:

kubectl run -it debian-pod --image=debian bash

Dentro do Debian, atualize o seu repositorio do sistema, com o comando:

apt-get update

Instale o curl:

apt-get install curl -y

Vamos fazer um teste de resposta entre os containers:


curl 10.107.33.57:80

Esse endereço IP é a do que está no terminal 1, no CLUSTER-IP. e a porta 80 é a que foi definido no arquivo, na parte do arquivo frontend-service port 80


A resposta de ser algo como:



Tivemos como retorno a saída do servidor apache,


Detalhes do ClusterIP e deleção de recursos em massa:


Após ter criado os servicos anteriores, veja quais são os serviços que estão sendo executados em seu minikube:

kubeclt get services


Par aobter mais informações e detalhamentos sobre os serviços, digite:

kubectl get services --all-namespaces -o wide

Vamos pegar mais detalhes sobre o frontend-service:

kubectl describe services frontend-service

Podemos obter o mesmo resultado de um get services com o comando:


Lembrando que podemos ter mais de um nome de serviço em diferentes namespaces

kubectl get services frontend-service --namespace=default

Execute o comando abaixo para especificar o namespace

kubectl get services frontend-service --namespace=default -o wide

Veja todos os recursos criados:


kubectl get all

Vamos fazer uma limpeza nos serviços que existem:


kubectl delete services frontend-service --namespace=default

Verifique novamente os componentes. Quando fazemos um delete nos services, ele não deleta os pods.


kubectl get all

Vamos deletar o Pod existente:

kubectl delete pods web-pod

Caso tivesse mais pods, poderíamos executar colocando um Pod subsequente ao outro como exemplo:

kubectl delete pods web-pod debian-pod

Confira novamente os componentes:

kubectl get all

Vamos fazer uma deleção que funcionaria para excluir todos os serviços existentes:

kubectl delete all --all

O primeiro all significa todos os recursos comuns (replicaset, services, pods, deployments, etc)


O segundo all significa todos os recursos nomeados (voce não está identificando o que voce quer, e está executando em tudo)


CUIDADO com esse comando em produção!


Verifique novamente os serviços:

kubectl get all

Isso é normal, pois o Control Pane irá recriar o service/kubernetes automaticamente.


Ao invés de utilizar para fazer o comando com toda a deleção, podemos especificar o namepace, que é mais seguro:

kubectl delete all --all --namespace=default

Outro tipo de deleção pode ser feito com o comando:

kubectl get all --all-namespaces

Podemos observar que esses componentes não são o que criamos, e sim o que o K8s controla.


Execute o comando:

kubectl delete --all -all --all-namespaces

Veja novamente e o Control Pane irá fazer a recrição novamente.



NodePort Service


É um serviço muito interessante do K8s, além de essencial. Com ele, vamos fazer a abertura de uma porta em nosso Node para que seja feito um acesso externo para dentro da nossa aplicação.


Temos o seguinte esquema:



A porta 30008 é o nosso nodePort, que irá fazer a abertura do node para o mundo externo

A porta 80 que é o nosso serviço, que é para a comunicação com o Pod.

O targetPort 80, que é o porta do Apache web.




Detalhes de Portas NodePort Service: Mandatory, Optional, Omiottee, Random.


NodePort Services tem alguns atributos:

  • port --> é obrigatório

  • targetPort --> é opcional (podemos criar ele sem ter que defini-lo)

  • nodePort --> é opcional (podemos criar ele sem ter que defini-lo)


Caso targetPort seja omitido, vai assumir o valor de Pod

  • targetPort omitted = Port


Caso nodePort seja omitido, vai assumir um valor aleatório de um range (30000 a 32767)

  • nodePort omitted = random value (30000 a 32767)


Exemplo de um arquivo com as definições de porta:


apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  ports:
    - targetPort: 80
      port: 80
      nodePort: 32055
  selector:
    app: nginx

Criação do NodePort Service


Vamos utilizar essa ilustração para que possamos fazer a nossa criação do NodePort:


Vamos transformar um serviço ClusterIP e transformá-lo em um NodePode Service,


Abra o arquivo my-clusterIP-service.yaml e faça a seguintes modificações e salve como my-nodePort-service.yaml


apiVersion: v1
kind: Pod
metadata:
  name: web-pod
  labels:
    type: web-app
spec:
  containers:
    - name: web-server-apache
      image: httpd
      ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: frontend-service-nodeport
spec:
  type: NodePort
  selector:
    type: web-app
  ports:
    - name: http
      port: 80
      targetPort: 80
      nodePort: 30008

Consumo externo do NodePort Service


Vamos fazer a aplicação do arquivo que foi criado. Abra um terminal e entre na pasta Downloads:

cd Downloads

Certifique-se de que tenha somente o service/kubernetes ativo:

kubectl get all

Vamos aplicar o arquivo:


kubectl apply -f my-nodePort-service.yaml


Verifique se realmente foi criado:

kubectl get all

Veja somente os serviços:

kubectl get svc

Podemos ver mais detalhamento desse serviço:

kubectl describe service frontend-service-nodeport

Veja com atenção os campos:

  • Name (Nome do serviço)

  • Namespace (em que o serviço se encontra)

  • Selector (muito importante pois precisamos selecionar onde o serviço está utilizando)

  • Type (O tipo do serviço)

  • IP Fields (Informações gerais sobre os IPs)

  • Port Fields (informações sobre as portas)


Para acessarmos (export) o nosso serviço que criamos de fora para dentro, execute o comando:

minikube service --url frontend-service-nodeport 

ou

minikube service --url frontend-service-nodeport --namespace=default

Caso ele apresente o erro abaixo:



Apague o arquivo de log que foi corrompido:

rm ~/.minikube/logs/audit.json


Apague todos os arquivos de log:

rm -rf ~/.minikube/logs/*

Tente novamente expor o serviço:

minikube service --url frontend-service-nodeport 

Foi criado uma url para acessar o serviço:


Vamos primeiramente testar o retorno do serviço com o Curl:

curl http://192.168.49.2:30008

O retorno abaixo é esperado:


Vamos acessar via Browser, Na URL de um navegador digite:

http://192.168.49.2:30008


Pronto! Temos um serviço nodePort que está funcionando


Também é possivel verificar o numero IP utilizando o kubectl, com o comando abaixo:

kubectl get nodes -o yaml | grep address

Troubleshooting - Couldn´t connect to server


Caso tenha dado que o serviço não conecte ao servidor, precisamos crriar todo o serviço novamente:



Delete o serviços criados:

kubectl delete service frontend-service-nodeport && kubectl delete pod web-pod

Reinicie o serviço do minikube:

minikube stop && minikube start

Recrie o cluster minikube

minikube delete && minikube start

Vamos reiniciar com a aplicação do arquivo my-nodePort-service.yaml

kubectl apply -f my-nodePort-service.yaml
kubectl get all
kubectl get svc
kubectl describe service frontend-service-nodeport
minikube service --url frontend-service-nodeport
curl http://192.168.49.2:30008 

Caso não tenha dado nenhum problema, o retorno será:


Como remover NodePorts


Vamos fazer uma limpeza com o que criamos. Verifique quais são os objetos que existem para voce:

kubectl get all

Vamos fazer a deleção do nodeport:

kubectl delete service/frontend-service-nodeport

Vamos verificar novamente os serviços existentes:

kubectl get all

Ainda podemos observar que o serviço existe:



Vamos fazer a deleção do Pod:

kubectl delete pod/web-pod

Vamos verificar novamente os serviços existentes:

kubectl get all

Temos somente agora o nosso serviço principal do K8s:



Esperamos que tenham gostado!


Até mais e obrigado!



Comentários


Nunca perca um post. Assine agora!

Caso queira receber noticias sobre o blog, assine!

© 2022 por datalib

  • Ícone do Facebook Cinza
  • Ícone do Linkedin Cinza
bottom of page