I wanted to make building and deploying new applications as easy as possible to lower the barrier to developing new projects. After considering the available options, I arrived at Kubernetes because it is widely available from cloud providers, with the option for hosting on premises if needed, resulting in a great build once, run anywhere system. I am also familiar with many of the building blocks used when deploying on Kubernetes and wanted to learn about Kubernetes directly by using it.

The Cluster

I started with a single node DigitalOcean Kubernetes cluster since initially I will not have very demanding apps running here to begin with. After deploying the cluster through the UI, obtain the kubeconfig to access the cluster.

Verify access by trying kubectl get nodes.

The App

The first thing I will deploy on this cluster is this website. The website is a static site packaged in a container as described in Gitlab CI Docker Container Build.

Since my image repository private, I followed the directions to create a secret containing the registry credentials.

I created a Deployment and a Service as shown below:

apiVersion: v1
kind: Service
metadata:
  name: andrewtchin-com
spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
  selector:
    app: andrewtchin-com
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: andrewtchin-com
spec:
  selector:
    matchLabels:
      app: andrewtchin-com
  replicas: 1
  template:
    metadata:
      labels:
        app: andrewtchin-com
    spec:
      containers:
      - name: andrewtchin-com
        image: andrewtchin/andrewtchin.com:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 80
      imagePullSecrets:
      - name: regcred

I then applied it with the following command:

kubectl apply -f andrewtchin.com.yaml

Verify that the deployment is running:

⇒  kubectl get deployments
NAME                                  READY   UP-TO-DATE   AVAILABLE   AGE
andrewtchin-com                       1/1     1            1           19h

View the pods for fun:

⇒  kubectl get pods
NAME                                                 READY   STATUS    RESTARTS   AGE
andrewtchin-com-55dfd65667-55ngf                     1/1     Running   0          19h

And verify that the service is running:

⇒  kubectl get svc
NAME                                  TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)                      AGE
andrewtchin-com                       ClusterIP      10.245.114.255   <none>          80/TCP                       19h

Conclusion

At this point the service is available, but only from within the cluster, so it’s not very useful.

In the next part, I will show how to make the service available publicly and how to automatically obtain TLS certificates with Let’s Encrypt.