한컴테크를 통해 한컴의 기술을 공유합니다. 한컴의 프로그래밍, 프레임워크, 라이브러리 및 도구 등 다양한 기술을 만나보세요. 한컴 개발자들의 다양한 지식을 회사라는 울타리를 넘어 여러분과 공유합니다. 한컴이 제공하는 기술블로그에서 새로운 아이디어와 도전을 마주하고, 개발자가 꿈꾸는 미래를 실현하세요.

한컴테크

K8s Tips & Tricks – 실전 쿠버네티스 핵심 꿀팁


요약

이 글은 클라우드 네이티브 환경에서 Kubernetes를 직접 운영하며 경험한 실용적인 팁들을 공유합니다. Namespace 기본값 설정부터 명령어 별칭(alias) 활용, YAML Manifest 자동 생성, ConfigMap 관리까지, 반복적인 작업을 줄이고 일상적인 운영 효율성을 높일 수 있는 방법들을 상세히 다룹니다. 실무에서 마주하는 다양한 상황에 적용할 수 있는 기본적이면서도 유용한 Kubernetes 활용법을 구체적으로 안내합니다.

kubernetes logo

시작하며


클라우드 네이티브 기술은 이제 선택이 아닌 필수가 되었습니다. 현재 공공 SaaS 사업 진출을 위해서도 클라우드 네이티브가 필수 기술 스택으로 자리 잡았으며, 한컴의 대부분 서비스도 클라우드 네이티브로 제공하고 있습니다.

이에 다수의 복잡한 컨테이너를 효과적으로 다루는 클라우드 네이티브의 핵심 기술인 Kubernetes를 직접 사용하면서 알게 된 실용적인 사용법과 팁을 공유하여, 독자 여러분의 소중한 시간을 아껴드리고자 합니다.

누구나 알 법하지만, 막상 모르고 있으면 당황스러운 기본적이면서도 유용한 팁들을 소개합니다.

모든 예제 코드는 실제 사용 시 오류가 발생할 수 있으므로, 참고용 의사코드(Pseudo-code)로 활용해 주세요. 필요한 경우, 함께 제공한 링크를 통해 추가 정보를 확인하실 수 있습니다.

1. Kubernetes? K8s?


Kubernetes란?

컨테이너화된 애플리케이션은 기존의 모놀리식(Monolithic) 애플리케이션과 달리, 여러 개의 컨테이너와 구성 요소가 유기적으로 통신하는 마이크로서비스(Microservices) 구조로 설계됩니다.

이처럼 수많은 마이크로서비스를 자동으로 배포하고 스케일링하기 위해서는 컨테이너 오케스트레이션(Container Orchestration) 도구가 필요합니다.

Kubernetes는 대표적인 오픈 소스 컨테이너 오케스트레이션 도구입니다.

Kubernetes 구성도

출처: Kubernetes Architecture

K8s란?

‘Kubernetes’는 발음하기도 길고, 타이핑도 번거롭습니다. 그래서 ‘K’로 시작하여 ‘s’로 끝나고, 가운데 글자들은 글자 수인 8을 숫자로 대체한 ‘K8s’라는 형태로 줄여 씁니다. 이렇게 줄여쓰는 방법을 ‘뉴머로님(Numeronym)‘이라고 합니다.

예: Kubernetes → K8s

영어로는 ‘케이에잇츠’, ‘케이츠’, ‘쿠버네티스’ 라고 읽는다고 하는데요. (참고 링크)
한글로는 ‘케이팔에스’ 또는 그대로 ‘쿠버네티스’라고 읽어도 무방합니다.

2. Namespace 기본값을 지정하세요!


왜 필요할까요?

K8s에서는 Namespace(참고 링크)를 리소스의 격리 단위로 사용합니다. 즉, Namespace를 통해 격리된 Context를 선택하면 해당 Context 내의 자원만 서로 공유되고 통신도 가능합니다.

CLI에서 kubectl 명령어를 사용할 때 이 Namespace를 명시적으로 지정할 수 있습니다.

