Posted on 

Github webhook call local Argocd server

1. cluster create

to create a k8s cluster by kind tool.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
โžœ  ~ kind create cluster
Creating cluster "kind" ...
โœ“ Ensuring node image (kindest/node:v1.30.0) ๐Ÿ–ผ
โœ“ Preparing nodes ๐Ÿ“ฆ
โœ“ Writing configuration ๐Ÿ“œ
โœ“ Starting control-plane ๐Ÿ•น๏ธ
โœ“ Installing CNI ๐Ÿ”Œ
โœ“ Installing StorageClass ๐Ÿ’พ
Set kubectl context to "kind-kind"
You can now use your cluster with:

kubectl cluster-info --context kind-kind

Not sure what to do next? ๐Ÿ˜… Check out https://kind.sigs.k8s.io/docs/user/quick-start/
โžœ ~ kubectl cluster-info --context kind-kind
Kubernetes control plane is running at https://127.0.0.1:55880
CoreDNS is running at https://127.0.0.1:55880/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

2. deploy ArgoCD

in this section will deploy the argocd by manifests and connect to the argocd server.

  1. to install argocd by manifests
1
2
3
4
5
6
โžœ  ~ kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
namespace/argocd created
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created
  1. change the argocd server to insecure mode

to change the argoCD with insecure mode by kubectl -n argocd edit deploy argocd-server and update the following lines

1
2
- name: ARGOCD_SERVER_INSECURE
value: "true"

check the argocd-server log to see if it is running. the keyworkd is tls: false

1
2
3
4
5
6
7
8
โžœ  ~ kubectl -n argocd logs argocd-server-7b4b4cdff5-xb6b5
time="2024-05-30T06:58:13Z" level=info msg="ArgoCD API Server is starting" built="2024-05-23T13:32:13Z" commit=25f7504ecc198e7d7fdc055fdb83ae50eee5edd0 namespace=argocd port=8080 version=v2.11.2+25f7504
time="2024-05-30T06:58:13Z" level=info msg="Starting configmap/secret informers"
time="2024-05-30T06:58:13Z" level=info msg="Configmap/secret informer synced"
time="2024-05-30T06:58:13Z" level=info msg="invalidated cache for resource in namespace: argocd with the name: argocd-notifications-secret"
time="2024-05-30T06:58:13Z" level=info msg="invalidated cache for resource in namespace: argocd with the name: argocd-notifications-cm"
time="2024-05-30T06:58:13Z" level=info msg="argocd v2.11.2+25f7504 serving on port 8080 (url: , tls: false, namespace: argocd, sso: false)"
time="2024-05-30T06:58:13Z" level=info msg="Enabled application namespace patterns: argocd"
  1. expose argocd k8s service

actually, the argocd server is running in the local k8s cluster, and we can expose the service to the localhost by kubectl port-forward svc/argocd-server -n argocd 8080:80

and if you have a cloud provider, you can change the service type to LoadBalancer by kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

1
2
3
4
5
โžœ  ~ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}' // optional
service/argocd-server patched
โžœ ~ kubectl port-forward svc/argocd-server -n argocd 8080:80
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

3. connect to argocd server

in this section, we will connect to the argocd server by argo cli.

  1. install argo cli
1
โžœ  argocd-example-apps git:(master) โœ— brew install argo
  1. get admin token
1
2
โžœ  argocd-example-apps git:(master) โœ— argocd admin initial-password -n argocd
749BdyGVluul4VYK
  1. connect to argocd server
1
2
3
4
5
6
โžœ  argocd-example-apps git:(master) โœ— argocd login localhost:8080
WARNING: server is not configured with TLS. Proceed (y/n)? y
Username: admin
Password:
'admin:login' logged in successfully
Context 'localhost:8080' updated

4. deploy example apps

install a example app guestbook which fork from argocd-example-apps.

1
2
โžœ  argocd-example-apps git:(master) โœ— argocd app create guestbook --repo https://github.com/sn0rt/argocd-example-apps.git --path guestbook --dest-server https://kubernetes.default.svc --dest-namespace default
application 'guestbook' created

