[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 grafana
  • grafana-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 grafana
1# 사내 레지스트리에 푸시
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. 프론트엔드 플러그인도 권한 문제가 생기나요? 대부분 없습니다. 실행 권한 문제는 백엔드 바이너리를 가진 플러그인(데이터소스 등)에서 발생합니다.


📚 참고 #

Advertisement