kubectl get pods -n my-awesome-app
kubectl exec -it -n my-awesome-app backend-0 -- bash
  • 보통 명령어의 가장 마지막에 Namespace를 지정해 주는데요. 예를 들어, 첫 번째 예시에서는 -n my-awesome-app 부분이 해당합니다.
  • 반면 두 번째 예시의 경우, backend-0이라는 Pod를 실행할 때는 – – bash와 같은 실행 옵션을 명령어의 가장 마지막에 넣기 때문에, Namespace는 Pod 이름 앞에 적어주어야 합니다.

위와 같은 혼동도 이유이지만, 무엇보다 타이핑 시간과 오타를 줄이기 위해 기본 값으로 지정하는 것이 좋습니다.

어떻게요?

아래와 같이 kubectl config 명령어를 통해 config에 추가해 줄 수 있습니다.

kubectl config set-context --current --namespace=my-awesome-app
  • set-context : config 파일 안의 Context에 값을 설정한다.
  • – – current : 현재 선택된 Context의 내용을 업데이트 한다.
  • – – namespace=my-awesome-app : namespace 키에 값을 설정해 준다.

또는 ~/.kube/config 파일의 context 항목 아래에 직접 추가할 수도 있습니다.

- context:
    cluster: rancher-desktop
    namespace: my-awesome-app
    user: rancher-desktop
  name: rancher-desktop

현재 선택된 Context의 Namespace는 다음 명령어로 확인할 수 있습니다.

kubectl config view --minify | grep namespace

명령을 실행하면 아래와 같이 출력됩니다.

출처 : How to Change Namespace in Kubernetes ? – GeeksforGeeks

장점

아래와 같이 명령어가 짧아지고 가독성도 높아집니다.

kubectl get pods
kubectl exec -it backend-0 -- bash

더해서 다른 Namespace로 명령어를 실행할 때 Context만 변경하고 명령어는 그대로 사용하면 됩니다.

출처 : Quick Start using Rancher Desktop | Rancher Opni

3. 별칭(alias)으로 시간 줄이기


왜 필요할까요?

CLI를 사용하면 타이핑이 생각보다 길고 반복적입니다. 이때 별칭(alias)을 설정하면 타이핑 시간과 오타를 줄일 수 있습니다. 지금 당장 별칭을 사용해보세요.

어떻게요?

아래는 kubectl에서 자주 사용하는 몇가지 별칭 추천 항목입니다. (참고 링크)

 k      => kubectl
 kg     => kubectl get
 kgp    => kubectl get pods
 kgd    => kubectl get deployments
 kgss   => kubectl get statefulsets
 kd     => kubectl describe
 kdd    => kubectl describe deployments
 kdss   => kubectl describe statefulsets
 kdp    => kubectl describe pods
 ke     => kubectl edit
 ked    => kubectl edit deployments
 kl     => kubectl logs
 kexec  => kubectl exec -it
 kdel   => kubectl delete
 krm    => kubectl delete

별칭을 쓰는 예는 아래와 같습니다. 참 간결해졌죠!

kgp
kexec backend-0 -- bash

참고 사항

본 포스트에서는 예제에 별칭을 사용하지 않습니다.
별칭은 개인의 선택 사항으로 다른 사람과의 커뮤니케이션에는 사용하지 않는 것이 바람직하겠습니다. ^-^

4. YAML Manifest를 만드는 초간단 레시피


왜 필요할까요?

K8s의 패키지 매니저인 Helm(참고 링크)은 Template이라는 고정된 공통 설정에 Values라는 변경 값을 적용하여 최종적인 Manifest의 묶음인 Chart를 생성해 주는 도구입니다.

그런데 이 Template(참고 링크)이라는 녀석, 생각보다 꽤 복잡합니다. 우선, 아주 기본적인 Pod Manifest를 살펴보시죠.

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

이렇게 복잡한 Manifest를 처음부터 빈 파일에서 작성하려고 하면 정말 난감합니다. 하지만 kubectl 명령어를 활용하면, 이런 기본적인 Manifest를 간단하게 생성할 수 있습니다.
어떻게 하는지 소개해 드릴게요.

