Neste documento, descrevemos como implantar um aplicativo no Google Distributed Cloud.
Antes de começar
Para implementar uma carga de trabalho, você precisa ter um cluster de usuário, híbrido ou independente capaz de executar cargas de trabalho.
Crie uma implantação
As etapas a seguir criam uma implantação no cluster:
copie o seguinte manifesto para um arquivo chamado
my-deployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment spec: selector: matchLabels: app: metrics department: sales replicas: 3 template: metadata: labels: app: metrics department: sales spec: containers: - name: hello image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"
Use
kubectl apply
para criar a implantação:kubectl apply -f my-deployment.yaml --kubeconfig CLUSTER_KUBECONFIG
Substitua CLUSTER_KUBECONFIG pelo caminho do arquivo kubeconfig do cluster.
Receba informações básicas sobre sua implantação para confirmar se ela foi criada com sucesso:
kubectl get deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
A saída mostra que a implantação tem três pods disponíveis:
NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 3/3 3 3 27s
Liste os pods na implantação:
kubectl get pods --kubeconfig CLUSTER_KUBECONFIG
A saída mostra que a implantação tem três pods em execução:
NAME READY STATUS RESTARTS AGE my-deployment-869f65669b-5259x 1/1 Running 0 34s my-deployment-869f65669b-9xfrs 1/1 Running 0 34s my-deployment-869f65669b-wn4ft 1/1 Running 0 34s
Encontre informações detalhadas sobre sua implantação:
kubectl get deployment my-deployment --output yaml --kubeconfig CLUSTER_KUBECONFIG
A saída mostra informações detalhadas sobre a especificação e o status da implantação:
apiVersion: apps/v1 kind: Deployment metadata: ... generation: 1 name: my-deployment namespace: default ... spec: ... replicas: 3 revisionHistoryLimit: 10 selector: matchLabels: app: metrics department: sales ... spec: containers: - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0 imagePullPolicy: IfNotPresent name: hello resources: {} terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst restartPolicy: Always schedulerName: default-scheduler securityContext: {} terminationGracePeriodSeconds: 30 status: availableReplicas: 3 conditions: - lastTransitionTime: "2023-06-29T16:17:17Z" lastUpdateTime: "2023-06-29T16:17:17Z" message: Deployment has minimum availability. reason: MinimumReplicasAvailable status: "True" type: Available - lastTransitionTime: "2023-06-29T16:17:12Z" lastUpdateTime: "2023-06-29T16:17:17Z" message: ReplicaSet "my-deployment-869f65669b" has successfully progressed. reason: NewReplicaSetAvailable status: "True" type: Progressing observedGeneration: 1 readyReplicas: 3 replicas: 3 updatedReplicas: 3
Descreva a implantação:
kubectl describe deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
A saída mostra informações detalhadas bem formatadas sobre a implantação, incluindo o ReplicaSet associado:
Name: my-deployment Namespace: default CreationTimestamp: Thu, 29 Jun 2023 16:17:12 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=metrics,department=sales Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=metrics department=sales Containers: hello: Image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0 Port: <none> Host Port: <none> Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: my-deployment-869f65669b (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 6m50s deployment-controller Scaled up replica set my-deployment-869f65669b to 3
Criar um serviço do tipo LoadBalancer
Uma maneira de expor a implantação para clientes fora do cluster é criar
um serviço do Kubernetes do tipo
LoadBalancer
.
Para criar um serviço do tipo LoadBalancer
:
Copie o seguinte manifesto para um arquivo chamado
my-service.yaml
:apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: metrics department: sales type: LoadBalancer ports: - port: 80 targetPort: 8080
Veja a seguir informações importantes sobre o Serviço neste exercício:
Qualquer pod que tenha o rótulo
app: metrics
e o rótulodepartment: sales
é um membro do serviço. Os pods emmy-deployment
têm esses rótulos.Quando um cliente envia uma solicitação ao serviço na porta TCP
80
, a solicitação é encaminhada a um pod membro na porta TCP8080
.Cada pod de membro precisa ter um contêiner detectando a porta TCP
8080
.
Por padrão, o contêiner
hello-app
detecta a porta TCP8080
. Essa configuração de porta pode ser vista no Dockerfile e no código-fonte do app.Use
kubectl apply
para criar o serviço no cluster:kubectl apply -f my-service.yaml --kubeconfig CLUSTER_KUBECONFIG
Substitua CLUSTER_KUBECONFIG pelo caminho do arquivo kubeconfig do cluster.
Veja seu serviço:
kubectl get service my-service --output yaml --kubeconfig CLUSTER_KUBECONFIG
O resultado será assim:
apiVersion: v1 kind: Service metadata: ... name: my-service namespace: default ... spec: allocateLoadBalancerNodePorts: true clusterIP: 10.96.2.165 clusterIPs: - 10.96.2.165 externalTrafficPolicy: Cluster internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - nodePort: 31565 port: 80 protocol: TCP targetPort: 8080 selector: app: metrics department: sales sessionAffinity: None type: LoadBalancer status: loadBalancer: ingress: - ip: 192.168.1.13
Na saída anterior, é possível ver que o serviço tem um
clusterIP
e um endereço IP externo. Ele também tem umnodePort
, umport
e umtargetPort
.O
clusterIP
não é relevante para este exercício. O endereço IP externo (status.loadBalancer.ingress.ip
) vem do intervalo de endereços que você especificou quando definiu os pools de endereços do balanceador de carga (spec.loadBalancer.addressPools
) no arquivo de configuração do cluster.Por exemplo, veja os valores mostrados na saída anterior do seu serviço:
- Endereço IP externo:
192.168.1.13
port
:80
nodePort
:31565
targetPort
:8080
Um cliente envia uma solicitação para
192.168.1.13
na porta TCP80
. A solicitação é encaminhada para o balanceador de carga e, a partir daí, é encaminhada para um pod membro na porta TCP8080
.- Endereço IP externo:
Chame o serviço:
curl INGRESS_IP_ADDRESS
Substitua INGRESS_IP_ADDRESS pelo endereço IP de entrada na seção
status
do Serviço que você recuperou na etapa anterior (status.loadBalancer.ingress
).A saída mostra uma mensagem
Hello, world!
:Hello, world! Version: 2.0.0 Hostname: my-deployment-869f65669b-wn4ft
Limites de portas do 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 do tipo 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
. Isso 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
Excluir o Serviço
Para excluir o serviço:
Use
kubectl delete
para excluir o serviço do cluster:kubectl delete service my-service --kubeconfig CLUSTER_KUBECONFIG
Verifique se o serviço foi excluído:
kubectl get services --kubeconfig CLUSTER_KUBECONFIG
A saída não mostra mais
my-service
.
Excluir a implantação
Para excluir a implantação:
Use
kubectl delete
para excluir a implantação do cluster:kubectl delete deployment my-deployment --kubeconfig CLUSTER_KUBECONFIG
Verifique se a implantação foi excluída:
kubectl get deployments --kubeconfig CLUSTER_KUBECONFIG
A saída não mostra mais
my-deployment
.