I have a fresh cluster installed and i will start with a simple deployment of static website.


Docker Image

For our Website, we will use Nginx for arm32 architecture.

FROM nginx

EXPOSE 80

COPY _site/ /usr/share/nginx/html

Just copy static website source code with index file to "_site" directory in Docker context and just build image, tag then push it to "docker.io" registry. It will be available to our cluster.

docker build . -t {{yourrepository}}/home
docker tag {{yourrepository}}/home:latest {{yourrepository}}/home:arm
docker push {{yourrepository}}/home:arm

We must be logged to Docker hub registry before pushing newly image and replacing {{yourrepository}} by our Docker Hub username.


Kubernetes deployment

After prepared image, it's time to deploy it.

Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: front

Create a simple namespace to be a scope for our project.

SSL Secret

apiVersion: v1
kind: Secret
metadata:
  name: home-tls
  namespace: front
type: Opaque  
data:
  tls.crt: {{crt}}
  tls.key: {{key}}
type: kubernetes.io/tls

To have a HTTPS access to our website, we need to get SSL certificate and it's easy and free with letsencrypt.org by just installing CertBot in any node of your cluster and use it to generate certificate for your domain.

You can use "TXT Record" identification method for certificate generation: CertBot give you a string token and you must add it to your DNS configuration of your domain as "TXT Record" to continue generation.

After, you must replace {{crt}} by fullchain and not just cert.pem certificate encoded base64, like {{key}} who is must be replace by the private key encoded also.

# private key
cat privkey.pem | base64
# fullchain certificate
cat fullchain.pem | base64

Deployment & Service

apiVersion: apps/v1
kind: Deployment
metadata:
  name: home
  namespace: front
  labels:
    app: home
spec:
  replicas: 1
  selector:
    matchLabels:
      app: home
  template:
    metadata:
      labels:
        app: home
    spec:
      containers:
      - name: home
        image: medinvention/home:arm
        imagePullPolicy: Always
        ports:
        - containerPort: 80

For our deployment, we define one container for built image and export one port 80 for web access. We defined a label selector "app: home" to bind pod to service and create a HTTP end point to access pod service from outside of cluster.

apiVersion: v1
kind: Service
metadata:
  name: home-service
  namespace: front
spec:
  ports:
  - name: http
    port: 80
    targetPort: 80
  selector:
    app: home

With this way, we have bound "home-servcice" to HTTP port of container inside pod deployed. "Kube" use match label configuration to make association between service and pod and define end point.

Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
  name: home
  namespace: front
  labels:
    app: home
spec:
  rules:
    - host: {{host}}
      http:
        paths:
          - backend:
              serviceName: home-service
              servicePort: http
            path: /
  tls:
    - hosts:
      - {{host}}
      secretName: home-tls

To make our service accessible from outside of cluster, we define an "Ingress" object to publish home service using Nginx Load Balancer. Change {{host}} by your host and apply it.

If you check the Load Balancer service, you will find dedicated ports like "80:31782/TCP,443:31179/TCP". You must configure your internet router (or box) to NAT 443 external port to 31179 port of master node.


It's done , enjoy :)