check the application status

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
โžœ  argocd-example-apps git:(master) โœ— argocd app get guestbook
Name: argocd/guestbook
Project: default
Server: https://kubernetes.default.svc
Namespace: default
URL: http://localhost:8080/applications/guestbook
Source:
- Repo: https://github.com/sn0rt/argocd-example-apps.git
Target:
Path: guestbook
SyncWindow: Sync Allowed
Sync Policy: Manual
Sync Status: OutOfSync from (09be403)
Health Status: Missing

GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
Service default guestbook-ui OutOfSync Missing
apps Deployment default guestbook-ui OutOfSync Missing

sync the application

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
โžœ  argocd-example-apps git:(master) โœ— argocd app sync guestbook
TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
2024-05-30T15:06:54+08:00 apps Deployment default guestbook-ui OutOfSync Missing
2024-05-30T15:06:54+08:00 Service default guestbook-ui OutOfSync Missing
2024-05-30T15:06:54+08:00 Service default guestbook-ui OutOfSync Missing service/guestbook-ui created
2024-05-30T15:06:54+08:00 apps Deployment default guestbook-ui OutOfSync Missing deployment.apps/guestbook-ui created
2024-05-30T15:06:54+08:00 Service default guestbook-ui Synced Healthy service/guestbook-ui created
2024-05-30T15:06:54+08:00 apps Deployment default guestbook-ui Synced Progressing deployment.apps/guestbook-ui created

Name: argocd/guestbook
Project: default
Server: https://kubernetes.default.svc
Namespace: default
URL: http://localhost:8080/applications/guestbook
Source:
- Repo: https://github.com/sn0rt/argocd-example-apps.git
Target:
Path: guestbook
SyncWindow: Sync Allowed
Sync Policy: Manual
Sync Status: Synced to (09be403)
Health Status: Progressing

Operation: Sync
Sync Revision: 09be403c29f45e9ce11f4fb268ec7fe214d80ef6
Phase: Succeeded
Start: 2024-05-30 15:06:54 +0800 CST
Finished: 2024-05-30 15:06:54 +0800 CST
Duration: 0s
Message: successfully synced (all tasks run)

GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
Service default guestbook-ui Synced Healthy service/guestbook-ui created
apps Deployment default guestbook-ui Synced Progressing deployment.apps/guestbook-ui created

5. Github webhook

  1. create a Github webhook

my repo is Sn0rt/argocd-example-apps , and it not reachable from the internet, so I use gh to forward the webhook events to my localhost.

1
2
โžœ  argocd-example-apps git:(master) โœ— gh webhook forward --repo=Sn0rt/argocd-example-apps --events=push --url="http://localhost:8080/api/webhook"
Forwarding Webhook events from GitHub...
  1. trigger the webhook
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
โžœ  argocd-example-apps git:(master) โœ— git remote show origin

* remote origin
Fetch URL: git@github.com:Sn0rt/argocd-example-apps.git
Push URL: git@github.com:Sn0rt/argocd-example-apps.git
HEAD branch: master
Remote branch:
master tracked
Local branch configured for 'git pull':
master merges with remote master
Local ref configured for 'git push':
master pushes to master (local out of date)

โžœ argocd-example-apps git:(master) โœ— git diff
diff --git a/guestbook/guestbook-ui-deployment.yaml b/guestbook/guestbook-ui-deployment.yaml
index 8a0975e..956af43 100644
--- a/guestbook/guestbook-ui-deployment.yaml
+++ b/guestbook/guestbook-ui-deployment.yaml
@@ -3,7 +3,7 @@ kind: Deployment
metadata:
name: guestbook-ui
spec:
- replicas: 1
+ replicas: 2
revisionHistoryLimit: 3
selector:
matchLabels:

โžœ argocd-example-apps git:(master) โœ— git add guestbook/guestbook-ui-deployment.yaml
โžœ argocd-example-apps git:(master) โœ— git ci -s -m "update: scale out 2 instances"
[master 1c2ed1b] update: scale out 2 instances
1 file changed, 1 insertion(+), 1 deletion(-)
โžœ argocd-example-apps git:(master) โœ— git push origin -f
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 10 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 418 bytes | 418.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To github.com:Sn0rt/argocd-example-apps.git
d7927a2..1c2ed1b master -> master
  1. inspect the argcd-server log

