In a series of previous articles, I covered a lot about the “Quarkus – Kubernetes extension” and also the “Helm Extension for Quarkus”.
In this article, you can read more about the “Argo CD Extension for Quarkus” I tried out. As a base for this, I used my already existing Linux demo environment, including Quarkus and K3s (a lightweight certified Kubernetes distribution) and setup via Vagrant. The focus of this part 1 article, is setting up the ArgoCD environment.
Argo CD
Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes.
Argo CD follows the GitOps pattern of using Git repositories as the source of truth for defining the desired application state. Kubernetes manifests can be specified in several ways:
- kustomize applications
- helm charts
- jsonnet files
- Plain directory of YAML/json manifests
- Any custom config management tool configured as a config management plugin
Argo CD automates the deployment of the desired application states in the specified target environments. Application deployments can track updates to branches, tags, or be pinned to a specific version of manifests at a Git commit. See tracking strategies for additional details about the different tracking strategies available.
Argo CD is implemented as a Kubernetes controller which continuously monitors running applications and compares the current, live state against the desired target state (as specified in the Git repo). A deployed application whose live state deviates from the target state is considered OutOfSync. Argo CD reports & visualizes the differences, while providing facilities to automatically or manually sync the live state back to the desired target state. Any modifications made to the desired target state in the Git repo can be automatically applied and reflected in the specified target environments.
Components:
- API Server
The API server is a gRPC/REST server which exposes the API consumed by the Web UI, CLI, and CI/CD systems. It has the following responsibilities:
- application management and status reporting
- invoking of application operations (e.g. sync, rollback, user-defined actions)
- repository and cluster credential management (stored as K8s secrets)
- authentication and auth delegation to external identity providers
- RBAC enforcement
- listener/forwarder for Git webhook events
- Repository Server
The repository server is an internal service which maintains a local cache of the Git repository holding the application manifests. It is responsible for generating and returning the Kubernetes manifests when provided the following inputs:
- repository URL
- revision (commit, tag, branch)
- application path
- template specific settings: parameters, helm values.yaml
- Application Controller
The application controller is a Kubernetes controller which continuously monitors running applications and compares the current, live state against the desired target state (as specified in the repo). It detects OutOfSync application state and optionally takes corrective action. It is responsible for invoking any user-defined hooks for lifecycle events (PreSync, Sync, PostSync)
[https://argo-cd.readthedocs.io/en/stable/]
For more information, please visit the Argo CD documentation:
https://argo-cd.readthedocs.io/en/stable/
Quarkus Extention “Argocd”
On the Quarkus website, I navigated to: Extension | Browse Extensions.
Via the “Find an extension” field, I searched for argocd.
[https://quarkus.io/extensions/?search-regex=argocd]
Next, I clicked on the “Argocd” link.
[https://quarkus.io/extensions/io.quarkiverse.argocd/quarkus-argocd/]
To add this extension to your project, use the relevant command in your Quarkus project directory:
For example, for maven:
./mvnw quarkus:add-extension -Dextensions="io.quarkiverse.argocd:quarkus-argocd"
[https://quarkus.io/extensions/io.quarkiverse.argocd/quarkus-argocd/]
I will be using this command later on (in my next article).
Quarkus guide “Quarkus ArgoCD”
Next, on the Quarkus website, I navigated to: Learn | Documentation.
Via the “Filter by keyword” field, I searched for argocd.
Next, I clicked on the “Argocd | Getting started” link.
[https://docs.quarkiverse.io/quarkus-argocd/dev/index.html]
Generate Argo CD Application or Project as part of the Quarkus build or using the Quarkus CLI.
Requirements
- Project added under a version control system and pushed on a repository (e.g. GitHub, etc.)
- A Kubernetes cluster with Argo CD installed and supporting argoproj.io/v1alpha1.
[https://docs.quarkiverse.io/quarkus-argocd/dev/index.html#_requirements]
Looking at the requirements, first I had to check if I had to prepare my demo environment for using the Argo CD Extension in Kubernetes.
I already had a Kubernetes cluster in place, in my already existing Linux demo environment, including Quarkus and K3s (a lightweight certified Kubernetes distribution) and setup via Vagrant, as described in a previous article.
[Quarkus – Kubernetes extension (reinvestigated, part 5), implementing a Service of service type LoadBalancer with K3s]
But, I still had some work to do.
Requirement: Project added under a version control system and pushed on a repository (e.g. GitHub, etc.)
First, I needed a project under version control.
I logged in into github.com with my own github account and created a Private repository.
[https://github.com/new]
I filled in the following fields (and left the rest as default):
- Repository name: kubernetes-quickstart
- Description: Repository with the kubernetes-quickstart application, needed for a Continuous Delivery (CD) workflow using Quarkus Helm and ArgoCD
- Choose visibility: Private
- Add README: On
Next , I clicked on “Create repository”.
Then, I clicked on “Code”.
In order to be able to clone this project onto my local computer, I clicked on “Copy URL to clipboard”.
https://github.com/marclameriks/kubernetes-quickstart.git
I will be using this remote repository URL later on.
The https:// clone URLs are available on all repositories, regardless of visibility. https:// clone URLs work even if you are behind a firewall or proxy.
When you git clone, git fetch, git pull, or git push to a private remote repository using HTTPS URLs on the command line, Git will ask for your GitHub username and password. When Git prompts you for your password, enter your personal access token.
[https://docs.github.com/en/get-started/git-basics/about-remote-repositories#cloning-with-https-urls]
On my Windows laptop, as you may remember from a previous article, I had a shared folder available.
[Quarkus – Supersonic Subatomic Java – Get Started (reinvestigated)]
So, in this shared folder, I navigated to github\repositories\private.
Next, in order to Clone a repository into a new directory, I used the following command:
[https://git-scm.com/docs/git-clone]
git.exe clone --progress –verbose https://marclameriks@github.com/marclameriks/kubernetes-quickstart.git
Remark about option –progress:
Progress status is reported on the standard error stream by default when it is attached to a terminal, unless –quiet is specified. This flag forces progress status even if the standard error stream is not directed to a terminal.
[https://git-scm.com/docs/git-clone#Documentation/git-clone.txt—progress]
Remark about option –verbose:
Run verbosely. Does not affect the reporting of progress status to the standard error stream.
[https://git-scm.com/docs/git-clone#Documentation/git-clone.txt–v]
Remark about authenticating with GitHub from Git:
In order to authenticate with GitHub from Git, I used the following format (after some research):
[https://stackoverflow.com/questions/10054318/how-do-i-provide-a-username-and-password-when-running-git-clone-gitremote-git]
https://<username>@<repository>
With the following output:
Cloning into 'kubernetes-quickstart'... info: please complete authentication in your browser... POST git-upload-pack (193 bytes) POST git-upload-pack (220 bytes) remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) Receiving objects: 100% (3/3), done.
Next, I checked my shared folder.
As you can see, up till now, only file README.md is part of the project.
So, now the first requirement was met, I added a project under version control system Git and pushed it on a GitHub repository.
Requirement: A Kubernetes cluster with Argo CD installed and supporting argoproj.io/v1alpha1
As I mentioned before, the second requirement was a Kubernetes cluster with Argo CD installed and supporting argoproj.io/v1alpha1.
[https://docs.quarkiverse.io/quarkus-argocd/dev/index.html#_requirements]
Next, I clicked on the “installed” link.
[https://argo-cd.readthedocs.io/en/stable/getting_started/#1-install-argo-cd]
From there, first I navigated to the “Getting Started” part of the Argo CD documentation.
[https://argo-cd.readthedocs.io/en/stable/getting_started/#getting-started]
The following requirements are mentioned:
- Installed kubectl command-line tool.
- Have a kubeconfig file (default location is ~/.kube/config).
- CoreDNS. Can be enabled for microk8s by microk8s enable dns && microk8s stop && microk8s start
As it turned out, I already had most of these requirements in place, in my already existing Linux demo environment, including Quarkus and K3s (a lightweight certified Kubernetes distribution) and setup via Vagrant, as described in a previous article.
[Quarkus – Kubernetes extension (reinvestigated, part 5), implementing a Service of service type LoadBalancer with K3s]
Remark about CoreDNS:
For now I skipped the CoreDNS part.
CoreDNS is a DNS server. It is written in Go. It can be used in a multitude of environments because of its flexibility. CoreDNS is licensed under the Apache License Version 2, and completely open source.
Development takes place on GitHub.
[https://coredns.io/]
Getting started with Argo CD
Below, you can see an overview of my Linux demo environment, as described in my previous article:
[Quarkus – trying out the “Helm Extension for Quarkus”]
For the Linux demo environment to start, from the Oracle VM VirtualBox Manager on my Windows laptop, I started the appliance (in “Headless Start” mode).
Once the VM was running, for executing later manual steps, I used vagrant ssh to connect into the running VM.
In order to getting started with Argo CD, I followed the steps as described in the “Getting Started” part of the Argo CD documentation.
[https://argo-cd.readthedocs.io/en/stable/getting_started/#getting-started]
Install Argo CD via kubectl
kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
This will create a new namespace, argocd, where Argo CD services and application resources will live.
Warning:
The installation manifests include ClusterRoleBinding resources that reference argocd namespace. If you are installing Argo CD into a different namespace then make sure to update the namespace reference.
Tip:
If you are not interested in UI, SSO, and multi-cluster features, then you can install only the core Argo CD components.
This default installation will have a self-signed certificate and cannot be accessed without a bit of extra work.
[https://argo-cd.readthedocs.io/en/stable/getting_started/#1-install-argo-cd]
In order to create the new namespace argocd, I used the following command on the Linux Command Prompt:
kubectl create namespace argocd
With the following output:
namespace/argocd created
In order to get a list of all the namespaces, I used the following command on the Linux Command Prompt:
kubectl get namespaces
With the following output:
NAME STATUS AGE argocd Active 72s default Active 128d kube-node-lease Active 128d kube-public Active 128d kube-system Active 128d kubernetes-dashboard Active 128d nl-amis-development Active 128d
In order to install the Argo CD services and application resources, I used the following command on the Linux Command Prompt:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
With the following output:
customresourcedefinition.apiextensions.k8s.io/applications.argoproj.io created customresourcedefinition.apiextensions.k8s.io/applicationsets.argoproj.io created customresourcedefinition.apiextensions.k8s.io/appprojects.argoproj.io created serviceaccount/argocd-application-controller created serviceaccount/argocd-applicationset-controller created serviceaccount/argocd-dex-server created serviceaccount/argocd-notifications-controller created serviceaccount/argocd-redis created serviceaccount/argocd-repo-server created serviceaccount/argocd-server created role.rbac.authorization.k8s.io/argocd-application-controller created role.rbac.authorization.k8s.io/argocd-applicationset-controller created role.rbac.authorization.k8s.io/argocd-dex-server created role.rbac.authorization.k8s.io/argocd-notifications-controller created role.rbac.authorization.k8s.io/argocd-redis created role.rbac.authorization.k8s.io/argocd-server created clusterrole.rbac.authorization.k8s.io/argocd-application-controller created clusterrole.rbac.authorization.k8s.io/argocd-applicationset-controller created clusterrole.rbac.authorization.k8s.io/argocd-server created rolebinding.rbac.authorization.k8s.io/argocd-application-controller created rolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created rolebinding.rbac.authorization.k8s.io/argocd-dex-server created rolebinding.rbac.authorization.k8s.io/argocd-notifications-controller created rolebinding.rbac.authorization.k8s.io/argocd-redis created rolebinding.rbac.authorization.k8s.io/argocd-server created clusterrolebinding.rbac.authorization.k8s.io/argocd-application-controller created clusterrolebinding.rbac.authorization.k8s.io/argocd-applicationset-controller created clusterrolebinding.rbac.authorization.k8s.io/argocd-server created configmap/argocd-cm created configmap/argocd-cmd-params-cm created configmap/argocd-gpg-keys-cm created configmap/argocd-notifications-cm created configmap/argocd-rbac-cm created configmap/argocd-ssh-known-hosts-cm created configmap/argocd-tls-certs-cm created secret/argocd-notifications-secret created secret/argocd-secret created service/argocd-applicationset-controller created service/argocd-dex-server created service/argocd-metrics created service/argocd-notifications-controller-metrics created service/argocd-redis created service/argocd-repo-server created service/argocd-server created service/argocd-server-metrics created deployment.apps/argocd-applicationset-controller created deployment.apps/argocd-dex-server created deployment.apps/argocd-notifications-controller created deployment.apps/argocd-redis created deployment.apps/argocd-repo-server created deployment.apps/argocd-server created statefulset.apps/argocd-application-controller created networkpolicy.networking.k8s.io/argocd-application-controller-network-policy created networkpolicy.networking.k8s.io/argocd-applicationset-controller-network-policy created networkpolicy.networking.k8s.io/argocd-dex-server-network-policy created networkpolicy.networking.k8s.io/argocd-notifications-controller-network-policy created networkpolicy.networking.k8s.io/argocd-redis-network-policy created networkpolicy.networking.k8s.io/argocd-repo-server-network-policy created networkpolicy.networking.k8s.io/argocd-server-network-policy created
So now, let’s check the Kubernetes objects that were created.
I checked whether the Pods were running successfully, via a series of commands on the Linux Command Prompt.
kubectl get services -n argocd
With the following output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE argocd-applicationset-controller ClusterIP 10.43.112.146 <none> 7000/TCP,8080/TCP 38m argocd-dex-server ClusterIP 10.43.28.231 <none> 5556/TCP,5557/TCP,5558/TCP 38m argocd-metrics ClusterIP 10.43.164.131 <none> 8082/TCP 38m argocd-notifications-controller-metrics ClusterIP 10.43.177.178 <none> 9001/TCP 38m argocd-redis ClusterIP 10.43.253.203 <none> 6379/TCP 38m argocd-repo-server ClusterIP 10.43.241.118 <none> 8081/TCP,8084/TCP 38m argocd-server ClusterIP 10.43.11.231 <none> 80/TCP,443/TCP 38m argocd-server-metrics ClusterIP 10.43.108.227 <none> 8083/TCP 38m
kubectl get replicasets -n argocd
With the following output:
NAME DESIRED CURRENT READY AGE argocd-applicationset-controller-694458f998 1 1 1 39m argocd-dex-server-746dd6b4b9 1 1 1 39m argocd-notifications-controller-746cd74b97 1 1 1 39m argocd-redis-db5bc49bf 1 1 1 39m argocd-repo-server-775b449c46 1 1 1 39m argocd-server-7d4d46b98 1 1 1 39m
kubectl get pods -n argocd
With the following output:
NAME READY STATUS RESTARTS AGE argocd-application-controller-0 1/1 Running 0 40m argocd-applicationset-controller-694458f998-cp4lk 1/1 Running 0 40m argocd-dex-server-746dd6b4b9-g9cgf 1/1 Running 0 40m argocd-notifications-controller-746cd74b97-28tgf 1/1 Running 0 40m argocd-redis-db5bc49bf-bdd9t 1/1 Running 0 40m argocd-repo-server-775b449c46-f54lw 1/1 Running 0 40m argocd-server-7d4d46b98-bpxrh 1/1 Running 0 40m
kubectl get endpoints -n argocd
With the following output:
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice NAME ENDPOINTS AGE argocd-applicationset-controller 10.42.0.37:8080,10.42.0.37:7000 41m argocd-dex-server 10.42.0.38:5558,10.42.0.38:5557,10.42.0.38:5556 41m argocd-metrics 10.42.0.34:8082 41m argocd-notifications-controller-metrics 10.42.0.39:9001 41m argocd-redis 10.42.0.33:6379 41m argocd-repo-server 10.42.0.36:8084,10.42.0.36:8081 41m argocd-server 10.42.0.35:8080,10.42.0.35:8080 41m argocd-server-metrics 10.42.0.35:8083 41m
kubectl get endpoints -n argocd --output json
With the following output:
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:17Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "applicationset-controller",
"app.kubernetes.io/name": "argocd-applicationset-controller",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-applicationset-controller",
"namespace": "argocd",
"resourceVersion": "54793",
"uid": "eb71700c-6df9-4149-8b79-8ddb0a57415c"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.37",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-applicationset-controller-694458f998-cp4lk",
"namespace": "argocd",
"uid": "5a34c928-10ec-4865-b480-39b52bfff6cb"
}
}
],
"ports": [
{
"name": "metrics",
"port": 8080,
"protocol": "TCP"
},
{
"name": "webhook",
"port": 7000,
"protocol": "TCP"
}
]
}
]
},
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:34Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "dex-server",
"app.kubernetes.io/name": "argocd-dex-server",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-dex-server",
"namespace": "argocd",
"resourceVersion": "54838",
"uid": "160c07f7-f4ba-476a-aaee-56a5c92fe5ad"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.38",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-dex-server-746dd6b4b9-g9cgf",
"namespace": "argocd",
"uid": "4c4afc20-dd1b-4313-8696-5cddad3678e5"
}
}
],
"ports": [
{
"name": "metrics",
"port": 5558,
"protocol": "TCP"
},
{
"name": "grpc",
"port": 5557,
"protocol": "TCP"
},
{
"appProtocol": "TCP",
"name": "http",
"port": 5556,
"protocol": "TCP"
}
]
}
]
},
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:35Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "metrics",
"app.kubernetes.io/name": "argocd-metrics",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-metrics",
"namespace": "argocd",
"resourceVersion": "54848",
"uid": "1a0fc1e6-0814-4d3f-8b80-bb0a44189753"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.34",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-application-controller-0",
"namespace": "argocd",
"uid": "73e3fd69-1dfb-47b6-a3d8-8839c67df0e5"
}
}
],
"ports": [
{
"name": "metrics",
"port": 8082,
"protocol": "TCP"
}
]
}
]
},
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:17Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "notifications-controller",
"app.kubernetes.io/name": "argocd-notifications-controller-metrics",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-notifications-controller-metrics",
"namespace": "argocd",
"resourceVersion": "54791",
"uid": "b4d533d1-ddd7-4d7c-8e77-7e0d81a2f977"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.39",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-notifications-controller-746cd74b97-28tgf",
"namespace": "argocd",
"uid": "693d646a-2f34-4a51-bf36-cef9d36ba1d7"
}
}
],
"ports": [
{
"name": "metrics",
"port": 9001,
"protocol": "TCP"
}
]
}
]
},
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:34Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "redis",
"app.kubernetes.io/name": "argocd-redis",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-redis",
"namespace": "argocd",
"resourceVersion": "54833",
"uid": "eb9a45e3-727f-4480-bfd8-1f8dd3c0d726"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.33",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-redis-db5bc49bf-bdd9t",
"namespace": "argocd",
"uid": "669c3195-2fd0-4748-b4d6-df64e129f8a1"
}
}
],
"ports": [
{
"name": "tcp-redis",
"port": 6379,
"protocol": "TCP"
}
]
}
]
},
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:35Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "repo-server",
"app.kubernetes.io/name": "argocd-repo-server",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-repo-server",
"namespace": "argocd",
"resourceVersion": "54841",
"uid": "c2498ce1-7b53-452e-b339-59358641ccd7"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.36",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-repo-server-775b449c46-f54lw",
"namespace": "argocd",
"uid": "9f3f3606-b05d-430e-b59a-f37cecc4b83d"
}
}
],
"ports": [
{
"name": "metrics",
"port": 8084,
"protocol": "TCP"
},
{
"name": "server",
"port": 8081,
"protocol": "TCP"
}
]
}
]
},
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:54Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "server",
"app.kubernetes.io/name": "argocd-server",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-server",
"namespace": "argocd",
"resourceVersion": "54857",
"uid": "d0fe2253-3184-4bce-8be0-b91cb9d1f965"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.35",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-server-7d4d46b98-bpxrh",
"namespace": "argocd",
"uid": "13235dc9-5e14-44ab-b4ac-921548acd270"
}
}
],
"ports": [
{
"name": "https",
"port": 8080,
"protocol": "TCP"
},
{
"name": "http",
"port": 8080,
"protocol": "TCP"
}
]
}
]
},
{
"apiVersion": "v1",
"kind": "Endpoints",
"metadata": {
"annotations": {
"endpoints.kubernetes.io/last-change-trigger-time": "2025-12-19T13:56:54Z"
},
"creationTimestamp": "2025-12-19T13:55:47Z",
"labels": {
"app.kubernetes.io/component": "server",
"app.kubernetes.io/name": "argocd-server-metrics",
"app.kubernetes.io/part-of": "argocd",
"endpoints.kubernetes.io/managed-by": "endpoint-controller"
},
"name": "argocd-server-metrics",
"namespace": "argocd",
"resourceVersion": "54862",
"uid": "43e6e02f-342e-49ea-8f6f-635fd86bebd8"
},
"subsets": [
{
"addresses": [
{
"ip": "10.42.0.35",
"nodeName": "ubuntu2204.localdomain",
"targetRef": {
"kind": "Pod",
"name": "argocd-server-7d4d46b98-bpxrh",
"namespace": "argocd",
"uid": "13235dc9-5e14-44ab-b4ac-921548acd270"
}
}
],
"ports": [
{
"name": "metrics",
"port": 8083,
"protocol": "TCP"
}
]
}
]
}
],
"kind": "List",
"metadata": {
"resourceVersion": ""
}
}
Remark about endpoints:
In the output you can see the following warning:
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
As of Kubernetes 1.33, the Endpoints API is now officially deprecated, and the API server will return warnings to users who read or write Endpoints resources rather than using EndpointSlices.
[https://kubernetes.io/blog/2025/04/24/endpoints-deprecation/]
So, I also used the following command on the Linux Command Prompt:
kubectl get endpointslice -n argocd
With the following output:
NAME ADDRESSTYPE PORTS ENDPOINTS AGE argocd-applicationset-controller-8mp9n IPv4 8080,7000 10.42.0.37 47m argocd-dex-server-9ctqf IPv4 5557,5556,5558 10.42.0.38 47m argocd-metrics-5hqkv IPv4 8082 10.42.0.34 47m argocd-notifications-controller-metrics-2cg8c IPv4 9001 10.42.0.39 47m argocd-redis-nsjkq IPv4 6379 10.42.0.33 47m argocd-repo-server-mh55z IPv4 8081,8084 10.42.0.36 47m argocd-server-khs46 IPv4 8080,8080 10.42.0.35 47m argocd-server-metrics-p7bck IPv4 8083 10.42.0.35 47m
And finally, I used the following command on the Linux Command Prompt:
kubectl get nodes
With the following output:
NAME STATUS ROLES AGE VERSION ubuntu2204.localdomain Ready control-plane,master 128d v1.33.3+k3s1
Below, you see an overview of my Kubernetes cluster at this moment, with regard to the Argo CD API Server (argocd-server):
The argocd-server service is of service type ClusterIP.
Remark about service type ClusterIP:
Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default that is used if you don’t explicitly specify a type for a Service.
[https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types]
Download Argo CD CLI
Download the latest Argo CD version from https://github.com/argoproj/argo-cd/releases/latest. More detailed installation instructions can be found via the CLI installation documentation.
[https://argo-cd.readthedocs.io/en/stable/getting_started/#2-download-argo-cd-cli]
First, I had a look at the CLI installation documentation.
[https://argo-cd.readthedocs.io/en/stable/cli_installation/]
You can download the latest Argo CD version from the latest release page of this repository, which will include the argocd CLI.
I opted for, Download With Curl, Download latest stable version.
You can download the latest stable release by executing below steps:
VERSION=$(curl -L -s https://raw.githubusercontent.com/argoproj/argo-cd/stable/VERSION) curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/download/v$VERSION/argocd-linux-amd64 sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd rm argocd-linux-amd64
You should now be able to run argocd commands.
In order to download the latest stable version of Argo CD (3.2.2
at the moment of writing this article), I used the following commands on the Linux Command Prompt:
VERSION=$(curl -L -s https://raw.githubusercontent.com/argoproj/argo-cd/stable/VERSION) curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/download/v$VERSION/argocd-linux-amd64
Remark about option -o, –output <file>:
Write output to the given file instead of stdout.
[https://curl.se/docs/manpage.html#–output]
In order to check the content of my current working directory (/home/vagrant), I used the following command on the Linux Command Prompt:
ls -latr
With the following output (only showing a part):
total 208572 … drwxr-x--- 9 vagrant vagrant 4096 Dec 19 14:07 . -rw-rw-r-- 1 vagrant vagrant 213488981 Dec 19 14:07 argocd-linux-amd64
Here we can see that the output is written to the given file argocd-linux-amd64.
In order to install the Argo CD cli, I used the following commands on the Linux Command Prompt:
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd rm argocd-linux-amd64
In order to check the content of my current working directory (/home/vagrant), I used the following command on the Linux Command Prompt:
ls -latr
With the following output (only showing a part):
total 84 … drwxr-x--- 9 vagrant vagrant 4096 Dec 19 14:08 .
Here we can see that the file argocd-linux-amd64 was removed.
In order to check the content of directory /usr/local/bin, I used the following commands on the Linux Command Prompt:
cd /usr/local/bin ls -latr
With the following output (only showing a part):
total 281480 … drwxr-xr-x 2 root root 4096 Dec 19 14:08 . -r-xr-xr-x 1 root root 213488981 Dec 19 14:08 argocd
Here we can see the file argocd was created.
After finishing the instructions above, I should now be able to run argocd commands.
So, let’s try it.
In order to print version information, I used the following command on the Linux Command Prompt:
[https://argo-cd.readthedocs.io/en/latest/user-guide/commands/argocd_version/#argocd-version-command-reference]
argocd version
With the following output:
argocd: v3.2.2+8d0dde1
BuildDate: 2025-12-18T10:17:02Z
GitCommit: 8d0dde1388a92ca4dc0daacec5707f4378b9d06a
GitTreeState: clean
GoVersion: go1.25.0
Compiler: gc
Platform: linux/amd64
{"level":"fatal","msg":"Argo CD server address unspecified","time":"2025-12-19T14:12:55Z"}
Access the Argo CD API Server
By default, the Argo CD API server is not exposed with an external IP. To access the API server, choose one of the following techniques to expose the Argo CD API server:
- Service Type Load Balancer
Change the argocd-server service type to LoadBalancer:
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'After a short wait, your cloud provider will assign an external IP address to the service. You can retrieve this IP with:
kubectl get svc argocd-server -n argocd -o=jsonpath='{.status.loadBalancer.ingress[0].ip}' - Ingress
Follow the ingress documentation on how to configure Argo CD with ingress.
- Port Forwarding
Kubectl port-forwarding can also be used to connect to the API server without exposing the service.
kubectl port-forward svc/argocd-server -n argocd 8080:443The API server can then be accessed using https://localhost:8080
[https://argo-cd.readthedocs.io/en/stable/getting_started/#3-access-the-argo-cd-api-server]
As you can read above, by default, the Argo CD API server is not exposed with an external IP. To access the API server, I opted for using port forwarding.
I wanted to be able to use a Web Browser on my Windows laptop, to connect to the
Argo CD API server.
So, the first thing I needed was a port forward from my Windows laptop to my VirtualBox Appliance with Ubuntu 22.04.
Because port 8080 on my Guest OS, was already in use on my Windows laptop, I had to use another one.
In the Oracle VM VirtualBox Manager on my Windows laptop, I navigated to the appliance | Details | Network | Advanced | Port Forwarding. Next, I added the two extra port forwarding rules (for ports 8085 en 8086):
Remark:
For now I didn’t add them also to my Vagrantfile.
Next, for port forwarding port 8085 on my Linux demo environment, I used the following command on the Linux Command Prompt:
kubectl port-forward -n argocd --address 0.0.0.0 svc/argocd-server 8085:80 </dev/null &>/dev/null &
With the following output:
[1] 8320
Then, for port forwarding port 8086 on my Linux demo environment, I used the following command on the Linux Command Prompt:
kubectl port-forward -n argocd --address 0.0.0.0 svc/argocd-server 8086:443 </dev/null &>/dev/null &
With the following output:
[2] 8358
Remark about the option –address:
–address strings Default: “localhost”
Addresses to listen on (comma separated). Only accepts IP addresses or localhost as a value. When localhost is supplied, kubectl will try to bind on both 127.0.0.1 and ::1 and will fail if neither of these addresses are available to bind.
[https://kubernetes.io/docs/reference/kubectl/generated/kubectl_port-forward/#options]
The command-line argument –address 0.0.0.0 tells a network application (like a web server) to listen for incoming connections on all available network interfaces (IP addresses) of the machine, rather than a specific one, making the service accessible from any network the server is connected to, not just localhost. While 0.0.0.0 isn’t a real, routable IP for a device but a special placeholder meaning “any address,” it’s crucial for servers to bind to it so they can accept traffic from external networks.
[AI overview]
AI responses may contain errors. Learn more.
Below, you see an overview of my Kubernetes cluster at this moment:
In order to check access to the Argo CD API Server via port 8085, I used the following command on the Linux Command Prompt:
curl http://localhost:8085
With the following output:
<a href="https://localhost:8085/">Temporary Redirect</a>.
Remark about redirect:
Argo CD API server runs both a gRPC server (used by the CLI), as well as a HTTP/HTTPS server (used by the UI). Both protocols are exposed by the argocd-server service object on the following ports:
- 443 – gRPC/HTTPS
- 80 – HTTP (redirects to HTTPS)
[https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#ingress-configuration]
In order to check access to the Argo CD API Server via port 8086, I used the following command on the Linux Command Prompt:
curl https://localhost:8086
With the following output:
curl: (60) SSL certificate problem: self-signed certificate More details here: https://curl.se/docs/sslcerts.html curl failed to verify the legitimacy of the server and therefore could not establish a secure connection to it. To learn more about this situation and how to fix it, please visit the web page mentioned above.
Remark about self-signed certificate:
This default installation will have a self-signed certificate and cannot be accessed without a bit of extra work. Do one of:
- Follow the instructions to configure a certificate (and ensure that the client OS trusts it).
- Configure the client OS to trust the self-signed certificate.
- Use the –insecure flag on all Argo CD CLI operations in this guide.
[https://argo-cd.readthedocs.io/en/stable/getting_started/#1-install-argo-cd]
For now, I didn’t want to look further into this.
I conclude this part 1 article.
In this article, you can read more about the “Argo CD Extension for Quarkus” I tried out. As a base for this, I used my already existing Linux demo environment, including Quarkus and K3s (a lightweight certified Kubernetes distribution) and setup via Vagrant.
The focus of this part 1 article, is setting up the ArgoCD environment. You can read for example about how I met a requirement for using the “Argo CD Extension for Quarkus”, by adding a project under version control system Git and pushing it on a GitHub Private repository.
I mainly followed the first steps as described in the “Getting Started” part of the Argo CD documentation:
- Install Argo CD (via kubectl)
- Download Argo CD CLI
- Access the Argo CD API Server
In my next article (part 2), I will continue following some of the next steps as described in the “Getting Started” part of the Argo CD documentation:
- Login Using The CLI
- Register A Cluster To Deploy Apps To (Optional)
- Create An Application From A Git Repository, Creating Apps Via CLI
- Create An Application From A Git Repository, Creating Apps Via UI
- Sync (Deploy) The Application, Syncing via CLI
- Sync (Deploy) The Application, Syncing via UI
[https://argo-cd.readthedocs.io/en/stable/getting_started/#getting-started]
And of course I will continue with the “Getting started” part of the “Argo CD Extension for Quarkus”, in order to generate an Argo CD Application or Project as part of the Quarkus build or by using the Quarkus CLI.
