Manipulação do componente Service do Kubernetes
- 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:80Esse 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-podConfira 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 DownloadsCertifique-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=defaultCaso 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:30008O 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-podReinicie 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 allAinda 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 allTemos somente agora o nosso serviço principal do K8s:

Esperamos que tenham gostado!
Até mais e obrigado!


Comentários