Este documento mostra como criar um objeto de Entrada do Kubernetes em um cluster de usuário, híbrido ou independente para o GKE em bare metal. Uma Entrada é associada a um ou mais Serviços, e cada um deles está associado a um conjunto de Pods.
Antes de começar
Consiga uma conexão SSH do cluster com a estação de trabalho de administrador.
Criar uma implantação
Veja o manifesto de uma implantação:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
selector:
matchLabels:
greeting: hello
replicas: 3
template:
metadata:
labels:
greeting: hello
spec:
containers:
- name: hello-world
image: "gcr.io/google-samples/hello-app:2.0"
env:
- name: "PORT"
value: "50000"
- name: hello-kubernetes
image: "gcr.io/google-samples/node-hello:1.0"
env:
- name: "PORT"
value: "8080"
Para este exercício, é importante entender os pontos a seguir sobre o manifesto de implantação:
Cada pod que pertence à implantação tem o rótulo
greeting: hello
.Cada pod tem dois contêineres.
Os campos
env
especificam que os contêinereshello-app
detectam atividade na porta TCP 50000 e os contêineresnode-hello
detectam atividade na porta TCP 8080. Parahello-app
, é possível ver o efeito da variável de ambientePORT
observando o código-fonte.
Copie o manifesto em um arquivo denominado hello-deployment.yaml
e crie a implantação:
kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f hello-deployment.yaml
Substitua CLUSTER_KUBECONFIG
pelo nome do
arquivo kubeconfig do cluster.
Expor a implantação com um Serviço
Se quiser oferecer uma forma estável para os clientes enviarem solicitações aos pods da implantação, crie um Serviço.
Veja aqui um manifesto para um Serviço que expõe a implantação a clientes dentro do cluster:
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
type: ClusterIP
selector:
greeting: hello
ports:
- name: world-port
protocol: TCP
port: 60000
targetPort: 50000
- name: kubernetes-port
protocol: TCP
port: 60001
targetPort: 8080
Copie o manifesto para um arquivo chamado hello-service.yaml
e crie o Service:
kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f hello-service.yaml
Substitua CLUSTER_KUBECONFIG
pelo nome do
arquivo kubeconfig do cluster.
Veja o Serviço:
kubectl --kubeconfig CLUSTER_KUBECONFIG get service hello-service --output yaml
A saída mostra o valor de clusterIP
que foi fornecido ao serviço.
Exemplo:
apiVersion: v1
kind: Service
metadata:
annotations:
...
spec:
clusterIP: 10.96.14.249
clusterIPs:
- 10.96.14.249
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: world-port
port: 60000
protocol: TCP
targetPort: 50000
- name: kubernetes-port
port: 60001
protocol: TCP
targetPort: 8080
selector:
greeting: hello
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
Na saída anterior, o campo ports
é uma matriz de objetos ServicePort
:
um chamado world-port
e outro chamado kubernetes-port
. Para mais informações
sobre os campos de serviço, consulte
ServiceSpec
na documentação do Kubernetes.
Veja como um cliente pode chamar o Serviço:
Usando
world-port
: um cliente que executa um dos nós do cluster envia uma solicitação paraclusterIP
emport
. Neste exemplo, 10.96.14.249:60000. A solicitação é encaminhada a um pod membro emtargetPort
. Neste exemplo,POD_IP_ADDRESS:50000
.Usando
kubernetes-port
: um cliente que executa um dos nós do cluster envia uma solicitação paraclusterIP
emport
. Neste exemplo, 10.96.14.249:60001. A solicitação é encaminhada a um pod membro emtargetPort
. Neste exemplo,POD_IP_ADDRESS:8080
.
Componentes da Entrada
Estes são alguns dos componentes do cluster relacionados à Entrada:
A implantação
istio-ingress
. Esse é o proxy de entrada. O proxy de entrada encaminha o tráfego para os Serviços internos de acordo com as regras especificadas em um objeto de Entrada.O serviço
istio-ingress
. Este serviço expõe a implantaçãoistio-ingress
.A implantação
istiod
. Este é o controlador de Entrada. O controlador de Entrada observa a criação de objetos de Entrada e configura o proxy de Entrada de acordo.
Todos esses componentes do Istio no cluster estão instalados no namespace
gke-system
. Esse namespace não entra em conflito com uma instalação completa
do Istio/Anthos Service Mesh.
Criar uma Entrada
Veja aqui um manifesto de uma Entrada:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
rules:
- http:
paths:
- path: /greet-the-world
pathType: Exact
backend:
service:
name: hello-service
port:
number: 60000
- path: /greet-kubernetes
pathType: Exact
backend:
service:
name: hello-service
port:
number: 60001
Copie o manifesto em um arquivo chamado my-ingress.yaml
e crie a
Entrada:
kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f my-ingress.yaml
Ao criar um cluster de usuário, especifique um valor para
loadbalancer.ingressVIP
no arquivo de configuração do cluster. Esse endereço IP é
configurado no balanceador de carga do cluster. Quando você cria uma Entrada, ela
recebe esse mesmo VIP como o endereço IP externo dela.
Quando um cliente envia uma solicitação ao VIP de Entrada do cluster de usuário, a solicitação é
roteada para o balanceador de carga. O balanceador de carga usa o Serviço istio-ingress
para encaminhar a solicitação ao proxy de Entrada, que é executada no cluster de usuário. O
Serviço de entrada está configurado para encaminhar a solicitação a back-ends diferentes, dependendo
do caminho no URL da solicitação.
Caminho /greet-the-world
No manifesto de Entrada, há uma regra que diz que o caminho
/greet-the-world
está associado a serviceName: hello-service
e
servicePort: 60000
. Lembre-se de que 60000 é o valor da port
na seção world-port
do Serviço hello-service
.
- name: world-port
port: 60000
protocol: TCP
targetPort: 50000
O Serviço de Entrada encaminha a solicitação para clusterIP
:50.000. Em seguida,
a solicitação vai para um dos pods membros do serviço hello-service
. O contêiner,
nesse pod, que detecta a porta 50000 exibe uma mensagem Hello World!
.
Caminho /greet-kubernetes
No manifesto de Entrada, há uma regra que diz que o caminho
/greet-kubernetes
está associado a serviceName: hello-service
e
servicePort: 60001
. Lembre-se de que 60001 é o valor da port
na
seção kubernetes-port
do Serviço hello-service
.
- name: kubernetes-port
port: 60001
protocol: TCP
targetPort: 8080
O Serviço de Entrada encaminha a solicitação para clusterIP
: 8080. Em seguida,
a solicitação vai para um dos pods membros do serviço hello-service
. O contêiner,
nesse pod, que detecta a porta 8080 exibe uma mensagem Hello Kubernetes!
.
Testar a Entrada
Teste o Entrada usando o caminho /greet-the-world
:
curl CLUSTER_INGRESS_VIP/greet-the-world
Substitua CLUSTER_INGRESS_VIP
pelo endereço IP externo da
Entrada.
A saída mostra uma mensagem Hello, world!
:
Hello, world!
Version: 2.0.0
Hostname: ...
Teste o Entrada usando o caminho /greet-kubernetes
:
curl CLUSTER_INGRESS_VIP/greet-kubernetes
A saída mostra uma mensagem Hello, Kubernetes!
:
Hello Kubernetes!
Desativar a entrada em pacote
O recurso de entrada em pacote no GKE em bare metal é compatível apenas com a funcionalidade de entrada. É possível fazer a integração com o Istio ou o Anthos Service Mesh. Esses produtos oferecem outros benefícios de uma malha de serviço totalmente funcional, como TLS mútuo (mTLS), capacidade de gerenciar autenticação entre serviços e observabilidade da carga de trabalho. Se você fizer a integração ao Istio ou ao Anthos Service Mesh, recomendamos que desative o recurso de entrada no pacote.
É possível ativar ou desativar a Entrada agrupada com o
campo spec.clusterNetwork.bundledIngress
no arquivo de configuração do cluster.
Este campo está disponível apenas nos clusters da versão 1.13.0 e mais recentes. O campo bundledIngress
assume como padrão true
e não está presente no arquivo de configuração do cluster gerado. Esse campo é mutável e pode ser alterado quando você
cria ou atualiza um cluster da versão 1.13.0 ou mais recente. Também é possível especificar esse
campo ao fazer upgrade de um cluster para a versão 1.13.0 ou mais recente.
No arquivo de configuração de cluster de amostra a seguir, mostramos como configurar o cluster para desativar o recurso de entrada em pacote:
apiVersion: v1
kind: Namespace
metadata:
name: cluster-hybrid-basic
---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: hybrid-basic
namespace: cluster-hybrid-basic
spec:
type: hybrid
profile: default
anthosBareMetalVersion: 1.13.0
gkeConnect:
projectID: project-fleet
controlPlane:
nodePoolSpec:
nodes:
- address: 10.200.0.2
clusterNetwork:
bundledIngress: false
pods:
cidrBlocks:
- 192.168.0.0/16
services:
cidrBlocks:
- 10.96.0.0/20
...
Configurar HTTPS para a Entrada
Se você quiser aceitar solicitações HTTPS dos clientes, o proxy de Entrada precisará ter um certificado para provar a identidade dele aos clientes. Esse proxy também precisa ter uma chave privada para concluir o handshake HTTPS.
O exemplo a seguir usa essas entidades:
Proxy de entrada: participa do handshake HTTPS e, em seguida, encaminha os pacotes para os pods membros do serviço
hello-service
.Domínio do serviço
hello-service
: altostrat.com na organização de exemplo
Siga estas etapas:
Crie um certificado raiz e uma chave privada. Este exemplo usa uma autoridade certificadora raiz de
root.ca.example.com
na organização de exemplo da CA raiz.openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj \ '/O=Root CA Example Inc./CN=root.ca.example.com' -keyout root-ca.key \ -out root-ca.crt
Crie uma solicitação de assinatura de certificado:
openssl req -out server.csr -newkey rsa:2048 -nodes -keyout server.key -subj \ "/CN=altostrat.com/O=Example Org"
Crie um certificado de exibição para o proxy de entrada.
openssl x509 -req -days 365 -CA root-ca.crt -CAkey root-ca.key -set_serial 0 \ -in server.csr -out server.crt
Você criou estes seguintes certificados e chaves:
root-ca.crt
: certificado da CA raiz;root-ca.key
: chave privada da CA raiz;server.crt
: certificado de exibição do proxy de entrada;server.key
: chave privada do proxy de entrada;
Crie um secret do Kubernetes que contenha o certificado e a chave de exibição.
kubectl create secret tls example-server-creds --key=server.key --cert=server.crt \ --namespace gke-system
O secret resultante é denominado
example-server-creds
.
Criar uma implantação e um serviço
Se você criou uma implantação e um Serviço na parte HTTP deste guia, deixe-os no lugar. Se você não fez isso, crie-os agora seguindo as etapas descritas para HTTP.
Criar uma Entrada
Se você já tiver criado uma Entrada na parte HTTP, exclua-a antes de continuar.
Exclua a Entrada:
kubectl --kubeconfig CLUSTER_KUBECONFIG delete ingress my-ingress
Para lidar com o tráfego do serviço que você criou anteriormente, crie uma nova
Entrada que tenha uma seção tls
. Isso ativará o HTTPS entre os clientes e o
proxy de entrada.
Veja aqui um manifesto de uma Entrada:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress-2
spec:
tls:
- hosts:
- altostrat.com
secretName: example-server-creds
rules:
- host: altostrat.com
http:
paths:
- path: /greet-the-world
pathType: Exact
backend:
service:
name: hello-service
port:
number: 60000
- path: /greet-kubernetes
pathType: Exact
backend:
service:
name: hello-service
port:
number: 60001
Salve o manifesto em um arquivo chamado my-ingress-2.yaml
e crie a Entrada:
kubectl apply --kubeconfig CLUSTER_KUBECONFIG -f my-ingress-2.yaml
Confirme por teste.
Teste o caminho
/greet-the-world
:curl -v --resolve altostrat.com:443:CLUSTER_INGRESS_VIP\ https://altostrat.com/greet-the-world \ --cacert root-ca.crt
Saída:
Hello, world! Version: 2.0.0 Hostname: hello-deployment-5ff7f68854-wqzp7
Teste o caminho
/greet-kubernetes
:curl -v --resolve altostrat.com:443:CLUSTER_INGRESS_VIP \ https://altostrat.com/greet-kubernetes --cacert root-ca.crt
Saída:
Hello Kubernetes!
Criar um serviço LoadBalancer
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
.
Por padrão, o Kubernetes aloca portas de nó para serviços LoadBalancer. Essas
alocações podem esgotar rapidamente as portas de nó disponíveis das 2.768 alocadas para
o cluster. Para salvar portas de nó, desative a alocação de porta de nó do balanceador de carga
definindo o campo allocateLoadBalancerNodePorts
como false
na especificação do serviço LoadBalancer. Essa configuração impede que o Kubernetes aloque portas de nó para
serviços LoadBalancer. Para mais informações, consulte
Como desativar a alocação de NodePort do balanceador de carga na documentação do Kubernetes.
Confira aqui um manifesto para criar um Serviço que não usa nenhuma porta de nó:
apiVersion: v1
kind: Service
metadata:
name: service-does-not-use-nodeports
spec:
selector:
app: my-app
type: LoadBalancer
ports:
- port: 8000
# Set allocateLoadBalancerNodePorts to false
allocateLoadBalancerNodePorts: false
Limpar
Exclua o Entrada:
kubectl --kubeconfig CLUSTER_KUBECONFIG delete ingress INGRESS_NAME
Substitua INGRESS_NAME
pelo nome da
Entrada, como my-ingress
ou my-ingress-2
.
Exclua o Serviço:
kubectl --kubeconfig CLUSTER_KUBECONFIG delete service hello-service
Exclua a implantação:
kubectl --kubeconfig CLUSTER_KUBECONFIG delete deployment hello-deployment
Exclua o serviço LoadBalancer:
kubectl --kubeconfig CLUSTER_KUBECONFIG delete service service-does-not-use-nodeports