A collection of my projects and thoughts!
by Alexander
In order to learn about Kubernetes I recently set up my own cluster from scratch, as documented in the previous post Kubernetes the hard way.
I used the cluster to deploy my own Limit order book application.
I started out by putting the manifest files in in a /k8s subdirectory in the application Github repository.
My workflow was as follows.
kubectl set image deployments/limit-order-book limit-order-book=limit-order-book:<NEW-TAG>I wanted to automate this flow and make it work closer to how it would in a production environment.
I started by converting my manifests into Helm charts.
By creating templates for all my resources that all referenced a single values-file made it got easier to get an overview of the current state of my cluster. It also made it easier to switch between different versions of the application.
After installing ArgoCD in my cluster I could add my application running the following command.
argocd app create limit-order-book --repo https://github.com/Alexandoooor/limit-order-book-helm.git --path limit-order-book --dest-server https://kubernetes.default.svc --dest-namespace default
By setting the sync-policy to automated ArgoCD will automatically sync the application when it detects differences in the manifests in git.
argocd app set limit-order-book --sync-policy automated
There was one thing missing to get the automated deployments working, secrets. I needed both imagePullSecrets for getting the docker image from a private repository,
as well as the password for the Postgres database.
I had previously manually added the secrets after setting up the cluster. But this approach is the opposite of automation. I instead decided to use sealed secrets.
Sealed secrets works by installing a controller in the cluster. The controller has a public encryption key, which you use to encrypt a secret, the Postgres password for example. The result is a sealed (encrypted) secret which can be included in the Helm charts of the application. The sealed secrets controller is the only holder of the private key needed unencrypt (unseal) the secret so that it can be used as a regular Kubernetes secret.
kubectl create secret generic limit-order-book-postgres-secret \
--from-literal=ps_password=hunter2 \
--dry-run=client -o yaml > secret.yaml
The above command outputs the secret.yaml with the content below.
apiVersion: v1
kind: Secret
metadata:
name: limit-order-book-postgres-secret
type: Opaque
stringData:
ps_password: hunter2
Running kubeseal as follows uses the public key to encrypt the secret into sealedsecret.yaml:
kubeseal --format yaml < secret.yaml > sealedsecret.yaml
The resulting sealedsecrets.yaml contains the encrypted secret which can safely be added to the git repository, since the controller is the only one holding the private key needed to unseal the secret.
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: limit-order-book-postgres-secret
namespace: default
spec:
encryptedData:
ps_password: AgByvKX3a...