어떻게요?

Dry Run 활용 예시

먼저, kubectl 명령어로 YAML Manifest를 만들 수 있는 명령문 형식은 아래와 같습니다.

kubectl ... --dry-run=client -o yaml > template.yaml
  • – – dry-run=client : 모의 실행을 한다.
  • -o yaml : 출력 포맷은 YAML로 한다.
  • > template.yaml : 출력 결과를 파일로 전송한다. 내용은 Manifest이나 추후 Template을 만드는 데 사용한다.

Dry Run 명령은 보통 아래와 같이 실제 적용될 내용을 모의로 돌려보고 그 결과를 확인하는 용도로 많이 사용합니다. (참고 링크)

kubectl apply --dry-run=client -f deployment.yaml

이렇게 미리 테스트한 후, 이상이 없으면 아래와 같이 실행해주는 것이죠.

kubectl apply -f deployment.yaml

이렇게 모의 실행을 해주는 Dry Run 명령에 YAML 형식 출력 명령을 더해서 우리가 원하는 YAML Manifest를 얻을 수 있는 것입니다.

NginX Pod Manifest 만들어보기

이 명령문을 이용해서 NginX 이미지를 Pod로 띄워주는 Manifest를 만들어 보겠습니다(참고 링크).
먼저 실행 명령문은 다음과 같습니다.

kubectl run nginx --image=nginx

위 명령은 nginx 이미지를 사용해서 nginx라는 이름으로 Pod를 띄워주는 명령문입니다.
이것을 모의로 실행하고 그 결과를 YAML 형식으로 파일에 출력해 보겠습니다.

kubectl run nginx --image=nginx --dry-run=client -o yaml > template.yaml

명령문 실행 결과를 보면 기본적인 Manifest가 만들어진 것을 확인할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
Deployment Manifest 만들어보기

이번엔 NginX배포해주는 Deployment Manifest도 만들어 보겠습니다(참고 링크).
마찬가지로 Deployment를 생성하는 명령 뒤에 모의 실행+YAML 형식 출력 명령문을 추가해 줍니다.

kubectl create deployment --image=nginx nginx
kubectl create deployment --image=nginx nginx --dry-run=client -o yaml > template.yaml

명령문을 실행하여 순식간에 만들어진 결과는 아래와 같을 것입니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx
        name: nginx
        resources: {}
status: {}

이제 만들어진 Manifest를 Template으로 감싸서 맛있게 드시면 됩니다! ^-^

5. 죽지 않는 Pod! 또는 Terminating 무한대기! 혹시 Finalizer?


왜 그럴까요?

컨테이너를 배포했는데 CrashLoopBackOff 오류가 발생하면서 계속 재시작하는 경우가 있습니다.
특히 이미지가 존재하지 않을 때는 무한 루프에 빠지기도 합니다.

출처 : OpenText Documentation Portal

설정에 문제가 없다면, 컨테이너 실행 단위인 Pod(참고 링크)나 Service(참고 링크)를 삭제해주면 대부분 해결됩니다.
ArgoCD로 자동 배포를 설정해 놓았다면 삭제만 하면 재배포는 알아서 되겠죠.

그런데, 이 Pod가 죽여도 죽여도 다시 살아나는 경우가 있습니다! 정말 죽지 않습니다.
에러가 반복되니 시급히 죽여야 하는데, 너무 당황스러운 상황입니다.

심지어 마운트된 Volume을 삭제해 초기화를 시도해도, Terminating만 뜨고 죽지 않는 경우도 있습니다.
아래는 Namespace를 삭제해도 Terminating만 뜨고 죽지 않는 경우의 예 입니다.

출처 : Kubernetes Namespace Terminating Stuck State

어떻게요?

이럴 땐 당황하지 말고, 먼저 Finalizer(참고 링크)를 확인해 보세요!

삭제하려는 구성요소의 YAML을 살펴봅시다. Namespace를 예로 들면 다음과 같습니다.

