본문 바로가기

CI-CD/Kubernetes

Kubernetes- 기본 개념 정리

Pod

쿠버네티스의 최소 단위로서 컨테이너(혹은 컨테이너들)를 추상화한다. 일반적으로 하나의 어플리케이션이 파드에 들어가게 되며 해당 pod들은 여러개의 노드에서 동작할 수 있다. 각 포드는 독립적인 private ip address를 가진다. 파드는 죽거나 다시 시작될 수 있는데 기존의 파드가 재시작 되는 경우, 포드의 ip주소는 변경된다. 기존의 다른 앱과 연결되어있던 파드가 재시작 되어 ip 주소가 변경되게 되었다면 일일히 새로운 주소에 맞도록 이를 수정해 주어야한다. 이는 불편한 과정이므로 쿠버네티스에서는 서비스를 제공하여, 이를 보조한다. 

 

Service

서비스는 영구적으로 할당된 ip 주소를 가진다.

 

CNI

container network interface의 약자로 컨테이너 간의 통신을 지원하는 VxLAN이다. 이는 pod network로도 불린다. 대표적으로 flannel, calico, weavenet이 존재한다. 컨테이너는 CNI를 통해서 물리 네트워크와 연결되어 정보를 보내고 물리 네트워크로 전송된 정보는 다시 CNI를 통해서 다른 컨테이너에게 전달된다. 이런식으로 컨테이너들 간의 통신을 해준다

 

Kubectl

kubectl 명령어의 구조는 다음과 같다.

$ Kubectl [command] [TYPE] [NAME] [flags]
$ kubectl get pod webserver -o wide
$ kubectl get pod webserver -o wide --watch // 변화를 line by line으로 계속 표기해줌 

// command: object에 실행할 명령(create, get, delete, edit ..)
// TYPE: object의 종류(node, pod, service ..)
// NAME: object의 이름
// flags: 부가적으로 설정할 수 있는 옵션 (--help, -o, ..)

 

명령어 약어 확인

$ kubectl api-resources

NAME                              SHORTNAMES   APIVERSION                             NAMESPACED   KIND
bindings                                       v1                                     true         Binding
componentstatuses                 cs           v1                                     false        ComponentStatus
configmaps                        cm           v1                                     true         ConfigMap
endpoints                         ep           v1                                     true         Endpoints
events                            ev           v1                                     true         Event
limitranges                       limits       v1                                     true         LimitRange
namespaces                        ns           v1                                     false        Namespace
nodes                             no           v1                                     false        Node
persistentvolumeclaims            pvc          v1                                     true         PersistentVolumeClaim
persistentvolumes                 pv           v1                                     false        PersistentVolume
pods                              po           v1                                     true         Pod

....

object들의 다양한 약어들을 해당 명령을 통해서 확인이 가능하다. 보통의 경우 tab을 통한 자동완성을 사용하므로 많이 필요하진 않을 것 같다.

 

명령어 사용법 알아보기

$ kubectl [command] --help
$ kubectl logs --help

명령어의 사용법을 자세히 알고 싶다면 해당 명령어 뒤에 --help 플레그를 붙여준다.

 

단일 pod 생성

$ kubectl run [NAME] [flags]
$ kubectl run webserver --image=nginx:1.14 --port 80

단일 컨테이너를 실행하는 경우에는 run 명령어를 사용한다. 이 경우 nginx이미지를 가져와 컨테이너를 만들고 컨테이너의 80번 포트를 외부로 노출시킨 예시이다. 단일 컨테이너에서는 위처럼 run 명령을 실행하여도 괜찮지만 kubectl create deployment를 통해서 deployment를 생성하는 것이 권장된다.

 

deployment를 통한 pod 생성

$ kubectl create deployment [name] [flags]
$ kubectl create deployment mainui --image=httpd --replicas=3
deployment.apps/mainui created

세개의 레플리카 셋을 가지는 디플로이먼트가 생성된다. 역시 get 명령을 통해서 정보 확인이 가능하다.

$ kubectl get deployments -o wide
NAME     READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
mainui   3/3     3            3           12s   httpd        httpd    app=mainui
$ kubectl get pods -o wide
NAME                      READY   STATUS    RESTARTS   AGE     IP         NODE    NOMINATED NODE   READINESS GATES
mainui-77c74c9674-bqlfg   1/1     Running   0          2m25s   10.5.1.5   node2   <none>           <none>
mainui-77c74c9674-c8csn   1/1     Running   0          2m25s   10.5.1.6   node2   <none>           <none>
mainui-77c74c9674-fzg9m   1/1     Running   0          2m25s   10.5.2.5   node3   <none>           <none>

