Workflow on K8s
Argo
What's KintoHub ?
Connect Repo
Build
Combine
Deploy
Call
KintoHub Flow
Integration
/
Build
The Problems
Using Jenkins
Learning Curve
Scalability
Too many plugins
Slowness
Kubernetes fit
Jenkins Slave - Many languages
Docker in Docker
Mount docker socket
Install language packages
- https://github.com/argoproj/argo -> Open Source
- Kubernetes Custom Resource Definition
- Cloud agnostic
- Designed for container
- Graph or Step definition of workflows
- Workflow is a YAML file
- Easy to deploy / Easy to use
- Artifact / Timeout / TTL / Retry / Exit Handler / ...
- Get logs by workflow/step
- Labels / Volumes / Env vars / Secrets / Scheduling / ...
Argo
Spec body
- Entrypoint invocation
- List of template definitions
- Name of the template
- Optionally a list of inputs /outputs
- List of steps
- Container/Pod invocation
Argo Workflow
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: coinflip-recursive-
spec:
entrypoint: coinflip
templates:
- name: coinflip
steps:
- - name: flip-coin
template: flip-coin
- - name: heads
template: heads
when: "{{steps.flip-coin.outputs.result}} == heads"
- name: tails
template: coinflip
when: "{{steps.flip-coin.outputs.result}} == tails"
- name: flip-coin
script:
image: python:alpine3.6
command: [python]
source: |
import random
result = "heads" if random.randint(0,1) == 0 else "tails"
print(result)
- name: heads
container:
image: alpine:3.6
command: [sh, -c]
args: ["echo \"it was heads\""]
UseCase
Build NodeJS Application
- `git clone` - `npm install` - `npm build` - `npm run test` - `push [artifact]`
pipeline {
agent any
stages {
stage('Cloning Git') {
steps { sh 'git clone ...' }
}
stage('Install dependencies') {
steps { sh 'npm install' }
}
stage('Testing') {
steps { sh 'npm run test' }
}
stage('Push') {
steps { sh '[push artifacts]' }
}
}
}
Jenkins
UseCase
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: k8s-meetup-
spec:
activeDeadlineSeconds: 600
ttlSecondsAfterFinished: 300
entrypoint: main
volumeClaimTemplates:
- metadata:
name: workdir
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
imagePullSecrets:
- name: regsecret
templates:
- name: main
steps:
- - name: git-init
template: git-init
- - name: build-app
template: build-app
- - name: upload-to-minio
template: upload-to-minio
- name: git-init
container:
image: alpine/git:latest
command:
- "sh"
- "-c"
args:
- "rm -rf * && git clone https://${GIT_REPO} . && git checkout ${GIT_COMMIT} || exit 1"
workingDir: /build
env:
- name: "GIT_COMMIT"
value: "b8167974a9efb7a2d0e1e4b87d7cfcdf009eff2e"
- name: "GIT_REPO"
value: "github.com/kintohub/node-examples.git"
volumeMounts:
- name: workdir
mountPath: /build
metadata:
labels:
workflowId: k8s-meetup
step: git-init
- name: build-app
container:
image: kintocloud.azurecr.io/node894-alpine:latest
command:
- "sh"
- "-c"
args:
- "npm install || exit 1"
workingDir: /build
volumeMounts:
- name: workdir
mountPath: /build
metadata:
labels:
workflowId: k8s-meetup
step: build-app
- name: upload-to-minio
container:
image: minio/mc:RELEASE.2018-06-22T23-32-12Z
command:
- "sh"
- "-c"
args:
- "mc config host add k8s http://${MINIO_HOST} ${MINIO_ACCESS_KEY} ${MINIO_SECRET_KEY} S3v4 && mc mb --ignore-existing k8s/artifact && mc cp -r * k8s/artifact || exit 1"
workingDir: /build
env:
- name: "MINIO_ACCESS_KEY"
valueFrom:
secretKeyRef:
name: minio-credentials
key: accessKey
- name: "MINIO_SECRET_KEY"
valueFrom:
secretKeyRef:
name: minio-credentials
key: secretKey
- name: "MINIO_HOST"
value: "minio-dev:9000"
volumeMounts:
- name: workdir
mountPath: /build
metadata:
labels:
workflowId: k8s-meetup
step: upload-to-minio
Argo
Result
Name: k8s-meetup-cvgvh
Namespace: dev
ServiceAccount: default
Status: Succeeded
Created: Tue Nov 06 20:50:01 +0800 (41 seconds ago)
Started: Tue Nov 06 20:50:01 +0800 (41 seconds ago)
Finished: Tue Nov 06 20:50:42 +0800 (now)
Duration: 41 seconds
STEP PODNAME DURATION MESSAGE
✔ k8s-meetup-cvgvh
├---✔ git-init k8s-meetup-cvgvh-678981496 27s
├---✔ build-app k8s-meetup-cvgvh-2911520064 7s
└---✔ upload-to-minio k8s-meetup-cvgvh-3551202965 4s
Infra
Automation
The Problems
How to deploy easily our K8s resources?
- Terraform
- No support for beta resources.
- No Deployment, StatefulSet, DeamonSet, ...
- Helm
- Tiller
- Both ?
- Spinnaker
- ...
KintoHub Stack
Gateway Middleware
Cache Processor
Loader
...
...
Infra Deployment
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: create-infra-
spec:
ttlSecondsAfterFinished: 600
activeDeadlineSeconds: 600
entrypoint: main
serviceAccountName: init-infra
imagePullSecrets:
- name: regsecret
templates:
- name: main
steps:
- - name: infra-preparation
template: infra-preparation
- - name: infra-install-minio
template: infra-install-minio
- name: infra-install-redis
template: infra-install-redis
- name: infra-install-rabbitmq
template: infra-install-rabbitmq
- name: infra-install-mongodb-replicaset
template: infra-install-mongodb-replicaset
- name: infra-install-nginx
template: infra-install-nginx
- name: infra-install-external-dns
template: infra-install-external-dns
- name: infra-install-openresty
template: infra-install-openresty
- name: infra-install-elasticsearch
template: infra-install-elasticsearch
when: "false"
- name: infra-install-elasticsearch-curator
template: infra-install-elasticsearch-curator
when: "false"
- name: infra-install-fluentd
template: infra-install-fluentd
when: "false"
- name: infra-install-kibana
template: infra-install-kibana
when: "false"
- name: infra-install-prometheus-operator
template: infra-install-prometheus-operator
when: "false"
- - name: infra-install-cache-processor
template: infra-install-cache-processor
- name: infra-install-gateway-middleware
template: infra-install-gateway-middleware
- name: infra-install-loader
template: infra-install-loader
- name: infra-install-jenkins
template: infra-install-jenkins
- name: infra-install-argo-rbmq-build
template: infra-install-argo-rbmq-build
- name: infra-install-argo-rbmq-consumer
template: infra-install-argo-rbmq-consumer
- name: infra-install-argo-workflow-generator
template: infra-install-argo-workflow-generator
- name: infra-install-services-creation
template: infra-install-services-creation
when: "false"
- name: infra-install-services-manager
template: infra-install-services-manager
when: "false"
- name: infra-install-shutdown-consumer
template: infra-install-shutdown-consumer
when: "false"
- name: infra-preparation
outputs:
artifacts:
- name: argocd
path: /argocd
s3:
endpoint: storage.googleapis.com
bucket: install-infra
key: argocd.tgz
accessKeySecret:
name: my-gcs-s3-credentials
key: accessKey
secretKeySecret:
name: my-gcs-s3-credentials
key: secretKey
container:
image: kintocloud.azurecr.io/kinto-argo:latest
command:
- "sh"
- "-c"
args:
- "argocd login argocd-server.argocd.svc.cluster.local --config /argocd/.argocd --username admin --password $ARGOCD_PWD --insecure || exit 1"
env:
- name: ARGOCD_PWD
value: admin123
metadata:
labels:
workflowId: create-infra
step: kinto-infra-preparation
- name: infra-install-minio
inputs:
artifacts:
- name: argocd
path: /argocd
s3:
endpoint: storage.googleapis.com
bucket: install-infra
key: argocd.tgz
accessKeySecret:
name: my-gcs-s3-credentials
key: accessKey
secretKeySecret:
name: my-gcs-s3-credentials
key: secretKey
container:
image: kintocloud.azurecr.io/kinto-argo:latest
command:
- "sh"
- "-c"
args:
- "APP=minio-$ENV && argocd app create $APP --config /argocd/.argocd --repo https://${GIT_TOKEN}@github.com/kintohub/KintoInfra.git --dest-namespace $ENV --path helm/charts/minio --values values-$ENV.yaml --revision $GIT_BRANCH --upsert --env default --dest-server https://kubernetes.default.svc --sync-policy automated && argocd app wait $APP --config /argocd/.argocd --timeout $TIMEOUT || exit 1"
env:
- name: "GIT_TOKEN"
valueFrom:
secretKeyRef:
name: argo-git-creds
key: token
- name: "GIT_BRANCH"
value: "dev"
- name: "ENV"
value: "dev"
- name: "TIMEOUT"
value: "600"
metadata:
labels:
workflowId: create-infra
step: kinto-infra-install-minio
- name: infra-install-redis
inputs:
artifacts:
- name: argocd
path: /argocd
s3:
endpoint: storage.googleapis.com
bucket: install-infra
key: argocd.tgz
accessKeySecret:
name: my-gcs-s3-credentials
key: accessKey
secretKeySecret:
name: my-gcs-s3-credentials
key: secretKey
container:
image: kintocloud.azurecr.io/kinto-argo:latest
command:
- "sh"
- "-c"
args:
- "APP=redis-ha-$ENV && argocd app create $APP --config /argocd/.argocd --repo https://${GIT_TOKEN}@github.com/kintohub/KintoInfra.git --dest-namespace $ENV --path helm/charts/redis-ha --values values-$ENV.yaml --revision $GIT_BRANCH --upsert --env default --dest-server https://kubernetes.default.svc --sync-policy automated && argocd app wait $APP --config /argocd/.argocd --timeout $TIMEOUT || exit 1"
env:
- name: "GIT_TOKEN"
valueFrom:
secretKeyRef:
name: argo-git-creds
key: token
- name: "GIT_BRANCH"
value: "dev"
- name: "ENV"
value: "dev"
- name: "TIMEOUT"
value: "600"
metadata:
labels:
workflowId: create-infra
step: kinto-infra-install-redis
- name: infra-install-prometheus-operator
inputs:
artifacts:
- name: argocd
path: /argocd
s3:
endpoint: storage.googleapis.com
bucket: install-infra
key: argocd.tgz
accessKeySecret:
name: my-gcs-s3-credentials
key: accessKey
secretKeySecret:
name: my-gcs-s3-credentials
key: secretKey
container:
image: kintocloud.azurecr.io/kinto-argo:latest
command:
- "sh"
- "-c"
args:
- "APP=prometheus-operator && argocd app create $APP --config /argocd/.argocd --repo https://${GIT_TOKEN}@github.com/kintohub/KintoInfra.git --dest-namespace monitoring --path helm/charts/prometheus-operator --revision $GIT_BRANCH --upsert --env default --dest-server https://kubernetes.default.svc --sync-policy automated && argocd app wait $APP --config /argocd/.argocd --timeout $TIMEOUT || exit 1"
env:
- name: "GIT_TOKEN"
valueFrom:
secretKeyRef:
name: argo-git-creds
key: token
- name: "GIT_BRANCH"
value: "dev"
- name: "TIMEOUT"
value: "600"
metadata:
labels:
workflowId: create-infra
step: kinto-infra-install-prometheus-operator
...
Argo + ArgoCD
Result
Name: create-infra-l89gx
Namespace: dev
ServiceAccount: init-infra
Status: Succeeded
Created: Tue Nov 06 20:21:39 +0800 (1 minute ago)
Started: Tue Nov 06 20:21:39 +0800 (1 minute ago)
Finished: Tue Nov 06 20:22:32 +0800 (15 seconds ago)
Duration: 53 seconds
STEP PODNAME DURATION MESSAGE
✔ create-infra-l89gx
├---✔ infra-preparation create-infra-l89gx-1326669295 3s
├-·-○ infra-install-elasticsearch when 'false' evaluated false
| ├-○ infra-install-elasticsearch-curator when 'false' evaluated false
| ├-✔ infra-install-external-dns create-infra-l89gx-3052507158 9s
| ├-○ infra-install-fluentd when 'false' evaluated false
| ├-○ infra-install-kibana when 'false' evaluated false
| ├-✔ infra-install-minio create-infra-l89gx-2877376357 19s
| ├-✔ infra-install-mongodb-replicaset create-infra-l89gx-682468434 14s
| ├-✔ infra-install-nginx create-infra-l89gx-2368329705 11s
| ├-✔ infra-install-openresty create-infra-l89gx-465791308 17s
| ├-○ infra-install-prometheus-operator when 'false' evaluated false
| ├-✔ infra-install-rabbitmq create-infra-l89gx-4269141425 23s
| └-✔ infra-install-redis create-infra-l89gx-42796882 6s
└-·-✔ infra-install-argo-rbmq-build create-infra-l89gx-1052447225 6s
├-✔ infra-install-argo-rbmq-consumer create-infra-l89gx-4148577219 15s
├-✔ infra-install-argo-workflow-generator create-infra-l89gx-2290595715 12s
├-✔ infra-install-cache-processor create-infra-l89gx-2554795665 9s
├-✔ infra-install-gateway-middleware create-infra-l89gx-4193299339 18s
├-✔ infra-install-jenkins create-infra-l89gx-2848110700 23s
├-✔ infra-install-loader create-infra-l89gx-1539524629 21s
├-○ infra-install-services-creation when 'false' evaluated false
├-○ infra-install-services-manager when 'false' evaluated false
└-○ infra-install-shutdown-consumer when 'false' evaluated false
{DemoTime}
What's next ?
Argo-CD https://github.com/argoproj/argo-cd
Argo-CI https://github.com/argoproj/argo-ci
Argo-Events https://github.com/argoproj/argo-events
https://kintohub.com
ben@kintohub.com
Argo - Workflow on K8s
By Benjamin
Argo - Workflow on K8s
How, at KintoHub, we are not only using Argo to run all users builds, but we also use it to orchestrate the deployment of all of KintoHub's initial services within our cluster.
- 217