kubectl edit namespase my-awesome-app
  • kubectl edit : vi 편집기로 파일 내용을 수정한다(참고 링크).
  • namespace : Namespace용 YAML Manifest 파일을 수정한다.
  • my-awesome-app : 편집할 Namespace 이름

Manifest 파일에 아래와 같이 Finalizer 항목이 보인다면, 해당 부분을 삭제해 줍니다.

출처 : Kubernetes Namespace Terminating Stuck State

변경 사항을 저장하고 편집기를 종료하면, 변경 내용이 자동으로 적용되어 Terminating 상태가 사라지고 정상적으로 삭제가 진행될 것입니다.

6. 무쇠 컨테이너 이미지에 ConfigMap으로 유연함 +1 추가하기


왜 필요할까요?

컨테이너 이미지는 변하지 않는 견고함을 자랑합니다.
하지만 여러 환경에서 유연하게 적용하려면, 설정값을 컨테이너 외부에서 관리할 수 있어야 합니다. 이때 사용하는 것이 바로 ConfigMap(참고 링크)입니다.

ConfigMap은 Volume을 마운트 하는 것과 원리는 유사하지만, 그 내용을 명시적으로 적시해 주는 것에 차이가 있습니다.
그리고 ConfigMap의 내용을 변경하면, 이를 참조하는 모든 실행 중인 컨테이너에 자동으로 적용됩니다.

단, 민감한 내용은 Secret(참고 링크)을 사용해야 합니다.

환경 변수로 ConfigMap 설정하기

Environment Variable로 설정하는 방법은 아래와 같습니다(참고 링크).

1단계: ConfigMap 작성

먼저 myconfigmap.yaml 파일(ConfigMap Manifest)에 다음과 같이 작성합니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfigmap
data:
  username: k8s-admin
  access_level: "1"

그리고 kubectl로 Manifest를 적용해 줍니다.

kubectl apply -f myconfigmap.yaml
2단계: Pod에서 ConfigMap 참조

이제 myconfigmap이라는 이름의 ConfigMap이 생성되었고, 이를 사용할 Pod의 Manifest에 configMapRef: 키를 추가하고, name: 에 ConfigMap의 이름을 적어줍니다.

apiVersion: v1
kind: Pod
metadata:
  name: env-configmap
spec:
  containers:
    - name: app
      command: ["/bin/sh", "-c", "printenv"]
      image: busybox:latest
      envFrom:
        - configMapRef:
            name: myconfigmap

이렇게 설정하면 컨테이너 내부에는 다음과 같은 환경변수가 자동으로 주입됩니다.

  • username = k8s-admin
  • access_level = 1
파일 기반 ConfigMap 사용하기

File을 ConfigMap으로 설정하는 방법은 아래와 같습니다. (참고 링크)

1단계: ConfigMap 작성

gameconfigmap.yaml 파일을 아래와 같이 작성합니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5

kubectl로 Manifest 파일을 적용해 줍니다.

kubectl apply -f gameconfigmap.yaml

이제 game-demo라는 이름의 ConfigMap이 생성되었습니다.

2단계: Pod에서 ConfigMap 파일 마운트하기

ConfigMap을 파일에 대한 Volume 마운트와 비슷한 방법으로 추가해 줍니다.

apiVersion: v1
kind: Pod
metadata:
  name: configmap-demo-pod
spec:
  containers:
    - name: demo
      image: alpine
      command: ["sleep", "3600"]
      volumeMounts:
      - name: config
        mountPath: "/config"
        readOnly: true
  volumes:
  - name: config
    configMap:
      name: game-demo
      items:
      - key: "game.properties"
        path: "game.properties"

이제 컨테이너 내부의 /config 파일 내용은 ConfigMap의 game.properties: 이하의 내용으로 채워집니다.

파일에서 바로 ConfigMap 만들기

파일 내용 부분을 ConfigMap의 data:에 넣을 수도 있지만, 별도 파일로 분리해두고 ConfigMap Template에서 파일 내용을 읽어오게 할 수도 있습니다(참고 링크).
내용 변경을 Template 파일에서 하지 않고 실제 파일에서 할 수 있는 방법입니다.

