- Đăng vào
Thiết lập GitHub ARC runner để chạy job trong container
Giới thiệu
Trong chuổi các bài viết liên quan đến Kubernetes, mình có giới thiệu đến việc triển khai GitHub ARC trên Kubernetes để tạo Self-hosted runner có thể tự đông scale (mở rộng) dựa theo số lượng job cần chạy.
Self-hosted runner chính là các runner do chính người dùng cung cấp, dùng để thực hiện các tác vụ CI/CD bên cạnh các runner do GitHub cung cấp và người dùng phải trả tiền theo tài nguyên sử dụng.
Tuy nhiên do bản thân runner đang chạy ở dạng container nên nếu workflow của bạn có chạy dạng container job sẽ dẫn tới vấn đề cần thiết lập docker trong một container (DinD).
Bài viết này sẽ hướng dẫn cách cấu hình để cho phép làm được điều đó
Runner image
Đầu tiên, mình sẽ hướng dẫn cách tạo docker image dành cho runner, trong Dockerfile của nó sẽ chứa những cấu hình, công cụ cần thiết để khi container chạy có thể phục vụ được các tác vụ CI/CD.
Nếu như đọc kỹ vào helm chart gha-runner-scale-set
thì mặc định, pod runner sẽ sử dụng image ghcr.io/actions/actions-runner:latest
Dưới đây là dockerfile của pod runner
# Source: https://github.com/dotnet/dotnet-docker
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy as build
ARG TARGETOS
ARG TARGETARCH
ARG RUNNER_VERSION
ARG RUNNER_CONTAINER_HOOKS_VERSION=0.6.1
ARG DOCKER_VERSION=27.3.1
ARG BUILDX_VERSION=0.18.0
RUN apt update -y && apt install curl unzip -y
WORKDIR /actions-runner
RUN export RUNNER_ARCH=${TARGETARCH} \
&& if [ "$RUNNER_ARCH" = "amd64" ]; then export RUNNER_ARCH=x64 ; fi \
&& curl -f -L -o runner.tar.gz https://github.com/actions/runner/releases/download/v${RUNNER_VERSION}/actions-runner-${TARGETOS}-${RUNNER_ARCH}-${RUNNER_VERSION}.tar.gz \
&& tar xzf ./runner.tar.gz \
&& rm runner.tar.gz
RUN curl -f -L -o runner-container-hooks.zip https://github.com/actions/runner-container-hooks/releases/download/v${RUNNER_CONTAINER_HOOKS_VERSION}/actions-runner-hooks-k8s-${RUNNER_CONTAINER_HOOKS_VERSION}.zip \
&& unzip ./runner-container-hooks.zip -d ./k8s \
&& rm runner-container-hooks.zip
RUN export RUNNER_ARCH=${TARGETARCH} \
&& if [ "$RUNNER_ARCH" = "amd64" ]; then export DOCKER_ARCH=x86_64 ; fi \
&& if [ "$RUNNER_ARCH" = "arm64" ]; then export DOCKER_ARCH=aarch64 ; fi \
&& curl -fLo docker.tgz https://download.docker.com/${TARGETOS}/static/stable/${DOCKER_ARCH}/docker-${DOCKER_VERSION}.tgz \
&& tar zxvf docker.tgz \
&& rm -rf docker.tgz \
&& mkdir -p /usr/local/lib/docker/cli-plugins \
&& curl -fLo /usr/local/lib/docker/cli-plugins/docker-buildx \
"https://github.com/docker/buildx/releases/download/v${BUILDX_VERSION}/buildx-v${BUILDX_VERSION}.linux-${TARGETARCH}" \
&& chmod +x /usr/local/lib/docker/cli-plugins/docker-buildx
FROM mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy
ENV DEBIAN_FRONTEND=noninteractive
ENV RUNNER_MANUALLY_TRAP_SIG=1
ENV ACTIONS_RUNNER_PRINT_LOG_TO_STDOUT=1
ENV ImageOS=ubuntu22
# 'gpg-agent' and 'software-properties-common' are needed for the 'add-apt-repository' command that follows
RUN apt update -y \
&& apt install -y --no-install-recommends sudo lsb-release gpg-agent software-properties-common curl jq unzip \
&& rm -rf /var/lib/apt/lists/*
# Configure git-core/ppa based on guidance here: https://git-scm.com/download/linux
RUN add-apt-repository ppa:git-core/ppa \
&& apt update -y \
&& apt install -y git \
&& rm -rf /var/lib/apt/lists/*
RUN adduser --disabled-password --gecos "" --uid 1001 runner \
&& groupadd docker --gid 123 \
&& usermod -aG sudo runner \
&& usermod -aG docker runner \
&& echo "%sudo ALL=(ALL:ALL) NOPASSWD:ALL" > /etc/sudoers \
&& echo "Defaults env_keep += \"DEBIAN_FRONTEND\"" >> /etc/sudoers
WORKDIR /home/runner
COPY /actions-runner .
COPY /usr/local/lib/docker/cli-plugins/docker-buildx /usr/local/lib/docker/cli-plugins/docker-buildx
RUN install -o root -g root -m 755 docker/* /usr/bin/ && rm -rf docker
USER runner
Trên thực tế thì, khi chúng ta sử dụng GitHub Actions, sẽ có rất nhiều trường hợp cần chạy container job và đòi hỏi runner phải có Docker daemon hay Docker host. Khi runner của chúng ta triển khai bằng ARC trên Kubernetes, bản thân nó đang chạy ở dạng container (Pod), việc cài đặt Docker engine trên một container người ta hay gọi là Docker in Docker (DinD)
Với image ở trên chúng ta chỉ mới có docker client, để runner có thể chạy được container job chúng ta thấy trên chart gha-runner-scale-set
có một thiết lập containerMode.type=dind
trong values.yaml
, theo như giải thích thì với cấu hình này, runner chạy với 2 container, trong đó 1 container là docker.io/docker:dind
đóng vài trò là docker host. Còn container còn lại, sử dụng image ghcr.io/actions/actions-runner
và nó sử dụng DOCKER_HOST
lấy từ container docker:dind
.
...
template:
spec:
initContainers:
- name: init-dind-externals
image: ghcr.io/actions/actions-runner:latest
command: ["cp", "-r", "-v", "/home/runner/externals/.", "/home/runner/tmpDir/"]
volumeMounts:
- name: dind-externals
mountPath: /home/runner/tmpDir
containers:
- name: runner
image: ghcr.io/actions/actions-runner:latest
command: ["/home/runner/run.sh"]
env:
- name: DOCKER_HOST
value: unix:///var/run/docker.sock
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-sock
mountPath: /var/run
- name: dind
image: docker:dind
args:
- dockerd
- --host=unix:///var/run/docker.sock
- --group=$(DOCKER_GROUP_GID)
env:
- name: DOCKER_GROUP_GID
value: "123"
securityContext:
privileged: true
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: dind-sock
mountPath: /var/run
- name: dind-externals
mountPath: /home/runner/externals
volumes:
- name: work
emptyDir: {}
- name: dind-sock
emptyDir: {}
- name: dind-externals
emptyDir: {}
...
Như vậy, đây là cách chính thống để giải quyết DinD cho GitHub ARC.
Ở các bài viết tiếp theo, mình sẽ giới thiệu 1 cách nữa để thiết lập docker trên runner.
Chúc thành công,
ANH NGUYỄN
Hiện tại mình đang tìm kiếm công việc mới với nhiều thử thách để chinh phục.
Mọi thông tin có thể gửi về me@nvtienanh.info.