Helm
Kubernetes 패키지 관리 (npm이나 pip같은)
Categories
Commands
-
completion- 지정된 셸에 대한 자동완성 스크립트 생성 -
create- 주어진 이름으로 새 차트 생성 -
dependency- 차트의 의존성 관리 -
env- Helm 클라이언트 환경 정보 -
get- 명명된 릴리스의 확장 정보 다운로드 -
help- 모든 명령어에 대한 도움말 -
history- 릴리스 히스토리 조회 -
install- 차트 설치 -
lint- 차트의 잠재적 문제 검사 -
list- 릴리스 목록 조회 -
package- 차트 디렉토리를 차트 아카이브로 패키징 -
plugin- Helm 플러그인 설치, 목록 조회 또는 제거 -
pull- 저장소에서 차트 다운로드 및 (선택적으로) 로컬 디렉토리에 압축 해제 -
push- 차트를 원격으로 푸시 -
registry- 레지스트리에 로그인 또는 로그아웃 -
repo- 차트 저장소 추가, 목록 조회, 제거, 업데이트 및 인덱싱 -
rollback- 릴리스를 이전 리비전으로 롤백 -
search- 차트에서 키워드 검색 -
show- 차트 정보 표시 -
status- 명명된 릴리스의 상태 표시 -
template- 로컬에서 템플릿 렌더링 -
test- 릴리스에 대한 테스트 실행 -
uninstall- 릴리스 제거 -
upgrade- 릴리스 업그레이드 -
verify- 주어진 경로의 차트가 서명되고 유효한지 검증 -
version- Helm 버전 정보 출력
헬름의 목적
헬름은 "차트" 라고 하는 쿠버네티스 패키지를 관리하는 도구이다. 헬름으로 다음과 같은 것들을 할 수 있다.
- 스크래치(scratch)부터 새로운 차트 생성
- 차트 아카이브(tgz) 파일로 차트 패키징
- 차트가 저장되는 곳인 차트 리포지터리와 상호작용
- 쿠버네티스 클러스터에 차트 인스톨 및 언인스톨
- 헬름으로 설치된 차트들의 릴리스 주기 관리
Install
snap이 있다면 이걸로 설치.
개념
헬름에는 다음과 같은 중요한 3가지 개념이 있다.
- 차트
- 쿠버네티스 애플리케이션의 인스턴스를 생성하는 데에 필요한 정보의 꾸러미이다.
- 설정
- 릴리스 가능한 객체를 생성하기 위해 패키징된 차트로 병합될 수 있는 설정 정보를 가진다.
- 릴리스
- "차트"의 구동중 인스턴스이며, 특정 "설정"이 결합되어 있다.
배포 방법
- (쿠버네티스) docker 이미지 빌드 부터 helm 배포까지 (1부) :: Jay's Code Factory
- (쿠버네티스) docker 이미지 빌드 부터 helm 배포까지 (2부) :: Jay's Code Factory
- Kubernetes Helm 쿠버네티스 헬름 - Chart 생성하고 배포하기(버전 관리 및 Release 관리)
Nginx 설치하기
# Stable Chart
helm repo add stable https://charts.helm.sh/stable
# Bitnami NginX는 통합된 php, mysql, nginx 개발환경을 제공한다.
helm repo add bitnami https://charts.bitnami.com/bitnami
# Helm Chart를 업데이트 해준다.
helm repo update
# 이번 실습에선 nginx 서버를 설치해야 하므로 nginx와 관련된 repository를 검색한다.
helm search repo nginx
# bitnami/nginx repository를 통해 서버를 설치한다.
helm install nginx bitnami/nginx
다음과 같이 출력됨:
NAME: nginx
LAST DEPLOYED: Thu Dec 18 16:00:38 2025
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
TEST SUITE: None
NOTES:
CHART NAME: nginx
CHART VERSION: 22.3.9
APP VERSION: 1.29.4
⚠ WARNING: Since August 28th, 2025, only a limited subset of images/charts are available for free.
Subscribe to Bitnami Secure Images to receive continued support and security updates.
More info at https://bitnami.com and https://github.com/bitnami/containers/issues/83267
** Please be patient while the chart is being deployed **
NGINX can be accessed through the following DNS name from within your cluster:
nginx.default.svc.cluster.local (port 80)
To access NGINX from outside the cluster, follow the steps below:
1. Get the NGINX URL by running these commands:
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
Watch the status with: 'kubectl get svc --namespace default -w nginx'
export SERVICE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].port}" services nginx)
export SERVICE_IP=$(kubectl get svc --namespace default nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "http://${SERVICE_IP}:${SERVICE_PORT}"
WARNING: Rolling tag detected (bitnami/nginx:latest), please note that it is strongly recommended to avoid using rolling tags in a production environment.
+info https://techdocs.broadcom.com/us/en/vmware-tanzu/application-catalog/tanzu-application-catalog/services/tac-doc/apps-tutorials-understand-rolling-tags-containers-index.html
WARNING: Rolling tag detected (bitnami/git:latest), please note that it is strongly recommended to avoid using rolling tags in a production environment.
+info https://techdocs.broadcom.com/us/en/vmware-tanzu/application-catalog/tanzu-application-catalog/services/tac-doc/apps-tutorials-understand-rolling-tags-containers-index.html
WARNING: Rolling tag detected (bitnami/nginx-exporter:latest), please note that it is strongly recommended to avoid using rolling tags in a production environment.
+info https://techdocs.broadcom.com/us/en/vmware-tanzu/application-catalog/tanzu-application-catalog/services/tac-doc/apps-tutorials-understand-rolling-tags-containers-index.html
WARNING: There are "resources" sections in the chart not set. Using "resourcesPreset" is not recommended for production. For production installations, please set the following values according to your workload needs:
- cloneStaticSiteFromGit.gitSync.resources
- resources
+info https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
요약하면 둘 중 하나의 방법으로 IP 주소 확인해서 들어가라:
# 방법 1
kubectl get svc --namespace default -w nginx
# 방법 2
export SERVICE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].port}" services nginx)
export SERVICE_IP=$(kubectl get svc --namespace default nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo "http://${SERVICE_IP}:${SERVICE_PORT}"
접속 안되는 현상 해결 방법
그런데 k3s 같은걸 설치했거나 별도의 로드벨런서를 설치했다면 아마 다음과 같이 출력될거다:
출력:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer 10.43.132.171 <pending> 80:30554/TCP,443:32117/TCP 35s
EXTERNAL-IP 가 계속 <pending> 상태에서 머물러 있다. 문제를 확인하기 위해 관련 pod 를 찾아보자:
다음과 같이 출력된다:
NAME READY STATUS RESTARTS AGE
coredns-6d668d687-sk8z4 1/1 Running 0 28m
helm-install-traefik-btnrc 0/1 Completed 1 28m
helm-install-traefik-crd-thplf 0/1 Completed 0 28m
local-path-provisioner-869c44bfbd-khd2x 1/1 Running 0 28m
metrics-server-7bfffcd44-bp7lr 1/1 Running 0 28m
svclb-nginx-526a66f9-pbzkk 0/2 Pending 0 8m20s
svclb-traefik-33133399-bhx7l 2/2 Running 0 27m
traefik-865bd56545-995lq 1/1 Running 0 27m
nginx 관련 pod 가 READY 0/2, Pending 상태 인걸 확인할 수 있다.
해당 pod (svclb-nginx-526a66f9-pbzkk) 를 확인하자:
다음과 같이 출력된다:
Name: svclb-nginx-526a66f9-pbzkk
Namespace: kube-system
Priority: 2000001000
Priority Class Name: system-node-critical
Service Account: svclb
Node: <none>
Labels: app=svclb-nginx-526a66f9
controller-revision-hash=7b448cb6fb
pod-template-generation=1
svccontroller.k3s.cattle.io/svcname=nginx
svccontroller.k3s.cattle.io/svcnamespace=default
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Controlled By: DaemonSet/svclb-nginx-526a66f9
Containers:
lb-tcp-80:
Image: rancher/klipper-lb:v0.4.13
Port: 80/TCP (lb-tcp-80)
Host Port: 80/TCP (lb-tcp-80)
Environment:
SRC_PORT: 80
SRC_RANGES: 0.0.0.0/0
DEST_PROTO: TCP
DEST_PORT: 80
DEST_IPS: 10.43.132.171
Mounts: <none>
lb-tcp-443:
Image: rancher/klipper-lb:v0.4.13
Port: 443/TCP (lb-tcp-443)
Host Port: 443/TCP (lb-tcp-443)
Environment:
SRC_PORT: 443
SRC_RANGES: 0.0.0.0/0
DEST_PROTO: TCP
DEST_PORT: 443
DEST_IPS: 10.43.132.171
Mounts: <none>
Conditions:
Type Status
PodScheduled False
Volumes: <none>
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: CriticalAddonsOnly op=Exists
node-role.kubernetes.io/control-plane:NoSchedule op=Exists
node-role.kubernetes.io/master:NoSchedule op=Exists
node.kubernetes.io/disk-pressure:NoSchedule op=Exists
node.kubernetes.io/memory-pressure:NoSchedule op=Exists
node.kubernetes.io/not-ready:NoExecute op=Exists
node.kubernetes.io/pid-pressure:NoSchedule op=Exists
node.kubernetes.io/unreachable:NoExecute op=Exists
node.kubernetes.io/unschedulable:NoSchedule op=Exists
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 9m10s default-scheduler 0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports.
Warning FailedScheduling 3m47s default-scheduler 0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports.
하단에 경고 이벤트가 출력되어 있다:
0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports. preemption: 0/1 nodes are available: 1 node(s) didn't have free ports for the requested pod ports.
번역하면:
사용 가능한 노드는 0/1개입니다. 요청된 Pod 포트에 사용할 수 있는 여유 포트가 1개 노드에 없습니다. 선점: 사용 가능한 노드는 0/1개입니다. 요청된 Pod 포트에 사용할 수 있는 여유 포트가 1개 노드에 없습니다.
K3s는 기본적으로 Traefik Ingress Controller가 80/443 포트를 선점하고 있습니다.
포트 사용 확인 방법:
# 80, 443 포트를 사용하는 프로세스 확인
sudo netstat -tulpn | grep ':80\|:443'
# 또는
sudo ss -tulpn | grep ':80\|:443'
# Traefik 서비스 확인
kubectl get svc -n kube-system traefik
LoadBalancer 대신 Traefik Ingress 로 접근하는 것이 K3s의 표준 방식입니다:
# Helm으로 Ingress 포함하여 재설치
helm upgrade nginx bitnami/nginx \
--set service.type=ClusterIP \
--set ingress.enabled=true \
--set ingress.hostname=nginx.local
이 경우 hostname 으로 지정한 nginx.local 으로 접속해야 한다. /etc/hosts 파일을 갱신하던가 해라.
참고로 다른 포트 사용하는 방법도 있다: (비추)
Troubleshooting
WARNING: Kubernetes configuration file is ***-readable. This is insecure. Location: ~/.kube/config
관련 명령을 치면 이런 경고가 출력된다.
WARNING: Kubernetes configuration file is group-readable. This is insecure. Location: ~/.kube/config
WARNING: Kubernetes configuration file is world-readable. This is insecure. Location: ~/.kube/config
chmod 600 ~/.kube/config 명령으로 접근 권한 바꾸자.