디플로이먼트의 레플리카 셋을 통해서 세개의 파드가 동시에 생성된 모습이다. deployment를 통해서는 파드를 좀 더 세부적으로 관리하는 것이 좋으니 간단한 테스트 용도에서는 kubectl run을, 외적으로는 kubectl create deployment가 적합한 선택이다.

 

pod 내부의 컨테이너 사용하기

$ kubectl exec [POD_NAME] -[flags] --[COMMAND]
$ kubectl exec webserver -it -- /bin/bash

exec 명령은 pod를 대상으로 하기 때문에 object를 명시할 필요 없이 pod 이름을 명시하여 내부 컨테이너에 접근이 가능하다.

 

pod 포트포워딩 하기

$ kubectl port-forward [POD_NAME] [HOST_PORT]:[POD_PORT]
$ kubectl port-forward webserver 80:80
Forwarding from 127.0.0.1:80 -> 80

kubectl port-forward 명령어를 통해서 컨테이너의 포트와 호스트의 포트를 포트 포워딩할 수 있다. port-forward는 pod를 대상으로만 진행하므로 object를 명시할 필요없이 pod 이름만을 명시하면 된다.

 

api resource 수정하기

$ kubectl edit [TYPE] [NAME] 
$ kubectl edit deployments.app mainui

edit 명령을 통해서 동작중인 api resource를 수정할 수 있다

 

deployment를 생성하게 되면 해당 yaml 파일이 생성되는데 edit을 통해서 이를 수정 가능하다.

예를 들어 deployment 생성시 replica를 3으로 설정했는데 이를 나중에 5로 변경하고 싶다면 해당 명령을 통해서 deployment의 yaml에 접근한 후 vi 에디터를 통해서 이를 수정하는 방식이다.

 

yaml 파일로 pod 생성하기

$ kubectl create -f [yaml_FILE]
$ kubectl create -f webserver-pod.yaml  // 리소스를 처음 생성할 때 사용하며, 이미 존재하는 리소스에 대해 오류가 발생

$ kubectl apply -f [yaml_FILE]
$ kubectl apply -f webserver-pod.yaml   // 이미 존재하는 리소스가 있다면 업데이트 하고 없다면 생성함.

 

 - 간단하게 yaml 생성하기

단일 컨테이너를 담은 pod를 위한 yaml 파일은 다음과 같이 생성하면 된다.

$ kubectl run [POD_NAME] --dry-run --image=[IMAGE] [flags] -o yaml > [yaml_FILE]
$ kubectl run webserver --dry-run --image-nginx --port 80 -o yaml > webserver-pod.yaml
  • --dry-run: 실제로 실행하지는 않고 실행 가능 여부만 확인
  • -o yaml: 실행 결과를 yaml로 보여줌

생성과정은 다음과 같다.

  1. "kubectl run webserver --dry-run --image=nginx --port 80 -o yaml"를 통해서 yaml 파일 포맷으로 만든 출력을
  2. ">" 명령어로
  3. "webserver-pod.yaml"에 입력한다.

이렇게 생성된 yaml 파일의 내용은 다음과 같다.

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

하지만 위의 yaml 내용으로는 바로 create를 할 수 없으므로 불필요한 부분은 지워주어야 한다. 혹은 필요한 내용은 더 추가해준다.

 

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: webserver
  name: webserver
spec:
  containers:
  - image: nginx
    name: webserver
    ports:
    - containerPort: 80

이 정도면 의도한대로 yaml 파일이 완성되었다.

이제 kubectl create -f webserver-pod.yaml 명령어로 파드를 생성하면 된다.

 

정보 확인하기

$ kubectl explain [TYPE]
$ kubectl explain pod

Api(pod, service, ...)의 api version과 같은 document 정보를 확인할 수 있다.

$ kubectl describe [TYPE] [NAME]
$ kubectl describe pod webserver

object의 구체적인 설정 정보를 확인할 수 있다.

 

파드 제거

$ kubectl delete pod [NAME] // 파드 제거
$ kubectl delete pod webserver

$ kubectl delete pod --all  // 실행 중인 모든 파드 제거

delete 명령어를 통해서 파드를 제거할 수 있다. 이때 간혹 특정 파드가 제거되지 않는 경우가 있는데 이는 해당 파드가 레플리카 셋이나 디플로이먼트등 상위 컨트롤러에서 생성이 되어 delete로 파드가 제거되어도 다시 재 시작되는 경우이다. 따라서 이 경우 해당 파드를 제거하고 싶다면 레플리카 셋, 디플로이먼트를 제거하면 해당 파드가 함께 제거된다.

'CI-CD > Kubernetes' 카테고리의 다른 글

Kubernetes- Service  (0) 2024.06.07
Kubernetes- Controller  (0) 2024.06.03
Kubernetes- Multi Container Pod 생성  (0) 2024.06.03
Kubernetes- Context  (0) 2024.06.01
Kubernetes- 동작원리  (0) 2024.06.01