Necesse Helm Chart 자동 버전 업데이트 및 Harbor OCI 배포 자동화
Necesse Docker 이미지 최신 버전 감지부터 Helm Chart 자동 업데이트, 그리고 Harbor OCI Registry로의 자동 배포까지 전체 자동화 파이프라인 구축 과정 기록
Necesse Helm Chart 자동 버전 업데이트 및 Harbor OCI 배포 자동화
이 포스트는 brammys/necesse-server Docker 이미지를 기반으로 Helm Chart를 만들고, GitHub Actions를 통한 버전 자동 업데이트, 그리고 Harbor OCI Registry에 자동 배포하도록 만든 전체 과정을 정리한 것이다.
전체 코드는 dakim/necesse-helm에서 확인할 수 있습니다.
시작 전 준비 사항
- Kubernetes 1.24+
- Harbor OCI Registry
- GitHub Actions (CI/CD)
- Necesse Dedicated Server용 컨테이너 이미지
- Helm 3.10+
Helm Chart 기본 구조
necesse-helm/
├── Chart.yaml # Helm chart metadata (appVersion 자동 업데이트)
├── values.yaml # 서버 설정, 이미지 태그, PVC 설정 등
│
├── templates/ # 쿠버네티스 템플릿
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── ingress.yaml (optional)
│ └── _helpers.tpl
│
├── scripts/
│ └── update-necesse-version.py # Docker Hub 최신 태그 조회 스크립트
│
└── .github/
└── workflows/ # GitHub Actions CI/CD
├── update-necesse-version.yaml # appVersion / image.tag 자동 갱신
└── publish-helm-oci.yaml # Helm chart → Harbor OCI 자동 배포
버전 업데이트 스크립트 작성
다음 로직을 기준으로 최신 태그 조회:
- Docker Hub에서 last_updated 기준으로 가장 최근 태그 수집
- major, minor, patch, build 순으로 숫자 비교
Chart.yaml과values.yaml에 태그 반영
1
2
3
4
5
6
7
8
9
10
def select_latest_tag(tag_records):
# 1) 날짜 기준 후보 필터링
parsed.sort(key=lambda x: x["last_updated"])
latest_time = parsed[-1]["last_updated"]
candidates = [p for p in parsed if p["last_updated"] == latest_time]
# 2) 숫자 비교
candidates.sort(key=lambda x: (x["major"], x["minor"], x["patch"], x["build"]))
chosen = candidates[-1]
return chosen["base"], chosen["name"]
스크립트를 GitHub Actions에서 실행하여
- Chart.yaml의 appVersion
- values.yaml의 image.tag
값을 자동으로 수정하도록 구성했다.
GitHub Actions 워크플로우 구성
1. Necesse 버전 자동 업데이트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
name: Update Necesse version
on:
schedule:
- cron: "0 21 * * *" # 한국 기준 6시 자동 실행
workflow_dispatch: {} # 수동 실행도 허용
permissions:
contents: write # Chart.yaml / values.yaml 변경 후 commit & push를 위해 필요
jobs:
update-necesse-version:
runs-on: ubuntu-latest # GitHub 제공 기본 러너
steps:
# -----------------------------
# 1. 저장소 소스 체크아웃
# -----------------------------
- name: Checkout
uses: actions/checkout@v4
with:
token: $ # 자동 커밋 & 푸시를 위한 권한 제공
# -----------------------------
# 2. Python 실행 환경 구성
# -----------------------------
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x" # Python 3 최신 버전 사용
# -----------------------------
# 3. 스크립트 실행에 필요한 패키지 설치
# -----------------------------
- name: Install dependencies
run: |
pip install requests pyyaml # Docker Hub API 요청 + YAML 파일 수정용 라이브러리
# -----------------------------
# 4. Docker Hub 최신 버전 조회 & Chart 업데이트 스크립트 실행
# -----------------------------
- name: Update Necesse versions
run: |
python scripts/update-necesse-version.py
# -----------------------------
# 5. 변경사항이 있을 경우 자동 커밋 & 푸시
# -----------------------------
- name: Commit and push changes
run: |
# 변경사항이 없으면 종료
if git diff --quiet; then
echo "No changes to commit."
exit 0
fi
# GitHub bot 계정으로 커밋
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git commit -am "chore: bump Necesse version (automated)" # 버전 업데이트 커밋 메시지
git push # 변경사항 푸시
작성한 워크플로우는 다음 역할을 수행한다:
- Docker Hub에서
brammys/necesse-server태그 목록 조회 - 날짜 및 버전 기준으로 최신 태그 선택
Chart.yaml의appVersion,values.yaml의image.tag갱신- 변경이 있으면 자동 커밋 후 GitHub 저장소에 push
2. Helm Chart를 Harbor OCI Registry로 배포
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
name: Publish Helm chart to Harbor (OCI)
on:
push:
branches:
- main
paths:
- "Chart.yaml" # Chart 메타데이터 변경 시
- "values.yaml" # values 변경 시
- "templates/**" # 템플릿 변경 시
- ".github/workflows/publish-helm-oci.yaml"
workflow_dispatch: {} # 수동 실행 가능
jobs:
publish-helm-chart:
runs-on: ubuntu-latest
env:
HARBOR_URL: $ # Harbor OCI endpoint
HARBOR_USERNAME: $ # Robot 계정
HARBOR_PASSWORD: $
steps:
# 저장소 체크아웃
- name: Checkout
uses: actions/checkout@v4
# Helm CLI 설치
- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: v4.0.1
- name: Show Helm version
run: helm version
# Harbor(OCI) 로그인
- name: Login to Harbor OCI registry
run: |
echo "${HARBOR_PASSWORD}" | helm registry login "${HARBOR_URL}" \
--username "${HARBOR_USERNAME}" \
--password-stdin
# yq 설치 (Chart.yaml에서 name/version 추출용)
- name: Install yq
run: |
sudo wget -qO /usr/local/bin/yq \
https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64
sudo chmod +x /usr/local/bin/yq
# Helm chart 패키징 (.tgz 생성)
- name: Package Helm chart
run: |
CHART_NAME=$(yq '.name' Chart.yaml)
CHART_VERSION=$(yq '.version' Chart.yaml)
echo "Packaging chart: ${CHART_NAME} (version: ${CHART_VERSION})"
helm package . --version "${CHART_VERSION}"
# Harbor에 OCI Artifact로 Push
- name: Push Helm chart as OCI artifact
run: |
CHART_NAME=$(yq '.name' Chart.yaml)
CHART_VERSION=$(yq '.version' Chart.yaml)
CHART_TGZ="${CHART_NAME}-${CHART_VERSION}.tgz"
if [ ! -f "${CHART_TGZ}" ]; then
echo "Chart package ${CHART_TGZ} not found"
exit 1
fi
echo "Pushing ${CHART_TGZ} to oci://${HARBOR_URL}/dedicated-server"
helm push "${CHART_TGZ}" "oci://${HARBOR_URL}/dedicated-server"
작성한 워크플로우는 다음 역할을 수행한다:
- 코드 변경 감지 → 워크플로우 실행
- Helm 설치
- Harbor OCI 로그인
Chart.yaml에서 Chart 이름 및 버전 추출- Helm Chart 패키징 (
.tgz생성) - Harbor OCI Registry로 Push
최종 시스템 동작 구조
flowchart TD
%% --- External Source Group ---
subgraph EXTERNAL["External Source"]
A["Docker Hub<br/>brammys/necesse-server"]
end
%% --- GitHub Automation System Group ---
subgraph GITHUB["GitHub Automation System"]
B["update-necesse-version.py<br/>(Version Update CI)"]
C["GitHub Repo<br/>necesse-helm"]
D["Publish Workflow<br/>(helm package → push OCI)"]
end
%% --- Artifact Storage Group ---
subgraph REGISTRY["Artifact Storage"]
E["Harbor OCI Registry<br/>dedicated-server"]
end
%% --- Flows ---
A -->|Check latest tag| B
B -->|Update appVersion & image.tag| C
C -->|Commit & Push| D
D -->|Publish chart| E
