dipup 이 go:embed 로 직접 보관·관리하던 Helm 차트를 카탈로그로 옮기는 첫 단계다.
두 저장소가 각자 CVE/SBOM 파이프라인을 운영하는 이중화를 해소하려면, 먼저 카탈로그가
dipup 과 같은 차트·같은 이미지를 보게 만들어야 한다.
배경: CVE 파이프라인 구성 이전에 두 곳에서 같은 차트를 유지하기 어려워 dipup 이 별도로
차트를 관리해 왔고, 그 결과 버전이 갈라졌다. 겹치는 10개 중 버전까지 일치하는 것은
postgresql-ha·dnsup 2개뿐이었다.
## 버전 갱신 (7개) — 신규 버전 디렉토리 추가, 구버전은 보존
| 차트 | 기존 | 신규 | appVersion |
|---|---|---|---|
| apisix | 2.14.0 | 2.16.0 | 3.16.0 → 3.17.0 |
| argo-cd | 7.7.0 | 7.8.11 | v2.13.0 → v2.14.5 |
| cert-manager | v1.16.1 | v1.21.0 | 동일 |
| gitea | 12.4.0 | 12.6.0 | 1.24.6 → 1.26.1 |
| harbor | 1.16.2 | 1.19.1 | 2.12.2 → 2.15.1 |
| kyverno | 3.4.1 | 3.8.2 | v1.14.1 → v1.18.2 |
| rancher | 2.10.1 | 2.14.3 | v2.10.1 → v2.14.3 |
차트 본문은 dipup 이 임베딩한 .tgz 를 그대로 전개했다(네트워크 pull 이 아니라 dipup 이
실제 배포하는 바이트와 동일함을 보장하기 위함). BUILD-README/CUSTOM-README/custom-values
3개 파일은 구버전에서 승계했다.
## 신규 추가 (5개)
infisical-standalone 1.9.0, longhorn 109.3.1+up1.11.2, longhorn-crd 109.3.1+up1.11.2,
metallb 0.16.1, secrets-operator v0.10.33.
longhorn/longhorn-crd 는 업스트림이 아니라 Rancher 패키징 차트(109.x 라인, Rancher 2.14
계열과 짝)다. BUILD-README 의 `helm repo add` 라인은 chart_version_detector 가 파싱하는
계약이라 실제 업스트림 repo 를 검증해 기재했고, 감지기로 현재/최신 버전이 정상 조회되는
것을 확인했다.
## custom-values — 버전과 결합된 이미지 핀 정리
카탈로그 스캐너가 dipup 의 effective image 를 보게 하려면 이미지 핀이 맞아야 한다.
- **kyverno: 승계본이 3.8.2 에서 깨져 재작성.** 3.4.1 은 정리 훅이
`registry: ~ / repository: bitnami/kubectl` 이라 bitnamilegacy 오버라이드가 맞았지만,
3.8.2 는 `registry: ghcr.io / repository: kyverno/readiness-checker` 로 바뀌었다.
그대로 옮기면 ghcr.io/bitnamilegacy/kubectl 이라는 없는 좌표가 된다. 해당 오버라이드를
제거하고, 3.8.2 에서 삭제된 policyReportsCleanup 키도 함께 뺐다. 남는 조치는 tag 고정뿐
(기본 tag 가 비어 latest 로 떨어짐 → v1.18.2 로 고정).
- apisix: 3.16.0-keycloak-authz → 3.17.0-keycloak-authz (차트 appVersion 과 함께 이동)
- gitea: image.tag 1.26.4 핀 추가 — 차트 기본 1.26.1 대비 CRITICAL 2→0, HIGH 44→12
- infisical: image.tag v0.162.7 핀 — 기본 v0.158.x 는 stale Debian base 로 OS 기인 CVE
다수(fixable CRITICAL 53→5, HIGH 491→55). redis/postgresql 은 bitnamilegacy 좌표로.
- longhorn: 실측 기반 리소스 튜닝(manager request, guaranteedInstanceManagerCPU,
systemManagedCSIComponentsResourceLimits). replica 수처럼 노드 수에 의존하는 값은
넣지 않았다 — 소비 측에서 주입한다.
## 검증
12개 차트 전부 `helm template --kube-version 1.34.1` 렌더 성공. 렌더 결과 이미지가
dipup 배포 이미지와 일치함을 확인(paasup/apisix:3.17.0-keycloak-authz,
gitea:1.26.4-rootless, readiness-checker:v1.18.2, infisical:v0.162.7).
## 범위에서 뺀 것
- **keycloak**: 카탈로그는 codecentric(app 17.0.1-legacy), dipup 은 bitnami(app 26.2.4)로
계보가 다르다. 이슈 #1(bitnami 대체 방안 검토)의 결론이 나온 뒤 처리한다.
- **rancher-monitoring(-crd)**: 14c05f1 에서 불필요 판단으로 제거된 차트이고
victoria-metrics 스택으로 대체 예정이라 추가하지 않는다.
- **dip-api/dip-console**: 자체 개발 차트로 각 앱 저장소가 출처다. 대조 결과 앱 저장소와
dipup 사본이 일치해 카탈로그가 개입할 이유가 없다.
- **postgresql-ha/dnsup**: 이미 버전이 일치해 작업 대상이 아니었다.
## 후속 과제
dnsup 은 카탈로그·dipup 사본(1.0.1)이 원본(dip-console-api helm/dnsup 1.0.0)보다 앞서
있다. 1.0.1 에만 있는 service.LoadBalancerIP·service.annotations 지원을 원본으로 백포트한
뒤, 카탈로그에서 dnsup 을 제거하는 것이 자체 개발 차트 출처 원칙에 맞다.
8.1 KiB
High Availability
All components (in-memory DB, volume/asset storage, code indexer) used by Gitea must be deployed in a HA-ready fashion to achieve a full HA-ready Gitea deployment. The following document explains how to achieve this for all individual components.
The resulting Gitea deployment will consist of ~ 10 pods (depending on the chosen components and their replicas). One should evaluate upfront whether a HA-deployment is required as switching between HA/non-HA comes with some effort. For production instances, HA is always recommended to increase uptime and have a frictionless update process.
A general comment about chart dependencies and external services: Instead of relying on chart dependencies, it is often better to rely on an external, (managed) instances (in-memory database, asset storage provider, database, etc.). Many cloud providers offer such services, at least for databases or in-memory databases. They might cost a bit more than using a self-hosted k8s variant but are usually easier to maintain and scale, if needed. Also they can be centrally managed and are not linked to the Gitea helm chart or namespace. Please consider using external services before you start with your Gitea HA setup, it will make your life (and the life of the Gitea maintainers) easier.
This helm chart tries to help as much as possible to simplify and assert the provisioning of a HA-ready Gitea instance by implementing smart conditionals if replicaCount is set to a value > 1.
Nevertheless, we cannot guarantee for every possible combination of Gitea settings to work together perfectly in a HA setup.
As a general advice, we recommend to have a test environment aside on which to test possible changes/upgrades before applying these to a production installation.
Requirements for HA
Storage-wise, the HA-Gitea setup requires a RWX file-system which can be shared among the deployment-based replica pods. In addition, the following components are required for full HA-readiness:
- A HA-ready issue (and optionally code) indexer:
elasticsearchormeilisearch - A HA-ready external object/asset storage (
minio) (optional, assets can also be stored on the RWX file-system) - A HA-ready cache (
valkey-cluster) - A HA-ready DB
postgres.enabled, which default to true, must be set to false for a HA setup.
The default postgres chart dependency is not HA-ready (there's a dedicated postgres-ha chart).
The following sections discuss each of the components in more detail. Note that for each component discussed, the shown configurations only provides a (working) starting point, not necessarily the most optimal setup. We try to optimize this document over time as we have gained more experience with HA setups from users.
Indexers (Issues and code/repo)
The default code indexer bleve is not able to allow multiple connections and hence cannot be used in a HA setup.
Alternatives are elasticsearch and meilisearch (as of >= 1.19.2).
Unless you have an existing elasticsearch cluster, we recommend using meilisearch as it is faster and requires way less resources.
Unfortunately, meilisearch does only support the ISSUE_INDEXER and not the REPO_INDEXER yet (tracking issue).
This means that the REPO_INDEXER must still be disabled for a HA setup right now.
An alternative to the two options above for the ISSUE_INDEXER is "db", however we recommend to just go with meilisearch in this case and to not bother the DB with indexing.
To configure meilisearch within Gitea, do the following:
gitea:
config:
indexer:
ISSUE_INDEXER_CONN_STR: <http://meilisearch.<namespace>.svc.cluster.local:7700>
ISSUE_INDEXER_ENABLED: true
ISSUE_INDEXER_TYPE: meilisearch
REPO_INDEXER_ENABLED: false
# REPO_INDEXER_TYPE: meilisearch # not yet working
Unfortunately meilisearch cannot be deployed in HA as of now.
Nevertheless it allows for multiple Gitea requests at the same time and is therefore required in a HA setup.
Exemplary configuration for the meilisearch-kubernetes chart:
persistence:
enabled: true
accessMode: ReadWriteOnce
size: 5Gi
Cache, session and queue
A valkey instance is required for the in-memory cache.
Two options exist:
valkeyvalkey-cluster
The chart provides valkey-cluster as a dependency as this one can be used for both HA and non-HA setups.
You're also welcome to go with valkey if you prefer or already have a running instance.
It should be noted that valkey-cluster support is only available starting with Gitea 1.19.2.
You can also configure an external (managed) valkey instance to be used.
To do so, you need to set the following configuration values yourself:
-
gitea.config.queue.TYPE: valkey` -
gitea.config.queue.CONN_STR:<your valkey connection string> -
gitea.config.session.PROVIDER:valkey -
gitea.config.session.PROVIDER_CONFIG:<your valkey connection string> -
gitea.config.cache.ENABLED:true -
gitea.config.cache.ADAPTER:valkey -
gitea.config.cache.HOST:<your valkey connection string>
By default, the valkey-cluster chart provisions three standalone master nodes of which each has a single replica.
To reduce the number of pods for a default Gitea deployment, we opted to omit the replicas (replicas: 0) by default.
Only the minimum required number of master pods for a functional valkey-cluster deployment are provisioned.
For a "proper" valkey-cluster setup however, we recommend to set replicas: 1 and nodes: 6.
Object and asset storage
Object/asset storage refers to the storage of attachments, avatars, LFS files, etc. While most of these can be stored on the RWX file-system, it is recommended to use an external S3-compatible object storage for such, mainly for performance reasons.
By default the chart provisions a single RWO volume to store everything (repos, avatars, packages, etc.). This volume cannot be mounted by multiple pods. Hence, a RWX volume is required and (optionally) an external HA-ready object storage.
Note: Double-check that the file permissions are set correctly on the RWX volume! That is everything should be owned by the
gituser which usually hasuid=1000andgid=1000.
To use minio you need to deploy and configure an external minio instance yourself and explicitly define the STORAGE_TYPE values as shown below.
Note that MINIO_BUCKET here is just a name and does not refer to a S3 bucket.
It's the root access point for all objects belonging to the respective application, i.e., to Gitea in this case.
gitea:
config:
attachment:
STORAGE_TYPE: minio
lfs:
STORAGE_TYPE: minio
picture:
AVATAR_STORAGE_TYPE: minio
"storage.packages":
STORAGE_TYPE: minio
storage:
MINIO_ENDPOINT: <minio-headless.<namespace>.svc.cluster.local:9000>
MINIO_LOCATION: <location>
MINIO_ACCESS_KEY_ID: <access key>
MINIO_SECRET_ACCESS_KEY: <secret key>
MINIO_BUCKET: <bucket name>
MINIO_USE_SSL: false
Exemplary configuration for the bitnami minio chart:
auth:
rootUser: minio
mode: distributed
replicaCount: 4
persistence:
enabled: true
size: 20Gi
accessModes:
- ReadWriteOnce
Database
If you do not have an HA-ready DB, using a managed database service in the cloud might be the easiest and most robust solution.
Remember: disable the built-in postgres dependency and configure the database connection manually via gitea.config.database:
gitea:
database:
builtIn:
postgresql:
enabled: false
config:
database:
DB_TYPE: postgres
HOST: <host>
NAME: <name>
USER: <user>
Known issues
-
Currently Cron jobs are run on all replicas as no leader election is implemented. See https://github.com/go-gitea/gitea/issues/13791 for a discussion and possible solution.
-
Running with multiple replicas slows down Gitea a bit, i.e. page loading time increases.