Nesta página, descrevemos os serviços do Kubernetes e como eles são usados no Google Kubernetes Engine (GKE). Há diferentes tipos de serviços, que podem ser usados para agrupar um conjunto de endpoints de pod em um único recurso. Para aprender a criar um serviço, consulte Como exibir aplicativos usando serviços.
O que é um serviço do Kubernetes?
Um Service agrupa um conjunto de endpoints de pod em um único recurso. É possível configurar várias maneiras de acessar o agrupamento. Por padrão, você recebe um endereço IP de cluster estável que os clientes dentro do cluster podem usar para contatar pods no serviço. Um cliente envia uma solicitação ao endereço IP estável e a solicitação é encaminhada a um dos pods no serviço.
Um serviço identifica seus pods membro com um seletor. Para que um pod seja membro do serviço, ele precisa ter todos os rótulos especificados no seletor. Um rótulo é um par de chave-valor arbitrário anexado a um objeto.
O manifesto de serviço a seguir tem um seletor que especifica dois rótulos. O campo selector
diz que qualquer pod que tenha o rótulo app: metrics
e o rótulo department:engineering
é membro deste serviço.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: metrics
department: engineering
ports:
...
Por que usar um serviço do Kubernetes?
Em um cluster do Kubernetes, cada pod tem um endereço IP interno. Mas, em uma implantação, os pods vêm e vão, e seus endereços IP mudam. Portanto, não faz sentido usar os endereços IP do pod diretamente. Com um serviço, você recebe um endereço IP estável válido durante a vida útil do serviço, mesmo quando os endereços IP dos pods membro são alterados.
Um serviço também fornece balanceamento de carga. Os clientes chamam um endereço IP único e estável, e suas solicitações são balanceadas nos pods que são membros do serviço.
Tipos de serviços do Kubernetes
Há cinco tipos de Services:
ClusterIP (padrão): os clientes internos enviam solicitações para um endereço IP interno estável.
NodePort: os clientes enviam solicitações para o endereço IP de um nó em um ou mais valores
nodePort
especificados pelo serviço.LoadBalancer: os clientes enviam solicitações para o endereço IP de um balanceador de carga de rede.
ExternalName: os clientes internos usam o nome DNS de um serviço como um alias para um nome DNS externo.
Sem comando: use um serviço sem comando quando quiser um agrupamento de pods, mas não precisar de um endereço IP estável.
O tipo NodePort
é uma extensão do tipo ClusterIP
. Portanto, um serviço do tipo NodePort
tem um endereço IP de cluster.
O tipo LoadBalancer
é uma extensão do tipo NodePort
. Portanto, um Service do tipo LoadBalancer
tem um endereço IP de cluster e um ou mais valores nodePort
.
Serviços do tipo ClusterIP
Quando você cria um Serviço do tipo ClusterIP
, o Kubernetes cria um endereço IP estável que pode ser acessado pelos nós no cluster.
Veja aqui um manifesto de um serviço do tipo ClusterIP:
apiVersion: v1
kind: Service
metadata:
name: my-cip-service
spec:
selector:
app: metrics
department: sales
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 8080
É possível criar o serviço usando kubectl apply -f [MANIFEST_FILE]
. Depois de criar o Serviço, use kubectl get service
para ver o endereço IP estável:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
my-cip-service ClusterIP 10.11.247.213 none 80/TCP
Os clientes no cluster chamam o Serviço usando o endereço IP do cluster e a porta TCP especificada no campo port
do manifesto Serviço. A solicitação é encaminhada para um dos pods de membro na porta TCP especificada no campo targetPort
. No exemplo anterior, um cliente chama o serviço em
10.11.247.213
na porta TCP 80. A solicitação é encaminhada a um dos pods membro na porta TCP 8080. Cada pod de membro precisa ter um contêiner detectando a porta
TCP 8080. Se nenhum contêiner estiver escutando a porta 8080, os clientes verão uma mensagem como "Falha ao conectar" ou "Este site não pode ser acessado".
Serviço do tipo NodePort
Quando você cria um serviço do tipo NodePort
, o Kubernetes fornece um valor nodePort
. Em seguida, o Serviço pode ser acessado usando o endereço IP de qualquer nó junto com o valor nodePort
.
Aqui está um manifesto para um Serviço do tipo NodePort
:
apiVersion: v1
kind: Service
metadata:
name: my-np-service
spec:
selector:
app: products
department: sales
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 8080
Depois de criar o Serviço, use kubectl get service -o yaml
para visualizar sua especificação e ver o valor nodePort
.
spec:
clusterIP: 10.11.254.114
externalTrafficPolicy: Cluster
ports:
- nodePort: 32675
port: 80
protocol: TCP
targetPort: 8080
Clientes externos chamam o Serviço usando o endereço IP externo de um nó junto com a porta TCP especificada por nodePort
. A solicitação é encaminhada para um dos pods de membro na porta TCP especificada pelo campo targetPort
.
Por exemplo, suponha que o endereço IP externo de um dos nós do cluster seja
203.0.113.2
. Em seguida, no exemplo anterior, o cliente externo chama o serviço em 203.0.113.2
na porta TCP 32675. A solicitação é encaminhada a um dos pods membro na porta TCP 8080. O pod membro precisa ter um contêiner escutando a porta TCP 8080.
O tipo de serviço NodePort
é uma extensão do tipo de serviço ClusterIP
. Portanto, os clientes internos têm duas maneiras de chamar o serviço:
- Use
clusterIP
eport
. - Use o endereço IP de um nó e
nodePort
.
Em algumas configurações de cluster, o balanceador de carga de aplicativo externo usa um Serviço do tipo NodePort
.
Um balanceador de carga de aplicativo externo é um servidor proxy e difere fundamentalmente do balanceador de carga de rede de passagem externa descrito neste tópico em Serviço do tipo LoadBalancer.
Serviços do tipo LoadBalancer
Para saber mais sobre os serviços do tipo LoadBalancer, consulte Conceitos do serviço do LoadBalancer.
Serviço do tipo ExternalName
Um serviço do tipo ExternalName
fornece um alias interno para um nome DNS externo. Clientes internos fazem solicitações usando o nome DNS interno e as solicitações são redirecionadas para o nome externo.
Aqui está um manifesto para um Serviço do tipo ExternalName
:
apiVersion: v1
kind: Service
metadata:
name: my-xn-service
spec:
type: ExternalName
externalName: example.com
Quando você cria um serviço, o Kubernetes cria um nome DNS que os clientes internos podem usar para chamar o serviço. No exemplo anterior, o nome DNS é my-xn-service.default.svc.cluster.local. Quando um cliente interno faz uma solicitação para esse DNS, ela é redirecionada para example.com.
O tipo de serviço ExternalName
é fundamentalmente diferente dos outros tipos de serviço. Na verdade, um Serviço do tipo ExternalName
não se ajusta à definição de Serviço fornecida no início deste tópico. Um serviço do tipo ExternalName
não está associado a um conjunto de pods e não tem um endereço IP estável. Em vez disso, um serviço do tipo ExternalName
é um mapeamento de um nome DNS interno para um nome DNS externo.
Serviço sem comando?
Um serviço sem comando é um tipo de serviço do Kubernetes que não aloca um endereço IP de cluster. Em vez disso, um serviço sem comando usa DNS para expor os endereços IP dos pods associados ao serviço. Isso permite que você se conecte diretamente aos pods em vez de usar um proxy.
Os serviços headless são úteis para uma variedade de cenários, incluindo:
Balanceamento de carga em pods: é possível usar serviços sem comando para balancear a carga em pods. Para implementar isso, crie um serviço com um seletor que corresponda aos pods para balancear a carga. O serviço distribuirá o tráfego de maneira uniforme em todos os pods que correspondem ao seletor.
Descoberta de serviços: é possível usar um serviço sem comando para implementar a descoberta de serviços. Para implementar isso, crie um serviço com um nome e um seletor. O registro DNS do serviço sem comando contém todos os IPs dos pods por trás do serviço que correspondem ao seletor. Os clientes podem usar esses registros DNS para encontrar os endereços IP dos pods associados ao serviço.
Acesso direto ao pod: os clientes podem se conectar diretamente aos pods associados a um serviço headless, o que pode ser útil para serviços que exigem acesso direto aos pods subjacentes, como balanceadores de carga e servidores DNS.
Flexibilidade: é possível usar serviços sem comando para criar várias topologias diferentes, como balanceadores de carga, servidores DNS e bancos de dados distribuídos.
Se você tiver requisitos de rede especiais para as cargas de trabalho que não podem ser resolvidos com serviços headless com seletores, também é possível usar serviços headless sem seletores. Os serviços headless são uma ferramenta útil para acessar serviços que não estão localizados no próprio cluster do Kubernetes. Como o plano de controle não cria objetos EndpointSlice, você pode ler mais sobre isso em Serviço sem seletores
O exemplo a seguir é um manifesto de um serviço sem comando:
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
clusterIP: None
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
Depois de criar um serviço sem comando, você pode consultar o DNS para encontrar os endereços IP dos pods associados ao serviço. Por exemplo, o comando a seguir lista os endereços IP dos pods associados ao serviço nginx:
dig +short nginx.default.svc.cluster.local
Outro exemplo que usa a expansão de consulta do Kubernetes:
dig +short +search nginx
É possível criar um serviço sem comando com um único comando, que é fácil de atualizar e escalonar.
kubectl create service clusterip my-svc --clusterip="None" --dry-run=client -o yaml > [file.yaml]
Abstração de serviço
Um Serviço é uma abstração no sentido de que não é um processo que escuta em alguma interface de rede. Parte da abstração é implementada nas regras do iptables dos nós do cluster. Dependendo do tipo do Serviço, outras partes da abstração são implementadas por um balanceador de carga de rede de passagem externa ou por um balanceador de carga de aplicativo externo.
Portas de serviço arbitrário
O valor do campo port
em um manifesto Serviço é arbitrário. No entanto, o valor de targetPort
não é arbitrário. Cada pod de membro precisa ter um contêiner de escuta em targetPort
.
Este é um serviço do tipo LoadBalancer
, que tem um valor de port
de 50000:
apiVersion: v1
kind: Service
metadata:
name: my-ap-service
spec:
clusterIP: 10.11.241.93
externalTrafficPolicy: Cluster
ports:
- nodePort: 30641
port: 50000
protocol: TCP
targetPort: 8080
selector:
app: parts
department: engineering
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 203.0.113.200
Um cliente chama o Serviço em 203.0.113.200
na porta TCP 50000. A solicitação é encaminhada a um dos pods membro na porta TCP 8080.
Várias portas
O campo ports
de um Serviço é uma matriz de objetos ServicePort. O objeto ServicePort tem estes campos:
name
protocol
port
targetPort
nodePort
Se você tiver mais de um ServicePort, cada um precisará ter um nome exclusivo.
Este é um Serviço do tipo LoadBalancer
, que tem dois objetos ServicePort
:
apiVersion: v1
kind: Service
metadata:
name: my-tp-service
spec:
clusterIP: 10.11.242.196
externalTrafficPolicy: Cluster
ports:
- name: my-first-service-port
nodePort: 31233
port: 60000
protocol: TCP
targetPort: 50000
- name: my-second-service-port
nodePort: 31081
port: 60001
protocol: TCP
targetPort: 8080
selector:
app: tests
department: engineering
sessionAffinity: None
type: LoadBalancer
status:
loadBalancer:
ingress:
- ip: 203.0.113.201
No exemplo anterior, se um cliente chamar o Serviço em 203.0.113.201
na porta
TCP 60000, a solicitação será encaminhada a um pod membro na porta TCP 50000. Mas se um cliente chamar o serviço em 203.0.113.201
na porta TCP 60001, a solicitação será encaminhada a um pod membro na porta TCP 8080.
Cada pod membro precisa ter um contêiner escutando a porta TCP 50000 e um contêiner escutando a porta TCP 8080. É possível ter um contêiner único com duas threads ou dois contêineres em execução no mesmo pod.
Endpoints de Serviço
Quando você cria um serviço, o Kubernetes cria um objeto Endpoints que tem o mesmo nome do seu serviço. O Kubernetes usa o objeto Endpoints para rastrear quais pods são membros do serviço.
Serviços de pilha única e dupla
É possível criar um serviço IPv6 do tipo ClusterIP
ou NodePort
.
O GKE é compatível com serviços de pilha dupla do tipo
LoadBalancer
durante a Visualização, que
não tem SLA ou suporte técnico.
Para cada um desses tipos de serviço, é possível definir os campos ipFamilies
e
ipFamilyPolicy
como IPv4, IPv6 ou como um serviço e
pilha dupla.
A seguir
- Saiba mais sobre os Serviços do Kubernetes.
- Exponha aplicativos usando serviços
- Saiba mais sobre StatefulSets
- Saiba mais sobre o Ingress