Kubernetes, Part 1
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.