1497 lines
50 KiB
Markdown
1497 lines
50 KiB
Markdown
# Настройка Gitea Actions для Go проекта: Полное руководство
|
||
|
||
**readTime:** 15-20 минут
|
||
**date:** 2025-07-27 18:00
|
||
**author:** Direct-Dev(aka Антон Кузнецов)
|
||
**level:** Средний
|
||
**tags:** #gitea #gitea-actions #ci-cd #go #docker #devops #automation #k3s
|
||
|
||
## Содержание
|
||
|
||
1. [Введение](#введение)
|
||
2. [Подготовка проекта](#подготовка-проекта)
|
||
3. [Настройка Gitea Actions](#настройка-gitea-actions)
|
||
4. [Создание workflow файла](#создание-workflow-файла)
|
||
5. [Настройка секретов](#настройка-секретов)
|
||
6. [Тестирование и запуск](#тестирование-и-запуск)
|
||
7. [Мониторинг и отладка](#мониторинг-и-отладка)
|
||
8. [Заключение](#заключение)
|
||
9. [Инфраструктура](#инфраструктура)
|
||
10. [Установка Gitea в кластере K3s](#установка-gitea-в-кластере-k3s)
|
||
11. [Настройка Gitea Runner в LXC контейнере](#настройка-gitea-runner-в-lxc-контейнере)
|
||
|
||
## Введение
|
||
|
||
Gitea Actions — это встроенная система непрерывной интеграции и развертывания (CI/CD) в Gitea, которая позволяет автоматизировать процессы сборки, тестирования и развертывания ваших проектов. Большой плюс этой системы в том, что она достаточна не требовательна к ресурсам и может быть развернута в собственном изолированном окружении.
|
||
|
||
В этой статье мы рассмотрим пример работы с данной системой, на примере того как настроить Gitea Actions для Go проекта с автоматической сборкой мультиплатформенных бинарников, созданием Docker образов и публикацией релизов.
|
||
|
||
### Итак, что мы будем делать
|
||
|
||
- Настроим автоматическую сборку Go приложения для разных платформ
|
||
- Создадим Docker образы для Linux AMD64 и ARM64
|
||
- Настроим публикацию в Docker Hub
|
||
- Автоматизируем создание релизов с бинарниками
|
||
- Настроим триггеры на основе Git тегов
|
||
|
||
## Подготовка проекта
|
||
|
||
### Структура проекта
|
||
|
||
Собственно функциональная часть проекта Go не блещет оригинальностью и имеет следующую простую структуру:
|
||
|
||
```
|
||
hello_gitea/
|
||
├── main.go # Основной код приложения
|
||
├── go.mod # Зависимости Go
|
||
├── go.sum # Хеши зависимостей
|
||
├── Dockerfile # Docker образ
|
||
├── .gitea/ # Конфигурация Gitea Actions
|
||
└── workflows/
|
||
└── build.yaml # Workflow для сборки
|
||
├── README.md # Документация
|
||
└── .gitignore # Исключения Git
|
||
```
|
||
|
||
### Анализ кода
|
||
|
||
Для упрощения востприятия не применяются сложные архитектурные паттерны и концепции - нам надо просто минимальное Go приложение. Тем не менее это работоспособный http api сервер, который можно расширить парой тройкой эндпойнтов и использовать в других проектах как заглушку или тестовый api.
|
||
|
||
Основная задача статьи не в написании api сервера на Go, а в автоматизации процесса его сборки.
|
||
|
||
Наше приложение — это простой REST API сервер на Go с использованием Gin framework:
|
||
|
||
```go
|
||
package main
|
||
|
||
import (
|
||
"net/http"
|
||
"os"
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
const version = "1.0.0"
|
||
|
||
func main() {
|
||
gin.SetMode(gin.ReleaseMode)
|
||
r := gin.Default()
|
||
|
||
// CORS middleware
|
||
r.Use(func(c *gin.Context) {
|
||
c.Header("Access-Control-Allow-Origin", "*")
|
||
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
||
c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
|
||
|
||
if c.Request.Method == "OPTIONS" {
|
||
c.AbortWithStatus(http.StatusNoContent)
|
||
return
|
||
}
|
||
c.Next()
|
||
})
|
||
|
||
// Endpoints
|
||
r.GET("/health", func(c *gin.Context) {
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"status": "ok",
|
||
"version": version,
|
||
})
|
||
})
|
||
|
||
r.GET("/", func(c *gin.Context) {
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"message": "Hello, World!",
|
||
"version": version,
|
||
})
|
||
})
|
||
|
||
// API group
|
||
api := r.Group("/api/v1")
|
||
{
|
||
api.GET("/info", func(c *gin.Context) {
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"service": "hello-api",
|
||
"version": version,
|
||
"status": "running",
|
||
})
|
||
})
|
||
|
||
api.POST("/echo", func(c *gin.Context) {
|
||
var request struct {
|
||
Message string `json:"message"`
|
||
}
|
||
|
||
if err := c.ShouldBindJSON(&request); err != nil {
|
||
c.JSON(http.StatusBadRequest, gin.H{
|
||
"error": "Invalid JSON",
|
||
})
|
||
return
|
||
}
|
||
|
||
c.JSON(http.StatusOK, gin.H{
|
||
"echo": request.Message,
|
||
"version": version,
|
||
})
|
||
})
|
||
}
|
||
|
||
port := os.Getenv("PORT")
|
||
if port == "" {
|
||
port = "8080"
|
||
}
|
||
|
||
r.Run(":" + port)
|
||
}
|
||
```
|
||
|
||
### Dockerfile
|
||
|
||
Помимо того, что мы будем собирать бинарники для разных платформ, мы также настроим сборку docker image в котором будем
|
||
запускать наш сервер api - это может быть полезным для развертывания нашего приложения, если мы настроим такое - например
|
||
через ArgoCD или flux (впрочем это тема отдельнйо статьи).
|
||
|
||
Итак для контейнеризации используем многоэтапную сборку, что как вещают мудрецы является якобы полезным и правильным.
|
||
Не будем спорить поэтому вот:
|
||
|
||
```dockerfile
|
||
# Build stage
|
||
FROM --platform=$BUILDPLATFORM golang:1.21-alpine AS builder
|
||
|
||
RUN apk --no-cache add git ca-certificates
|
||
WORKDIR /app
|
||
|
||
COPY go.mod go.sum ./
|
||
RUN go mod download
|
||
|
||
COPY . .
|
||
|
||
ARG TARGETPLATFORM
|
||
ARG BUILDPLATFORM
|
||
ARG TARGETOS
|
||
ARG TARGETARCH
|
||
|
||
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -a -installsuffix cgo -o hello-api main.go
|
||
|
||
# Final stage
|
||
FROM alpine:latest
|
||
|
||
RUN apk --no-cache add ca-certificates jq
|
||
|
||
RUN addgroup -g 1001 -S appgroup && \
|
||
adduser -u 1001 -S appuser -G appgroup
|
||
|
||
WORKDIR /app
|
||
COPY --from=builder /app/hello-api .
|
||
RUN chown appuser:appgroup hello-api
|
||
|
||
USER appuser
|
||
EXPOSE 8080
|
||
CMD ["./hello-api"]
|
||
```
|
||
|
||
**Ремарка:**
|
||
|
||
Тут хочется немного поразмышлять - по хорошему надо или разобраться в вариантах кэширования gitea или в качестве
|
||
базововго образа для каждого из этапов использовать предварительно собранный образ со всем необходимым.
|
||
При каждом запуске workflow будет запускаться новый контейнер docker in docker и там запускаться построение образа естественно кэшей не будет или надо как то придумывать как их хранить на ранере и пробрасывать в dind. Ну или руками сделать нужные образы и использоват их в Dockerfile. Правда пулиться они опять же будут походу каждый раз. Короче говоря тут есть чем поразбираться и пооптимизировать ...
|
||
|
||
|
||
## Настройка Gitea Actions
|
||
|
||
### Включение Actions в Gitea
|
||
|
||
1. **Проверьте версию Gitea**
|
||
|
||
Gitea Actions доступны начиная с версии 1.17.0. Убедитесь, что ваш сервер Gitea поддерживает Actions.
|
||
|
||
2. **Включите Actions в настройках репозитория**
|
||
|
||
- Перейдите в настройки репозитория
|
||
- Найдите раздел "Actions"
|
||
- Включите "Enable Actions"
|
||
|
||
### Создание токена доступа
|
||
|
||
1. **Создайте токен для Actions**
|
||
|
||
- Перейдите в настройки профиля → "Applications"
|
||
- Создайте новый токен с правами на репозиторий
|
||
- Скопируйте токен (он понадобится позже)
|
||
|
||
## Создание workflow файла
|
||
|
||
### Структура директории
|
||
|
||
Создайте директорию `.gitea/workflows/` в корне вашего проекта:
|
||
|
||
```bash
|
||
mkdir -p .gitea/workflows
|
||
```
|
||
|
||
### Основной workflow файл
|
||
|
||
Создайте файл `.gitea/workflows/build.yaml`:
|
||
|
||
```yaml
|
||
name: Release Build
|
||
on:
|
||
push:
|
||
tags:
|
||
- v*
|
||
|
||
jobs:
|
||
create-docker-image:
|
||
runs-on: ubuntu-latest
|
||
container:
|
||
image: docker:28.3.2-dind
|
||
steps:
|
||
- name: Checkout repository
|
||
run: |
|
||
# Install git
|
||
apk add --no-cache git
|
||
|
||
echo "=== GitHub Variables ==="
|
||
echo "github.ref = ${{ github.ref }}"
|
||
echo "github.ref_name = ${{ github.ref_name }}"
|
||
echo "github.sha = ${{ github.sha }}"
|
||
echo "github.repository = ${{ github.repository }}"
|
||
echo "========================"
|
||
git clone https://oauth2:${{ secrets.GITEATOKEN }}@direct-dev.ru/gitea/GiteaAdmin/hello_gitea.git hello_gitea
|
||
cd hello_gitea
|
||
git checkout ${{ github.ref }}
|
||
|
||
- name: Setup Docker Buildx
|
||
run: |
|
||
# Docker is already installed in docker:dind image
|
||
docker --version
|
||
|
||
# Setup Docker Buildx for multi-platform builds
|
||
docker buildx create --use
|
||
docker buildx inspect --bootstrap
|
||
|
||
- name: Login to Docker Hub
|
||
run: |
|
||
echo ${{ secrets.DOCKERHUB_TOKEN }} | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
|
||
|
||
- name: Build multi-platform Docker images
|
||
run: |
|
||
cd hello_gitea
|
||
# Build multi-platform images using buildx
|
||
docker buildx build \
|
||
--platform linux/amd64,linux/arm64 \
|
||
--tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:${{ github.ref_name }} \
|
||
--tag ${{ secrets.DOCKERHUB_USERNAME }}/hello-api:latest \
|
||
--push \
|
||
.
|
||
|
||
create-release:
|
||
runs-on: ubuntu-latest
|
||
container:
|
||
image: golang:1.21
|
||
needs: create-docker-image
|
||
steps:
|
||
- name: Checkout repository
|
||
run: |
|
||
git clone https://oauth2:${{ secrets.GITEATOKEN }}@direct-dev.ru/gitea/GiteaAdmin/hello_gitea.git hello_gitea
|
||
cd hello_gitea
|
||
git checkout ${{ github.ref }}
|
||
|
||
- name: Setup Go
|
||
run: |
|
||
# Install jq for JSON parsing
|
||
apt-get update && apt-get install -y jq
|
||
git --version
|
||
go version
|
||
jq --version
|
||
|
||
- name: Build all binaries
|
||
run: |
|
||
cd hello_gitea
|
||
mkdir -p bin
|
||
|
||
# Build for all platforms
|
||
GOOS=linux GOARCH=amd64 go build -o bin/hello-api-linux-amd64 main.go
|
||
GOOS=linux GOARCH=arm64 go build -o bin/hello-api-linux-arm64 main.go
|
||
GOOS=windows GOARCH=amd64 go build -o bin/hello-api-windows-amd64.exe main.go
|
||
GOOS=darwin GOARCH=amd64 go build -o bin/hello-api-darwin-amd64 main.go
|
||
GOOS=darwin GOARCH=arm64 go build -o bin/hello-api-darwin-arm64 main.go
|
||
|
||
# Create archives
|
||
cd bin
|
||
tar -czf hello-api-linux-amd64.tar.gz hello-api-linux-amd64
|
||
tar -czf hello-api-linux-arm64.tar.gz hello-api-linux-arm64
|
||
tar -czf hello-api-windows-amd64.tar.gz hello-api-windows-amd64.exe
|
||
tar -czf hello-api-darwin-amd64.tar.gz hello-api-darwin-amd64
|
||
tar -czf hello-api-darwin-arm64.tar.gz hello-api-darwin-arm64
|
||
|
||
ls -la
|
||
|
||
- name: Create Release
|
||
run: |
|
||
cd hello_gitea
|
||
# Create release using Gitea API
|
||
curl -X POST \
|
||
-H "Authorization: token ${{ secrets.GITEATOKEN }}" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"tag_name": "${{ github.ref_name }}",
|
||
"name": "Release ${{ github.ref_name }}",
|
||
"body": "Automated release with multi-platform binaries and Docker image",
|
||
"draft": false,
|
||
"prerelease": false
|
||
}' \
|
||
"https://direct-dev.ru/gitea/api/v1/repos/GiteaAdmin/hello_gitea/releases"
|
||
|
||
# Upload assets
|
||
RELEASE_ID=$(curl -s -H "Authorization: token ${{ secrets.GITEATOKEN }}" \
|
||
"https://direct-dev.ru/gitea/api/v1/repos/GiteaAdmin/hello_gitea/releases/tags/${{ github.ref_name }}" | \
|
||
jq -r '.id')
|
||
|
||
# Upload all binaries
|
||
for file in bin/*.tar.gz; do
|
||
echo "Uploading $file..."
|
||
curl -X POST \
|
||
-H "Authorization: token ${{ secrets.GITEATOKEN }}" \
|
||
-H "Content-Type: application/octet-stream" \
|
||
--data-binary @$file \
|
||
"https://direct-dev.ru/gitea/api/v1/repos/GiteaAdmin/hello_gitea/releases/$RELEASE_ID/assets?name=$(basename $file)"
|
||
done
|
||
```
|
||
|
||
### Объяснение workflow
|
||
|
||
**Триггеры:**
|
||
- Workflow запускается при создании тега, начинающегося с `v*` (например, `v1.0.0`)
|
||
|
||
**Jobs:**
|
||
|
||
1. **create-docker-image:**
|
||
- Использует Docker-in-Docker контейнер
|
||
- Настраивает Docker Buildx для мультиплатформенной сборки
|
||
- Авторизуется в Docker Hub
|
||
- Собирает образы для Linux AMD64 и ARM64
|
||
- Публикует образы с тегом версии и `latest`
|
||
|
||
2. **create-release:**
|
||
- Запускается после успешной сборки Docker образов
|
||
- Использует Go контейнер для сборки бинарников
|
||
- Собирает бинарники для всех платформ (Linux, Windows, macOS)
|
||
- Создает архивы с бинарниками
|
||
- Создает релиз через Gitea API
|
||
- Загружает бинарники как assets релиза
|
||
|
||
## Настройка секретов
|
||
|
||
### Необходимые секреты
|
||
|
||
В настройках репозитория → "Secrets and variables" → "Actions" добавьте следующие секреты:
|
||
|
||
1. **GITEATOKEN**
|
||
- Токен доступа к Gitea API
|
||
- Используется для клонирования репозитория и создания релизов
|
||
|
||
2. **DOCKERHUB_USERNAME**
|
||
- Ваше имя пользователя в Docker Hub
|
||
- Используется для публикации образов
|
||
|
||
3. **DOCKERHUB_TOKEN**
|
||
- Токен доступа к Docker Hub
|
||
- Используется для авторизации в Docker Hub
|
||
|
||
### Создание токенов
|
||
|
||
**Gitea Token:**
|
||
1. Перейдите в настройки профиля → "Applications"
|
||
2. Создайте новый токен с правами на репозиторий
|
||
3. Скопируйте токен
|
||
|
||
**Docker Hub Token:**
|
||
1. Войдите в Docker Hub
|
||
2. Перейдите в Account Settings → Security
|
||
3. Создайте новый Access Token
|
||
4. Скопируйте токен
|
||
|
||
## Тестирование и запуск
|
||
|
||
### Локальное тестирование
|
||
|
||
1. **Проверьте синтаксис workflow:**
|
||
```bash
|
||
# Убедитесь, что YAML синтаксис корректен
|
||
yamllint .gitea/workflows/build.yaml
|
||
```
|
||
|
||
2. **Протестируйте сборку локально:**
|
||
```bash
|
||
# Сборка для текущей платформы
|
||
go build -o hello-api main.go
|
||
|
||
# Сборка для других платформ
|
||
GOOS=linux GOARCH=amd64 go build -o hello-api-linux-amd64 main.go
|
||
GOOS=linux GOARCH=arm64 go build -o hello-api-linux-arm64 main.go
|
||
```
|
||
|
||
3. **Тестирование Docker образа:**
|
||
```bash
|
||
# Сборка образа
|
||
docker build -t hello-api:test .
|
||
|
||
# Запуск контейнера
|
||
docker run -p 8080:8080 hello-api:test
|
||
|
||
# Тестирование API
|
||
curl http://localhost:8080/health
|
||
```
|
||
|
||
### Запуск Actions
|
||
|
||
1. **Создайте тег:**
|
||
```bash
|
||
git tag v1.0.0
|
||
git push origin v1.0.0
|
||
```
|
||
|
||
2. **Мониторинг выполнения:**
|
||
- Перейдите в репозиторий → "Actions"
|
||
- Найдите запущенный workflow
|
||
- Отслеживайте выполнение каждого job
|
||
|
||
### Ожидаемый результат
|
||
|
||
После успешного выполнения:
|
||
|
||
1. **Docker образы** будут опубликованы в Docker Hub:
|
||
- `username/hello-api:v1.0.0`
|
||
- `username/hello-api:latest`
|
||
|
||
2. **Релиз** будет создан в Gitea с бинарниками:
|
||
- `hello-api-linux-amd64.tar.gz`
|
||
- `hello-api-linux-arm64.tar.gz`
|
||
- `hello-api-windows-amd64.tar.gz`
|
||
- `hello-api-darwin-amd64.tar.gz`
|
||
- `hello-api-darwin-arm64.tar.gz`
|
||
|
||
## Мониторинг и отладка
|
||
|
||
### Просмотр логов
|
||
|
||
1. **В Gitea:**
|
||
- Перейдите в репозиторий → "Actions"
|
||
- Выберите workflow
|
||
- Нажмите на job для просмотра логов
|
||
|
||
2. **Отладка ошибок:**
|
||
- Проверьте правильность секретов
|
||
- Убедитесь в корректности путей к репозиторию
|
||
- Проверьте права доступа токенов
|
||
|
||
### Частые проблемы
|
||
|
||
1. **Ошибка авторизации в Docker Hub:**
|
||
- Проверьте правильность `DOCKERHUB_TOKEN`
|
||
- Убедитесь, что токен не истек
|
||
|
||
2. **Ошибка создания релиза:**
|
||
- Проверьте права токена `GITEATOKEN`
|
||
- Убедитесь, что тег не существует
|
||
|
||
3. **Ошибка сборки:**
|
||
- Проверьте зависимости в `go.mod`
|
||
- Убедитесь в корректности Dockerfile
|
||
|
||
### Оптимизация
|
||
|
||
1. **Кэширование зависимостей:**
|
||
```yaml
|
||
- name: Cache Go modules
|
||
uses: actions/cache@v3
|
||
with:
|
||
path: |
|
||
~/.cache/go-build
|
||
~/go/pkg/mod
|
||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||
restore-keys: |
|
||
${{ runner.os }}-go-
|
||
```
|
||
|
||
2. **Параллельная сборка:**
|
||
- Разделите сборку бинарников на отдельные jobs
|
||
- Используйте matrix strategy для разных платформ
|
||
|
||
## Заключение
|
||
|
||
В этой статье мы рассмотрели полный процесс настройки Gitea Actions для Go проекта. Мы создали автоматизированный pipeline, который:
|
||
|
||
- ✅ Собирает мультиплатформенные бинарники
|
||
- ✅ Создает Docker образы для разных архитектур
|
||
- ✅ Публикует образы в Docker Hub
|
||
- ✅ Создает релизы с бинарниками
|
||
- ✅ Запускается автоматически при создании тегов
|
||
|
||
### Преимущества такого подхода
|
||
|
||
1. **Автоматизация:** Минимизация ручной работы
|
||
2. **Консистентность:** Одинаковые условия сборки
|
||
3. **Мультиплатформенность:** Поддержка разных ОС и архитектур
|
||
4. **Безопасность:** Использование секретов для токенов
|
||
5. **Масштабируемость:** Легко добавить новые платформы или этапы
|
||
|
||
### Следующие шаги
|
||
|
||
1. Добавьте тестирование в workflow
|
||
2. Настройте автоматическое развертывание
|
||
3. Добавьте уведомления о результатах сборки
|
||
4. Настройте мониторинг и алерты
|
||
|
||
Gitea Actions предоставляет мощные возможности для автоматизации процессов разработки, и с правильной настройкой вы можете значительно упростить процесс доставки вашего ПО.
|
||
|
||
---
|
||
|
||
## Инфраструктура
|
||
|
||
### Архитектура системы
|
||
|
||
Этот и последующие разделы описывают инфраструктуру на которой я проверял все описанное выше.
|
||
Если у вас используются другие подходы, то можете пропустить их или ознакомиться для общего развития.
|
||
|
||
Итак инфраструктура состоит из следующих компонентов:
|
||
|
||
```
|
||
Proxmox VE (ARM64)
|
||
├── K3s Cluster
|
||
├── Master Node
|
||
└── Gitea Server (Helm Chart)
|
||
└── Worker Nodes
|
||
└── LXC Containers
|
||
└── Gitea Runner Container
|
||
├── Docker Engine
|
||
├── Go Toolchain
|
||
└── Build Tools
|
||
```
|
||
|
||
### Требования к системе
|
||
|
||
**Proxmox VE:**
|
||
- ARM64 архитектура
|
||
- Минимум 8GB RAM
|
||
- 100GB свободного места
|
||
- Поддержка LXC контейнеров
|
||
|
||
**K3s Cluster:**
|
||
- Kubernetes 1.24+
|
||
- Helm 3.8+
|
||
- Ingress Controller (Traefik)
|
||
- Persistent Storage (Longhorn)
|
||
|
||
**LXC Container:**
|
||
- Ubuntu 22.04 LTS
|
||
- 4GB RAM
|
||
- 20GB дискового пространства
|
||
- Docker Engine
|
||
- Go 1.21+
|
||
|
||
## Установка Gitea в кластере K3s
|
||
|
||
### Анализ существующего кластера
|
||
|
||
Ваш кластер уже настроен и работает. Вот текущая конфигурация:
|
||
|
||
**Узлы кластера:**
|
||
```bash
|
||
kubectl get nodes -o wide
|
||
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
|
||
k3s-control-01 Ready control-plane,etcd,master 544d v1.33.2+k3s1 10.xxx.x.2 10.xx.x.2 Ubuntu 20.04.6 LTS 5.10.160-rockchip-rk3588 containerd://2.0.5-k3s1
|
||
k3s-control-02 Ready control-plane,etcd,master 544d v1.33.2+k3s1 10.xxx.x.3 10.xx.x.3 Ubuntu 20.04.6 LTS 5.10.160-rockchip-rk3588 containerd://2.0.5-k3s1
|
||
k3s-control-03 Ready control-plane,etcd,master 544d v1.33.2+k3s1 10.xxx.x.4 10.xx.x.4 Ubuntu 20.04.6 LTS 6.1.31-sun50iw9 containerd://2.0.5-k3s1
|
||
```
|
||
|
||
**Существующие компоненты:**
|
||
- Kubernetes v1.33.2+k3s1
|
||
- 3 узла control-plane с etcd
|
||
- Traefik Ingress Controller
|
||
- NFS Storage Class для persistent storage
|
||
- Cert-Manager для SSL сертификатов
|
||
- Gitea уже установлен и работает
|
||
|
||
### Проверка существующей установки Gitea
|
||
|
||
```bash
|
||
# Проверка подов Gitea
|
||
kubectl get pods -n gitea
|
||
NAME READY STATUS RESTARTS AGE
|
||
gitea-798c56b58f-bsp2h 1/1 Running 0 30h
|
||
gitea-postgres-0 2/2 Running 10 (10d ago) 357d
|
||
gitea-valkey-cluster-0 1/1 Running 0 30h
|
||
gitea-valkey-cluster-1 1/1 Running 0 30h
|
||
gitea-valkey-cluster-2 1/1 Running 0 30h
|
||
|
||
# Проверка сервисов
|
||
kubectl get svc -n gitea
|
||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||
gitea-http ClusterIP None <none> 3000/TCP 543d
|
||
gitea-postgres ClusterIP 10.xx.xx.xx <none> 5432/TCP 543d
|
||
gitea-ssh ClusterIP None <none> 22/TCP 543d
|
||
gitea-valkey-cluster ClusterIP 10.xx.xx.xx <none> 6379/TCP 30h
|
||
gitea-valkey-cluster-headless ClusterIP None <none> 6379/TCP,16379/TCP 30h
|
||
|
||
# Проверка persistent storage
|
||
kubectl get pvc -n gitea
|
||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||
gitea-shared-storage Bound pvc-c869aea8-7b49-4b40-9b86-1a7fbe9b2ce8 10Gi RWO nfs 543d
|
||
pgdata-gitea-postgres-0 Bound pvc-c3405a46-594d-401f-91ae-e7398b3c5cc3 15Gi RWO nfs 543d
|
||
valkey-data-gitea-valkey-cluster-0 Bound pvc-a927baf5-b8f8-4c0b-b12f-68fbc63162d9 8Gi RWO nfs 30h
|
||
valkey-data-gitea-valkey-cluster-1 Bound pvc-b43a399b-fdf4-4c27-baf4-7056ecc4143b 8Gi RWO nfs 30h
|
||
valkey-data-gitea-valkey-cluster-2 Bound pvc-368f0ab9-7851-423f-afb9-443287c0c728 8Gi RWO nfs 30h
|
||
```
|
||
|
||
### Анализ конфигурации
|
||
|
||
**Gitea версия:** 1.24.3 (rootless)
|
||
**База данных:** PostgreSQL с persistent storage (15Gi)
|
||
**Кэш:** Valkey cluster (Redis) с 3 репликами
|
||
**Storage:** NFS Storage Class
|
||
**Ingress:** Traefik
|
||
|
||
### Настройка доступа к Gitea
|
||
|
||
Доступ к gitea лучше сделать через ingress или на худой конец через port-forward:
|
||
|
||
1. **Временный доступ через port-forward:**
|
||
|
||
```bash
|
||
# Доступ к Gitea через port-forward
|
||
kubectl port-forward -n gitea svc/gitea-http 3000:3000
|
||
|
||
# В другом терминале проверьте доступ
|
||
curl http://localhost:3000
|
||
```
|
||
|
||
2. **Создание IngressRoute для постоянного доступа:**
|
||
|
||
```yaml
|
||
# gitea-ingressroute.yaml
|
||
# image: docker.io/traefik:v3.0.0 поэтому используется абстракция
|
||
# apiVersion: traefik.io/v1alpha1
|
||
# kind: IngressRoute
|
||
|
||
apiVersion: traefik.io/v1alpha1
|
||
kind: IngressRoute
|
||
metadata:
|
||
annotations:
|
||
cert-manager.io/cluster-issuer: letsencrypt-dns-cloudflare
|
||
creationTimestamp: "2024-05-24T03:50:33Z"
|
||
name: gitea-https-route
|
||
namespace: gitea
|
||
spec:
|
||
entryPoints:
|
||
- websecure
|
||
routes:
|
||
- kind: Rule
|
||
match: Host(`direct-dev.ru`) && PathPrefix(`/gitea`)
|
||
middlewares:
|
||
- name: strip-gitea-prefix
|
||
services:
|
||
- name: gitea-http
|
||
port: 3000
|
||
tls:
|
||
secretName: le-root-direct-dev-ru
|
||
```
|
||
|
||
```bash
|
||
# Применение ingressroute
|
||
KUBECONFIG=~/.kube/config_hlab kubectl apply -f gitea-ingress.yaml
|
||
```
|
||
|
||
Таким образом мой инстанс gitea доступен с внешнего адреса https://direct-dev.ru/gitea
|
||
|
||
в /data/gitea/conf/app.ini
|
||
|
||
[server]
|
||
ROOT_URL = https://direct-dev.ru/gitea
|
||
DOMAIN = direct-dev.ru
|
||
|
||
### Конфигурация Gitea
|
||
|
||
Gitea установлен через Helm.
|
||
|
||
**Версия:** Gitea 1.24.3 (rootless)
|
||
**Архитектура:**
|
||
- PostgreSQL для базы данных (развернут отдельно )
|
||
- Valkey cluster (Redis) для кэширования
|
||
- NFS Storage Class для persistent storage
|
||
|
||
```bash
|
||
helm repo add gitea-charts https://dl.gitea.io/charts/
|
||
helm repo update
|
||
|
||
kubectl create namespace gitea
|
||
|
||
helm install gitea gitea-charts/gitea -n gitea
|
||
```
|
||
|
||
установка с кастомными значениями параметров
|
||
|
||
``` bash
|
||
helm show values gitea-charts/gitea > gitea-values.yaml
|
||
#Отредактируйте файл (например, database или service).
|
||
helm install gitea gitea-charts/gitea -n gitea -f gitea-values.yaml
|
||
```
|
||
|
||
Обновление
|
||
|
||
```bash
|
||
helm repo update
|
||
helm upgrade gitea gitea-charts/gitea -n gitea -f gitea-values.yaml
|
||
```
|
||
|
||
|
||
**Проверка конфигурации:**
|
||
|
||
```bash
|
||
# Проверка Helm релиза
|
||
helm list -n gitea
|
||
|
||
# Просмотр конфигурации
|
||
helm get values gitea -n gitea
|
||
```
|
||
|
||
```yaml
|
||
USER-SUPPLIED VALUES:
|
||
gitea:
|
||
admin:
|
||
existingSecret: xxxxxx
|
||
config:
|
||
cache:
|
||
ADAPTER: memory
|
||
database:
|
||
DB_TYPE: postgres
|
||
HOST: gitea-postgres.gitea.svc.cluster.local:5432
|
||
NAME: gitea
|
||
PASSWD: xxxxxxx
|
||
SCHEMA: gitea
|
||
USER: xxxx
|
||
indexer:
|
||
ISSUE_INDEXER_TYPE: bleve
|
||
REPO_INDEXER_ENABLED: true
|
||
queue:
|
||
TYPE: level
|
||
server:
|
||
APP_DATA_PATH: /data
|
||
DOMAIN: direct-dev.ru
|
||
ENABLE_PPROF: false
|
||
HTTP_PORT: 3000
|
||
PROTOCOL: http
|
||
ROOT_URL: https://direct-dev.ru/gitea
|
||
SSH_DOMAIN: git.k3s-cluster-01.direct-dev.ru
|
||
SSH_LISTEN_PORT: 2222
|
||
SSH_PORT: 22
|
||
service:
|
||
DISABLE_REGISTRATION: true
|
||
SHOW_REGISTRATION_BUTTON: false
|
||
session:
|
||
PROVIDER: db
|
||
persistence:
|
||
enabled: true
|
||
storageClass: nfs
|
||
postgresql:
|
||
enabled: false
|
||
postgresql-ha:
|
||
enabled: false
|
||
redis-cluster:
|
||
enabled: false
|
||
```
|
||
|
||
``` bash
|
||
# Проверка секретов
|
||
kubectl get secrets -n gitea
|
||
```
|
||
|
||
### Настройка Actions в существующем Gitea
|
||
|
||
1. **Проверка включения Actions:**
|
||
|
||
```bash
|
||
# Проверка конфигурации Actions
|
||
kubectl exec -n gitea deployment/gitea -c gitea -- cat /data/gitea/conf/app.ini"
|
||
```
|
||
|
||
2. **Включение Actions через веб-интерфейс:**
|
||
- Откройте Gitea через port-forward или ingress
|
||
- Перейдите в Site Administration → Actions
|
||
- Включите "Enable Actions"
|
||
- Настройте "Default Actions URL" (например, https://gitea.com)
|
||
|
||
3. **Проверка работы Actions:**
|
||
|
||
```bash
|
||
# Проверка логов Gitea на предмет ошибок Actions
|
||
kubectl logs -n gitea deployment/gitea | grep -i action
|
||
```
|
||
|
||
### Настройка DNS и SSL
|
||
|
||
Cert-Manager установлен. Инструкций вагон и маленькая тележка - не смысла повторяться. Проверим конфигурацию:
|
||
|
||
```bash
|
||
# Проверка Cert-Manager
|
||
kubectl get pods -n cert-manager
|
||
|
||
# Проверка ClusterIssuer
|
||
kubectl get clusterissuer
|
||
```
|
||
|
||
1. **Настройка DNS записи:**
|
||
|
||
```bash
|
||
# Добавить A-запись в DNS (у меня сloudflare)
|
||
gitea.your-domain.com -> внешний (белый) Ip - за ним пробросы портов если нужно ... чтобы в итоге запрос поступил на traefik
|
||
```
|
||
|
||
2. **Создание ClusterIssuer (если не существует):**
|
||
|
||
```bash
|
||
# Создание ClusterIssuer для Let's Encrypt - лучше через dns resolver
|
||
cat <<EOF | KUBECONFIG=~/.kube/{configfile} kubectl apply -f -
|
||
apiVersion: cert-manager.io/v1
|
||
kind: ClusterIssuer
|
||
metadata:
|
||
annotations:
|
||
name: letsencrypt-dns-cloudflare
|
||
spec:
|
||
acme:
|
||
email: info@somedomain.ru
|
||
privateKeySecretRef:
|
||
name: le-issuer-acct-key
|
||
server: https://acme-v02.api.letsencrypt.org/directory
|
||
solvers:
|
||
- dns01:
|
||
cloudflare:
|
||
apiTokenSecretRef:
|
||
key: api-token
|
||
name: cloudflare-api-token-secret
|
||
email: info@somedomain.ru
|
||
selector:
|
||
dnsZones:
|
||
- somedomain.ru
|
||
- '*.somedomain.ru'
|
||
EOF
|
||
```
|
||
|
||
### Доступ к Gitea
|
||
|
||
1. **Временный доступ через port-forward:**
|
||
|
||
```bash
|
||
# Доступ к Gitea через port-forward
|
||
kubectl port-forward -n gitea svc/gitea-http 3000:3000
|
||
|
||
# В браузере http://localhost:3000/gitea
|
||
```
|
||
|
||
2. **Постоянный доступ через ingressroute:**
|
||
|
||
``` bash
|
||
# Проверка сертификата
|
||
kubectl get certificate -n gitea
|
||
```
|
||
|
||
3. **Проверка доступа:**
|
||
|
||
```bash
|
||
# Проверка через curl
|
||
curl -I https://gitea.your-domain.com
|
||
|
||
# Проверка SSL сертификата
|
||
openssl s_client -connect gitea.your-domain.com:443 -servername gitea.your-domain.com
|
||
```
|
||
|
||
если нет сертификата
|
||
|
||
```yaml
|
||
apiVersion: cert-manager.io/v1
|
||
kind: Certificate
|
||
metadata:
|
||
annotations:
|
||
name: root-somedomain-ru
|
||
namespace: default
|
||
spec:
|
||
commonName: somedomain.ru
|
||
dnsNames:
|
||
- somedomain.ru
|
||
- www.somedomain.ru
|
||
issuerRef:
|
||
kind: ClusterIssuer
|
||
name: letsencrypt-dns-cloudflare
|
||
secretName: le-root-somedomain-ru
|
||
```
|
||
|
||
## Настройка Gitea Runner в LXC контейнере
|
||
|
||
### Создание LXC контейнера в Proxmox
|
||
|
||
Учитывая мою ARM64 архитектуру (Rockchip RK3588), контейнер надо создать с правильным шаблоном:
|
||
|
||
1. **Создание контейнера через веб-интерфейс:**
|
||
|
||
```bash
|
||
|
||
# Или через веб-интерфейс Proxmox:
|
||
# 1. Перейдите в Datacenter → local → CT Templates
|
||
# 2. Скачайте ubuntu-22.04-standard_22.04-1_arm64.tar.zst
|
||
# 3. Создайте контейнер с параметрами:
|
||
# - Template: ubuntu-22.04-standard_22.04-1_arm64
|
||
# - Memory: 4096 MB
|
||
# - Cores: 2
|
||
# - Root disk: 20 GB
|
||
# - Network: DHCP
|
||
```
|
||
|
||
2. **Настройка сети:**
|
||
|
||
```bash
|
||
# В контейнере
|
||
ip addr show
|
||
|
||
# в силу особенностей развертывания gitea раннер будет получать к нему доступ через интернет - в моем случае контейнер надо выпустить в интернет
|
||
|
||
```
|
||
|
||
### Подготовка контейнера
|
||
|
||
1. **Обновление системы:**
|
||
|
||
```bash
|
||
# В контейнере
|
||
apt update && apt upgrade -y
|
||
apt install -y curl wget git vim htop
|
||
```
|
||
|
||
2. **Установка Docker:**
|
||
|
||
```bash
|
||
# Удаление старых версий
|
||
apt remove -y docker docker-engine docker.io containerd runc
|
||
|
||
# Установка зависимостей
|
||
apt install -y \
|
||
apt-transport-https \
|
||
ca-certificates \
|
||
curl \
|
||
gnupg \
|
||
lsb-release
|
||
|
||
# Добавление GPG ключа Docker
|
||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||
|
||
# Добавление репозитория Docker
|
||
echo \
|
||
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
|
||
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||
|
||
# Установка Docker
|
||
apt update
|
||
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||
|
||
# Добавление пользователя в группу docker
|
||
usermod -aG docker $USER
|
||
|
||
# Запуск Docker
|
||
systemctl enable docker
|
||
systemctl start docker
|
||
|
||
# Проверка установки
|
||
docker --version
|
||
```
|
||
|
||
3. **Установка Go:**
|
||
|
||
```bash
|
||
# Скачивание Go для ARM64
|
||
wget https://go.dev/dl/go1.21.0.linux-arm64.tar.gz
|
||
|
||
# Распаковка
|
||
tar -C /usr/local -xzf go1.21.0.linux-arm64.tar.gz
|
||
|
||
# Настройка переменных окружения
|
||
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
|
||
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
|
||
echo 'export GOROOT=/usr/local/go' >> ~/.bashrc
|
||
source ~/.bashrc
|
||
|
||
# Проверка установки
|
||
go version
|
||
# Должно показать: go version go1.21.0 linux/arm64
|
||
|
||
# Создание рабочей директории
|
||
mkdir -p $HOME/go/{bin,src,pkg}
|
||
```
|
||
|
||
4. **Установка дополнительных инструментов:**
|
||
|
||
```bash
|
||
# Установка build tools
|
||
apt install -y build-essential
|
||
|
||
# Установка jq для JSON обработки
|
||
apt install -y jq
|
||
|
||
# Установка yamllint для проверки YAML
|
||
apt install -y yamllint
|
||
|
||
# Установка Docker Buildx
|
||
docker buildx version
|
||
```
|
||
|
||
### Установка Gitea Runner
|
||
|
||
1. **Скачивание Gitea Runner:**
|
||
|
||
```bash
|
||
# Определение архитектуры
|
||
ARCH=$(uname -m)
|
||
case $ARCH in
|
||
x86_64) ARCH=amd64 ;;
|
||
aarch64) ARCH=arm64 ;;
|
||
armv7l) ARCH=armv7 ;;
|
||
esac
|
||
|
||
# Скачивание последней версии
|
||
# visit https://dl.gitea.com/act_runner/ copy link to version and arch you need
|
||
|
||
wget https://dl.gitea.com/act_runner/0.2.12/act_runner-0.2.12-linux-arm64
|
||
|
||
# Переименование и установка
|
||
mv act_runner-0.2.12-linux-arm64 /usr/local/bin/act_runner
|
||
chmod +x /usr/local/bin/act_runner
|
||
|
||
# Проверка установки
|
||
act_runner --version
|
||
```
|
||
|
||
2. **Создание пользователя для runner:**
|
||
|
||
```bash
|
||
# Создание пользователя
|
||
useradd -m -s /bin/bash gitea-runner
|
||
usermod -aG docker gitea-runner
|
||
|
||
# Создание директории для конфигурации
|
||
mkdir -p /opt/gitea-runner
|
||
chown gitea-runner:gitea-runner /opt/gitea-runner
|
||
```
|
||
|
||
3. **Настройка конфигурации runner:**
|
||
|
||
```bash
|
||
# Переключение на пользователя runner
|
||
su - gitea-runner
|
||
|
||
# Создание конфигурационного файла
|
||
cat > /opt/gitea-runner/config.yaml <<EOF
|
||
# just run `./act_runner generate-config > config.yaml` to generate a config file.
|
||
|
||
log:
|
||
# The level of logging, can be trace, debug, info, warn, error, fatal
|
||
level: info
|
||
|
||
runner:
|
||
# Where to store the registration result.
|
||
file: .runner
|
||
# Execute how many tasks concurrently at the same time.
|
||
capacity: 1
|
||
# Extra environment variables to run jobs.
|
||
envs:
|
||
A_TEST_ENV_NAME_1: a_test_env_value_1
|
||
A_TEST_ENV_NAME_2: a_test_env_value_2
|
||
|
||
# Extra environment variables to run jobs from a file.
|
||
# It will be ignored if it's empty or the file doesn't exist.
|
||
env_file: .env
|
||
|
||
# The timeout for a job to be finished.
|
||
# Please note that the Gitea instance also has a timeout (3h by default) for the job.
|
||
# So the job could be stopped by the Gitea instance if it's timeout is shorter than this.
|
||
timeout: 3h
|
||
|
||
# The timeout for the runner to wait for running jobs to finish when shutting down.
|
||
# Any running jobs that haven't finished after this timeout will be cancelled.
|
||
shutdown_timeout: 0s
|
||
|
||
# Whether skip verifying the TLS certificate of the Gitea instance.
|
||
insecure: true
|
||
|
||
# The timeout for fetching the job from the Gitea instance.
|
||
fetch_timeout: 5s
|
||
|
||
# The interval for fetching the job from the Gitea instance.
|
||
fetch_interval: 2s
|
||
|
||
# The labels of a runner are used to determine which jobs the runner can run, and how to run them.
|
||
# Like: "macos-arm64:host" or "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
|
||
# Find more images provided by Gitea at https://gitea.com/docker.gitea.com/runner-images .
|
||
# If it's empty when registering, it will ask for inputting labels.
|
||
# If it's empty when execute `daemon`, will use labels in `.runner` file.
|
||
labels:
|
||
- "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest"
|
||
- "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04"
|
||
- "ubuntu-20.04:docker://docker.gitea.com/runner-images:ubuntu-20.04"
|
||
|
||
cache:
|
||
# Enable cache server to use actions/cache.
|
||
enabled: true
|
||
# The directory to store the cache data.
|
||
# If it's empty, the cache data will be stored in $HOME/.cache/actcache.
|
||
dir: ""
|
||
# The host of the cache server.
|
||
# It's not for the address to listen, but the address to connect from job containers.
|
||
# So 0.0.0.0 is a bad choice, leave it empty to detect automatically.
|
||
host: ""
|
||
# The port of the cache server.
|
||
# 0 means to use a random available port.
|
||
port: 0
|
||
# The external cache server URL. Valid only when enable is true.
|
||
# If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself.
|
||
# The URL should generally end with "/".
|
||
external_server: ""
|
||
|
||
container:
|
||
# Specifies the network to which the container will connect.
|
||
# Could be host, bridge or the name of a custom network.
|
||
# If it's empty, act_runner will create a network automatically.
|
||
network: ""
|
||
# Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
|
||
privileged: false
|
||
# And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway).
|
||
options:
|
||
# The parent directory of a job's working directory.
|
||
# NOTE: There is no need to add the first '/' of the path as act_runner will add it automatically.
|
||
# If the path starts with '/', the '/' will be trimmed.
|
||
# For example, if the parent directory is /path/to/my/dir, workdir_parent should be path/to/my/dir
|
||
# If it's empty, /workspace will be used.
|
||
workdir_parent:
|
||
# Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob
|
||
# You can specify multiple volumes. If the sequence is empty, no volumes can be mounted.
|
||
# For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to:
|
||
# valid_volumes:
|
||
# - data
|
||
# - /src/*.json
|
||
# If you want to allow any volume, please use the following configuration:
|
||
# valid_volumes:
|
||
# - '**'
|
||
valid_volumes: []
|
||
# overrides the docker client host with the specified one.
|
||
# If it's empty, act_runner will find an available docker host automatically.
|
||
# If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers.
|
||
# If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work.
|
||
docker_host: ""
|
||
# Pull docker image(s) even if already present
|
||
force_pull: true
|
||
# Rebuild docker image(s) even if already present
|
||
force_rebuild: false
|
||
|
||
host:
|
||
# The parent directory of a job's working directory.
|
||
# If it's empty, $HOME/.cache/act/ will be used.
|
||
workdir_parent:
|
||
EOF
|
||
```
|
||
|
||
### Регистрация Runner в Gitea
|
||
|
||
1. **Получение токена регистрации:**
|
||
|
||
- Войдите в веб-интерфейс Gitea
|
||
- Перейдите в Settings → Actions → Runners
|
||
- Нажмите "New Runner"
|
||
- Скопируйте токен регистрации
|
||
|
||
2. **Регистрация runner:**
|
||
|
||
```bash
|
||
# В контейнере LXC под пользователем gitea-runner
|
||
act_runner register \
|
||
--instance https://gitea.your-domain.com \
|
||
--token YOUR_REGISTRATION_TOKEN \
|
||
--name "k3s-runner-arm64" \
|
||
--labels "ubuntu-latest:docker://node:18,ubuntu-22.04:docker://node:18,self-hosted:docker://golang:1.21,arm64:docker://golang:1.21" \
|
||
--no-interactive
|
||
|
||
```
|
||
|
||
3. **Создание systemd сервиса:**
|
||
|
||
```bash
|
||
# Создание файла сервиса
|
||
cat > /etc/systemd/system/gitea-runner.service <<EOF
|
||
[Unit]
|
||
Description=Gitea Actions Runner
|
||
After=network.target docker.service
|
||
Requires=docker.service
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=gitea-runner
|
||
Group=gitea-runner
|
||
WorkingDirectory=/opt/gitea-runner
|
||
ExecStart=/usr/local/bin/act_runner daemon --config /opt/gitea-runner/config.yaml
|
||
Restart=always
|
||
RestartSec=10
|
||
Environment=PATH=/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
# Перезагрузка systemd
|
||
systemctl daemon-reload
|
||
|
||
# Включение и запуск сервиса
|
||
systemctl enable gitea-runner
|
||
systemctl start gitea-runner
|
||
|
||
# Проверка статуса
|
||
systemctl status gitea-runner
|
||
```
|
||
|
||
### Настройка мониторинга
|
||
|
||
1. **Создание скрипта мониторинга:**
|
||
|
||
```bash
|
||
cat > /opt/gitea-runner/monitor.sh <<'EOF'
|
||
#!/bin/bash
|
||
|
||
LOG_FILE="/opt/gitea-runner/logs/monitor.log"
|
||
RUNNER_STATUS=$(systemctl is-active gitea-runner)
|
||
|
||
echo "$(date): Runner status: $RUNNER_STATUS" >> $LOG_FILE
|
||
|
||
if [ "$RUNNER_STATUS" != "active" ]; then
|
||
echo "$(date): Restarting gitea-runner service" >> $LOG_FILE
|
||
systemctl restart gitea-runner
|
||
fi
|
||
|
||
# Проверка свободного места
|
||
DISK_USAGE=$(df /opt/gitea-runner | tail -1 | awk '{print $5}' | sed 's/%//')
|
||
if [ $DISK_USAGE -gt 80 ]; then
|
||
echo "$(date): High disk usage: ${DISK_USAGE}%" >> $LOG_FILE
|
||
# Очистка старых логов и кэша
|
||
find /opt/gitea-runner/logs -name "*.log" -mtime +7 -delete
|
||
docker system prune -f
|
||
fi
|
||
EOF
|
||
|
||
chmod +x /opt/gitea-runner/monitor.sh
|
||
```
|
||
|
||
2. **Настройка cron для мониторинга:**
|
||
|
||
```bash
|
||
# Добавление в crontab
|
||
echo "*/5 * * * * /opt/gitea-runner/monitor.sh" | crontab -
|
||
```
|
||
|
||
### Тестирование Runner
|
||
|
||
1. **Проверка подключения:**
|
||
|
||
```bash
|
||
# Проверка статуса runner в Gitea
|
||
curl -H "Authorization: token YOUR_GITEA_TOKEN" \
|
||
https://gitea.your-domain.com/api/v1/actions/runners
|
||
```
|
||
|
||
2. **Создание тестового workflow:**
|
||
|
||
```yaml
|
||
# .gitea/workflows/test-runner.yaml
|
||
name: Test Runner
|
||
on:
|
||
push:
|
||
branches: [main]
|
||
|
||
jobs:
|
||
test:
|
||
runs-on: self-hosted
|
||
steps:
|
||
- name: Checkout
|
||
run: |
|
||
git clone https://oauth2:${{ secrets.GITEATOKEN }}@gitea.your-domain.com/your-username/your-repo.git
|
||
cd your-repo
|
||
|
||
- name: Test Go
|
||
run: |
|
||
go version
|
||
go mod download
|
||
go build -o test-app main.go
|
||
|
||
- name: Test Docker
|
||
run: |
|
||
docker --version
|
||
docker run hello-world
|
||
|
||
- name: Test ARM64 Build
|
||
run: |
|
||
# Тестирование сборки для ARM64
|
||
GOOS=linux GOARCH=arm64 go build -o test-app-arm64 main.go
|
||
file test-app-arm64
|
||
# Должно показать: ELF 64-bit LSB executable, ARM aarch64
|
||
```
|
||
|
||
### Оптимизация производительности
|
||
|
||
1. **Настройка Docker daemon:**
|
||
|
||
```bash
|
||
# Создание daemon.json
|
||
cat > /etc/docker/daemon.json <<EOF
|
||
{
|
||
"storage-driver": "overlay2",
|
||
"log-driver": "json-file",
|
||
"log-opts": {
|
||
"max-size": "10m",
|
||
"max-file": "3"
|
||
},
|
||
"default-ulimits": {
|
||
"nofile": {
|
||
"Hard": 64000,
|
||
"Name": "nofile",
|
||
"Soft": 64000
|
||
}
|
||
}
|
||
}
|
||
EOF
|
||
|
||
systemctl restart docker
|
||
```
|
||
|
||
2. **Настройка ограничений ресурсов:**
|
||
|
||
```bash
|
||
# Обновление systemd сервиса с ограничениями
|
||
cat > /etc/systemd/system/gitea-runner.service <<EOF
|
||
[Unit]
|
||
Description=Gitea Actions Runner
|
||
After=network.target docker.service
|
||
Requires=docker.service
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=gitea-runner
|
||
Group=gitea-runner
|
||
WorkingDirectory=/opt/gitea-runner
|
||
ExecStart=/usr/local/bin/act_runner daemon --config /opt/gitea-runner/config.yaml
|
||
Restart=always
|
||
RestartSec=10
|
||
Environment=PATH=/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||
|
||
# Ограничения ресурсов
|
||
MemoryMax=3G
|
||
CPUQuota=200%
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
systemctl daemon-reload
|
||
systemctl restart gitea-runner
|
||
```
|
||
|
||
### Резервное копирование
|
||
|
||
1. **Создание скрипта резервного копирования:**
|
||
|
||
```bash
|
||
cat > /opt/gitea-runner/backup.sh <<'EOF'
|
||
#!/bin/bash
|
||
|
||
BACKUP_DIR="/opt/gitea-runner/backups"
|
||
DATE=$(date +%Y%m%d_%H%M%S)
|
||
|
||
mkdir -p $BACKUP_DIR
|
||
|
||
# Резервное копирование конфигурации
|
||
tar -czf $BACKUP_DIR/config_$DATE.tar.gz /opt/gitea-runner/config.yaml
|
||
|
||
# Резервное копирование логов
|
||
tar -czf $BACKUP_DIR/logs_$DATE.tar.gz /opt/gitea-runner/logs/
|
||
|
||
# Удаление старых резервных копий (старше 30 дней)
|
||
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
|
||
|
||
echo "Backup completed: $DATE"
|
||
EOF
|
||
|
||
chmod +x /opt/gitea-runner/backup.sh
|
||
|
||
# Добавление в crontab (ежедневно в 2:00)
|
||
echo "0 2 * * * /opt/gitea-runner/backup.sh" | crontab -
|
||
```
|
||
|
||
Теперь у вас есть полностью настроенная инфраструктура с Gitea в K3s кластере и Gitea Runner в LXC контейнере на Proxmox ARM64!
|
||
|
||
## Работа с вашим кластером
|
||
|
||
### Основные команды для работы с кластером
|
||
|
||
```bash
|
||
# Установка переменной окружения для работы с кластером
|
||
export KUBECONFIG=~/.kube/config_hlab
|
||
|
||
# Проверка состояния кластера
|
||
kubectl get nodes -o wide
|
||
kubectl get pods -A
|
||
|
||
# Работа с Gitea
|
||
kubectl get pods -n gitea
|
||
kubectl logs -n gitea deployment/gitea
|
||
kubectl port-forward -n gitea svc/gitea-http 3000:3000
|
||
|
||
# Проверка storage
|
||
kubectl get pvc -n gitea
|
||
kubectl get storageclass
|
||
|
||
# Проверка ingress и сервисов
|
||
kubectl get svc -n default | grep traefik
|
||
kubectl get ingress -A
|
||
```
|
||
|
||
### Мониторинг и обслуживание
|
||
|
||
```bash
|
||
# Проверка ресурсов кластера
|
||
kubectl top nodes
|
||
kubectl top pods -n gitea
|
||
|
||
# Проверка событий
|
||
kubectl get events -n gitea --sort-by='.lastTimestamp'
|
||
|
||
# Резервное копирование Gitea
|
||
kubectl exec -n gitea deployment/gitea -- gitea dump -c /data/gitea/conf/app.ini
|
||
|
||
# Обновление Gitea
|
||
helm repo update
|
||
helm upgrade gitea gitea-charts/gitea -n gitea --values gitea-values.yaml
|
||
```
|
||
|
||
### Устранение неполадок
|
||
|
||
```bash
|
||
# Проверка логов Gitea
|
||
kubectl logs -n gitea deployment/gitea -f
|
||
|
||
# Проверка логов PostgreSQL
|
||
kubectl logs -n gitea statefulset/gitea-postgres -c postgres
|
||
|
||
# Проверка логов Valkey
|
||
kubectl logs -n gitea statefulset/gitea-valkey-cluster -c valkey
|
||
|
||
# Проверка сетевой связности
|
||
kubectl exec -n gitea deployment/gitea -- ping gitea-postgres
|
||
kubectl exec -n gitea deployment/gitea -- ping gitea-valkey-cluster
|
||
```
|
||
|
||
---
|
||
|
||
**Автор:** [Ваше имя]
|
||
**Дата:** [Дата публикации]
|
||
**Версия:** 1.0.0 |