1단계: 설정 파일 작성

위의 gameconfigmap.yaml 예제를 수정해 보겠습니다. 아래의 내용으로 gameproperties 파일을 생성합니다.

enemy.types=aliens,monsters
player.maximum-lives=5
2단계: Helm 템플릿 구성

gameconfigmap.yaml 파일을 아래와 같이 수정합니다.

apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  game.properties: |
{{ .Files.Get gameproperties | indent 4 }}

결과는 동일하지만, 수정사항이 있을 경우 이제 YAML 파일 대신 gameproperties 파일을 수정하면 됩니다.

7. 컨테이너 초기화는 Init Container에서 수행하자


왜 필요할까요?

컨테이너 시작 시 딱 한 번만 필요한 초기화 작업 등은 이미지 자체에 스크립트를 넣지 말고, Init Container분리해서 넣어두고 사용하는 것이 좋습니다.

DB를 초기화하거나 외부 서비스를 대기하는 등의 초기화 작업은 컨테이너가 시작되기 전에 준비되어야 합니다. Init Container는 컨테이너 시작 직전에 수행되기 때문에 이러한 상황에 사용하기 적합합니다.

어떻게요?

Manifest 내 containers: 이후에 initContainers: 를 추가해 줍니다. (참고 링크)

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox
    command: ['sh', '-c', "until nslookup myservice; do echo waiting for myservice; sleep 2; done"]
  • until nslookup myservice; : nslookup myservice 성공 여부를 검사합니다.
  • do echo … ; : 실패일 경우 반복하여 실행됩니다.
  • sleep 2; : 2초 동안 대기합니다.

initContainers: 아래에 하나 이상의 작업을 넣어줄 수 있습니다.

주의!

Init Container가 실패하면 컨테이너가 시작조차 되지 않습니다. 오류가 없도록 구성해야 합니다.

8. 우아하게 Pod 죽이기 by PreStop Hook


왜 필요할까요?

컨테이너가 내려가기 전에 완료해야 할 작업이 있을 수 있습니다. 이 작업은 어디에서 해주어야 할까요? 원칙적으로는 컨터이너 내의 앱이 모든 처리를 마치고 종료되어야 합니다. K8s에서는 앱의 수명관리에만 집중할 수 있도록 말이죠.

그런데 부득이하게 앱을 수정할 수 없거나 두번째 안전장치가 필요할 경우 등 특정 상황에서, 컨테이너가 죽기 직전에 특정 작업을 수행한 후 종료되도록 hooking할 수 있습니다.

이때 사용할 수 있는 여러 가지 방법 중 lifecycle:preStop을 소개해 드립니다.

어떻게요?

Manifest 내 containers: 항목에 lifecycle:preStop을 추가합니다. (참고 링크)

아래는 NginX 종료 시 30초 대기 후 정상적으로 종료되도록 설정하는 예제입니다.

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh","-c","sleep 30 && nginx -s quit"]

주의!

PreStop을 설정해도 무한정 기다려주지는 않습니다. Termination Grace Period 동안만 대기하며, 해당 시간이 지나면 PreStop 실행 여부와 상관없이 강제로 종료됩니다. (참고 링크)
기본값은 30초입니다.

위의 예제 맨 아래에 Termination Grace Period를 추가하면 다음과 같습니다.

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh","-c","sleep 30 && nginx -s quit"]
  terminationGracePeriodSeconds: 40

이렇게 하면 종료 요청 이후 최대 40초까지 기다렸다가, 그 이후에는 강제로 컨테이너를 종료하게 됩니다.

하나 더! 수명주기 관리에 불필요한 시간이 소요될 수 있습니다. 오남용이 되지 않도록 한번 더 생각해보시고 사용해보세요.

9. Error: INSTALLATION FAILED: create: failed to create: Secret “sh.helm.release.v1.my-awesome-app.v1” is invalid: data: Too long: must have at most 1048576 bytes


뭐죠?

