Kubernetes World

이번 포스트에서는 kubectl의 기본적인 명령어와 여러가지 object kind, 그리고 나아가 Helm에 대해서 리뷰해 보겠다.

Kubectl Intro

다음과 같이 코드 블럭에 kubectl의 기본 명령어를 주석과 함께 잘 정리해두었다.

# apply를 통해 원하는 상태를 적용
kubectl apply -f ./example.yaml # -f flag로 파일 지정

# get를 통해 리소스 목록 보여줌
kubectl get pods --namespace=example # 네임스페이스 내 pod 받아오기

kubectl get all # pod, replicaset, deployment 등 다 보여줌

kubectl get svc # service를 list

kubectl get pod –namespace=example example-1lkj1kjdklajgk -o yaml # yaml definition 확인

# describe를 통해 kubernetes 리소스의 상세한 상태를 확인할 수 있다. 
kubectl describe pod/example-1lkj1kjdklajgk

# delete를 통해 리소스를 제가 할 수 있다.
kubectl delete pod/example-1lkj1kjdklajgk

# logs 를 통해 로그를 볼 수 있다. 실시간 로그를 보고싶다면 -f 옵션을 이용해야하고, 하나의 pod에 여러 개의 컨테이너가 있다면 -c 로 특정 컨테이너를 지정해야한다.

kubectl logs pod/example-1lkj1kjdklajgk

# exex을 통해 명령어를 전달할 수 있다. -it를 통해 shell에 접속할 수 있다. 마찬가지로 하나의 pod에 여러개가 있는 경우에는 -c로 특정 컨테이너를 지정해야한다.
kubectl exec -it pod/example-1lkj1kjdklajgk -- bash

기본 Object

Pod

Pod는 이미 이전에 말하였듯 가장 작은 크기의 배포 단위입니다. 다음과 같이 yaml 파일로 생성할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

다음과 같이 apiversion을 정해주고, kind에 pod를 넣어주면 됩니다. 또한 구분을 하기 위해 metadata에 이름과 labels을 달아주어야합니다. 그리고 spec에 컨테이너를 넣어주고 다음과 같이 컨테이너를 생성해주면 가능합니다. 여기에는 나와있지 않지만, 모니터링이 필요하다면 image바로 밑에 livenessProbe와 readinessProbe를 넣어주면 됩니다. 전자는 정상적으로 동작하는지 확인하고 그렇지않다면 컨테이너를 재시작해주고, 후자는 정상적으로 동작하지않으면 pod로 들어오는 요청을 제외해줍니다. 또한 env를 놔둬서 환경변수도 제어가 가능합니다. 이외에도 정말 여러가지가 가능합니다…resources로 리소스 양 제어, imagePullPolicy로 이미지를 어떻게 가져올지 조절, nodeSelector로 어떤 노드에 들어갈지 결정, affinity와 toleration으로 taint 컨트롤이 가능합니다.

ReplicaSet

yaml에서 pod를 ReplicaSet으로 바꿔주고 spec밑에 replicas와 원하는 복제수를 넣어주면 사용가능합니다. pod를 복제 수 만큼 복제해줍니다.

Deployment

가장 자주 쓰는 Object입니다. ReplicaSet을 이용하여 pod를 업데이트하고 롤백 및 특정 버전으로 갈 수 있습니다. ReplicaSet과 비슷하지만 업데이트할 경우 새로운 replicaset을 만들고 개수를 조정해가면서 편하게 업데이트를 해줍니다. spec에 selector를 놓고 matchLabels밑에 특정 app과 label을 선택해줘야하고, kind는 deployment로 해줍니다.

DaemonSet와 StatefulSet

DaemonSet은 모든 노드에 pod의 사본이 실행되는 것을 보장합니다. Prometheus나 Fluentd 같은 것을 띄울때 좋다. StatefulSet은 컨테이너 애플리케이션의 상태를 관리하는데 사용하는 컨트롤러이다. 파드들의 순차 및 고유성을 보장해준다.

Job

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

다음과 같이 잡에서 하나 이상의 pod를 실행하고 종료될때까지 파드를 실행한다.

Service

Service를 통해 Pod를 노출하고 Cluster 외부에서 접근할 수 있게 해준다. Service에는 크게 ClusterIP, NodePort, LoadBalancer가 있다. ClusterIP는 Cluster 내부적으로 사용하고, NodePort는 고정 포트로 노출시킨다. 클러스터 외부에서 접속할 수 있다. LoadBalancer는 클라우드 공급자의 LoadBalancer를 이용하여 서비스를 외부에 노출시킨다.

Ingress

Ingress를 붙여 외부와 통신할 수 있게 해준다. 필자는 ExternalSecret을 통해 public key와 private key를 받아왔다.

Volume

Pod 컨테이너간 디렉토리를 공유하기 위해서는 yaml에서 volumeMount를 써주면 된다. 만약 데이터 저장이 필요하다면 (컨테이너가 리스타트해도 날라가면 안돼!) Persistent Volume (PV) 와 Persistent Volume Claim (PVC)를 써주면 된다. Storage를 PV형태로 추가하고 PVC로 Service에 할당해 주는 방식으로 구성된다.

ConfigMap and Secret

ConfigMap은 설정파일과 환경변수를 관리하고, Secret은 비밀번호 등 노출되지 말아야할 것을 관리한다.

Helm

Helm이란 kubernetes를 위한 Package Manager다. Helm은 Mac에서 간단히 Brew Install Helm으로 설치해줄 수 있다. Helm은 다음과 같은 아키텍쳐를 가지고 있다.
다음과 같이 Helm Client와 Tiller Server가 있어서 통신을 해준다.
Helm의 기본 명령어는 다음과 같다.

helm create example # 디폴트 차트 생성
helm template . --dry-run # 어떤 리소스가 생성되는지, Syntax Error는 없는지 확인
helm install example . --namespace=example --create-namespace # 네임스페이스에 현재 경로에 있는 차트 설치
helm list --namespace=example # 현재 설치되어있는 차트 목록 확인
helm upgrade example . --namespace=example # 변경된 내용 반영
helm uninstall example --namespace=example # 차트 삭제

Reference

https://subicura.com/k8s/
https://kubernetes.io/ko/docs/home/
https://woojinger.tistory.com/80