Self-Hosted Blog Part 7 - Kubernetes
In part 6 we got our blog building in our CI2/CD pipeline. Now we’re going to run that built image in our Raspberry Pi K8S cluster. In my setup I have a single Linode VPS node exposed to the internet. First let’s get all of Kubernetes nodes serving HTTP.
Let’s create a Kubernetes service that will use the container we created earlier with our CI/CD pipeline. I have a file in my repo called k8s-blog.yml
which has the following contents which create a Kubernetes service running the container we created and creates an ingress controller which exposes that container for the host clintsharp.com:
---
apiVersion: v1
kind: Namespace
metadata:
name: blog
---
apiVersion: v1
kind: Service
metadata:
name: blog
namespace: blog
labels:
app.kubernetes.io/name: blog
annotations:
{}
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
name: web
selector:
app.kubernetes.io/name: blog
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: blog
namespace: blog
labels:
app.kubernetes.io/name: blog
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: blog
template:
metadata:
labels:
app.kubernetes.io/name: blog
spec:
containers:
- name: blog
image: clintsharp/blog:latest
imagePullPolicy: Always
resources:
limits:
cpu: 2000m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: blog
namespace: "blog"
spec:
rules:
- host: "clintsharp.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: blog
port:
number: 80
I’m assuming you know a bit about Kubernetes if this interested you, so I’ll not go through intimate details on what all of this is. We’re creating a namespace, a deployment, a service, and a ingress configuration. After running kubectl apply -f ./deployment/k8s-blog.yml
and after the deployment finishes converging I’ll have a working blog in Kubernetes.
To validate, I ran kubectl get po -n blog
and I see pods deployed:
NAME READY STATUS RESTARTS AGE
blog-5844664449-pbqpw 1/1 Running 0 5d17h
blog-5844664449-627kt 1/1 Running 0 5d17h
blog-5844664449-gdrpl 1/1 Running 1 5d17h
Now I can interrogate the service with kubectl get svc -n blog
:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
blog ClusterIP 10.152.183.132 <none> 80/TCP 4h33m
The last thing I want to do is setup the deployment for autoscaling, which I do with kubectl autoscale deployment blog --cpu-percent=50 --min=3 --max=20
. This will automatically scale up to 20 pods when we see the average CPU usage above 50% for the running pods.
Now, I can verify the blog service is serving our blog contents with a simple curl request from a machine on the local network. Note, we’re setting the Host
header so we’re routed to the right service:
curl -H "Host: clintsharp.com" http://192.168.68.2/
This shows we’re serving the right HTML content.
We have a running blog in Kubernetes on bare metal! Next, we will expose this to the internet and deploy on change.
Posts in this Series
- Self-Hosted Blog Part 1 - Overview
- Self-Hosted Blog Part 2 - The Hardware
- Self-Hosted Blog Part 3 - OS & Kubernetes
- Self-Hosted Blog Part 4 - The Blog
- Self-Hosted Blog Part 5 - Container
- Self-Hosted Blog Part 6 - Build
- Self-Hosted Blog Part 7 - Kubernetes
- Self-Hosted Blog Part 8 - Internet Accessibility
- Self-Hosted Blog Part 9 - Performance