홈랩 K8s 프로젝트에 Renovate 도입하기 — Helm Chart와 컨테이너 이미지 버전 자동 관리
TL;DR
- 홈랩 K3s 클러스터의 Helm Chart, 컨테이너 이미지 3종을 Renovate로 자동 추적
- 날짜 기반 태그(
2026.5.22), justfile 내 Helm 버전 등 비표준 형식도 customManagers로 감지packageRules로 beta/nightly/rc 등 불안정 버전 자동 제외- 주말마다 체크 → 업데이트 있으면 PR 자동 생성
매번 수동으로 버전을 확인하고 있었다
홈랩 K3s 클러스터에서 OpenClaw를 운영하고 있어요. 구성은 단순한 편인데:
- OpenClaw — AI 어시스턴트 (Helm Chart로 배포)
- LiteLLM Proxy — LLM 라우터 (K8s manifest로 배포)
- Chromium — 브라우저 sidecar (Helm Chart 기본값)
문제는 업그레이드 체크를 매번 수동으로 해야 한다는 점이었어요. GitHub Releases 확인하고, Docker 이미지 태그 비교하고, 보안 어드바이저리까지 훑어보면 한 번에 20~30분은 걸려요. 그리고 잊어버리면? 보안 패치가 나왔는데 몇 주를 모르고 지나가기도 하고요.
실제로 이번에 확인해보니 LiteLLM의 stable 트랙(v1.83.x-stable)이 종료되고 GA 트랙(v1.84+)으로 넘어간 상태였어요. 보안 하드닝 커밋들이 GA에만 포함되어 있었고, stable에는 백포트되지 않고 있었죠. 수동 체크를 안 했으면 한동안 더 놓쳤을 거예요.
왜 Renovate인가
의존성 자동 업데이트 도구로 Dependabot과 Renovate가 대표적이에요. Dependabot은 GitHub 네이티브라 설정이 간편하지만, 이번 프로젝트에는 안 맞았어요:
values.yaml의 커스텀 이미지 태그(2026.5.22같은 날짜 형식)를 감지 못함justfile같은 비표준 파일에서 Helm chart 버전을 추적할 수 없음- 버전 필터링 옵션이 제한적
Renovate는 customManagers(정규식 기반)로 어떤 파일이든, 어떤 형식이든 버전을 추출할 수 있어요. 데이터소스도 Docker registry, GitHub Releases, Helm repo 등 다양하게 지원하고요.
감지 대상 3가지
이 프로젝트에서 Renovate가 추적하는 버전은 세 가지예요:
| 대상 | 파일 | 버전 형식 | 데이터소스 |
|---|---|---|---|
| OpenClaw 이미지 | values.yaml | 2026.5.22 (날짜) | GitHub Releases |
| LiteLLM 이미지 | manifests/litellm/deployment.yaml | v1.85.1 (semver) | Docker registry |
| Helm Chart | justfile | 0.1.15 (semver) | Helm repo |
각각 감지 방식이 달라서 설정이 좀 다릅니다.
설정 상세
1. LiteLLM — 가장 간단한 케이스
# manifests/litellm/deployment.yaml
image: ghcr.io/berriai/litellm:v1.85.1
표준 K8s Deployment의 image 필드라 Renovate의 내장 Kubernetes manager가 자동 감지해요. 다만 기본적으로 K8s 매니페스트 스캔이 비활성화되어 있어서 파일 패턴만 지정하면 돼요:
{
"kubernetes": {
"managerFilePatterns": ["manifests/.+\\.yaml$"]
}
}
이렇게만 하면 ghcr.io에서 새 태그를 자동 조회하고, 업데이트가 있으면 PR을 만들어줘요.
2. OpenClaw 이미지 태그 — 커스텀 버전 형식
여기서부터 좀 복잡해져요. values.yaml의 이미지 태그가 일반적인 Docker 이미지 참조 형식이 아니에요:
# values.yaml
image:
tag: "2026.5.22"
ghcr.io/openclaw/openclaw:2026.5.22라는 정보가 파일에 명시적으로 없고, 2026.5.22라는 날짜 기반 버전만 있죠. 이걸 Renovate에 알려주려면 customManager가 필요해요:
{
"customManagers": [
{
"customType": "regex",
"managerFilePatterns": ["values.yaml"],
"matchStrings": [
"image:\\n\\s*tag:\\s*\"(?<currentValue>[^\"]+)\""
],
"depNameTemplate": "openclaw/openclaw",
"datasourceTemplate": "github-releases",
"extractVersionTemplate": "^v(?<version>.*)$",
"versioningTemplate": "regex:^(?<major>\\d{4})\\.(?<minor>\\d{1,2})\\.(?<patch>\\d{1,2})$"
}
]
}
핵심 포인트 몇 가지:
matchStrings— 파일 전체를 대상으로 정규식 매칭.image:\n tag: "2026.5.22"에서currentValue로2026.5.22를 추출datasourceTemplate: "github-releases"— Docker registry가 아니라 GitHub Releases에서 새 버전을 조회. OpenClaw는 릴리스 태그로 버전을 관리하기 때문extractVersionTemplate: "^v(?<version>.*)$"— GitHub 태그는v2026.5.22인데 values.yaml에는v없이2026.5.22로 기록하므로,v를 벗겨내는 변환 규칙versioningTemplate—2026.5.22형식을 major.minor.patch로 매핑하는 커스텀 버저닝. Renovate가 기본 지원하는 semver나 CalVer에 딱 맞지 않아서 regex 버저닝을 사용
3. Helm Chart 버전 — justfile에서 추적
Helm chart 버전은 원래 justfile에서 관리하고 있었는데, 버전 번호가 명시되어 있지 않았어요. helm upgrade에 --version 플래그 없이 항상 최신 chart를 설치하는 구조였죠.
Renovate로 추적하려면 먼저 버전을 명시해야 해요. justfile에 Renovate 주석(annotation)과 함께 버전 변수를 추가했어요:
chart := "openclaw/openclaw"
# renovate: datasource=helm registryUrl=https://chrisbattarbee.github.io/openclaw-helm depName=openclaw
chart_version := "0.1.15"
그리고 helm install/upgrade 명령에 --version 플래그를 추가:
upgrade: repo-update setup-plugin apply-manifests
helm upgrade {{ release }} {{ chart }} \
--namespace {{ namespace }} \
--version {{ chart_version }} \
...
Renovate 설정에서는 이 주석 패턴을 정규식으로 읽어요:
{
"customType": "regex",
"managerFilePatterns": ["justfile"],
"matchStrings": [
"# renovate: datasource=(?<datasource>[a-z-]+) registryUrl=(?<registryUrl>\\S+) depName=(?<depName>\\S+)\\nchart_version := \"(?<currentValue>[^\"]+)\""
]
}
주석 안에 datasource, registryUrl, depName이 모두 포함되어 있어서, 정규식의 named capture group으로 한번에 추출해요. 별도의 template 필드가 필요 없는 깔끔한 패턴이에요.
불안정 버전 필터링
홈랩이라고 해도 beta나 nightly 버전이 자동으로 올라오면 곤란해요. 실제로 OpenClaw는 2026.5.22-beta.1 같은 사전 릴리스가 자주 나오고, LiteLLM도 nightly, rc, dev 태그가 섞여 있어요.
packageRules로 안정 버전만 허용했어요:
{
"packageRules": [
{
"matchDepNames": ["openclaw/openclaw"],
"matchDatasources": ["github-releases"],
"allowedVersions": "/^\\d{4}\\.\\d{1,2}\\.\\d{1,2}$/"
},
{
"matchDepNames": ["ghcr.io/berriai/litellm"],
"allowedVersions": "/^v\\d+\\.\\d+\\.\\d+(-stable(\\.patch\\.\\d+)?)?$/"
}
]
}
OpenClaw은 2026.5.22 형식만 매칭하여 -beta.1, -alpha.1 등을 자동 제외해요. 추가로 GitHub Releases의 prerelease 플래그도 기본적으로 걸러주기 때문에 이중 방어가 됩니다.
LiteLLM은 v1.85.1(GA) 또는 v1.83.14-stable.patch.3(stable) 패턴만 허용하고, v1.83.14-nightly, 1.84.0-dev.1, v1.83.14.rc.1 같은 태그는 모두 제외해요.
실행 스케줄
{
"schedule": ["every weekend"]
}
홈랩이라 주말에 한 번 체크하는 것으로 충분해요. 급한 보안 패치는 어차피 수동으로 대응하게 되고, Renovate의 역할은 “놓치지 않게 알려주는 것”이니까요.
GitHub App 설치
설정 파일을 레포에 머지한 뒤, Renovate GitHub App을 레포에 설치하면 바로 동작해요. 별도 서버나 CI 파이프라인이 필요 없어요.
설치하면 Renovate가 자동으로:
- Dependency Dashboard Issue를 생성하고 — 전체 의존성 현황을 한눈에 볼 수 있음
- 스케줄에 따라 새 버전을 체크하고
- 업데이트가 있으면 PR을 자동 생성
PR에는 릴리스 노트, 버전 비교, 호환성 정보가 포함되어 있어서 업그레이드 판단에 도움이 돼요.
정리
| 항목 | Before | After |
|---|---|---|
| 버전 체크 | 수동 (GitHub Releases, Docker Hub 직접 확인) | 자동 (주말마다 Renovate가 PR 생성) |
| 놓칠 위험 | 높음 (잊으면 몇 주~몇 달) | 낮음 (PR로 알림) |
| 불안정 버전 | 직접 필터링 | 정규식으로 자동 제외 |
| Chart 버전 | 미고정 (항상 최신) | --version으로 고정 + 자동 추적 |
홈랩 규모에서는 과한 설정처럼 보일 수 있지만, 한번 설정해두면 신경 쓸 일이 없어요. 특히 LiteLLM처럼 릴리스 트랙이 바뀌거나, 보안 패치가 별도 트랙에서만 나오는 경우를 놓치지 않을 수 있다는 게 가장 큰 장점이에요.