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.git은lumie-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는 파드가 최초로 스케줄링된 노드에 바인딩됩니다. 데이터를 마스터 노드 디스크에 고정하기 위해 nodeAffinity와 tolerations를 함께 설정합니다.
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/common의 additionalIngresses로 별도 관리합니다.
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