[Grafana] 폐쇄망 K8s에서 VictoriaLogs 플러그인 수동 설치와 permission denied 해결
폐쇄망(에어갭) 쿠버네티스 환경에서는 grafana-cli로 플러그인을 자동 설치할 수 없어, 파일을 외부에서 반입해 수동 설치해야 합니다. 이 글에서는 Grafana에 VictoriaLogs 데이터소스 플러그인을 수동으로 넣는 과정과, 그 과정에서 흔히 만나는 Could not start plugin backend: permission denied 에러의 원인·해결(임시 chmod → 영구 커스텀 이미지)을 실전 기록으로 정리합니다.
🔌 폐쇄망에서 Grafana 플러그인 설치가 까다로운 이유 #
폐쇄망은 외부 인터넷이 차단돼 있어 grafana-cli plugins install ... 같은 온라인 자동 설치가 동작하지 않습니다. 따라서 플러그인 파일을 인터넷이 되는 곳에서 받아 사내망으로 반입한 뒤 직접 배치해야 합니다.
여기서 핵심은 플러그인의 종류입니다.
| 구분 | 프론트엔드 플러그인 | 백엔드 플러그인 |
|---|---|---|
| 구성 | JS/HTML만 | JS + Go 바이너리 |
| 실행 | 브라우저에서 렌더 | Grafana가 바이너리를 실행 |
| 함정 | 거의 없음 | 실행 권한(+x) 필요 |
⚠️ VictoriaLogs 데이터소스는 백엔드 플러그인입니다(
victoriametrics-logs-datasource). Go 바이너리를 Grafana가 직접 실행하므로 실행 권한이 없으면 기동에 실패합니다. 이 점이 뒤에서 다룰 에러의 직접 원인입니다.
1️⃣ Grafana 파드 구조 확인 (멀티 컨테이너) #
Helm으로 배포한 Grafana 파드는 보통 멀티 컨테이너입니다. 플러그인을 복사할 대상은 메인 grafana 컨테이너이므로, 먼저 컨테이너 이름을 확인합니다.
1kubectl get pod <grafana-pod> -n <ns> \
2 -o jsonpath='{.spec.containers[*].name}'
3# 예: grafana-sc-dashboard grafana-sc-datasources grafanagrafana-sc-dashboard/grafana-sc-datasources— 대시보드·데이터소스를 자동 등록하는 사이드카grafana— 실제 Grafana 앱 컨테이너 (플러그인 배치 대상)
2️⃣ 플러그인 수동 복사 (kubectl cp) #
외부에서 받은 플러그인 디렉터리를 메인 컨테이너의 플러그인 경로(기본 /var/lib/grafana/plugins)로 복사합니다. -c grafana로 컨테이너를 반드시 명시합니다.
1kubectl cp <plugin-dir> \
2 <ns>/<grafana-pod>:/var/lib/grafana/plugins/victorialogs-datasource \
3 -c grafana복사 후 파드를 재시작합니다.
1kubectl rollout restart deployment/<grafana> -n <ns>2️⃣가 끝났는데 왜 안 보일까? — 막힌 지점 #
재시작했는데도 Grafana 데이터소스 목록에 VictoriaLogs가 나타나지 않습니다. 이럴 때는 추측하지 말고 로그부터 봅니다.
1kubectl logs <grafana-pod> -n <ns> -c grafana | grep -i plugin로그에 다음과 같은 에러가 보입니다.
1Could not start plugin backend ... permission denied원인은? #
kubectl cp로 로컬 → 컨테이너로 파일을 복사하는 과정에서 리눅스 실행 권한(+x)이 누락됩니다. 백엔드 플러그인의 Go 바이너리가 실행되지 못해 플러그인 기동에 실패한 것입니다. 즉 “plugin backend + permission denied” = 실행 권한 문제로 보면 거의 맞습니다.
3️⃣ 임시 해결 — chmod로 실행 권한 부여 #
원인 확인 차원에서 컨테이너 안에서 플러그인 경로에 실행 권한을 줍니다.
1kubectl exec -it <grafana-pod> -n <ns> -c grafana -- \
2 chmod -R 755 /var/lib/grafana/plugins/victorialogs-datasource재시작하면 플러그인이 정상 기동하고 데이터소스 목록에 나타납니다.
⚠️ 이건 운영 해법이 아닙니다. 파드가 재생성(노드 이동·스케일링·업그레이드)되면 복사한 파일과 권한이 모두 사라져 매번 반복해야 합니다. 원인 규명·임시 확인용으로만 쓰세요.
4️⃣ 영구 해결 — 커스텀 이미지로 빌드 #
플러그인을 이미지에 포함시키고 실행 권한까지 부여해 빌드하면, 파드가 몇 번 재생성되어도 항상 플러그인이 존재하고 권한이 유지됩니다. 폐쇄망에서는 보통 사내 레지스트리(예: Harbor)에 푸시해 사용합니다.
1FROM grafana/grafana:11.2.0
2
3USER root
4
5# 폐쇄망에서 미리 받아 반입한 플러그인을 이미지에 포함
6ENV GF_PATHS_PLUGINS=/var/lib/grafana/plugins
7COPY victorialogs-datasource ${GF_PATHS_PLUGINS}/victorialogs-datasource
8
9# 핵심: 백엔드 바이너리에 실행 권한 부여
10RUN chmod -R 755 ${GF_PATHS_PLUGINS}/victorialogs-datasource
11
12# 미서명 플러그인 로딩 허용(서명 안 된 플러그인일 때)
13ENV GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS=victoriametrics-logs-datasource
14
15USER grafana1# 사내 레지스트리에 푸시
2docker build -t harbor.example.com/monitoring/grafana-victorialogs:11.2.0 .
3docker push harbor.example.com/monitoring/grafana-victorialogs:11.2.0이후 Helm values.yaml에서 이미지를 교체해 배포합니다.
1image:
2 repository: harbor.example.com/monitoring/grafana-victorialogs
3 tag: "11.2.0"💡 미서명 플러그인은
grafana.ini의[plugins]섹션에allow_loading_unsigned_plugins = victoriametrics-logs-datasource로도 허용할 수 있습니다(위 Dockerfile의 환경변수와 동일 효과).
🧩 더 깔끔하게: 사이드카로 데이터소스 자동 등록 (선택) #
플러그인을 손으로 추가하는 대신, grafana-sc-datasources 사이드카를 활용하면 라벨이 달린 ConfigMap을 자동으로 데이터소스로 등록해 줍니다(선언적·재현 가능).
1apiVersion: v1
2kind: ConfigMap
3metadata:
4 name: victorialogs-datasource
5 labels:
6 grafana_datasource: "1" # 사이드카가 탐지하는 라벨(차트 sidecar.datasources.label 값)
7data:
8 victorialogs.yaml: |
9 apiVersion: 1
10 datasources:
11 - name: VictoriaLogs
12 type: victoriametrics-logs-datasource
13 access: proxy
14 url: http://victorialogs:9428
15 isDefault: false💡 단, 사이드카는 데이터소스 “등록” 을 자동화할 뿐, 플러그인 바이너리 자체는 여전히 이미지에 있어야 합니다(4단계). 둘은 보완 관계입니다.
🤔 교훈 요약 #
- 폐쇄망에서는 자동 설치가 막혀 수동 복사가 불가피하고, 그 과정에서 실행 권한 누락이 흔한 함정입니다.
plugin backend+permission denied에러는 곧 실행 권한(+x) 문제일 가능성이 높습니다 → 로그부터 확인.kubectl cp+chmod는 원인 규명·임시 확인용이지 운영 해법이 아닙니다. 영구 해법은 커스텀 이미지(또는 차트의 플러그인 주입 메커니즘).- 멀티 컨테이너 파드에서는
-c로 메인 컨테이너를 정확히 지정해야 합니다.
❓ 자주 묻는 질문 #
Q. 데이터소스 목록에 플러그인이 안 보이면 가장 먼저 볼 것은?
kubectl logs <pod> -c grafana | grep -i plugin. permission denied가 보이면 실행 권한 문제입니다.
Q. chmod로 고쳤는데 며칠 뒤 또 사라졌어요.
파드가 재생성되면서 kubectl cp로 넣은 파일이 사라진 것입니다. 커스텀 이미지로 전환하세요.
Q. 서명되지 않은 플러그인이라 로드가 거부됩니다.
allow_loading_unsigned_plugins(또는 GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS)에 플러그인 ID(victoriametrics-logs-datasource)를 추가하세요.
Q. 프론트엔드 플러그인도 권한 문제가 생기나요? 대부분 없습니다. 실행 권한 문제는 백엔드 바이너리를 가진 플러그인(데이터소스 등)에서 발생합니다.
📚 참고 #
- Install a plugin — Grafana documentation
- Configure a Grafana Docker image — Grafana documentation
- How to install grafana plugin in airgap container environment — Grafana Community
- “Could not start plugin backend” from multiple plugins — Grafana Community
- VictoriaMetrics/victorialogs-datasource — GitHub
- Grafana Integration — VictoriaMetrics Helm Charts