Подготовка инфраструктуры
Важно: раздел описывает подготовку инфраструктуры для self-hosted GitHub Runner
Требования
- GitHub Actions;
- Кластер Kubernetes;
- Helm;
-
Хост для запуска GitHub Runner, с установленным:
- Bash;
Включите поддержку непривилегированных пространств имён пользователей (требуется на worker-нодах)
sudo sysctl -w kernel.unprivileged_userns_clone=1
echo 'kernel.unprivileged_userns_clone = 1' | sudo tee -a /etc/sysctl.conf
Установка контроллера GitHub Actions Runner (ARC)
Установите Helm-чарт контроллера ARC:
helm install arc \
--namespace arc-systems \
--create-namespace \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
Создание Kubernetes ресурсов
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: job-template-gha-runner-werf
namespace: arc-runners
data:
content: |
spec:
serviceAccountName: arc-runner-sa
securityContext:
runAsUser: 1001
containers:
- name: \$job
EOF
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: arc-runner-sa
namespace: arc-runners
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: arc-runner-cluster-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: arc-runner-sa
namespace: arc-runners
EOF
Примечание Для повышения безопасности рекомендуется создать более ограниченную роль (ClusterRole/Role) и использовать её вместо
cluster-admin
.
Развертывание
Создайте файл values.yaml
со следующим содержимым:
githubConfigUrl: "https://github.com/myenterprise/myorg/myrepo"
githubConfigSecret:
github_token: "<PAT>"
template:
spec:
serviceAccountName: arc-runner-sa
containers:
- name: runner
image: ghcr.io/actions/actions-runner:latest
command: ["/home/runner/run.sh"]
env:
- name: ACTIONS_RUNNER_CONTAINER_HOOKS
value: /home/runner/k8s/index.js
- name: ACTIONS_RUNNER_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER
value: "true"
- name: ACTIONS_RUNNER_CONTAINER_HOOK_TEMPLATE
value: /home/runner/job-template/content
volumeMounts:
- name: work
mountPath: /home/runner/_work
- name: job-template
mountPath: /home/runner/job-template
readOnly: true
resources:
requests:
cpu: 400m
memory: 800Mi
volumes:
- name: job-template
configMap:
name: job-template-gha-runner-werf
- name: work
ephemeral:
volumeClaimTemplate:
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "<your-storageClassName>"
resources:
requests:
storage: 1Gi
job:
enabled: true
resources:
requests:
cpu: 500m
memory: 1024Mi
limits:
memory: 2048Mi
helm install arc-runner-set -f values.yaml \
--create-namespace \
--namespace arc-runners \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
Настройка проекта
Требования
- Self-hosted GitHub runner.
Настройка проекта GitHub
-
Создайте и сохраните access token для очистки ненужных образов из container registry со следующей конфигурацией:
-
Token name:
werf-images-cleanup
; -
Scopes:
read:packages
иdelete:packages
.
-
-
В секреты проекта добавьте следующую переменную:
-
Access token для очистки ненужных образов:
-
Name:
REGISTRY_CLEANUP_TOKEN
; -
Secret:
<сохранённый "werf-images-cleanup" access token>
.
-
-
-
Сохраните kubeconfig-файл для доступа к Kubernetes-кластеру в зашифрованный секрет
KUBECONFIG_BASE64
, предварительно закодировав его в Base64.
Конфигурация CI/CD проекта
Так может выглядеть репозиторий, использующий werf для сборки и развертывания:
name: cleanup
on:
schedule:
- cron: "0 3 * * *"
jobs:
cleanup:
name: cleanup
runs-on: arc-runner-set
container:
image: ghcr.io/werf/werf:2-stable-ubuntu
steps:
- uses: actions/checkout@v3
- run: git fetch --prune --unshallow
- run: |
. "$(werf ci-env github --as-file)"
werf cleanup
env:
WERF_KUBECONFIG_BASE64: ${{ secrets.KUBECONFIG_BASE64 }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WERF_REPO_GITHUB_TOKEN: ${{ secrets.REGISTRY_CLEANUP_TOKEN }}
name: prod
on:
push:
branches:
- main
jobs:
prod:
name: prod
runs-on: arc-runner-set
container:
image: ghcr.io/werf/werf:2-stable-ubuntu
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- run: |
. "$(werf ci-env github --as-file)"
werf converge
env:
WERF_ENV: prod
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WERF_KUBECONFIG_BASE64: ${{ secrets.KUBECONFIG_BASE64 }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
spec:
containers:
- name: app
image: {{ .Values.werf.image.app }}
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: app
ports:
- name: app
port: 80
FROM node
WORKDIR /app
COPY . .
RUN npm ci
CMD ["node", "server.js"]
{
"name": "app",
"version": "1.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "app",
"version": "1.0.0"
}
}
}
{
"name": "app",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"start": "node server.js"
}
}
const http = require('http');
const hostname = '127.0.0.1';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
configVersion: 1
project: myproject
---
image: app
dockerfile: Dockerfile
context: ./app
Дополнительно:
-
Если вы не используете GitHub Container Registry в качестве реестра контейнеров, выполните следующие действия:
- Установите переменную окружения
WERF_REPO
в адрес вашего реестра контейнеров; - Выполните вход в реестр с помощью команды werf cr login;
- При выполнении очистки обязательно ознакомьтесь с особенностями работы выбранного реестра, которые могут повлиять на поведение очистки.
- Установите переменную окружения
-
Подробнее о подключении к Kubernetes смотрите в документации по аутентификации.