Skip to content

Commit 5167591

Browse files
JoibelCopilot
andcommitted
feat: non-root argoexec (#14477)
Signed-off-by: Alan Clucas <[email protected]> Co-authored-by: Copilot <[email protected]>
1 parent fb15753 commit 5167591

File tree

5 files changed

+90
-39
lines changed

5 files changed

+90
-39
lines changed

.github/workflows/release.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
strategy:
2828
matrix:
2929
platform: [ linux/amd64, linux/arm64 ]
30-
target: [ workflow-controller, argocli, argoexec ]
30+
target: [ workflow-controller, argocli, argoexec, argoexec-nonroot ]
3131
steps:
3232
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
3333

@@ -182,7 +182,7 @@ jobs:
182182
tag="latest"
183183
fi
184184
185-
targets="workflow-controller argoexec argocli"
185+
targets="workflow-controller argoexec argoexec-nonroot argocli"
186186
for target in $targets; do
187187
image_name="${docker_org}/${target}:${tag}"
188188
@@ -209,7 +209,7 @@ jobs:
209209
strategy:
210210
matrix:
211211
platform: [ linux/amd64 ]
212-
target: [ workflow-controller, argocli, argoexec ]
212+
target: [ workflow-controller, argocli, argoexec, argoexec-nonroot ]
213213
steps:
214214
- name: Docker Login
215215
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
@@ -317,6 +317,7 @@ jobs:
317317
- run: bom generate --image quay.io/argoproj/workflow-controller:$VERSION -o dist/workflow-controller.spdx
318318
- run: bom generate --image quay.io/argoproj/argocli:$VERSION -o dist/argocli.spdx
319319
- run: bom generate --image quay.io/argoproj/argoexec:$VERSION -o dist/argoexec.spdx
320+
- run: bom generate --image quay.io/argoproj/argoexec-nonroot:$VERSION -o dist/argoexec-nonroot.spdx
320321
# pack the boms into one file to make it easy to download
321322
- run: tar -zcf dist/sbom.tar.gz dist/*.spdx
322323
- run: make release-notes VERSION=$VERSION

Dockerfile

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,27 @@ RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache
8080

8181
####################################################################################################
8282

83-
FROM gcr.io/distroless/static as argoexec
83+
FROM gcr.io/distroless/static as argoexec-base
8484

85-
COPY --from=argoexec-build /go/src/github.com/argoproj/argo-workflows/dist/argoexec /bin/
8685
COPY --from=argoexec-build /etc/mime.types /etc/mime.types
8786
COPY hack/ssh_known_hosts /etc/ssh/
8887
COPY hack/nsswitch.conf /etc/
8988

89+
####################################################################################################
90+
91+
FROM argoexec-base as argoexec-nonroot
92+
93+
USER 8737
94+
95+
COPY --chown=8737 --from=argoexec-build /go/src/github.com/argoproj/argo-workflows/dist/argoexec /bin/
96+
97+
ENTRYPOINT [ "argoexec" ]
98+
99+
####################################################################################################
100+
FROM argoexec-base as argoexec
101+
102+
COPY --from=argoexec-build /go/src/github.com/argoproj/argo-workflows/dist/argoexec /bin/
103+
90104
ENTRYPOINT [ "argoexec" ]
91105

92106
####################################################################################################

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ else
245245
endif
246246

247247
argoexec-image:
248+
argoexec-nonroot-image:
248249

249250
%-image:
250251
[ ! -e dist/$* ] || mv dist/$* .

docs/workflow-executors.md

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,51 @@
11
# Workflow Executors
22

3-
A workflow executor is a process that conforms to a specific interface that allows Argo to perform certain actions like monitoring pod logs, collecting artifacts, managing container life-cycles, etc.
3+
A Workflow executor runs in the Pods that execute your workloads.
4+
It runs as both an init container and as a sidecar to the container you specify.
5+
It allows Argo to perform certain actions like monitoring Pod logs, providing and collecting artifacts, and managing container life-cycles.
46

5-
## Emissary (emissary)
7+
Historically there were multiple available executor types, but as of 3.4 the only available executor is called `emissary`.
68

7-
> v3.1 and after
8-
9-
Default in >= v3.3.
10-
Only option in >= v3.4.
11-
12-
This is the most fully featured executor.
9+
## Emissary Executor
1310

1411
* Reliability:
1512
* Works on GKE Autopilot
16-
* Does not require `init` process to kill sub-processes.
17-
* More secure:
13+
* Does not require `init` process to kill sub-processes
14+
* Security:
1815
* No `privileged` access
1916
* Cannot escape the privileges of the pod's service account
20-
* Can [`runAsNonRoot`](workflow-pod-security-context.md).
21-
* Scalable:
22-
* It reads and writes to and from the container's disk and typically does not use any network APIs unless resource
23-
type template is used.
17+
* Supports [running as non-root](workflow-pod-security-context.md)
18+
* Scalability:
19+
* Reads and writes to and from the container's disk
20+
* Typically does not use network APIs unless resource type template is used
2421
* Artifacts:
25-
* Output artifacts can be located on the base layer (e.g. `/tmp`).
26-
* Configuration:
27-
* `command` should be specified for containers.
22+
* Output artifacts can be located on the base layer (e.g. `/tmp`)
23+
24+
### Container Command
2825

29-
You can determine values as follows:
26+
You can determine the default command for a container image using:
3027

3128
```bash
32-
docker image inspect -f '{{.Config.Entrypoint}} {{.Config.Cmd}}' argoproj/argosay:v2
29+
docker pull alpine:latest
30+
docker image inspect -f '{{.Config.Entrypoint}} {{.Config.Cmd}}' alpine:latest
3331
```
3432

3533
[Learn more about command and args](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes)
3634

3735
### Image Index/Cache
3836

39-
If you don't provide command to run, the emissary will grab it from container image. You can also specify it using the workflow spec or emissary will look it up in the **image index**. This is nothing more fancy than
40-
a [configuration item](workflow-controller-configmap.yaml).
37+
The emissary executor determines the command to run in this order:
38+
39+
1. Command specified in the workflow spec
40+
2. Command from the image index cache
41+
3. Command from the container image
42+
43+
The image index is a [configuration item](workflow-controller-configmap.yaml), called `images`.
4144

42-
Emissary will create a cache entry, using image with version as key and command as value, and it will reuse it for specific image/version.
45+
The controller creates a cache entry using the image with version as key and command as value.
46+
It reuses this cache for specific image:version combinations, so you may get surprising behavior if you update the command in an image without changing its version tag.
4347

44-
### Exit Code 64
48+
### Troubleshooting
4549

46-
The emissary will exit with code 64 if it fails. This may indicate a bug in the emissary.
50+
The emissary will exit with code 64 if it fails.
51+
This may indicate a bug in the emissary.

docs/workflow-pod-security-context.md

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
# Workflow Pod Security Context
22

3-
By default, all workflow pods run as root.
3+
This document explains how to configure security context for Workflow Pods in Argo Workflows.
44

5-
You can run your workflow pods more securely by configuring the [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for your workflow pod.
5+
Running Workflow Pods as non-root is best practice for security.
66

7-
This is likely to be necessary if pod security standards ([PSS](https://kubernetes.io/docs/concepts/security/pod-security-standards)) are enforced by
8-
[PSA](https://kubernetes.io/docs/concepts/security/pod-security-admission/) or other means, or if you have a
9-
[pod security policy](https://kubernetes.io/docs/concepts/policy/pod-security-policy/) (deprecated).
7+
You may need to do this if:
8+
9+
* Your cluster requires [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards), as enforced by [PSA](https://kubernetes.io/docs/concepts/security/pod-security-admission/) or other means.
10+
* You need to comply with security policies that restrict root access.
11+
12+
## Basic Configuration
13+
14+
By default, all Workflow Pods run as root.
15+
16+
You can configure the [security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) for your Workflow Pod.
17+
18+
Here's a basic example that runs the Pod as a non-root user:
1019

1120
```yaml
1221
apiVersion: argoproj.io/v1alpha1
@@ -16,13 +25,34 @@ metadata:
1625
spec:
1726
securityContext:
1827
runAsNonRoot: true
19-
runAsUser: 8737 #; any non-root user
28+
runAsUser: 8737 # or any non-root user
2029
```
2130
22-
You can configure this globally using [workflow defaults](default-workflow-specs.md).
23-
2431
!!! Warning "It is easy to make a workflow need root unintentionally"
2532
You may find that user's workflows have been written to require root with seemingly innocuous code. E.g. `mkdir /my-dir` would require root.
2633

27-
!!! Note "You must use volumes for output artifacts"
28-
If you use `runAsNonRoot` - you cannot have output artifacts on base layer (e.g. `/tmp`). You must use a volume (e.g. [empty dir](empty-dir.md)).
34+
## Global Configuration
35+
36+
You can set these security context settings globally using [workflow defaults](default-workflow-specs.md).
37+
38+
## Non-root Executor Image
39+
40+
Argo provides a non-root executor image that runs by default as user 8737.
41+
42+
This is not the default executor for backwards compatibility, but using it is best practice.
43+
Use this image when your security policies restrict pulling images that run as root.
44+
You can run this image as root by specifying `runAsUser: 0`.
45+
46+
The image is available at `quay.io/argoproj/argoexec-nonroot:<version>`.
47+
48+
You can configure this as the default executor image in the [workflow-controller-configmap](workflow-controller-configmap.yaml):
49+
50+
```yaml
51+
apiVersion: v1
52+
kind: ConfigMap
53+
metadata:
54+
name: workflow-controller-configmap
55+
data:
56+
executor: |
57+
image: quay.io/argoproj/argoexec-nonroot:<version>
58+
```

0 commit comments

Comments
 (0)