

Implement GitOps on Kubernetes with ArgoCD and Kustomize
source link: https://rogerwelin.github.io//kubernetes/argocd/gitops/2020/11/20/gitops-using-argocd-and-kustomize.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Implement GitOps on Kubernetes with ArgoCD and Kustomize
Nov 20, 2020
GitOps is a term first coined and popularized at Weaveworks. GitOps can in it’s most concise form be described as a philospohy or a workflow on how infrastructure and application code changes/deployments should be applied to a desired state where Git is the single source of truth. GitOps is not limited to Kubernetes but in the Kubernetes ecosystem we have specialized tools that can easily helps us implement GitOps due to the already declarative nature of Kubernetes manifests.
In this guide we will build a complete GitOps workflow on Kubernetes using ArgoCD as the GitOps engine and orchestrated from Github Actions as the CI part.
What is GitOps and why it matters
The pillars of GitOps are:
- Git is the single source of truth for the desired state of the whole system. By viewing Git one should be able to describe the whole Kubernetes setup
- All changes to the desired state are Git commits. Drift, i.e. changes outside of git, will automatically trigger a convergenece to the desired state described in Git
- Built in observability - we should be able to detect that the desired and observed states are the same or diverged
In Kubernetes two popular GitOps tools are ArgoCD and Flux. Both are installed in Kubernetes and they are configured to watch one or several Git repos storing declarative Kubernetes manifests. Whenever someone pushes changes to that repo the tool will take action to update the cluster accordingly. In other words we are using Kubernetes to update the Kubernetes cluster itself! (think push vs pull)
To be honest when I first read about GitOps I scoffed at it, to my ears it sounded like someone was trying to reinvent CI/CD with a new buzzword. However after working on large Kubernetes environments I can definitely say that GitOps is THE best way to manage Kubernetes objects and application deployments. Here are some arguments why:
- Simplicity - GitOps removes the need for brittle and imperative CD scripts
- Security - by following the principle of least permission we grant the GitOps tool permission to provision objects. The CI system does not need credentials or know to how to apply changes to the Kubernetes environment, all changes are done by PRs in Git
- Discoverability - just by looking at Git one can describe the whole Kubernetes setup and we can use Git as an audit-log on who did what and when
- Standardization - the GitOps workflow describes a standard thus onboarding for both devs and ops is greatly simplified
To sum it up: one of the more difficult things i experience when working with clients are what part of the terraform/cloudformationkubernetes/ansible are actually applied and to which AWS account / k8 cluster. With GitOps that confusion mostly goes away.
Prereqs
With the theory out of the way lets review what prereqs we need to get starting on our GitOps workflow:
- A GitHub account
- A DockerHub account
- kubectl
- A Docker installation (Docker Desktop on Windows and MacOS or appropriate packages on your Linux distribution)
- A running Kubernetes cluster (any flavor works but here I will use Kind)
You can use this Git repo to follow along this guide, easiest way is to just fork it.
GitOps Workflow
With a Go application as a starting point we will use GitHub Actions for the CI part (compiling the application and build a docker image). We will use Kustomize as the tool for managing the Kubernetes manifests and lastly ArgoCD as the GitOps tool to orchestrate our application deployments. The pipeline will look like this:
Compile, build image and push to DockerHub -> Inject new image tag into Kubernets manifest using Kustomize -> Push changes to git repo -> ArgoCD will take over to deploy our application
Kubernetes (Kind) and ArgoCD setup
After installing Kind and kubectl we can boot up our cluster. Use the following configuration when initializing the Kind cluster (or just use the kind-config.yaml provided in the repo):
kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: node-labels: "ingress-ready=true" extraPortMappings: - containerPort: 80 hostPort: 80 protocol: TCP - containerPort: 443 hostPort: 443 protocol: TCP
Now we can set up Kind, Ingress and ArgoCD with these commands:
$ kind create cluster --config kind-config.yaml
# install the Nginx ingress
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/kind/deploy.yaml
# install ArgoCD
$ kubectl create namespace argocd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# use port-forwarding to access the ArgoCD UI
$ kubectl port-forward --address 0.0.0.0 svc/argocd-server -n argocd 8080:443
# get the admin password
$ kubectl get pods -n argocd -l app.kubernetes.io/name=argocd-server -o name | cut -d'/' -f 2
Head over to localhost:8080 and login with admin and password from the last command. We’ll come back to Argo UI in a bit but first lets talk about the Go application and it’s k8 manifests which will be handled by Kustomize
Go Application and k8 manifests
Our Go application is fairly simplistic, I’ve left out the imports and the main function. As we can see below we have two http endpoints, the root endpoint (helloArgo) will output a json response with the commit id the application was built on. For that we’re using the Version variable, in the compilation step we’ll inject the git hash so “dev” is just a placeholder.
var Version = "dev"
type Message struct { Msg string `json:"msg"` Version string `json:"version"` }
func pingHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) fmt.Fprintf(w, "pong") }
func helloArgo(w http.ResponseWriter, r *http.Request) { msg := &Message{Msg: "Hello ArgoCD!", Version: Version} out, err := json.Marshal(msg) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(200) w.Write(out) }
The Dockerfile is fairly basic (see below). It’s a multistage build, where we’ll compile the source code in one container and transfer it to a tiny scratch image.
FROM golang:1.14 as build ARG version WORKDIR /build COPY . . RUN CGO_ENABLED=0 go build -ldflags "-X main.Version=$version"
FROM scratch WORKDIR /app EXPOSE 8080 COPY --from=build /build/hello-argocd-app . CMD ["./hello-argocd-app"]
Kustomize blabla
kustomize/
├── base
│ ├── deployment.yaml
│ ├── ingress.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── envs
├── dev
│ ├── deployment-patch.yaml
│ └── kustomization.yaml
└── test
├── deployment-patch.yaml
└── kustomization.yaml
Sync ArgoCD with our Git repo
Github Actions pipeline
Conclusion
Recommend
-
81
README.md kustomize kustomize lets you customize raw, template-free YAML files for multiple purposes, leaving the original YAML untouched and usable as is. kustomize
-
33
Jan 29, 2019 by Abraham Ingersoll Frustration over Helm vs Kustomize and Kubernetes development maturity Unless you binge watch Kubernetes’ utopian distributed systems Truman Show, you may have miss...
-
100
作者:Jeff Regan (Google), Phil Wittrock (Google) 2018-05-29 如果你在运行 kubernetes 集群,你可能会拷贝一些包含 kubernetes API 对象的 YAML 文件,并且根据你的需求来修改这些文件,通过这些 YAML 文件来定义你的 kubern...
-
29
Estimated read time: 11 minutes :gb: Article in English We always need to customize our deployment with Kubernetes and, I don’...
-
59
In an ideal world you wouldn't have to perform multiple steps for the rendering, but unfortunately we don't live in an ideal world... Kustomize Nowadays, most applications that are meant to be deploy...
-
6
: 10人将获赠CNCF士多$100礼券!
-
10
GitOps with ArgoCD and Hashicorp Vault on kubernetesLast month I was picking my brain about GitOps and how this model fits with other kubernetes technologies like operators and backups. I decided to give it a try with ArgoCD. I creat...
-
31
Since few weeks now, the operator Red Hat OpenShift GitOps became GA and embbed tools like Tekton and ArgoCD. When the operator is deployed, it provisions a vanilla ArgoCD which miss the OpenShift integrated login. In this post, we ar...
-
6
GitOps总结与实践 GitOps 什么是GitOps GitOps是Weaveworks公司于2017年首创的一种进行Kubernetes集群管理和应用交付的方式。GitOps通过使用Git作为声明性基础设施和应用程序的...
-
9
Argo CD 是一款基于 kubernetes 的声明式的Gitops 持续部署工具。 应用程序定义、配置和环境都是声明式的,并受版本控制 应用程序部署和生命周期管理都是...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK