Install Argo Workflow in k3s Cluster and Run a Simple Hello World
1. Introduction
After setting up a k3s cluster recently, I wanted to try a cloud-native CI/CD tool, so I chose Argo. However, I didn't expect this tool to fall far behind Jenkins in terms of documentation, installation, and usage.
Many points aren't even mentioned in the official documentation!!! WTF. While searching for solutions, I found that some issues from 2022 already pointed out their misleading documentation, making me question whether this open-source tool has enough support for updates.
Hopefully this won't turn into a rant post.
2. Installing Argo Workflow
2.1 Prerequisites
- k8s cluster, k3s cluster, or minikube, etc.
- Familiarity with some kubectl syntax
2.2 Installation
The installation process looks simple. According to the official quick-start documentation, just two commands:
Replace ${ARGO_WORKFLOWS_VERSION} with your desired version, e.g., v3.6.4
kubectl create namespace argo
kubectl apply -n argo -f "https://github.com/argoproj/argo-workflows/releases/download/${ARGO_WORKFLOWS_VERSION}/quick-start-minimal.yaml"
See this blog post: Deploy Argo on Kubernetes Without HTTPS
Run kubectl get all -n argo to see two pods started:

Since you've configured domain access, you can open it directly using your domain.
2.3 Configure Access Token
After opening, you'll see this page. To log in, there are 2 methods:
- Single Sign-on
- Configure Access Token
We'll choose the second option - Access Token, because we want the automated workflow to work not only in the web UI but also via CLI.

Creating this Access Token is a major pitfall in Argo's Access Token documentation.
The k8s service account created in the original documentation only has very limited permissions: list, update. When creating one, we usually want to get it right the first time. At least the documentation should provide a link explaining all available permissions, but it doesn't!!!
That page really only tells you how to create a simple service account with the most basic usage...

After extensive Googling, I finally found someone's blog with the same problem: Installing Argo Workflows with ui access explained step by step
It says:
Before accessing the argo workflow's user interface, we need an access token. This confused me a bit because no default secret is created during normal installation, the getting started guide doesn't mention the token creation documentation process, and the ui role example documentation is on another page.

Reading this felt like finding a kindred spirit. Without this blog, I really wouldn't know how to continue. Here's the documentation from the article: Argo Security
What we need to do is create from the complete permissions yaml described in Argo Security. I've organized it for you here, and that Argo Security documentation doesn't even include permissions for creating and deleting pods and services.
Create an argo-setup.yaml file and paste the following content. It creates a ServiceAccount, ClusterRole, then uses ClusterRoleBinding to bind the ClusterRole to the ServiceAccount, and finally a Secret.
You can see all permissions directly in the ClusterRole. The highlighted parts show which resources this role has access to.
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: argo-service-account
namespace: argo
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: argo-cluster-role
rules:
- apiGroups:
- ""
resources:
- pods
- pods/exec
verbs:
- create
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- watch
- list
- apiGroups:
- ""
resources:
- persistentvolumeclaims
- persistentvolumeclaims/finalizers
verbs:
- create
- update
- delete
- get
- apiGroups:
- argoproj.io
resources:
- workflows
- workflows/finalizers
- workflowtasksets
- workflowtasksets/finalizers
- workflowartifactgctasks
verbs:
- get
- list
- watch
- update
- patch
- delete
- create
- apiGroups:
- argoproj.io
resources:
- workflowtemplates
- workflowtemplates/finalizers
- clusterworkflowtemplates
- clusterworkflowtemplates/finalizers
verbs:
- get
- list
- watch
- apiGroups:
- argoproj.io
resources:
- workflowtaskresults
verbs:
- list
- watch
- deletecollection
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- list
- apiGroups:
- argoproj.io
resources:
- cronworkflows
- cronworkflows/finalizers
verbs:
- get
- list
- watch
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "policy"
resources:
- poddisruptionbudgets
verbs:
- create
- get
- delete
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
resourceNames:
- argo-workflows-agent-ca-certificates
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: argo-cluster-rolebinding
subjects:
- kind: ServiceAccount
name: argo-service-account
namespace: argo
roleRef:
kind: ClusterRole
name: argo-cluster-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
metadata:
name: argo-service-account-token
namespace: argo
annotations:
kubernetes.io/service-account.name: argo-service-account
type: kubernetes.io/service-account-token
See issue: workflowtaskresults doesn't work (typo)
After creating the file, just run kubectl apply -f argo-setup.yaml to create the corresponding service account. If you want to delete everything, just run kubectl delete -f argo-setup.yaml.
2.4 View Your Access Token
This is the simplest step. After execution, you should see the token:
ARGO_TOKEN="Bearer $(kubectl get secret argo-service-account-token -n argo -o=jsonpath='{.data.token}' | base64 --decode)"
echo $ARGO_TOKEN

Then enter it in the web UI window to log in.

After logging in, don't think everything is fine and you can use the web UI. Nope! Although you logged in with this token and have its permissions, submitting a new workflow on the page uses the default account.

You'll get this error. You might wonder what the service account you just created is for?? This brings us to the CLI part.

3. Using the CLI
Official documentation: https://argo-workflows.readthedocs.io/en/latest/walk-through/argo-cli/
The CLI installation is even more heavyweight. Argo documentation jumps through two pages, finally landing on the GitHub Release Page with a shell script for you to execute yourself...

Let's be direct here. Open the GitHub Releases page, download the corresponding version to your server (needs to be the server node).
Then extract it and add execute permissions. It's basically the shell script from the page, but I wonder why they don't write it more completely - wouldn't it be better to just run ./xxx.sh?
# Add permissions
chmod +x "argo-$ARGO_OS-amd64"
# Move to bin directory
mv "./argo-$ARGO_OS-amd64" /usr/local/bin/argo
# Test if it works
argo version
As shown:

Finally, you've completed all the above steps perfectly, thinking you can now try a simple example.
That's right, let's try it!
Open Argo Workflow Examples, then copy hello-world.yaml. You can also copy the content below directly:
apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
generateName: hello-world-
labels:
workflows.argoproj.io/archive-strategy: "false"
annotations:
workflows.argoproj.io/description: |
This is a simple hello world example.
spec:
entrypoint: hello-world
templates:
- name: hello-world
container:
image: busybox
command: [echo]
args: ["hello world"]
Then execute:
argo submit -n argo --watch hello-world.yaml
You might encounter this error:
If you're also using k3s, execute this command:
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
If you see the workflow seems to be executing, don't celebrate too early, because this execution is no different from executing in the web UI - the service account is still the default one. As expected, you'll see this error:

The error is because this service account doesn't have permissions. The solution is simple - use the service account with permissions that we created earlier:
argo submit -n argo --watch hello-world.yaml --serviceaccount argo-service-account
When you see this, it means you've finally completed all the installation:

Then go back to the web UI and you can see the corresponding workflow:

If you want to view logs, you can do so in the web UI or command line:
kubectl logs hello-world-kx92r -n argo
