Argo CD Installation #
Create Namespace #
# Create a Kubernetes namespace named "argocd" for Argo CD installation
kubectl create namespace argocd
Install Argo CD #
# Deploy Argo CD in the "argocd" namespace
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
Verify Installation / Resources #
# List the Argo CD resources
kubectl get all -n argocd
Shell Output:
# Shell output:
NAME READY STATUS RESTARTS AGE
pod/argocd-application-controller-0 1/1 Running 0 95s
pod/argocd-applicationset-controller-5ccbf46fd8-9q86h 1/1 Running 0 95s
pod/argocd-dex-server-7b6b9b5cb7-njbv9 1/1 Running 2 (36s ago) 95s
pod/argocd-notifications-controller-5b9566d4c7-xml75 1/1 Running 0 95s
pod/argocd-redis-665dd47d9b-zbl9m 1/1 Running 0 95s
pod/argocd-repo-server-fc97bfb4d-mqcb2 1/1 Running 0 95s
pod/argocd-server-69754c4fb-v22hk 1/1 Running 0 95s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/argocd-applicationset-controller ClusterIP 10.98.75.52 <none> 7000/TCP,8080/TCP 95s
service/argocd-dex-server ClusterIP 10.106.123.125 <none> 5556/TCP,5557/TCP,5558/TCP 95s
service/argocd-metrics ClusterIP 10.105.206.145 <none> 8082/TCP 95s
service/argocd-notifications-controller-metrics ClusterIP 10.111.191.232 <none> 9001/TCP 95s
service/argocd-redis ClusterIP 10.99.233.254 <none> 6379/TCP 95s
service/argocd-repo-server ClusterIP 10.106.212.7 <none> 8081/TCP,8084/TCP 95s
service/argocd-server ClusterIP 10.108.205.157 <none> 80/TCP,443/TCP 95s
service/argocd-server-metrics ClusterIP 10.98.216.166 <none> 8083/TCP 95s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/argocd-applicationset-controller 1/1 1 1 95s
deployment.apps/argocd-dex-server 1/1 1 1 95s
deployment.apps/argocd-notifications-controller 1/1 1 1 95s
deployment.apps/argocd-redis 1/1 1 1 95s
deployment.apps/argocd-repo-server 1/1 1 1 95s
deployment.apps/argocd-server 1/1 1 1 95s
NAME DESIRED CURRENT READY AGE
replicaset.apps/argocd-applicationset-controller-5ccbf46fd8 1 1 1 95s
replicaset.apps/argocd-dex-server-7b6b9b5cb7 1 1 1 95s
replicaset.apps/argocd-notifications-controller-5b9566d4c7 1 1 1 95s
replicaset.apps/argocd-redis-665dd47d9b 1 1 1 95s
replicaset.apps/argocd-repo-server-fc97bfb4d 1 1 1 95s
replicaset.apps/argocd-server-69754c4fb 1 1 1 95s
NAME READY AGE
statefulset.apps/argocd-application-controller 1/1 95s
Adapt Argo CD Service #
Convert ClusterIP to LoadBalancer Service #
# Change the Argo CD Service service to type LoadBalancer
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
Verify Service Details #
# List Argo CD serivce details
kubectl describe service argocd-server -n argocd
Shell Output:
# Shell output:
Name: argocd-server
Namespace: argocd
Labels: app.kubernetes.io/component=server
app.kubernetes.io/name=argocd-server
app.kubernetes.io/part-of=argocd
Annotations: metallb.universe.tf/ip-allocated-from-pool: main-pool
Selector: app.kubernetes.io/name=argocd-server
Type: LoadBalancer # Check!
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.108.205.157
IPs: 10.108.205.157
LoadBalancer Ingress: 192.168.30.201
Port: http 80/TCP
TargetPort: 8080/TCP
NodePort: http 32430/TCP
Endpoints: 10.0.1.226:8080
Port: https 443/TCP
TargetPort: 8080/TCP
NodePort: https 30980/TCP
Endpoints: 10.0.1.226:8080
Session Affinity: None
External Traffic Policy: Cluster
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal IPAllocated 6s metallb-controller Assigned IP ["192.168.30.201"]
Normal nodeAssigned 6s metallb-speaker announcing from node "ubuntu4" with protocol "layer2"
Custom TLS Certificate Secret #
Update the default self-signed TLS certificate with a custom TLS certificate:
# Update the TLS Kubernetes secret
kubectl create -n argocd secret tls argocd-server-tls \
--cert=fullchain.pem \
--key=privkey.pem
Argo CD Webinterface #
DNS Entry #
To access the Argo CD webinterface from your host, create a DNS entry that points to the external IP provided by the LoadBalancer service:
# Create a DNS entry
192.168.30.201 argocd.jklug.work
Access Webinterface #
# Access the webinterface: Via LoadBalancer service
https://argocd.jklug.work
Initial Admin Password #
# Default user
admin
# Retrieve "admin" password
kubectl get secret argocd-initial-admin-secret -n argocd -o jsonpath="{.data.password}" | base64 --decode; echo
# Shell output:
jchy00fSWDPqA375
Delete the Kubernetes secret after the password was retrieved:
# Delete the "argocd-initial-admin-secret" secret
kubectl delete secret argocd-initial-admin-secret
Argo CD CLI Installation #
In this example, I’m installing the Argo CD CLI on my Kubernetes Controller node.
Install Argo CD CLI #
Find the latest stable release:
https://github.com/argoproj/argo-cd/tags
Install Argo CD CLI:
# Download Argo CD binary (This takes a while)
curl -SL --progress-bar -o argocd https://github.com/argoproj/argo-cd/releases/download/v2.12.7/argocd-linux-amd64
# Change permissions
chmod +x argocd
# Move the binary
sudo mv argocd /usr/local/bin/
# Verify the installation / check version
argocd version
# Shell output:
argocd: v2.12.7+4d70c51
BuildDate: 2024-11-05T15:52:38Z
GitCommit: 4d70c51e64e534ffe656c45317037b2bcdaa69f9
GitTreeState: clean
GoVersion: go1.22.8
Compiler: gc
Platform: linux/amd64
FATA[0000] Argo CD server address unspecified
Argo CD CLI Configuration #
Argo CD DNS Entry #
Make sure the host where the Argo CD CLI is deploy can resolve the DNS name of the Argo CD server and of GitLab:
# Add DNS entry to /etc/hosts
sudo tee -a /etc/hosts <<EOF
192.168.30.201 argocd.jklug.work
192.168.70.4 gitlab.jklug.work gitlab-registry.jklug.work
EOF
Login & Set Argo CD Server Address #
# Set the the Argo CD server address
argocd login argocd.jklug.work
# Shell output:
Username: admin # Enter default admin user
Password: jchy00fSWDPqA375 # Enter the admin pw
'admin:login' logged in successfully
Context 'argocd.jklug.work' updated
GitLab DNS Entry #
Add DNS Entry #
Add DNS entries for GitLab & the GitLab registry to the Kubernetes cluster nodes:
# Add DNS entry to /etc/hosts
sudo tee -a /etc/hosts <<EOF
192.168.70.4 gitlab.jklug.work
192.168.70.4 gitlab-registry.jklug.work
EOF
CoreDNS ConfigMap #
Backup the ConfigMap #
# Export the current ConfigMap
kubectl get cm coredns -n kube-system -o yaml > coredns-configmap-backup.yaml
Add GitLab DNS Entry #
Create a DNS entry that points to GitLab:
# Add the following DNS section to the CoreDNS ConfigMap
hosts {
192.168.70.4 gitlab.jklug.work
192.168.70.4 gitlab-registry.jklug.work
fallthrough
}
# Edit the CoreDNS ConfigMap
kubectl edit cm coredns -n kube-system
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
Corefile: |
.:53 {
errors
health {
lameduck 5s
}
ready
kubernetes cluster.local in-addr.arpa ip6.arpa {
pods insecure
fallthrough in-addr.arpa ip6.arpa
ttl 30
}
hosts {
192.168.70.4 gitlab.jklug.work
192.168.70.4 gitlab-registry.jklug.work
fallthrough
}
prometheus :9153
forward . /etc/resolv.conf {
max_concurrent 1000
}
cache 30
loop
reload
loadbalance
}
kind: ConfigMap
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"Corefile":".:53 {\n errors\n health {\n lameduck 5s\n }\n ready\n kubernetes cluster.local in-addr.arpa ip6.arpa {\n pods insecure\n fallthrough in-addr.arpa ip6.arpa\n ttl 30\n }\n prometheus :9153\n forward . /etc/resolv.conf {\n max_concurrent 1000\n }\n cache 30\n loop\n reload\n loadbalance\n}\n"},"kind":"ConfigMap","metadata":{"annotations":{},"creationTimestamp":"2024-11-23T11:51:59Z","name":"coredns","namespace":"kube-system","resourceVersion":"253","uid":"7780f5a2-09c9-418c-b139-43231097afe7"}}
creationTimestamp: "2024-12-06T11:27:57Z"
name: coredns
namespace: kube-system
resourceVersion: "12187"
uid: 4c18c50e-fba5-4335-8431-2bf1cd31ef01
# Restart CoreDNS
kubectl rollout restart deployment coredns -n kube-system
Verify DNS Resolution #
# Run a busybox pod
kubectl run busybox --image=busybox --restart=Never --stdin --tty
# Test the GitLab DNS resolution
nslookup gitlab.jklug.work
# Shell output:
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: gitlab.jklug.work
Address: 192.168.70.4
# Exit the container terminal
exit
# Delete the busybox pod
kubectl delete pod busybox