잘 설치되던 Helm Chart가 갑자기 알 수 없는 에러 메시지를 뱉어내고 실행이 되지 않는다면?
Secret을 수정한 적도 없고, 게다가 8자 밖에 안되는 이름인데 너무 길다니 이게 무슨 일인가 싶습니다.

이럴 때 Helm Chart의 용량을 한번 확인해 보세요!

Helm Chart의 최대 용량은 1MB라고 합니다. (참고 링크)
Text 파일로만 구성되기에 이해는 되지만, 보통 Git repository에 넣어두는 방식으로 작업하다 보면 예상치 못한 문제가 생길 수 있습니다.

출처 : HELM(error) data: Too long: must have at most 1048576 bytes

어떻게요?

용량을 줄이는 해법은 간단합니다. .helmignore를 생성하는 것입니다. (참고 링크)
.helmignore에 Helm Chart에 포함되지 않아도 되는 항목들을 명시해두면 불필요한 파일이 패키징되지 않아 용량 문제를 해결할 수 있습니다.

.helmignore에 넣기 좋은 예시는 다음과 같습니다.

# Match any file or path named .helmignore
.helmignore

# Match any file or path named .git
.git

# Match any text file
*.txt

# Match only directories named mydir
mydir/

# Match only text files in the top-level directory
/*.txt

# Match only the file foo.txt in the top-level directory
/foo.txt

# Match any file named ab.txt, ac.txt, or ad.txt
a[b-d].txt

# Match any file under subdir matching temp*
*/temp*

