Zum Hauptinhalt springen

Gitea

개요

Gitea(github.lumie-infra.com/Lumie-Edu/...)는 Lumie 플랫폼의 정식 Git 호스트입니다. 모든 애플리케이션 소스 코드의 canonical origin이며, Tekton CI/CD 파이프라인이 Gitea 웹훅(X-Gitea-Event: push)을 감시하여 빌드를 트리거합니다. GitHub(github.com/Lumie-Edu/...)는 push-mirror 전용 백업입니다 — ArgoCD나 Tekton은 GitHub를 사용하지 않습니다.

github.lumie-infra.com은 Teleport 리버스 프록시를 통해 접근 제어가 이루어집니다. Teleport는 mTLS 인증서를 통해 git push는 허용하지만 REST API(curl)는 차단됩니다. 클러스터 내 Tekton 태스크는 공개 호스트명이 아닌 내부 서비스 URL(http://gitea-http.gitea.svc.cluster.local:3000)을 직접 사용합니다.

아키텍처

Git 원격 구조

저장소Canonical 원격역할
모든 앱 저장소Gitea (github.lumie-infra.com)개발자 코드 푸시, Tekton 빌드 트리거
모든 앱 저장소GitHub (github.com)push-mirror 백업 전용 — ArgoCD/Tekton 미사용

ArgoCD의 repoURL: https://github.com/Lumie-Edu/lumie-infra.gitlumie-infra 인프라 선언 소스입니다. 애플리케이션 소스 코드의 빌드 트리거는 Gitea 웹훅으로만 이루어집니다.

Tekton CI/CD 연동

웹훅 이벤트 헤더

Tekton EventListener의 CEL 필터는 header.match('X-Gitea-Event', 'push') 조건으로 Gitea 이벤트를 식별합니다. GitHub와 달리 X-GitHub-Event 헤더가 아닌 X-Gitea-Event를 사용합니다.

내부 서비스 URL

git-update-values 태스크는 lumie-infra 레포에 이미지 태그를 커밋할 때 공개 호스트명이 아닌 클러스터 내부 서비스 URL을 사용합니다:

http://gitea-http.gitea.svc.cluster.local:3000/Lumie-Edu/lumie-infra.git

Teleport 경유 외부 URL(https://github.lumie-infra.com)은 REST API가 차단되므로 Tekton에서 사용하지 않습니다. gitea-credentials Secret(Vault 관리)으로 인증합니다.

수동 Tekton 트리거 시 주의사항

수동으로 PipelineRun을 트리거할 때는 내부 Gitea svc URL과 gitea-credentials, zot-registry-credentials를 올바르게 지정해야 합니다. 상세 내용은 CI/CD 파이프라인을 참고하세요.

배포 구성

ArgoCD Application

Gitea는 bootstrap sync-wave 3에 배포됩니다. Vault(admin 자격증명)와 Zot(이미지 풀 미러)에 의존하므로 이들보다 늦게 배포됩니다.

sync-wave 순서: 0 minio → 1 zot → 2 vault → 3 gitea
# bootstrap/gitea/argocd.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: gitea
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "3"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: https://dl.gitea.com/charts/
chart: gitea
targetRevision: 11.0.1
helm:
valueFiles:
- $values/bootstrap/gitea/helm-values.yaml
- repoURL: https://github.com/Lumie-Edu/lumie-infra.git
targetRevision: main
ref: values
path: charts/common
helm:
valueFiles:
- $values/bootstrap/gitea/common-values.yaml
# 커스텀 UI 테마 (GitHub 테마 CSS → ConfigMap)
- repoURL: https://github.com/Lumie-Edu/lumie-infra.git
targetRevision: main
path: bootstrap/gitea/themes
destination:
server: https://kubernetes.default.svc
namespace: gitea
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
managedNamespaceMetadata:
labels:
goldilocks.fairwinds.com/enabled: 'true'
revisionHistoryLimit: 10

컨테이너 이미지

이미지는 Zot 온디맨드 미러를 통해 Docker Hub에서 풀합니다. tag: "" 설정으로 Helm 차트의 appVersion을 그대로 사용하며, Renovate가 argocd.yaml의 차트 버전을 업데이트하면 이미지 버전이 함께 갱신됩니다.

image:
registry: zot.lumie-infra.com
repository: gitea/gitea
tag: "" # 차트 appVersion 사용 (Renovate 자동 업데이트)
rootless: true

스케줄링 및 퍼시스턴스

마스터 노드 고정

local-path PVC는 파드가 최초로 스케줄링된 노드에 바인딩됩니다. 데이터를 마스터 노드 디스크에 고정하기 위해 nodeAffinitytolerations를 함께 설정합니다.

tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-role.kubernetes.io/control-plane
operator: Exists

단일 레플리카

PostgreSQL을 외부 DB로 사용하지만, 단일 인스턴스로 운영합니다. 재배포 시 중단 없이 전환하기 위해 Recreate 전략을 사용합니다.

replicaCount: 1
strategy:
type: Recreate

스토리지

persistence:
enabled: true
create: true
size: 20Gi
storageClass: local-path-retain # PV가 PVC 삭제 후에도 유지됨
accessModes:
- ReadWriteOnce

local-path-retain StorageClass를 사용하므로 PVC를 삭제해도 PV와 실제 데이터가 보존됩니다.

데이터베이스

번들 DB 서브차트(postgresql, redis)는 모두 비활성화하고 클러스터 공유 infra-db CNPG PostgreSQL 클러스터를 사용합니다. DB 비밀번호는 Vault에서 VaultStaticSecret으로 주입됩니다.

postgresql:
enabled: false
postgresql-ha:
enabled: false
redis-cluster:
enabled: false
redis:
enabled: false

deployment:
env:
- name: GITEA__database__PASSWD
valueFrom:
secretKeyRef:
name: gitea-db-secret
key: password
# Gitea 설정에서의 DB 연결
gitea:
config:
database:
DB_TYPE: postgres
HOST: infra-db-rw.infra-db.svc.cluster.local:5432
NAME: gitea
USER: gitea
SSL_MODE: disable

Gitea 주요 설정

서버 설정

gitea:
config:
APP_NAME: "Lumie Git"
server:
DOMAIN: github.lumie-infra.com
ROOT_URL: https://github.lumie-infra.com/
DISABLE_SSH: true # SSH 비활성화, HTTPS만 허용
OFFLINE_MODE: false

SSH는 비활성화되어 있으며, HTTPS 전용으로 운영됩니다.

인덱서 및 캐시

gitea:
config:
cache:
ADAPTER: memory
session:
PROVIDER: memory
queue:
TYPE: level
indexer:
ISSUE_INDEXER_TYPE: bleve
REPO_INDEXER_ENABLED: true # 코드 검색 활성화

외부 Redis 없이 인메모리 캐시와 세션을 사용합니다. 레포지토리 인덱서는 bleve(내장 전문 검색 엔진)로 코드 검색을 지원합니다.

서비스 정책

gitea:
config:
service:
DISABLE_REGISTRATION: true # 가입 비활성화
REQUIRE_SIGNIN_VIEW: false # 공개 저장소는 로그인 없이 열람 가능
SHOW_REGISTRATION_BUTTON: false

신규 사용자 자가 등록이 비활성화되어 있으며, 관리자 또는 Teleport 자동 등록으로만 계정이 생성됩니다.

웹훅

gitea:
config:
webhook:
ALLOWED_HOST_LIST: "*" # Tekton Triggers로의 웹훅 허용

저장소 기본값

gitea:
config:
repository:
DEFAULT_BRANCH: main

미러링

GitHub를 핫 백업으로 활용하기 위해 Push Mirror 기능이 활성화되어 있습니다.

gitea:
config:
mirror:
ENABLED: true

인증

Teleport 리버스 프록시 자동 로그인

공개 Ingress 없이 Teleport 리버스 프록시를 통해서만 접근이 가능합니다. Teleport가 주입하는 HTTP 헤더로 Gitea에 자동 로그인합니다.

gitea:
config:
service:
ENABLE_REVERSE_PROXY_AUTHENTICATION: "true"
ENABLE_REVERSE_PROXY_AUTO_REGISTRATION: "false" # 자동 계정 생성 비활성화
ENABLE_REVERSE_PROXY_EMAIL: "true"
REVERSE_PROXY_AUTHENTICATION_USER: X-Teleport-User
REVERSE_PROXY_AUTHENTICATION_EMAIL: X-Teleport-Email
REVERSE_PROXY_LIMIT: "1"
REVERSE_PROXY_TRUSTED_PROXIES: "*"

Bootstrap 관리자 (Break-glass 계정)

Keycloak/Teleport를 사용할 수 없는 상황을 위한 비상 계정입니다. 자격증명은 Vault KV에서 VaultStaticSecret으로 주입됩니다.

# common-values.yaml
vaultStaticSecrets:
- name: gitea-admin-vss
path: infrastructure/gitea # Vault 경로: secret/infrastructure/gitea
destination:
name: gitea-admin
transformation:
templates:
username: "{{ .Secrets.GITEA_ADMIN_USERNAME }}"
password: "{{ .Secrets.GITEA_ADMIN_PASSWORD }}"
email: "{{ .Secrets.GITEA_ADMIN_EMAIL }}"
rolloutRestartTargets:
- kind: Deployment
name: gitea

Vault에 저장해야 할 키:

Vault 키설명
GITEA_ADMIN_USERNAME관리자 계정 이름
GITEA_ADMIN_PASSWORD관리자 비밀번호
GITEA_ADMIN_EMAIL관리자 이메일
gitea:
admin:
existingSecret: gitea-admin
# 시크릿에 필요한 키: username, password, email

DB 자격증명

# common-values.yaml
vaultStaticSecrets:
- name: gitea-db-vss
path: infrastructure/postgresql # Vault 경로: secret/infrastructure/postgresql
destination:
name: gitea-db-secret
transformation:
templates:
password: "{{ .Secrets.POSTGRES_PASSWORD }}"
rolloutRestartTargets:
- kind: Deployment
name: gitea

커스텀 UI 테마

GitHub 테마 CSS(lutinglt/gitea-github-theme v1.23.3)를 적용합니다. bootstrap/gitea/themes/의 Kustomize 소스가 gitea-custom-themes ConfigMap을 생성하고, 이를 컨테이너 내부 CSS 경로에 마운트합니다.

# bootstrap/gitea/themes/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: gitea
configMapGenerator:
- name: gitea-custom-themes
files:
- theme-github.css
options:
disableNameSuffixHash: true
# helm-values.yaml — ConfigMap 마운트
extraVolumes:
- name: custom-themes
configMap:
name: gitea-custom-themes
extraContainerVolumeMounts:
- name: custom-themes
mountPath: /data/gitea/public/assets/css/theme-github.css
subPath: theme-github.css
readOnly: true
# UI 테마 설정
gitea:
config:
ui:
THEMES: "gitea-auto,gitea-light,gitea-dark,github"
DEFAULT_THEME: "github"

리소스 및 네트워킹

리소스 할당

resources:
requests:
cpu: 100m
memory: 512Mi
limits:
memory: 1Gi # CPU 제한 없음 (VPA 권장)

서비스

SSH는 비활성화되어 HTTP 서비스만 노출됩니다.

service:
http:
type: ClusterIP
port: 3000

Ingress는 helm-values.yaml에서 비활성화하고, charts/commonadditionalIngresses로 별도 관리합니다.

ingress:
enabled: false

모니터링

Prometheus ServiceMonitor가 활성화되어 있어 Gitea 메트릭이 자동으로 수집됩니다.

# helm-values.yaml
serviceMonitor:
enabled: true

gitea:
config:
metrics:
ENABLED: true

문제 해결

파드 상태 확인

# Gitea 파드 확인
kubectl get pods -n gitea

# 파드 로그 확인
kubectl logs -n gitea deployment/gitea

DB 연결 문제

# infra-db 클러스터 상태 확인
kubectl get cluster -n infra-db

# DB 연결 테스트
kubectl exec -n gitea deployment/gitea -- \
psql "postgres://gitea@infra-db-rw.infra-db.svc.cluster.local:5432/gitea?sslmode=disable" -c "\l"

VSO 시크릿 동기화 확인

# VaultStaticSecret 상태 확인
kubectl get vaultstaticsecret -n gitea

# 생성된 시크릿 확인
kubectl get secret gitea-admin -n gitea
kubectl get secret gitea-db-secret -n gitea

테마 ConfigMap 확인

# 테마 ConfigMap 확인
kubectl get configmap gitea-custom-themes -n gitea

# 마운트된 CSS 파일 확인
kubectl exec -n gitea deployment/gitea -- \
ls /data/gitea/public/assets/css/ | grep github

ArgoCD 동기화 확인

# ArgoCD Application 상태 확인
kubectl get application gitea -n argocd

# 동기화 강제 실행
argocd app sync gitea

관련 문서