k8spractice Services

This is part 3 of a 4-part series on deploying an application to Azure Kubernetes. Here’s a full list of this series:

Now that we have a running PostgreSQL server with the necessary database, tables, and roles configured it’s time to deploy k8spractice web app itself.

The containers are available from Github Packages if you want to skip creating them yourself. I want to remind you again that this app was written mainly to provide something to deploy to a Kubernetes cluster. Many security-related liberties were taken; you have been warned.

Deploy Redis Cache

The backend k8spractice service uses Redis Cache for session management. Below is the complete redis.yaml file to deploy a Redis instance:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      role: redis
  template:
    metadata:
      labels:
        role: redis
    spec:
      containers:
      - name: redis
        image: redis:alpine
        imagePullPolicy: IfNotPresent

---

apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  selector:
    role: redis
  ports:
  - port: 6379
    protocol: TCP

Just like the PostgreSQL instance the Redis deployment will use one replica instance. Persistent store is not enabled since Redis is only used as a session cache. For k8spractice a restart of the Redis server will simply mean the user will have to login again.

Backend Service

The backend service needs access to the PostgreSQL service and Redis Cache services that were created in the previous posts. The Backend service uses environment variables for its configuration which are listed below:

SECRET_KEY = This is for the environment variable Flask needs to sign the session token. See here for more info.
DB_DSN = The database DSN string to pass to psycopg2.connect().
REDIS_HOST = Host to the Redis Cache server.
REDIS_PORT = Port the Redis Cache server is listening in.

For the deployment the SECRET_KEY, and DB_DSN environment variables are created in Kubernetes Secrets. This was done to prevent exposing these values in the yaml configuration file; and the secrets were created on the command-line using the commands below:

kubectl create secret generic backendsecretkey --from-literal="SECRET_KEY=$(python -c 'import os; print(os.urandom(16))')"

The DB_DSN environment variable should contain DSN string to connect to the PostgreSQL service deployed in the previous post. For this series the DSN will be like the following:

host=dbserver dbname=<DB NAME> user=<Backend DB user> password=<Backend DB password>

<DB NAME>, <Backend DB user>, and <Backend DB password> are values for the database where k8spractice.user is, and the login that the Backend service should use. The value of host is the Kubernetes Service of the PostgreSQL server. If you opted to deploy an “Azure Database for PostgreSQL”, this can be the value of the ExternalName service pointing to that server.

Below is a copy of the backend.yaml from the project repo:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  replicas: 4
  selector:
    matchLabels:
      app: backend
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: k8sbackend
        image: ghcr.io/keithmendozasr/k8spractice/backend:release1
        imagePullPolicy: IfNotPresent
        envFrom:
        - secretRef:
            name: backendsecretkey
            optional: false
        - secretRef:
            name: backenddb
            optional: false
        env:
        - name: REDIS_HOST
          value: redis
        - name: REDIS_PORT
          value: "6379"
        ports:
        - name: "backendport"
          containerPort: 5000
          protocol: TCP
---

apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: backend
  ports:
  - name: "backendport"
    targetPort: "backendport"
    port: 5000

Frontend Service

Below is the full yaml config file for the frontend service; which is also available here.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 4
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: k8sfrontend
        image: ghcr.io/keithmendozasr/k8spractice/frontend:release1
        imagePullPolicy: Always
        ports:
        - name: "frontendport"
          containerPort: 80
          protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  selector:
    app: frontend
  ports:
  - name: "frontendport"
    targetPort: "frontendport"
    port: 80

It’s a straight-forward deployment of a static site running on Apache. The number of replicas is set to 4, it’s using the k8spractice frontend container that I created and exposes TCP port 80. The matching “frontend” Service resource is also defined.

At this point, the k8spractice services are running; however, it’s not accessible to anyone that’s not directly in the cluster’s network. In the final post of this series, I’ll show you how to configure the ingress rules and set up TLS certificates.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.