- Git
- Brew (To install deps)
- Docker Desktop
- Kubernetes (Via Docker Desktop)
- VS Code
- Kubernetes Extension (VS Code)
- Freelens
- Download Docker Desktop from official installer
- Once installed: Docker Desktop → Settings → Kubernetes → check “Enable Kubernetes.”
- Configure: Docker Desktop → Settings → Resources, to the max settings you can allocate from your machine.
-
This will spin up a single-node K8s cluster inside Docker.
-
kubectl is bundled with Docker Desktop.
- Download VS Code from the official installer.
- Install the Official Kubernetes extension
- This is a GUI tool for viewing Kubernetes under the hood.
brew install --cask freelens
brew install helm
kubectl create namespace gitlab
- GitLab CE Omnibus in K8s (simple, one pod).
kubectl apply -n gitlab -f - <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab
labels:
app: gitlab
spec:
replicas: 1
selector:
matchLabels:
app: gitlab
template:
metadata:
labels:
app: gitlab
spec:
containers:
- name: gitlab
image: gitlab/gitlab-ce:latest
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: ssh
containerPort: 22
volumeMounts:
- name: gitlab-data
mountPath: /var/opt/gitlab
- name: gitlab-logs
mountPath: /var/log/gitlab
- name: gitlab-config
mountPath: /etc/gitlab
volumes:
- name: gitlab-data
emptyDir: {}
- name: gitlab-logs
emptyDir: {}
- name: gitlab-config
emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
name: gitlab
spec:
type: NodePort
selector:
app: gitlab
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
- name: https
protocol: TCP
port: 443
targetPort: 443
nodePort: 30443
- name: ssh
protocol: TCP
port: 22
targetPort: 22
nodePort: 30022
EOF
kubectl exec -n gitlab deploy/gitlab -- cat /etc/gitlab/initial_root_password
-
GitLab UI at
http://localhost:30080 -
Git over SSH at port
30022 -
HTTPS (self-signed inside container) at
https://localhost:30443
- Inside of a terminal window
kubectl exec -n gitlab deploy/gitlab -it -- bash -lc '
cat > /etc/gitlab/gitlab.rb <<CFG
external_url "http://localhost:30080"
gitlab_rails["gitlab_shell_ssh_port"] = 30022
nginx["listen_port"] = 80
nginx["listen_https"] = false
CFG
gitlab-ctl reconfigure
'
-
Admin → Runners → Create instance runner (since you want a cluster-wide runner)
-
Check:
Run untagged jobs(Since we want all jobs to run) -
Runner description:
Kuber Cluster(nameing doesn't really matter) -
Click
Create Runner, no other options are needed.
-
Since we are installing the Kuber runner via Helm, you do not run gitlab-runner registration manually. (Typical Installs)
-
We pass the runner auth token to the Helm Chart values then it auto-registers and syncs, then runs as expected.
-
We have a script that will handle all Helm creation, namespacing, and installing the runner:
-
chmod +x install-runner.sh -
./install-runner.sh -
GitLab UI will confirm the new runner is registered.
-
Apple-Silicon gotcha. Runner is arm64, but the job’s init container tries to pull the x86_64 helper image - FIX:
-
NOTE: This will take a while to clean up.
# 1) Get a single runner version like "18.3.1"
VER=$(kubectl -n gitlab-runner exec deploy/gitlab-runner -- \
sh -lc 'gitlab-runner --version | awk "/^Version:/ {print \$2; exit} /^gitlab-runner / {print \$2; exit}"')
echo "Runner version: $VER" # should print something like 18.3.1
# 2) Create the override file (arm64 helper image)
cat > /tmp/runner-arm64-values.yaml <<EOF
runners:
config: |
[[runners]]
[runners.kubernetes]
image = "alpine:3.20"
helper_image = "registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:arm64-v${VER}"
EOF
# 3) Apply it on top of your current release
helm upgrade gitlab-runner gitlab/gitlab-runner \
-n gitlab-runner \
-f /tmp/runner-arm64-values.yaml \
--reuse-values
# 4) Wait for rollout, then re-run your pipeline
kubectl rollout status -n gitlab-runner deploy/gitlab-runner
VER=$(kubectl -n gitlab-runner exec deploy/gitlab-runner -- \
sh -lc 'gitlab-runner --version | awk "/^Version:/ {print \$2; exit} /^gitlab-runner / {print \$2; exit}"')
echo "Runner version: $VER"
cat > /tmp/runner-values.yaml <<EOF
runners:
config: |
[[runners]]
clone_url = "http://gitlab.gitlab.svc.cluster.local/"
[runners.kubernetes]
image = "alpine:3.20"
helper_image = "registry.gitlab.com/gitlab-org/gitlab-runner/gitlab-runner-helper:arm64-v${VER}"
EOF
helm upgrade gitlab-runner gitlab/gitlab-runner \
-n gitlab-runner \
-f /tmp/runner-values.yaml \
--reuse-values
kubectl rollout status -n gitlab-runner deploy/gitlab-runner
http://localhost:30080/projects/new#blank_project
-
Create file
.gitlab-ci.yml -
Contents:
stages: [test]
hello:
stage: test
image: alpine:3.20
script:
- echo "Hello from K8s runner on $(uname -m)"
- Commit those changes to new branch, and auto-open MR.
- It should pass
- Modify Pipeline to use RHEL 10, from RedHat package Registry
stages: [test]
hello:
stage: test
image: registry.access.redhat.com/ubi10/ubi:latest
script:
- echo "Hello from K8s runner on $(uname -m)"
- cat /etc/redhat-release