본문 바로가기

Docker & Kubernetes

쿠버네티스(Kubernetes) - 기본적인 사용방법

파드 생성

= nginx-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: container-name
    image: nginx

 

= 파드 생성 명령어 (kubectl)

# 파드를 생성한다. --image=nginx는 생성할 이미지의 이름
[root@m-k8s-ys vagrant]# kubectl run nginx-pod --image=nginx

# 파드 확인
[root@m-k8s-ys vagrant]# kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          41s

[root@m-k8s-ys vagrant]# kubectl create nginx --image=nginx
Error: unknown flag: --image
See 'kubectl create --help' for usage.

# deployment를 추가해야함. 기존 이름은 피해서 dpy-nginx로 지정해 생성
[root@m-k8s-ys vagrant]# kubectl create deployment dpy-nginx --image=nginx

(?) 파드생성시, run과 create의 차이는?

: run으로 파드를 생성하면 단일 파드 1개만 생성되고 관리되고, create deployment로 파드를 생성하면 디플로이먼트(Deployment)라는 관리 그룹 내에서 파드가 생성됨. (그냥 1개와 포장지안에있는 1개의 차이)

(?) nginx 이미지는 어디에서 가져올까? 컨테이너로 도커를 사용하므로 https://hub.docker.com/_/nginx 에서 가져옴. 기본저장소 이외에도 구글의 GCR, 아마존의 ECR, 마이크로소프트의 ACR 등을 사용할 수도 있다.

오브젝트란?

: 쿠버네티스를 사용하는 관점에서 파드와 디플로이먼트는 스펙(spec)과 상태(status) 등의 값을 가지고 있다. 이러한 값을 가지고 있는 파드와 디플로이먼트를 개별 속성을 포함해 부르는 단위를 오브젝트(Object)라 한다.

 

= 기본 오브젝트 4가지

- 파드(Pod): 쿠버네티스에서 실행되는 최소 단위이다. 독립적인 공간과 사용 가능한 IP를 가지고 있다. 하나의 파드는 1개 이상의 컨테이너를 갖고 있기 때문에 여러 기능을 묶어 하나의 목적으로 사용할 수도 있다.

- 네임스페이스(Namespaces): 쿠버네티스 클러스터에서 사용되는 리소스들을 구분해 관리하는 그룹.

- 볼륨(Volume): 파드가 생성될 때 파드에서 사용할 수 있는 디렉터리를 제공. 기본적으로 파드는 영속되는 개념이 아니라 제공되는 디렉터리도 임시로 사용한다. 파드가 사라지더라도 저장과 보존이 가능한 디렉터리를 볼륨 오브젝트를 통해 생성하고 사용할 수 있다.

- 서비스(Service): 파드는 클러스터 내에서 유동적이기 때문에 접속 정보가 고정일 수 없기 때문에 파드 접속을 안정적으로 유지하도록 서비스를 통해 내/외부로 연결된다. 쿠버네티스 외부에서 쿠버네티스 내부로 접속할 때 내부가 어떤 구조로 돼 있는지, 파드가 살았는지 죽었는지 신경 쓰지 않아도 이를 논리적으로 연결하는 것이 서비스이다.

레플리카셋으로 파드 수 관리하기

# 디플로이먼트에 싸서 파드 생성
[root@m-k8s-ys vagrant]# kubectl create deployment dpy-nginx --image=nginx

# nginx-pod를 3개로 맞춘다
[root@m-k8s-ys vagrant]# kubectl scale pod nginx-pod --replicas=3
Error from server (NotFound): the server could not find the requested resource
# nginx-pod는 파드로 생성됐기 때문에 디플로이먼트 오브젝트에 속하지 않으므로 리소스를 확인할 수 없다는 오류 출력.

# 디플로이먼트에 포장한다
[root@m-k8s-ys vagrant]# kubectl scale deployment dpy-nginx --replicas=3
deployment.apps/dpy-nginx scaled

# dpy-nginx 디플로이먼트 파드 제거
[root@m-k8s-ys vagrant]# kubectl delete deployment dpy-nginx
deployment.apps "dpy-nginx" deleted

=> 파드를 생성하고 scale하여 replica를 조절해야한다. (create에는 replicas 옵션을 사용할 수 없다)

따라서, 디플로이먼트 오브젝트 스펙을 yaml파일로 만들어서 동작시킬 수 있다.

 

= echo-hname.yaml

apiVersion: apps/v1 # API 버전
kind: Deployment # 오브젝트 종류
metadata:
  name: echo-hname
  labels:
    app: nginx
spec:
  replicas: 3 # n 개의 파드를 생성할지 결정
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: echo-hname
        image: sysnet4admin/echo-hname # 사용되는 이미지

 

 

# 쿠버네티스 버전에 따라 사용 가능한 API 버전확인
[root@m-k8s-ys vagrant]# kubectl api-versions