*/*/temp*
temp?

실제 파일의 용량을 줄이려 하지 마시고, 불필요한 항목을 제거해주세요!

10. 추가 설치 없이 Pod 사용량 모니터링 하기


왜 필요할까요?

Prometheus, Grafana 같은 훌륭한 모니터링 툴들은 많이 있습니다.
그러나 설치와 설정도 필요하고 접근 권한이 주어지지 않기도 합니다.

이럴 때 간단히 kubectl 명령어로 Pod 사용량을 확인할 수 있는 방법이 있습니다.

어떻게요?

kubectltop pod 명령어를 사용합니다. (참고 링크)

kubectl top pod

결과는 다음과 같이 출력됩니다.

출처 : Monitoring Kubernetes Resource Usage with kubectl top | Last9
  • 각 Pod의 CPU 사용량과 Memory 사용량을 확인할 수 있습니다.

필터링도 가능합니다.

kubectl top pod --sort-by=cpu
kubectl top pod --sort-by=memory

간단히 빠르게 살펴보기에 딱입니다.

11. 어쨌든 Bitnami!


왜 필요할까요?

출처 : https://www.arrow.com/globalecs/pt/produtos/bitnami/

Bitnami는 가상 어플라이언스 및 웹 애플리케이션, 개발 스택용 소프트웨어 패키지 및 설치 라이브러리입니다.
여러 인기 있는 컨테이너 앱의 이미지를 제공합니다.

각 앱의 공식 컨테이너 이미지 보다 Bitnami 이미지가 더 나은 경우도 많습니다.

  • 사용 방식이 비슷해 일관성 있는 경험 제공
  • 다양한 환경에서 안정적인 버전 지원
출처 : https://hub.docker.com/u/bitnamicharts

MongoDB, RabbitMQ 등 인기 있는 앱들도 포함되어 있습니다. (참고 링크)

컨테이너 이미지뿐 아니라 Helm Chart도 제공해 주어서 K8s에서 바로 사용이 가능합니다.

어떻게요?

Helm Chart에 외부 Chart 추가하기

Helm Chart에서 Dependency를 이용하여 외부 Chart를 불러올 수 있습니다. (참고 링크)

Char.yaml 파일의 가장 아래 쪽에 dependencies:를 추가합니다.

dependencies:
- name: nginx
  version: "1.2.3"
  repository: "https://example.com/charts"
  • name : 외부 Chart의 앱 이름
  • version : 외부 Chart의 버전(앱의 버전 아님!)
  • repository : 외부 Chart가 있는 저장소

Bitnami Charts 설치 예

먼저 Values.yaml에 옵션을 추가해 줍니다.

nginx:
  enabled: true

그리고 Chart.yaml을 수정합니다.

dependencies:
- name: nginx
  version: "1.2.3"
  repository: "oci://registry-1.docker.io/bitnamicharts"
  condition: nginx.enabled

Values.yaml에서 nginx:enabled:false로 바꾸면 NginX Chart가 삭제됩니다.
너무 심플해서 추천을 안할 수가 없습니다.

추가 설정은 어디서?

Bitnami 공식 사이트에서 찾을 수 있고, 찾은 옵션을 Values.yaml에 추가해 주기만 하면 됩니다.
예) nginx => charts/bitnami/nginx at main · bitnami/charts

출처 : charts/bitnami/nginx at main · bitnami/charts

필요한 앱이 있다면?

oci://registry-1.docker.io/bitnamicharts 저장소에는 Bitnami에서 제공하는 다양한 앱들이 존재합니다.
필요한 앱이 있다면 일단 Bitnami에서 제공하는 지 검색해보고, 있다면 바로 사용해보세요!

마치며


K8s는 복잡한 컨테이너를 자동으로 배포·실행·스케일링·관리해 주는 매우 편하고 필수적인 도구입니다. 그러나 Helm Chart 구성이 복잡하여 진입 장벽이 높고, 단순한 오류에도 컨테이너가 동작하지 않는 등 당황스러운 함정들이 다수 존재합니다.

기본적이지만 체계적으로 정리되어 있지 않거나, 이곳저곳에 흩어져 있는 내용 중 실제로 개발·운영하면서 많은 도움이 되었던 팁들을 소개해 보았습니다. 이러한 정보들이 시간을 절약하고 문제를 예방하는 데 도움이 되길 바랍니다.

도커 컨테이너를 넘어 클라우드 네이티브 환경으로 이어지는 쉽지 않은 여정에 조금이나마 도움이 되었으면 합니다. ^-^

요약


  1. Kubernetes? K8s?
    • Kubernetes는 컨테이너 오케스트레이션을 위한 오픈소스 도구입니다.
  2. Namespace 기본값을 지정하세요!
    • CLI에서 kubectl 명령어를 사용할 때 Namespace를 매번 지정하지 말고 기본값을 설정하자.
  3. 별칭(alias)으로 시간 줄이기
    • CLI에서 kubectl 명령어를 사용할 때 별칭(alias)을 사용하여 타이핑 시간과 오타를 줄이자.
  4. YAML Manifest를 만드는 초간단 레시피
    • Helm Chart의 YAML Manifest를 kubectl 명령어로 간단히 만들어 쓰자.
  5. 죽지 않는 Pod! 또는 Terminating 무한대기! 혹시 Finalizer?
    • 죽여도 계속 되살아난다면 Finalizer를 먼저 확인해 보자.
  6. 무쇠 컨테이너 이미지에 Config Map으로 유연함 +1 추가하기
    • 변하지 않는 컨테이너 이미지를 여러 환경에서 사용하려면 Config Map으로 다이나믹하게 설정해주자.
  7. 컨테이너 초기화는 Init Container에서 수행하자
    • 컨테이너 시작 전 딱 한 번만 필요한 초기화 작업은 Init Container에 분리해서 넣어두고 수행하자.
  8. 우아하게 Pod 죽이기 by PreStop Hook
    • Graceful shutdown을 앱에서 처리할 수 없다면 PreStop도 사용해 보자.
  9. Error: INSTALLATION FAILED: create: failed to create: Secret “sh.helm.release.v1.my-awesome-app.v1” is invalid: data: Too long: must have at most 1048576 bytes
    • 잘 설치되던 Helm Chart가 알 수 없는 에러문과 함께 실행이 안된다면 용량 한번 확인해 보자.
  10. 추가 설치 없이 Pod 사용량 모니터링 하기
    • Pod 사용량 모니터링을 kubectl로 간단히 확인해 보자.
  11. 어쨌든 Bitnami!
    • MongoDB, RabbitMQ 등 외부 서비스 설치 고민은 Bitnami Charts 하나면 끝!

Reference


Scroll to Top