This document describes how to deploy an application on Google Distributed Cloud.
Before you begin
To deploy a workload, you must have a user, hybrid, or standalone cluster capable of running workloads.
Create a Deployment
The following steps create a Deployment on your cluster:
Copy the following manifest to a file named
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 applyto create the Deployment:kubectl apply -f my-deployment.yaml --kubeconfig CLUSTER_KUBECONFIGReplace CLUSTER_KUBECONFIG with the path of the kubeconfig file for your cluster.
Get basic information about your Deployment to confirm it was created successfully:
kubectl get deployment my-deployment --kubeconfig CLUSTER_KUBECONFIGThe output shows that the Deployment has three Pods that are all available:
NAME READY UP-TO-DATE AVAILABLE AGE my-deployment 3/3 3 3 27sList the Pods in your Deployment:
kubectl get pods --kubeconfig CLUSTER_KUBECONFIGThe output shows that your Deployment has three running Pods:
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 34sGet detailed information about your Deployment:
kubectl get deployment my-deployment --output yaml --kubeconfig CLUSTER_KUBECONFIGThe output shows details about the Deployment spec and status:
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: 3Describe your Deployment:
kubectl describe deployment my-deployment --kubeconfig CLUSTER_KUBECONFIGThe output shows nicely formatted details about the Deployment, including the associated ReplicaSet:
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
Create a Service of type LoadBalancer
One way to expose your Deployment to clients outside your cluster is to create
a Kubernetes Service of type
LoadBalancer.
To create a Service of type LoadBalancer:
Copy the following manifest to a file named
my-service.yaml:apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: metrics department: sales type: LoadBalancer ports: - port: 80 targetPort: 8080Here are the important things to understand about the Service in this exercise:
Any Pod that has the label
app: metricsand the labeldepartment: salesis a member of the Service. The Pods inmy-deploymenthave these labels.When a client sends a request to the Service on TCP port
80, the request is forwarded to a member Pod on TCP port8080.Every member Pod must have a container that is listening on TCP port
8080.
By default, the
hello-appcontainer listens on TCP port8080. You can see this port setting by looking at the Dockerfile and the source code for the app.Use
kubectl applyto create the Service on your cluster:kubectl apply -f my-service.yaml --kubeconfig CLUSTER_KUBECONFIGReplace CLUSTER_KUBECONFIG with the path of the kubeconfig file for your cluster.
View your Service:
kubectl get service my-service --output yaml --kubeconfig CLUSTER_KUBECONFIGThe output is similar to the following:
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.13In the preceding output, you can see that your Service has a
clusterIP, and an external IP address. It also has anodePort, aport, and atargetPort.The
clusterIPisn't relevant to this exercise. The external IP address (status.loadBalancer.ingress.ip) comes from the range of addresses that you specified when you defined load balancer address pools (spec.loadBalancer.addressPools) in the cluster configuration file.As an example, take the values shown in the preceding output for your Service:
- External IP address:
192.168.1.13 port:80nodePort:31565targetPort:8080
A client sends a request to
192.168.1.13on TCP port80. The request is routed to your load balancer, and from there it is forwarded to a member Pod on TCP port8080.- External IP address:
Call your Service:
curl INGRESS_IP_ADDRESSReplace INGRESS_IP_ADDRESS with the ingress IP address in the
statussection of the Service that you retrieved in the preceding step (status.loadBalancer.ingress).The output shows a
Hello, world!message:Hello, world! Version: 2.0.0 Hostname: my-deployment-869f65669b-wn4ft
LoadBalancer port limits
The LoadBalancer type is an extension of the NodePort type. So a Service of
type LoadBalancer has a cluster IP address and one or more nodePort values.
By default, Kubernetes allocates node ports to Services of type LoadBalancer.
These allocations can quickly exhaust available node ports from the 2,768
allotted to your cluster. To save node ports, disable load balancer node port
allocation by setting the allocateLoadBalancerNodePorts field to false in
the LoadBalancer Service spec. This setting prevents Kubernetes from
allocating node ports to LoadBalancer Services. For more information, see
Disabling load balancer NodePort allocation
in the Kubernetes documentation.
Here's a manifest to create a Service that doesn't use any node ports:
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
Delete your Service
To delete your Service:
Use
kubectl deleteto delete your Service from your cluster:kubectl delete service my-service --kubeconfig CLUSTER_KUBECONFIGVerify that your Service has been deleted:
kubectl get services --kubeconfig CLUSTER_KUBECONFIGThe output no longer shows
my-service.
Delete your Deployment
To delete your Deployment:
Use
kubectl deleteto delete your Deployment from your cluster:kubectl delete deployment my-deployment --kubeconfig CLUSTER_KUBECONFIGVerify that your Deployment has been deleted:
kubectl get deployments --kubeconfig CLUSTER_KUBECONFIGThe output no longer shows
my-deployment.
What's next
Create a Service and an Ingress