- Some basic understanding of Kubernetes
- A DO account
- A domain
- Postgres CLI (psql)
- kubectl, lens, and helm
- Create a VPC (networking -> VPC -> Create VPC Network)
- Create a Kube Cluster
- Node pool name: pool-kube-challenge
- Node plan: $15 a month; count 3
- Finalize
- Name: kube-challenge
- Download cluster config file
- Connect to the cluster; two ways
-
Kubectl
$ mv ~/Downloads/kube-challenge-kubeconfig.yaml ./ $ export KUBECONFIG=./kube-challenge-kubeconfig.yaml $ kubectl config get-contexts $ kubectl get nodes
-
Lens
- Add cluster from kubeconfig
- Paste content into the textarea
- Add cluster
- Add to hotbar
- Go to the cluster's settings and apply the 3 options in tab "Lens Metrics"
Use
kubectl get -A pods
to check if the pods are up
-
Create the template based on https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
# app.yml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-app-deployment spec: selector: matchLabels: app: nginx replicas: 2 # tells deployment to run 2 pods matching the template template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
-
Apply the template,
$ kubectl apply -f app.yml
, under the repo directory
-
Create a service template
# app-service.yml apiVersion: v1 kind: Service metadata: name: nginx-app-service spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80
-
Apply the template,
$ kubectl apply -f app-service.yml
, under the repo directory
-
Add and install repo "ingress-nginx"
$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx $ helm repo update $ helm install nginx-ingress ingress-nginx/ingress-nginx --set controller.publishService.enabled=true
-
Create a template based on the tutorial
# app-ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
# change below to your domain
- host: "k8s-challenge.chenghsuan.me"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: nginx-app-service
port:
number: 80
- Apply the template,
$ kubectl apply -f app-ingress.yml
, under the repo directory - Use the IP address (of the load balancer) to create an A record in your DNS
- Now the app is publicly accessible via http://k8s-challenge.chenghsuan.me/ (or your domain)
Ref: https://github.com/mittwald/kubernetes-secret-generator
$ helm repo add mittwald https://helm.mittwald.de
$ helm repo update
$ helm upgrade --install kubernetes-secret-generator mittwald/kubernetes-secret-generator
-
$ kubectl apply -f https://raw.githubusercontent.com/reactive-tech/kubegres/v1.15/kubegres.yaml
-
Generate passwords for master and replica postgres
# postgres-secrets.yml apiVersion: v1 kind: Secret metadata: name: postgres-master-secret annotations: secret-generator.v1.mittwald.de/autogenerate: password data: {} --- apiVersion: v1 kind: Secret metadata: name: postgres-replica-secret annotations: secret-generator.v1.mittwald.de/autogenerate: password data: {}
$ kubectl apply -f postgres-secrets.yml
-
Inspect the generated passwords from Lens
-
Create a cluster of Postgres instances
# postgres.yml apiVersion: kubegres.reactive-tech.io/v1 kind: Kubegres metadata: name: postgres spec: replicas: 3 image: postgres:14.1 database: size: 1Gi env: - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: postgres-master-secret key: password - name: POSTGRES_REPLICATION_PASSWORD valueFrom: secretKeyRef: name: postgres-replica-secret key: password
$ kubectl apply -f postgres.yml
-
Generate app database secrets
# app-secrets.yml apiVersion: v1 kind: Secret metadata: name: app-postgres-secret annotations: secret-generator.v1.mittwald.de/autogenerate: password secret-generator.v1.mittwald.de/encoding: base64url # to prevent slash in the secret from breaking DATABASE_URL data: {}
$ kubectl apply -f app-secrets.yml
-
Forward port of Postgres cluster; get the port from Lens
-
Copy raw value of
postgres-master-secret
andapp-postgres-secret
-
Log into Postgres cluster via Postgres CLI
$ psql -h localhost -U postgres -p port_from_lens # then paste the password from postgres-master-secret
-
Create user "app" (with password of
app-postgres-secret
raw value) and database "app_prod"CREATE USER app WITH PASSWORD 'APPPOSTGRESSECRETVALUEFROMLENS'; CREATE DATABASE app_prod OWNER app; # verify change \l # quit quit
- Create a board app with Elixir Phoenix (example in dir
phx-docker-app
) - Configure app*.yml for the new board app
- Apply the changes
$ kubectl apply app-secrets.yml $ kubectl apply app.yml $ kubectl apply app-service.yml $ kubectl apply app-ingress.yml
- Open pod shell in one of the board-app-deployment pod and
$ ./bin/migrate
- Open the app http://k8s-challenge.chenghsuan.me/ (or your domain)