GitOps for Kubernetes using Github Actions

© Atul R

Github Actions

 

Allows you to create automated workflows for building, testing, and deploying your code right from GitHub.

 

on:
  push:
    branches:
      - master
jobs:
  deploy-my-app:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: echo "step 1"
      - run: echo "step 2"
      - run: echo "step 3"

.github/workflows/mytask.yaml

 

Kubernetes

 

Container orchestration platform:

K8s is a system to manage, scale and deploy applications packaged as containers.

 

Desired state config
--------------------
...
...
image: eu.gcr.io/app:af7d5b9e
cpu: 400m
memory: 300Mi
replica : 3
...
...
host: myapp.example.com
...
...
# deployment.yaml

replicas: 3
image: APP_IMAGE_URL
labels:
  app: app-a
envFrom:
- configMapRef:
    name: app-a-config
- secretRef:
    name: app-a-secrets
ports:
  - containerPort: 5000
resources:
    cpu: 100m
    memory: 300Mi
# ingress.yaml

host: app-a.example.com
backend:
  serviceName: app-a-svc
  servicePort: 5000
# service.yaml

metadata:
  name: app-a-svc
spec:
  type: ClusterIP
  ports:
    - port: 5000
      targetPort: 5000
  selector:
    app: app-a
$ kubectl apply -f <filename>.yaml
http://app-a.example.com

node/vm

http://app-a-svc:5000
# configmap.yaml

metadata:
  name: app-a-config
data:
  MY_SERVICE_B: https://app-b.example.com
  MY_SERVICE_C: https://app-c.example.com
  MY_SERVICE_D: https://app-d.example.com

# secrets.yaml

metadata:
  name: app-a-secrets
data:
  FIREBASE_KEY: 611ff190-7fe1-4a71-ae75
  GOOGLE_SECRET: $kILat8GKeUqoaGY8w34sgg
  MAIL_API_KEY: f415aacd443eecd1634a59d

  

Environment variables

  • sensitive key values pairs
  • encrypted and stored
  • Shouldn't be committed to git repo
  • deployed manually using cli
  • stored as plain text
  • non sensitive key values pairs
  • Can be committed to git repo

Config maps

$ kubectl apply -f secrets.yaml 

Secrets

# deployment.yaml
...
...
envFrom:
- configMapRef:
    name: app-a-config
- secretRef:
    name: app-a-secrets

Kustomize

 

.
├── base
│   ├── deployment.yaml
│   ├── configmap.yaml
│   ├── service.yaml
│   └── ingress.yaml

Kustomize is a cli tool to merge, add, remove or update k8s configuration

.
├── base
│   ├── deployment.yaml
│   ├── configmap.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
# kustomization.yaml

kind: Kustomization

resources:
  - deployment.yaml
  - service.yaml
  - configmap.yaml
  - ingress.yaml

commonLabels:
  app: app-a
 $ kustomize build ./base > myapp.yaml

 $ kubectl apply -f myapp.yaml 
 $ kustomize build ./base | kubectl apply -f -
PS: Remember to deploy secrets separately
name: Build and Deploy to K8s
on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # Checkout repo
      # Setup gcloud SDK
      # Setup docker
      # Setup kubectl
      # Setup kustomize

      - run: |-
          docker build --tag "eu.gcr.io/myorg/app-a:$GITHUB_SHA" .
          docker push "eu.gcr.io/myorg/app-a:$GITHUB_SHA"
	  
      - run: kustomize edit set image APP_IMAGE_URL="eu.gcr.io/myorg/app-a:$GITHUB_SHA"

      - run: kustomize build base | kubectl apply -f -

Deploying via Github Actions

PR test apps

.
├── base
│   ├── deployment.yaml
│   ├── configmap.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
 $ kustomize build ./base | kubectl apply -f -
.
├── base
│   ├── deployment.yaml
│   ├── configmap.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
├── pr
│   ├── deployment.yaml
│   └── ingress.yaml
# ./pr/kustomization.yaml

bases:
  - ../base
  
patchesStrategicMerge:
  - deployment.yaml
  - ingress.yaml

nameSuffix:
  -pr-1
  
commonLabels:
  pr: 1
# ./pr/ingress.yaml

host: app-a-pr-1.example.com
backend:
  serviceName: app-a-svc
  servicePort: 5000
# ./pr/deployment.yaml

metadata:
  name: app-a-deploy
spec:
  replicas: 1
 $ kustomize build ./pr | kubectl apply -f -
.
├── base
│   ├── deployment.yaml
│   ├── configmap.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
├── pr
│   ├── deployment.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
// app-a-pr-1
.
├── base
│   ├── deployment.yaml
│   ├── configmap.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
├── pr
│   ├── deployment.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
# ./base/configmap.yaml

metadata:
  name: app-a-config
data:
  MY_SERVICE_B: https://app-b.example.com
  MY_SERVICE_C: https://app-c.example.com
  MY_SERVICE_D: https://app-d.example.com

Linking app-a-pr-1

app-b-pr-2

D

C

B

A

A

PR1

B

PR2

# ./base/configmap.yaml

metadata:
  name: app-a-config
data:
-  MY_SERVICE_B: https://app-b.example.com
+  MY_SERVICE_B: https://app-b-pr-2.example.com
   MY_SERVICE_C: https://app-c.example.com
   MY_SERVICE_D: https://app-d.example.com
// app-a-pr-1
.
├── base
│   ├── deployment.yaml
│   ├── configmap.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
├── pr
│   ├── deployment.yaml
│   ├── ingress.yaml
│   └── kustomization.yaml
# ./base/configmap.yaml

metadata:
  name: app-a-config
data:
  MY_SERVICE_B: https://app-b.example.com
  MY_SERVICE_C: https://app-c.example.com
  MY_SERVICE_D: https://app-d.example.com

Linking app-a-pr-1

app-b-pr-2

D

C

B

A

A

PR1

B

PR2

# ./base/configmap.yaml

metadata:
  name: app-a-config
data:
-  MY_SERVICE_B: https://app-b.example.com
+  MY_SERVICE_B: https://app-b-pr-2.example.com
   MY_SERVICE_C: https://app-c.example.com
   MY_SERVICE_D: https://app-d.example.com

Cleaning up

 

on:
  pull_request:
    types:
      - closed

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      # Checkout repo
      # Setup gcloud SDK
      # Setup kubectl
	  
      - run: |-
      
         export PR_NUMBER=${{github.event.number}}
      
         kubectl delete \
          configmap,deployment,ingress,pods,replicasets,service \
          -l app=app-a,pr=$PR_NUMBER

GitOps for Kubernetes using github actions

By Atul R

GitOps for Kubernetes using github actions

TechTree Show The Code | EQT Ventures Edition | 10th Dec 2020

  • 3,045