In previous articles we talked about installing a k3s cluster, using Longhorn for resilient storage, using MetalLB for load-balancing and managing certificates with Cert-Manager. In this article we will set up continuous deployment using ArgoCD. Then we can start deploying workloads on our cluster. Now, full disclosure, this is not absolutely necessary, you can deploy using kubectl or helm, but that’s no way to live your life.
ArgoCD id a GitOps tool. The main advantage to using ArgoCD (or its alternative FluxCD for that matter) is that you can take a hands-off approach to your deployments. You commit the definition of your service to git and Argo makes sure any changes made to those definitions are reflected in the cluster. You just commit the changes to git, Argo takes care of everything else.
Setup
Alright, let’s get it installed. This is a fairly straightforward process.
First, create the namespace:
$ kubectl create namespace argocd
Then create all the resources:
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
It’s possible you might run into the error below:
The CustomResourceDefinition "applicationsets.argoproj.io" is invalid: metadata.annotations: Too long: may not be more than 262144 bytes
If you do, you should use the --server-side option:
$ kubectl apply --server-side -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Updating
If/when you’re updating Argo, you’ll probably run into this error:
Apply failed with 1 conflict: conflict with "kubectl-client-side-apply" using apps/v1: .spec.template.spec.containers[name="argocd-applicationset-controller"].env[name="NAMESPACE"].valueFrom.fieldRef
You have to run the command using the --force-conflicts flag:
$ kubectl apply --server-side --force-conflicts -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Accessing Argo
You can, of course, access the interface by creating a local port-forward:
$ kubectl port-forward -n argocd svc/argocd-server 8080:80
Then open http://localhost:8080 in a browser.
But, having installed MetalLB and Cert-Manager, we are now ready to do something better. We will use an ingress to access it.
I’ll go through the steps needed to set up a subdomain that points to Argo, but I won’t go into too much detail since this is highly on each person’s setup, or desired setup. What you can do is create a DNS record for the subdomain in your DNS provider (Cloudflare or whatever). Unless you absolutely need to, you don’t have to make this service public, so you can point the DNS record to the private IP of the Traefik ingress. If this sounds unfamiliar, you can follow this article.
Now you can create Argo’s ingress. Create a file named ingress.yml with this content:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-ingress
namespace: argocd
annotations:
cert-manager.io/cluster-issuer: letsencrypt-dns
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
rules:
- host: argocd.k3s.alexmihai.rocks
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80
tls:
- hosts:
- argocd.k3s.alexmihai.rocks
secretName: argocd-k3s-tls
Apply it to the cluster:
$ kubectl apply -f ingress.yml
Disable internal HTTPS redirect
When you try to point your browser to the subdomain at this point, you will hit a ERR_TOO_MANY_REDIRECTS error. This happens because the traffic hits the Argo service on the HTTP port (80). Internally, Argo attempts to redirect to HTTPS by default and so the process starts all over again.
What we need to do is to disable Argo’s internal redirect and let this be handled externally.
To do that, edit the argocd-cmd-params-cm config map from the argocd namespace. Preferably you use some client like Lens for this, or you can run:
$ kubectl edit cm argocd-cmd-params-cm -n argocd
Add data.insecure: 'true' in the data section, which, if not present, you can add. Your config map would look something like this:
apiVersion: v1
kind: ConfigMap
metadata:
...
spec: {}
data:
server.insecure: 'true'
Now restart the service:
$ kubectl rollout restart deployment argocd-server -n argocd
You should now be able to access Argo’s UI. The default user is admin. The password is randomized and located in a k8s secret, in order to retrieve it you need to run:
$ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
Hope this helps, have fun clickity-clacking.
Leave a Reply