February 22, 2020

Creating your first Kubernetes deployment

Kubernetes deployments

Creating your first Kubernetes deployment

Before we get into how you make your first kubernetes (k8s) deployment let's go over the high levels of what a deployment in Kubernetes is.

What is a deployment?

A deployment is the high level template of what your POD, ReplicaSet are. Deployments have a wide variety of options you can put in the template, but there some that are typically always there:

replicas - This defaults to 1 to say there is always one pod (copy) of this deployment. If you were to say replicas = 20 then you'd have 20 pods that are all the same copy of your deployment.

template.spec.containers.image - What is the image (typically docker) that you're deployment is running. Typically it's formatted like:

image: REPO(gcr.io/docker/etc)/PROJECT/IMAGE

strategy - The strategy is how you plan on updating your pods when your deployment image is updated. Having deployments that are unified makes it easy to setup a CICD (Continuous Integration and Continuous Deployment) pipeline so as you're updating your code then your images automatically get updated on the fly. As you push out those images kubernetes has different ways to update those images to minimize downtime or help you test deploys before you roll them out fleet wide.

template.spec.containers.port - This is where you setup any port mappings between your pod and containers.

ports:
- containerPort: 3030
  name: my pod
  protocol: TCP
Yaml example for a port mapping

That's the jist of what you can do with a deployment.

Now lets go ahead and create a test deployment so we can see how it works.

Hello World!

kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10

This will create a deployment on our k8s cluster. You will be able to see it from your dashboard UI.

K8S Dashboard Deployments

Though at first it's intimidating you will get used to the CLI you'll be able to see it more quickly from the command line with kubectl

...\kubernetes> kubectl get deployments
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
hello-minikube   1/1     1            1           8h

If you want to see the actual yaml of the deployment you can do

kubernetes> kubectl get deployment hello-minikube -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2020-02-22T09:34:44Z"
  generation: 1
  labels:
    app: hello-minikube
  name: hello-minikube
  namespace: default
  resourceVersion: "736"
  selfLink: /apis/apps/v1/namespaces/default/deployments/hello-minikube
  uid: 072ecb27-b058-49ae-a21e-ab7de1712fff
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: hello-minikube
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: hello-minikube
    spec:
      containers:
      - image: k8s.gcr.io/echoserver:1.10
        imagePullPolicy: IfNotPresent
        name: echoserver
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2020-02-22T09:34:50Z"
    lastUpdateTime: "2020-02-22T09:34:50Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2020-02-22T09:34:44Z"
    lastUpdateTime: "2020-02-22T09:34:50Z"
    message: ReplicaSet "hello-minikube-797f975945" has successfully progressed.

How do we see our new deployment?

So we're created our first deployment how do we actually see it?

We need to make a service (svc) so that we can let kubernetes know that we'd like to expose that pod to a specific port on the kubernetes node, that we can then map to a load balancer in a more traditional sense. We're going to use the NodePort service type

kubectl expose deployment hello-minikube --type=NodePort --port=8080
service/hello-minikube exposed
Expose the deployment to port 8080 using NodePort service type

See our pods

\kubernetes> kubectl get pod
NAME                              READY   STATUS    RESTARTS   AGE
hello-minikube-797f975945-4dd7v   1/1     Running   0          8h

See our new service

kubernetes> kubectl get svc
NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
hello-minikube   NodePort    10.99.250.162   <none>        8080:31568/TCP   51s
kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP          8h

Lets visualize it

kubectl port-forward svc/hello-minikube 8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Handling connection for 8080
Handling connection for 8080

Now lets open our web browser and goto http://127.0.0.1:8080/

So now we have seen what happens with our first service & deployment. Now that we're done with them lets clean up something we're done with.

Lets remove the service.

\kubernetes> kubectl delete svc hello-minikube
service "hello-minikube" deleted

Lets remove the deployment & the underlying pods

PS C:\Users\bill\kubernetes> kubectl delete deployment hello-minikube
deployment.apps "hello-minikube" deleted

Congratulations now we're done with our first deployment and service. We'll be adding more complex examples later.

If there is something you'd like to see feel free to leave a comment about it.