so.. the conclusion is that the webhook event is received by the argocd-server, and the application is refreshed. and just tell me the application status is OutOfSync and Healthy

1
2
3
time="2024-05-30T07:14:21Z" level=info msg="Received push event repo: https://github.com/Sn0rt/argocd-example-apps, revision: master, touchedHead: true"
time="2024-05-30T07:14:21Z" level=info msg="Requested app 'guestbook' refresh"
time="2024-05-30T07:14:28Z" level=info msg="received streaming call /application.ApplicationService/Watch" grpc.method=Watch grpc.request.claims="{\"exp\":1717139359,\"iat\":1717052959,\"iss\":\"argocd\",\"jti\":\"2ce7ca0b-81e3-463c-a4cd-be02781eb364\",\"nbf\":1717052959,\"sub\":\"admin\"}" grpc.request.content="name:\"guestbook\" appNamespace:\"argocd\" " grpc.service=application.ApplicationService grpc.start_time="2024-05-30T07:14:28Z" span.kind=server system=grpc
  1. check the application status

confirm the application status is OutOfSync and Healthy again.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
โžœ  argocd-example-apps git:(master) โœ— argocd app get guestbook
Name: argocd/guestbook
Project: default
Server: https://kubernetes.default.svc
Namespace: default
URL: http://localhost:8080/applications/guestbook
Source:
- Repo: https://github.com/sn0rt/argocd-example-apps.git
Target:
Path: guestbook
SyncWindow: Sync Allowed
Sync Policy: Manual
Sync Status: OutOfSync from (17b6eb1)
Health Status: Healthy

GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE
Service default guestbook-ui Synced Healthy service/guestbook-ui created
apps Deployment default guestbook-ui OutOfSync Healthy deployment.apps/guestbook-ui created

6. Blue-Green Deployment

in this section, we will deploy a blue-green deployment by argocd and argocd-rollouts.

  1. install argocd-rollouts
1
2
โžœ  kubectl create namespace argo-rollouts
โžœ kubectl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml
  1. install argocd-rollouts plugin

the argocd-rollouts is a plugin for kubectl, and we can install it by brew if you are using macOS.

1
2
3
4
5
6
7
8
9
โžœ  brew install argoproj/tap/kubectl-argo-rollouts
โžœ argocd-example-apps git:(master) โœ— kubectl argo rollouts version
kubectl-argo-rollouts: v1.6.0+7eae71e
BuildDate: 2023-09-06T18:41:21Z
GitCommit: 7eae71ed89f1a3769864435bddebe3ca05384df3
GitTreeState: clean
GoVersion: go1.20.7
Compiler: gc
Platform: darwin/amd64
  1. create a blue-green deployment

in this section, we will create a blue-green deployment by argocd-rollouts and argocd.

first, we need to convert the Deployment to Rollout and update the guestbook-ui-deployment.yaml file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
โžœ  argocd-example-apps git:(master) โœ— git show HEAD~1
...
diff --git a/guestbook/guestbook-ui-deployment.yaml b/guestbook/guestbook-ui-deployment.yaml
index 8a0975e..af7d242 100644
--- a/guestbook/guestbook-ui-deployment.yaml
+++ b/guestbook/guestbook-ui-deployment.yaml
@@ -1,10 +1,21 @@
-apiVersion: apps/v1
-kind: Deployment
+apiVersion: argoproj.io/v1alpha1
+kind: Rollout
metadata:
name: guestbook-ui
spec:
- replicas: 1
- revisionHistoryLimit: 3
+ replicas: 5
+ strategy:
+ canary:
+ steps:
+ - setWeight: 20
+ - pause: {}
+ - setWeight: 40
+ - pause: {duration: 10}
+ - setWeight: 60
+ - pause: {duration: 10}
+ - setWeight: 80
+ - pause: {duration: 10}
+ revisionHistoryLimit: 2
selector:
matchLabels:
app: guestbook-ui
@@ -14,7 +25,9 @@ spec:
app: guestbook-ui
spec:
containers:
- - image: gcr.io/heptio-images/ks-guestbook-demo:0.2
- name: guestbook-ui
- ports:
- - containerPort: 80
+ - name: guestbook-ui
+ image: gcr.io/heptio-images/ks-guestbook-demo:0.1
+ ports:
+ - name: http
+ containerPort: 80
+ protocol: TCP

