diff --git a/acceptance/testdata/kubernetes_container_mode.envsubst.yaml b/acceptance/testdata/kubernetes_container_mode.envsubst.yaml new file mode 100644 index 00000000..6c7b4465 --- /dev/null +++ b/acceptance/testdata/kubernetes_container_mode.envsubst.yaml @@ -0,0 +1,82 @@ +# USAGE: +# cat acceptance/testdata/kubernetes_container_mode.envsubst.yaml | NAMESPACE=default envsubst | kubectl apply -f - +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: k8s-mode-runner +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "create", "delete"] +- apiGroups: [""] + resources: ["pods/exec"] + verbs: ["get", "create"] +- apiGroups: [""] + resources: ["pods/log"] + verbs: ["get", "list", "watch",] +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "list", "create", "delete"] +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "create", "delete"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: runner-status-updater +rules: +- apiGroups: ["actions.summerwind.dev"] + resources: ["runners/status"] + verbs: ["get", "update", "patch"] +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: runner + namespace: ${NAMESPACE} +--- +# To verify it's working, try: +# kubectl auth can-i --as system:serviceaccount:default:runner get pod +# If incomplete, workflows and jobs would fail with an error message like: +# Error: Error: The Service account needs the following permissions [{"group":"","verbs":["get","list","create","delete"],"resource":"pods","subresource":""},{"group":"","verbs":["get","create"],"resource":"pods","subresource":"exec"},{"group":"","verbs":["get","list","watch"],"resource":"pods","subresource":"log"},{"group":"batch","verbs":["get","list","create","delete"],"resource":"jobs","subresource":""},{"group":"","verbs":["create","delete","get","list"],"resource":"secrets","subresource":""}] on the pod resource in the 'default' namespace. Please contact your self hosted runner administrator. +# Error: Process completed with exit code 1. +apiVersion: rbac.authorization.k8s.io/v1 +# This role binding allows "jane" to read pods in the "default" namespace. +# You need to already have a Role named "pod-reader" in that namespace. +kind: RoleBinding +metadata: + name: runner-k8s-mode-runner + namespace: ${NAMESPACE} +subjects: +- kind: ServiceAccount + name: runner + namespace: ${NAMESPACE} +roleRef: + kind: ClusterRole + name: k8s-mode-runner + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: runner-runner-stat-supdater + namespace: ${NAMESPACE} +subjects: +- kind: ServiceAccount + name: runner + namespace: ${NAMESPACE} +roleRef: + kind: ClusterRole + name: runner-status-updater + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: org-runnerdeploy-runner-work-dir + labels: + content: org-runnerdeploy-runner-work-dir +provisioner: rancher.io/local-path +reclaimPolicy: Delete +volumeBindingMode: WaitForFirstConsumer diff --git a/acceptance/testdata/runnerdeploy.envsubst.yaml b/acceptance/testdata/runnerdeploy.envsubst.yaml index 9dc29567..7c476b8c 100644 --- a/acceptance/testdata/runnerdeploy.envsubst.yaml +++ b/acceptance/testdata/runnerdeploy.envsubst.yaml @@ -43,6 +43,17 @@ spec: # Non-standard working directory # # workDir: "/" + + # # Uncomment the below to enable the kubernetes container mode + # # See https://github.com/actions-runner-controller/actions-runner-controller#runner-with-k8s-jobs + containerMode: kubernetes + workVolumeClaimTemplate: + accessModes: + - ReadWriteOnce + storageClassName: "${NAME}-runner-work-dir" + resources: + requests: + storage: 10Gi --- apiVersion: actions.summerwind.dev/v1alpha1 kind: HorizontalRunnerAutoscaler diff --git a/acceptance/values.yaml b/acceptance/values.yaml index 28d9fc99..95b1c8a9 100644 --- a/acceptance/values.yaml +++ b/acceptance/values.yaml @@ -5,6 +5,11 @@ imagePullSecrets: image: actionsRunnerImagePullSecrets: - name: +runner: + statusUpdateHook: + enabled: true +rbac: + allowGrantingKubernetesContainerModePermissions: true githubWebhookServer: imagePullSecrets: - name: diff --git a/charts/actions-runner-controller/templates/manager_role.yaml b/charts/actions-runner-controller/templates/manager_role.yaml index 9101adb1..637b5328 100644 --- a/charts/actions-runner-controller/templates/manager_role.yaml +++ b/charts/actions-runner-controller/templates/manager_role.yaml @@ -283,4 +283,28 @@ rules: - create - delete - get -{{- end }} \ No newline at end of file +{{- end }} +{{- if .Values.rbac.allowGrantingKubernetesContainerModePermissions }} +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create + - get +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete +{{- end }} diff --git a/charts/actions-runner-controller/values.yaml b/charts/actions-runner-controller/values.yaml index 6137f62d..f0540b09 100644 --- a/charts/actions-runner-controller/values.yaml +++ b/charts/actions-runner-controller/values.yaml @@ -71,6 +71,13 @@ runner: statusUpdateHook: enabled: false +rbac: + # # This allows ARC to dynamically create a ServiceAccount and a Role for each Runner pod that uses "kubernetes" container mode, + # # by extending ARC's manager role to have the same permissions required by the pod runs the runner agent in "kubernetes" container mode. + # # Without this, Kubernetes blocks ARC to create the role to prevent a priviledge escalation. + # # See https://github.com/actions-runner-controller/actions-runner-controller/pull/1268/files#r917327010 + # allowGrantingKubernetesContainerModePermissions: true + serviceAccount: # Specifies whether a service account should be created create: true diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index f4c4c8d2..5658b507 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -105,6 +105,10 @@ func TestE2E(t *testing.T) { } t.Run("RunnerSets", func(t *testing.T) { + if os.Getenv("ARC_E2E_SKIP_RUNNERSETS") != "" { + t.Skip("RunnerSets test has been skipped due to ARC_E2E_SKIP_RUNNERSETS") + } + var ( testID string )