|
| 1 | +--- |
| 2 | +title: "Bring GitOps to your OpenFaaS functions with ArgoCD" |
| 3 | +description: "In this post you'll learn how to manage OpenFaaS functions based on GitOps principles by using ArgoCD" |
| 4 | +date: 2021-04-15 |
| 5 | +image: /images/2021-04-08-bring-gitops-to-your-openfaas-functions-with-argocd/argo-horizontal.jpg |
| 6 | +categories: |
| 7 | +- arkade |
| 8 | +- kubectl |
| 9 | +- argocd |
| 10 | +- gitops |
| 11 | +- openfaas-operator |
| 12 | +- helm |
| 13 | +author_staff_member: developer-guy |
| 14 | +dark_background: true |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +In this post you'll learn how to manage OpenFaaS functions based on GitOps principles by using ArgoCD |
| 19 | + |
| 20 | +## What is GitOps? |
| 21 | + |
| 22 | +[Alexis Richardson](https://twitter.com/monadic) coined the term _GitOps_ in 2017. Since then it's gained significant interest in the enterprise companies because it allows for easier auditing of deployments. |
| 23 | + |
| 24 | +With a GitOps approach, build artifacts from your Continuous Integration (CI) pipeline are deployed to your cluster. The desired state is set in a number of configuration files in a Git repository, and a second agent component runs inside the cluster to compare the delta. The differences are known as drift, and the agent's role is to detect and correct it. |
| 25 | + |
| 26 | + |
| 27 | + |
| 28 | +> From [Weaveworks.com](https://www.weave.works/technologies/gitops/) |
| 29 | +
|
| 30 | +> In the diagram above, we can see that GitOps separates our code repository, where our teams push and test code, from the repo containing deployment information, aka "config repo". When new images or artifacts are created, the tags and versions in the config repo can be updated automatically or via a separate commit from a team member. |
| 31 | +
|
| 32 | +Two of the most popular open-source projects for GitOps are [Flux](https://fluxcd.io/), which was created at Weaveworks. Intuit, an American payroll company created [ArgoCD](https://argoproj.github.io/argo-cd/). Both projects were donated to the Cloud Computing Foundation (CNCF) to encourage broader use and contributions. |
| 33 | + |
| 34 | +We have [previously looked at FluxCD with OpenFaaS](https://www.openfaas.com/blog/openfaas-flux/), but in this post we'll show how to use ArgoCD with the OpenFaaS Function CRD to continuously deploy your functions. |
| 35 | + |
| 36 | +You can read more about ArgoCD on the [project homepage](https://argoproj.github.io/argo-cd/). |
| 37 | + |
| 38 | +## Introducing the OpenFaaS Operator |
| 39 | + |
| 40 | +The normal installation of OpenFaaS uses its REST API to create functions using the CLI, REST API or UI. It also has a mode called "operator mode" where a Custom Resource can be used with `kubectl` to apply and deploy functions. |
| 41 | + |
| 42 | +```yaml |
| 43 | +apiVersion: openfaas.com/v1 |
| 44 | +kind: Function |
| 45 | +metadata: |
| 46 | + name: nodeinfo |
| 47 | + namespace: openfaas-fn |
| 48 | +spec: |
| 49 | + name: nodeinfo |
| 50 | + image: functions/nodeinfo:latest |
| 51 | +``` |
| 52 | +
|
| 53 | +The `faas-cli generate` command can be used to convert the OpenFaaS stack.yml file into the Function CustomResource for use with `kubectl`. |
| 54 | + |
| 55 | +The _OpenFaaS Operator_ comes with an extension to the Kubernetes API that allows you to manage OpenFaaS functions in a |
| 56 | +declarative manner. The operator implements a control loop that tries to match the desired state of your OpenFaaS |
| 57 | +functions, defined as a collection of custom resources, with the actual state of your cluster. |
| 58 | + |
| 59 | +To get more detail please refer to this [link](https://blog.alexellis.io/introducing-the-openfaas-operator/). |
| 60 | + |
| 61 | +## Tutorial |
| 62 | + |
| 63 | +In this section, we are going to create two application for ArgoCD, first one is OpenFaaS Operator, the second one is the repository that holds OpenFaaS functions manifest files. |
| 64 | + |
| 65 | +ArgoCD can work against Kubernetes manifests in a various ways: |
| 66 | + |
| 67 | +* kustomize applications |
| 68 | +* helm charts |
| 69 | +* ksonnet applications |
| 70 | +* jsonnet files |
| 71 | +* Plain directory of YAML/json manifests |
| 72 | +* Any custom config management tool configured as a config management plugin |
| 73 | + |
| 74 | +So, we are going to use the OpenFaaS [Helm Chart](https://github.com/openfaas/faas-netes) to deploy OpenFaaS and ist Operator. Once OpenFaaS Operator is deployed, we can use the _Custom Resource_ called _"Function"_ in order to define our OpenFaaS functions like any other Kubernetes resources such as Deployment, Pod etc. |
| 75 | + |
| 76 | +In the second part, we'll to use plain manifests to deploy OpenFaaS functions. A dedicated chart can also be created for deploying functions. |
| 77 | + |
| 78 | +### Prerequisites |
| 79 | + |
| 80 | +Once we have arkade, we can create a cluster and install ArgoCD. If you prefer, you can also manually download all the tools required, and find the instructions for ArgoCD's helm chart. |
| 81 | + |
| 82 | + * [arkade](https://get-arkade.dev) (v0.7.10) Kubernetes marketplace |
| 83 | + |
| 84 | + ```bash |
| 85 | + # Run with or without sudo |
| 86 | + $ curl -sLS https://dl.get-arkade.dev | sudo sh |
| 87 | + ``` |
| 88 | + |
| 89 | +* KinD (Kubernetes in Docker) v0.10.0 |
| 90 | + |
| 91 | + Kubernetes is our recommendation for teams running at scale, but in this demo we will be |
| 92 | + using [KinD](https://kind.sigs.k8s.io/docs/user/quick-start/) for the sake of simplicity. |
| 93 | + |
| 94 | + ```bash |
| 95 | + $ arkade get kind --version=v0.10.0 |
| 96 | + ``` |
| 97 | + |
| 98 | +* kubectl v1.21.0 |
| 99 | + |
| 100 | + You can control your cluster using [kubectl](https://github.com/kubernetes/kubectl) CLI. |
| 101 | + |
| 102 | + ```bash |
| 103 | + $ arkade get kubectl --version=v1.21.0 |
| 104 | + ``` |
| 105 | + |
| 106 | +* ArgoCD CLI v2.0.0 |
| 107 | + |
| 108 | + ArgoCD CLI controls an Argo CD server. More detailed installation instructions can be found via |
| 109 | + the [CLI installation documentation](https://argoproj.github.io/argo-cd/cli_installation/). Fortunately, we can |
| 110 | + install it via arkade too. |
| 111 | + |
| 112 | + ```bash |
| 113 | + $ arkade get argocd --version=v2.0.0 |
| 114 | + ``` |
| 115 | + |
| 116 | +### Setup |
| 117 | + |
| 118 | +### 1. Provision a local Kubernetes Cluster with KinD |
| 119 | + |
| 120 | +You can start a Kubernetes cluster with KinD if you don't have one already. |
| 121 | + |
| 122 | +```bash |
| 123 | +$ kind create cluster |
| 124 | +``` |
| 125 | + |
| 126 | +Verify if your cluster working properly before moving onto the next step. |
| 127 | + |
| 128 | +```bash |
| 129 | +$ kubectl cluster-info |
| 130 | +Kubernetes control plane is running at https://127.0.0.1:49809 |
| 131 | +KubeDNS is running at https://127.0.0.1:49809/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy |
| 132 | +
|
| 133 | +To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. |
| 134 | +``` |
| 135 | + |
| 136 | +### 2. Deploy ArgoCD |
| 137 | + |
| 138 | +There are various ways to install ArgoCD, one of them is _ArgoCD Operator_, and the other one is just with plain YAML |
| 139 | +manifest. We are going to deploy ArgoCD with plain YAML manifest in this section. |
| 140 | + |
| 141 | +arkade is not only for the CLI tooling, it also helps you to get started to install applications using helm under the hood, |
| 142 | +hopefully arkade also supports installing ArgoCD. |
| 143 | + |
| 144 | +```bash |
| 145 | +$ kubectl create namespace argocd |
| 146 | +$ arkade install argocd |
| 147 | +``` |
| 148 | + |
| 149 | +Verify if everything is working properly in _argocd_ namespace before moving onto the next step. |
| 150 | + |
| 151 | +```bash |
| 152 | +$ kubectl get pods --namespace argocd |
| 153 | +NAME READY STATUS RESTARTS AGE |
| 154 | +argocd-application-controller-0 1/1 Running 0 86s |
| 155 | +argocd-dex-server-5dd657bd9-zkhb8 1/1 Running 0 86s |
| 156 | +argocd-redis-759b6bc7f4-92l4b 1/1 Running 0 86s |
| 157 | +argocd-repo-server-6c495f858f-rx8hh 1/1 Running 0 86s |
| 158 | +argocd-server-859b4b5578-sczvk 1/1 Running 0 86s |
| 159 | +``` |
| 160 | + |
| 161 | +### 3. Deploy OpenFaaS Operator and OpenFaaS functions through ArgoCD |
| 162 | + |
| 163 | +There are two ways of defining applications to ArgoCD, one of them is by using CLI, the other one is by using CRDs. We |
| 164 | +are going to demonstrate both of them in here. |
| 165 | + |
| 166 | +#### Option 1: by using CLI |
| 167 | + |
| 168 | +First, we need to authenticate to ArgoCD server.Argo CD v1.9. Later the initial password for the admin account is |
| 169 | +auto-generated and stored as clear text in the field password in a secret named argocd-initial-admin-secret in your Argo |
| 170 | +CD installation namespace. |
| 171 | + |
| 172 | +You can simply retrieve this password using kubectl: |
| 173 | + |
| 174 | +```bash |
| 175 | +$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo |
| 176 | +SyudUgAtDobmgSjM |
| 177 | +``` |
| 178 | + |
| 179 | +Because ArgoCD Server is running on a Kubernetes, we should do port-forwarding first in order to access the server, it |
| 180 | +can be achieved by the following command easily: |
| 181 | + |
| 182 | +```bash |
| 183 | +$ kubectl port-forward svc/argocd-server -n argocd 8080:443 |
| 184 | +Forwarding from 127.0.0.1:8080 -> 8080 |
| 185 | +Forwarding from [::1]:8080 -> 8080 |
| 186 | +``` |
| 187 | + |
| 188 | +After that, by using the username _admin_ and the password from above, lets log into ArgoCD: |
| 189 | + |
| 190 | +```bash |
| 191 | +$ argocd login --name local localhost:8080 |
| 192 | +WARNING: server certificate had error: x509: certificate signed by unknown authority. Proceed insecurely (y/n)? y |
| 193 | +Username: admin |
| 194 | +Password: |
| 195 | +'admin:login' logged in successfully |
| 196 | +Context 'local' updated |
| 197 | +``` |
| 198 | + |
| 199 | +To get more detail about login process, please refer to |
| 200 | +this [link](https://argoproj.github.io/argo-cd/getting_started/#4-login-using-the-cli). |
| 201 | + |
| 202 | +Verify if you log into ArgoCD properly before moving on the next step. |
| 203 | + |
| 204 | +```bash |
| 205 | +$ argocd account list |
| 206 | +NAME ENABLED CAPABILITIES |
| 207 | +admin true login |
| 208 | +
|
| 209 | +$ argocd app list |
| 210 | +NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET |
| 211 | +
|
| 212 | +``` |
| 213 | + |
| 214 | +After you logged into ArgoCD, lets create our applications. |
| 215 | + |
| 216 | +```bash |
| 217 | +$ kubectl create namespace openfaas |
| 218 | +namespace/openfaas created |
| 219 | +
|
| 220 | +$ kubectl create namespace openfaas-fn |
| 221 | +namespace/openfaas-fn created |
| 222 | +
|
| 223 | +$ argocd app create openfaas-operator \ |
| 224 | + --repo https://github.com/openfaas/faas-netes.git \ |
| 225 | + --dest-namespace openfaas \ |
| 226 | + --dest-server https://kubernetes.default.svc \ |
| 227 | + --path chart/openfaas \ |
| 228 | + --helm-set operator.create=true \ |
| 229 | + --helm-set generateBasicAuth=true \ |
| 230 | + --helm-set functionNamespace=openfaas-fn \ |
| 231 | + --self-heal \ |
| 232 | + --sync-policy automatic |
| 233 | +application 'openfaas-operator' created |
| 234 | +``` |
| 235 | + |
| 236 | +> When deploying internally (to the same cluster that Argo CD is running in), https://kubernetes.default.svc should be used as the application's K8s API server address. To get more detail about registering another cluster to deploy apps to, please refer to this [link](https://argoproj.github.io/argo-cd/getting_started/#5-register-a-cluster-to-deploy-apps-to-optional). |
| 237 | + |
| 238 | +Verify if everything is working before moving onto the next step. |
| 239 | + |
| 240 | +First, check the application status: |
| 241 | + |
| 242 | +```bash |
| 243 | +$ argocd app list -o wide |
| 244 | +NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET |
| 245 | +openfaas-operator https://kubernetes.default.svc openfaas default Synced Healthy Auto <none> https://github.com/openfaas/faas-netes.git chart/openfaas |
| 246 | +``` |
| 247 | + |
| 248 | +Then, check the _openfaas_ namespace for the installation: |
| 249 | + |
| 250 | +```bash |
| 251 | +$ kubectl get pods --namespace openfaas |
| 252 | +NAME READY STATUS RESTARTS AGE |
| 253 | +alertmanager-84d7b88f74-kt7jg 1/1 Running 0 4m6s |
| 254 | +basic-auth-plugin-85d885557c-cgz4j 1/1 Running 0 4m6s |
| 255 | +gateway-764b7b4865-p4rk8 2/2 Running 1 4m6s |
| 256 | +nats-5fdf6476f-pmftg 1/1 Running 0 4m6s |
| 257 | +prometheus-844fffb-5rkc7 1/1 Running 0 4m6s |
| 258 | +queue-worker-7cbc9f8688-qfww6 1/1 Running 0 4m6s |
| 259 | +``` |
| 260 | + |
| 261 | +Before deploying OpenFaaS functions as custom resources, check the available CRDs on the Kubernetes, you should see the |
| 262 | +list like the following: |
| 263 | + |
| 264 | +```bash |
| 265 | +$ kubectl get customresourcedefinitions.apiextensions.k8s.io |
| 266 | +NAME CREATED AT |
| 267 | +applications.argoproj.io 2021-04-09T09:33:59Z |
| 268 | +appprojects.argoproj.io 2021-04-09T09:33:59Z |
| 269 | +functions.openfaas.com 2021-04-09T10:43:03Z |
| 270 | +profiles.openfaas.com 2021-04-09T10:43:03Z |
| 271 | +``` |
| 272 | + |
| 273 | +If you see the same output above, it means you are now ready to deploy OpenFaaS functions. |
| 274 | + |
| 275 | +I prepared a repository that holds the function definitions, so, before running the following code, don't forget to fork |
| 276 | +your own copy of this repository and give it to _"--repo"_ flag. |
| 277 | + |
| 278 | +```bash |
| 279 | +$ argocd app create openfaas-functions \ |
| 280 | + --repo https://github.com/developer-guy/bring-gitops-to-your-openfaas-functions-with-argocd.git \ |
| 281 | + --dest-server https://kubernetes.default.svc \ |
| 282 | + --path functions \ |
| 283 | + --self-heal \ |
| 284 | + --sync-policy automatic |
| 285 | +application 'openfaas-functions' created |
| 286 | +``` |
| 287 | + |
| 288 | +Verify if everything is working before moving onto the next step. |
| 289 | + |
| 290 | +First, check the application status, now, you should see two applications: |
| 291 | + |
| 292 | +```bash |
| 293 | +$ argocd app list -o wide |
| 294 | +NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET |
| 295 | +openfaas-functions https://kubernetes.default.svc default Synced Healthy Auto <none> https://github.com/developer-guy/bring-gitops-to-your-openfaas-functions-with-argocd.git functions |
| 296 | +openfaas-operator https://kubernetes.default.svc openfaas default Synced Healthy Auto <none> https://github.com/openfaas/faas-netes.git |
| 297 | +``` |
| 298 | + |
| 299 | +Then, check the _openfaas-fn_ namespace for the installation: |
| 300 | + |
| 301 | +```bash |
| 302 | +$ kubectl get functions --namespace openfaas-fn |
| 303 | +NAME AGE |
| 304 | +nodeinfo 35s |
| 305 | +``` |
| 306 | + |
| 307 | +Verify if it is working. |
| 308 | + |
| 309 | +``` |
| 310 | +$ kubectl get pods --namespace openfaas-fn |
| 311 | +NAME READY STATUS RESTARTS AGE |
| 312 | +nodeinfo-6d5434f4744-l6kfd 1/1 Running 0 2m6s |
| 313 | +``` |
| 314 | +
|
| 315 | +#### Option 2: by using CRDs |
| 316 | +
|
| 317 | +We are going to apply _**apps-of-apps**_ pattern in here, which means we can create an app that creates other apps, |
| 318 | +which in turn can create other apps. This allows you to declaratively manage a group of app that can be deployed and |
| 319 | +configured in concert. In order to do that, we create an _apps-of-apps.yaml_ in the repository and within this manifest |
| 320 | +we refer to the exact path which holds the actual application manifests. |
| 321 | +
|
| 322 | +To get more detail about _**apps-of-apps**_ pattern, please refer to |
| 323 | +this [link](https://argoproj.github.io/argo-cd/operator-manual/declarative-setup/#app-of-apps). |
| 324 | +
|
| 325 | +Lets deploy the applications. |
| 326 | +
|
| 327 | +```bash |
| 328 | +$ kubectl create namespace openfaas |
| 329 | +namespace/openfaas created |
| 330 | +
|
| 331 | +$ kubectl create namespace openfaas-fn |
| 332 | +namespace/openfaas-fn created |
| 333 | +
|
| 334 | +$ argocd app create apps-of-apps \ |
| 335 | + --repo https://github.com/developer-guy/bring-gitops-to-your-openfaas-functions-with-argocd.git \ |
| 336 | + --dest-server https://kubernetes.default.svc \ |
| 337 | + --path . \ |
| 338 | + --self-heal \ |
| 339 | + --sync-policy automatic |
| 340 | +application 'apps-of-apps' created |
| 341 | +``` |
| 342 | + |
| 343 | +We just created one application called _apps-of-apps_ in here, but if you look at the output of the _list_ command, you |
| 344 | +should see three application: |
| 345 | + |
| 346 | +```bash |
| 347 | +$ argocd app list |
| 348 | +NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET |
| 349 | +apps-of-apps https://kubernetes.default.svc default OutOfSync Healthy Auto <none> https://github.com/developer-guy/bring-gitops-to-your-openfaas-functions-with-argocd.git applications |
| 350 | +openfaas-functions https://kubernetes.default.svc default Synced Healthy Auto <none> https://github.com/developer-guy/bring-gitops-to-your-openfaas-functions-with-argocd.git functions |
| 351 | +openfaas-operator https://kubernetes.default.svc openfaas default OutOfSync Missing Auto <none> https://github.com/openfaas/faas-netes.git chart/openfaas |
| 352 | +``` |
| 353 | + |
| 354 | +Verify if everything is working. |
| 355 | + |
| 356 | +```bash |
| 357 | +$ kubectl get functions --namespace openfaas-fn |
| 358 | +NAME AGE |
| 359 | +nodeinfo 35s |
| 360 | + |
| 361 | +$ kubectl get pods --namespace openfaas-fn |
| 362 | +NAME READY STATUS RESTARTS AGE |
| 363 | +nodeinfo-7c564f4744-l6kfd 1/1 Running 0 101s |
| 364 | +``` |
| 365 | + |
| 366 | +### Taking it further |
| 367 | + |
| 368 | +### Join the community |
| 369 | + |
| 370 | +Have you got questions, comments, or suggestions? Join the community on [Slack](https://slack.openfaas.io). |
| 371 | + |
| 372 | +Would you like help to set up your OpenFaaS installation, or someone to call when things don't quite go to |
| 373 | +plan? [Our OpenFaaS PRO Subscription plan](https://www.openfaas.com/support/) gives you a say in the project roadmap, a |
| 374 | +support contact, and access to Enterprise-grade authentication with OIDC. |
| 375 | + |
| 376 | +### Acknowledgements |
| 377 | + |
| 378 | +* Special Thanks to [Alex Ellis](https://twitter.com/alexellisuk) for all guidance and for merging changes into OpenFaaS to better support this workflow. |
| 379 | +* Special Thanks to [Furkan Türkal](https://twitter.com/furkanturkaI) for all the support. |
| 380 | + |
| 381 | +### References |
| 382 | + |
| 383 | +* [Argo CD - Declarative GitOps CD for Kubernetes](https://argoproj.github.io/argo-cd/getting_started) |
| 384 | +* [Getting Started with the OpenFaaS Kubernetes Operator](https://dzone.com/articles/getting-started-with-the-openfaas-kubernetes-opera) |
| 385 | +* [Weaveworks' Guide To GitOps](https://www.weave.works/technologies/gitops/) |
| 386 | +* [GitOps](https://www.gitops.tech) |
0 commit comments