apply this change to the k8s cluster. and sync the application by argocd

update the guestbook-ui-deployment.yaml file

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
โžœ  argocd-example-apps git:(master) โœ— git show HEAD
...
diff --git a/guestbook/guestbook-ui-deployment.yaml b/guestbook/guestbook-ui-deployment.yaml
index af7d242..db5e23f 100644
--- a/guestbook/guestbook-ui-deployment.yaml
+++ b/guestbook/guestbook-ui-deployment.yaml
@@ -26,7 +26,7 @@ spec:
spec:
containers:
- name: guestbook-ui
- image: gcr.io/heptio-images/ks-guestbook-demo:0.1
+ image: gcr.io/heptio-images/ks-guestbook-demo:0.2
ports:
- name: http
containerPort: 80

and verify the application status

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
โžœ  argocd-example-apps git:(master) โœ— kubectl get rollouts guestbook-ui -o wide
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
guestbook-ui 5 5 1 5 11m
โžœ argocd-example-apps git:(master) โœ— kubectl argo rollouts get rollout guestbook-ui
Name: guestbook-ui
Namespace: default
Status: เฅฅ Paused
Message: CanaryPauseStep
Strategy: Canary
Step: 1/8
SetWeight: 20
ActualWeight: 20
Images: gcr.io/heptio-images/ks-guestbook-demo:0.1 (stable)
gcr.io/heptio-images/ks-guestbook-demo:0.2 (canary)
Replicas:
Desired: 5
Current: 5
Updated: 1
Ready: 5
Available: 5

NAME KIND STATUS AGE INFO
โŸณ guestbook-ui Rollout เฅฅ Paused 11m
โ”œโ”€โ”€# revision:2
โ”‚ โ””โ”€โ”€โง‰ guestbook-ui-648b46976d ReplicaSet โœ” Healthy 9m59s canary
โ”‚ โ””โ”€โ”€โ–ก guestbook-ui-648b46976d-8ct97 Pod โœ” Running 9m58s ready:1/1
โ””โ”€โ”€# revision:1
โ””โ”€โ”€โง‰ guestbook-ui-66545968f ReplicaSet โœ” Healthy 11m stable
โ”œโ”€โ”€โ–ก guestbook-ui-66545968f-26hhh Pod โœ” Running 11m ready:1/1
โ”œโ”€โ”€โ–ก guestbook-ui-66545968f-2bjmx Pod โœ” Running 11m ready:1/1
โ”œโ”€โ”€โ–ก guestbook-ui-66545968f-5s5wl Pod โœ” Running 11m ready:1/1
โ””โ”€โ”€โ–ก guestbook-ui-66545968f-zjvjz Pod โœ” Running 11m ready:1/1

and check the kubernetes service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
โžœ  argocd-example-apps git:(master) โœ— kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
guestbook-ui ClusterIP 10.96.145.162 <none> 80/TCP 144m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 157m
rollouts-demo ClusterIP 10.96.178.254 <none> 80/TCP 68m
โžœ argocd-example-apps git:(master) โœ— kubectl get ep guestbook-ui
NAME ENDPOINTS AGE
guestbook-ui 10.244.0.26:80,10.244.0.27:80,10.244.0.28:80 + 2 more... 144m
โžœ argocd-example-apps git:(master) โœ— kubectl get ep guestbook-ui -o yaml
apiVersion: v1
kind: Endpoints
metadata:
annotations:
endpoints.kubernetes.io/last-change-trigger-time: "2024-05-30T09:21:08Z"
creationTimestamp: "2024-05-30T07:06:54Z"
labels:
app.kubernetes.io/instance: guestbook
name: guestbook-ui
namespace: default
resourceVersion: "18395"
uid: e695b85b-4a10-432b-99b7-c09ff5bec9cd
subsets:
- addresses:
- ip: 10.244.0.26
nodeName: kind-control-plane
targetRef:
kind: Pod
name: guestbook-ui-66545968f-26hhh
namespace: default
uid: 48e72d31-d6ad-4837-988b-99279bab5f3c
...
ports:
- port: 80
protocol: TCP