# replicas 값 변경하기
[root@m-k8s-ys vagrant]# sed -i 's/replicas: 3/replicas: 6/' ./echo-hname.yaml

# yaml파일 변경내용 create 사용시 오류발생
[root@m-k8s-ys vagrant]# kubectl create -f ./echo-hname.yaml
Error from server (AlreadyExists): error when creating "./echo-hname.yaml": deployments.apps "echo-hname" already exists

# yaml파일 변경내용 apply 사용
[root@m-k8s-ys vagrant]# kubectl apply -f ./echo-hname.yaml

 

오브젝트 생성 명령어 비교

구분 Run Create Apply
명령 실행 제한적임 가능함 안 됨
파일 실행 안 됨 가능함 가능함
변경 가능 안 됨 안 됨 가능함
실행 편의성 매우 좋음 매우 좋음 좋음
기능 유지 제한적임 지원됨 다양하게 지원됨

노드 자원 보호 및 유지보수하기

# 워커노드에 할당되지 않도록 상태 변경
[root@m-k8s-ys vagrant]# kubectl cordon w3-k8s-ys
node/w3-k8s-ys cordoned

# node 확인
[root@m-k8s-ys vagrant]# kubectl get nodes
NAME        STATUS                     ROLES    AGE   VERSION
m-k8s-ys    Ready                      master   7d    v1.18.4
w1-k8s-ys   Ready                      <none>   7d    v1.18.4
w2-k8s-ys   Ready                      <none>   7d    v1.18.4
w3-k8s-ys   Ready,SchedulingDisabled   <none>   7d    v1.18.4

# 워커노드에 할당되도록 상태 변경
[root@m-k8s-ys vagrant]# kubectl uncordon w3-k8s-ys
node/w3-k8s-ys uncordoned

# drain으로 지정된 노드의 파드를 전부 다른 곳으로 이동(삭제->신규생성)시켜 해당 노드를 유지보수 할 수 있는 상태로 바꿈.
[root@m-k8s-ys vagrant]# kubectl drain w3-k8s-ys
node/w3-k8s-ys cordoned
error: unable to drain node "w3-k8s-ys", aborting command...

There are pending nodes to be drained:
 w3-k8s-ys
cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): kube-system/calico-node-d8v8p, kube-system/kube-proxy-cv5qr
cannot delete Pods not managed by ReplicationController, ReplicaSet, Job, DaemonSet or StatefulSet (use --force to override): default/nginx-pod
# 데몬셋은 각 노드에 1개만 존재하는 파드라서 drain으로는 삭제할 수 없다.

# ignore-daemonsets 옵션 사용하여 drain 진행
[root@m-k8s-ys vagrant]# kubectl drain w3-k8s-ys --ignore-daemonsets

# 유지보수가 끝나고나서 다시 워커노드에 할당되도록 상태 변경
[root@m-k8s-ys vagrant]# kubectl uncordon w3-k8s-ys
node/w3-k8s-ys uncordoned

파드 업데이트하기

= rollout-nginx.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rollout-nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.12

 

 

# 파드 생성
[root@m-k8s-ys vagrant]# kubectl apply -f ./rollout-nginx.yaml 
deployment.apps/rollout-nginx created

# record 옵션으로 기록된 히스토리를 조회함
[root@m-k8s-ys vagrant]# kubectl rollout history deployment rollout-nginx
deployment.apps/rollout-nginx 
REVISION  CHANGE-CAUSE
1         <none>

# 배포된 파드에 속해 있는 nginx 컨테이너 버전을 curl -I(헤더 정보만 보여주는 옵션) 명령으로 확인
[root@m-k8s-ys vagrant]# curl -I --silent 172.16.138.69 | grep Server
Server: nginx/1.15.12

# set image 명령으로 업데이트
[root@m-k8s-ys vagrant]# kubectl set image deployment rollout-nginx nginx=nginx:1.16.0 --record
deployment.apps/rollout-nginx image updated

# 상태값, 히스토리 확인
[root@m-k8s-ys vagrant]# kubectl rollout status deployment rollout-nginx
deployment "rollout-nginx" successfully rolled out
[root@m-k8s-ys vagrant]# kubectl rollout history deployment rollout-nginx
deployment.apps/rollout-nginx 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment rollout-nginx nginx=nginx:1.16.0 --record=true

# 쿠버네티스 상태를 살펴봄
[root@m-k8s-ys vagrant]# kubectl describe deployment rollout-nginx

# 히스토리를 가지고 복구하기
[root@m-k8s-ys vagrant]# kubectl rollout undo deployment rollout-nginx
deployment.apps/rollout-nginx rolled back

# 히스토리 넘버(특정시점)로도 복구가능
[root@m-k8s-ys vagrant]# kubectl rollout undo deployment rollout-nginx --to-revision=1

 

참고자료

= 서적 - 컨테이너 인프라 환경 구축을 위한 쿠버네티스/도커, 길벗 - 제 3장