Kubernetes

Kubernetes 인강 정리

JAEJUNG 2021. 8. 20. 18:09

kubectl 명령어를 이용한 Container 쉘 접속하기(한 개 컨테이너의 경우)

vagrant@kube-control1:~/tmp$ kubectl exec --stdin --tty hello-pod /bin/bash

멀티 컨테이너의 경우

vagrant@kube-control1:~/tmp$ kubectl exec --stdin --tty pod-1 -c container2 /bin/bash

 

Service를 만들어서 외부에서도 접속이 가능하게 할 수 있다.

Pod의 labels: 부분과 selector: 부분이 매칭되어 Service와 Pod를 연결할 수 있다.

apiVersion: v1
kind: Service
metadata:
  name: hello-svc
spec:
  selector:
    app: hello
  ports:
    - port: 8200
      targetPort: 8000
  externalIPs:
  - 192.168.0.30
vagrant@kube-control1:~/tmp$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP    PORT(S)    AGE    SELECTOR
hello-svc    ClusterIP   10.105.101.24   192.168.0.30   8200/TCP   3m3s   app=hello

 

curl 명령어를 통해 서비스를 확인한다.

vagrant@kube-control1:~/tmp$ curl http://192.168.0.30:8100
Hello Kubernetes!

 

Pod

먼저 아래 yaml 파일을 통해 Pod를 생성한다.

apiVersion: v1
kind: Pod
metadata:
  name: pod-1
spec:
  containers:
  - name: container1
    image: kubetm/p8000
    ports:
    - containerPort: 8000
  - name: container2
    image: kubetm/p8080
    ports:
    - containerPort: 8080

 

생성된 pod로 통신을 시도한다.

vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE    IP             NODE         NOMINATED NODE   READINESS GATES
pod-1   2/2     Running   0          115s   192.168.9.65   kube-node1   <none>           <none>

vagrant@kube-control1:~/tmp$ curl 192.168.9.65:8000
containerPort : 8000

vagrant@kube-control1:~/tmp$ curl 192.168.9.65:8080
containerPort : 8080

 

containerPort를 중복으로 만든 후 파드를 생성해보자.

아래 명령어는 8000번 포트를 가진 컨테이너 두 개를 생성하는 명령어이다.

vagrant@kube-control1:~/tmp$ cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-2
spec:
  containers:
  - name: container1
    image: kubetm/p8000
    ports:
    - containerPort: 8000
  - name: container2
    image: kubetm/p8000
    ports:
    - containerPort: 8000

 

describe 명령어로 생성된 pod-2를 확인해보자

vagrant@kube-control1:~/tmp$ kubectl describe pod pod-2

container1은 생성됐지만 container2는 생성 시 failed 하는 것을 볼 수 있다.

Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  57s                default-scheduler  Successfully assigned default/pod-2 to kube-node1
  Normal   Pulling    51s                kubelet            Pulling image "kubetm/p8000"
  Normal   Pulled     46s                kubelet            Successfully pulled image "kubetm/p8000" in 4.820224576s
  Normal   Created    45s                kubelet            Created container container1
  Normal   Started    44s                kubelet            Started container container1
  Normal   Pulled     39s                kubelet            Successfully pulled image "kubetm/p8000" in 4.918907458s
  Normal   Pulled     29s                kubelet            Successfully pulled image "kubetm/p8000" in 4.652612655s
  Normal   Pulling    11s (x3 over 44s)  kubelet            Pulling image "kubetm/p8000"
  Normal   Pulled     7s                 kubelet            Successfully pulled image "kubetm/p8000" in 4.013264951s
  Normal   Created    6s (x3 over 39s)   kubelet            Created container container2
  Normal   Started    5s (x3 over 37s)   kubelet            Started container container2
  Warning  BackOff    4s (x3 over 26s)   kubelet            Back-off restarting failed container

 

로그를 확인해보자.

8000번 포트가 이미 사용 중이라는 로그가 찍힌다.

vagrant@kube-control1:~/tmp$ kubectl logs pod-2 container2
events.js:187
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRINUSE: address already in use :::8000

✅ 한 Pod 내의 컨테이너들은 같은 포트를 사용할 수 없다.

 

ReplicationController

파드를 생성해주고 파드에 문제가 생기면 재 생성 시켜준다.(IP는 변경된다.)

아래와 같이 controller를 생성해주자.

  • control.yaml
apiVersion: v1
kind: ReplicationController
metadata:
  name: replication-1
spec:
  replicas: 1
  selector:
    app: rc
  template:
    metadata:
      name: pod-1
      labels:
        app: rc
    spec:
      containers:
      - name: container
        image: kubetm/init
vagrant@kube-control1:~/tmp$ kubectl create -f control.yaml
replicationcontroller/replication-1 created

 

현재 192.168.233.194의 ip를 가진 pod가 생성됐다.

이제 이 파드를 삭제해보자.

vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME                  READY   STATUS    RESTARTS   AGE     IP                NODE         NOMINATED NODE   READINESS GATES
replication-1-ktsbs   1/1     Running   0          3m54s   192.168.233.194   kube-node2   <none>           <none>

 

pod를 직접 삭제해도 다른 이름을 가진 pod가 재 생성되어 동작 중이다.

vagrant@kube-control1:~/tmp$ kubectl delete pod replication-1-ktsbs
pod "replication-1-ktsbs" deleted

vagrant@kube-control1:~/tmp$ kubectl get pods
NAME                  READY   STATUS    RESTARTS   AGE
replication-1-mrv6z   1/1     Running   0          59s

 

pod의 ip를 살펴보면 192.168.233.196으로 변경된 것을 확인할 수 있다.

vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME                  READY   STATUS    RESTARTS   AGE    IP                NODE         NOMINATED NODE   READINESS GATES
replication-1-mrv6z   1/1     Running   0          2m6s   192.168.233.196   kube-node2   <none>           <none>

 

Label

먼저 아래와 같이 6개의 Pod를 생성해준다.

 

vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE     IP                NODE         NOMINATED NODE   READINESS GATES
pod-1   1/1     Running   0          3m43s   192.168.233.197   kube-node2   <none>           <none>
pod-2   1/1     Running   0          3m3s    192.168.9.68      kube-node1   <none>           <none>
pod-3   1/1     Running   0          2m30s   192.168.233.198   kube-node2   <none>           <none>
pod-4   1/1     Running   0          69s     192.168.9.69      kube-node1   <none>           <none>
pod-5   1/1     Running   0          46s     192.168.233.199   kube-node2   <none>           <none>
pod-6   1/1     Running   0          16s     192.168.9.70      kube-node1   <none>           <none>

 

이제 서비스를 만들 때 원하는 pod를 선택해보자.

selector는 type: web으로 설정하여 service를 생성한다.

vagrant@kube-control1:~/tmp$ cat label-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-for-web
spec:
  selector:
    type: web
  ports:
  - port: 8080

 

생성된 서비스의 상세 정보를 확인하면 endpoint에 192.168.233.197(pod-1), 192.168.9.69(pod-4)가

포함된 것을 확인할 수 있다.

이 두 파드는 labels의 type이 web으로 설정된 파드들이다.

vagrant@kube-control1:~/tmp$ kubectl describe svc svc-for-web
Name:              svc-for-web
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          type=web
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.100.17.151
IPs:               10.100.17.151
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         192.168.233.197:8080,192.168.9.69:8080
Session Affinity:  None
Events:            <none>

 

이번엔 label의 lo가 production인 파드를 연결해보자.

vagrant@kube-control1:~/tmp$ cat label-prod.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-for-prod
spec:
  selector:
    lo: production
  ports:
  - port: 8080

 

서비스의 상세정보를 확인하면 라벨의 lo가 production인 파드들이 Endpoint에 속한 것을

확인할 수 있다.

vagrant@kube-control1:~/tmp$ kubectl describe svc svc-for-prod
Name:              svc-for-prod
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          lo=production
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.106.85.173
IPs:               10.106.85.173
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         192.168.233.199:8080,192.168.9.69:8080,192.168.9.70:8080
Session Affinity:  None
Events:            <none>

✅ selector를 활용하면 서비스와 파드의 label을 묶어서 사용할 수 있다.

 

NodeSchedule

Pod를 생성할 때 nodeSelector를 지정하면 정해진 노드에 파드를 생성할 수 있다.

먼저 node들의 label을 확인해보자.

vagrant@kube-control1:~/tmp$ kubectl get nodes --show-labels
NAME            STATUS   ROLES                  AGE    VERSION   LABELS
kube-node1      Ready    <none>                 171m   v1.22.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=kube-node1,kubernetes.io/os=linux
kube-node2      Ready    <none>                 170m   v1.22.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=kube-node2,kubernetes.io/os=linux

 

node1에 pod를 생성하기 위해 nodeSelector 부분에 kube-node1의 label을 입력한다.

vagrant@kube-control1:~/tmp$ cat nodeselect.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-3
spec:
  nodeSelector:
    kubernetes.io/hostname: kube-node1
  containers:
  - name: container
    image: kubetm/init

 

pod-3를 생성하고 NODE 부분을 확인하면 kube-node1에 생성된 것을 확인할 수 있다.

vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
pod-3   1/1     Running   0          19s   192.168.9.71   kube-node1   <none>           <none>

 

또는, node의 현재 자원 상황에 따라 스케쥴러가 자동으로 자원을 할당한다.

 

kube-node1

Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                250m (12%)  0 (0%)
  memory             0 (0%)      0 (0%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)

kube-node2

Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                250m (12%)  0 (0%)
  memory             0 (0%)      0 (0%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)

 

먼저 새 pod를 생성해준다.

vagrant@kube-control1:~/tmp$ cat schedule.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-3
spec:
  containers:
  - name: container
    image: kubetm/init
    resources:
      requests:
        memory: 2Gi
      limits:
        memory: 3Gi

 

현재 node1과 node2 둘 다 메모리에 여유가 있으므로 node1에 파드가 생성된다.

vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE   IP             NODE         NOMINATED NODE   READINESS GATES
pod-3   1/1     Running   0          9s    192.168.9.73   kube-node1   <none>           <none>

 

이제 동일한 yaml 파일로 다른 파드를 생성해보자.

vagrant@kube-control1:~/tmp$ cat schedule.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-4
spec:
  containers:
  - name: container
    image: kubetm/init
    resources:
      requests:
        memory: 2Gi
      limits:
        memory: 3Gi

 

아래와 같이 두 번째 pod는 node2에 생성된 것을 확인한다.

vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE    IP                NODE         NOMINATED NODE   READINESS GATES
pod-3   1/1     Running   0          108s   192.168.9.73      kube-node1   <none>           <none>
pod-4   1/1     Running   0          6s     192.168.233.201   kube-node2   <none>           <none>

 

Service

1. ClusterIP

2. NodePort

3. Load Balancer

 

먼저 여러 서비스 중 ClusterIP를 소개한다.

위 그림과 같이 IP가 부여된 Service를 pod에 연결하여 외부에서 접속하여 사용할 수 있다.

pod에도 ip가 있는데 왜 굳이 service를 연결하여 사용할까?

Pod는 시스템 장애 등의 문제가 발생하면 Pod가 재생성되며, 이 때 pod의 ip는 변경된다.

그럼 지속적인 서비스가 불가능해지기 때문에 pod가 아닌 service와 연결하여 서비스를 제공한다.

 

먼저 pod를 생성한다.

apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  labels:
     app: pod
spec:
  nodeSelector:
    kubernetes.io/hostname: kube-node1
  containers:
  - name: container
    image: kubetm/app
    ports:
    - containerPort: 8080

 

그런 다음 Service를 생성해준다.

type을 지정하지 않으면 default로 ClusterIP로 생성되기 때문에 맨 아랫줄은 생략해도 무방하다.

여기서 pod의 label을 통해 pod와 service가 연결된 상태이다.

apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080
  type: ClusterIP

 

vagrant@kube-control1:~/tmp$ kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE    SELECTOR
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP    17d    <none>
svc-1        ClusterIP   10.105.28.62   <none>        9000/TCP   5m4s   app=pod
vagrant@kube-control1:~/tmp$ kubectl get pods -o wide
NAME    READY   STATUS    RESTARTS   AGE     IP             NODE         NOMINATED NODE   READINESS GATES
pod-1   1/1     Running   0          3m23s   192.168.9.74   kube-node1   <none>           <none>

 

curl 명령어를 통해 Service -> Pod로 통신해보자.

vagrant@kube-control1:~/tmp$ curl 10.105.28.62:9000/hostname
Hostname : pod-1

 

다음으로 NodePort를 살펴보자.

< 출처 : KUBETM BLOG >

NodePort 또한 기본적으로 service에 ip가 할당된다.

특징은 Cluster 내에 연결된 모든 Node에 똑같은 Port가 할당된다.

그럼 외부에서 이 port로 접속을 하면 해당 Service로 연결이 된다.

Service는 외부에서 트래픽이 들어오면 Node1과 Node2 모두에게 트래픽을 전송할 수 있는데,

여기서 "externalTrafficPolicy" 옵션을 설정하면 특정 Node의 ip로 접속한 트래픽은 Servcie가

그 Node에 해당하는 pod에만 트래픽을 전송할 수 있다.

 

테스트를 위해 먼저 pod를 하나 더 생성한다.

현재 pod-1과 pod-2가 모두 service와 연결된 상태이다.

vagrant@kube-control1:~/tmp$ cat cluster_pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-2
  labels:
     app: pod
spec:
  nodeSelector:
    kubernetes.io/hostname: kube-node2
  containers:
  - name: container
    image: kubetm/app
    ports:
    - containerPort: 8080
    
vagrant@kube-control1:~/tmp$ kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
pod-1   1/1     Running   0          22m
pod-2   1/1     Running   0          2m55s

 

Service를 생성한다.

apiVersion: v1
kind: Service
metadata:
  name: svc-2
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080
    nodePort: 30000
  type: NodePort

 

아래와 같이 nodeport가 생성돼있다.

vagrant@kube-control1:~/tmp$ kubectl get svc -o wide | grep svc-2
svc-2        NodePort    10.100.175.188   <none>        9000:30000/TCP   79s   app=pod

 

node1의 30000번 포트로 통신 시 pod-1과 pod-2 모두 표시되는 것을 확인할 수 있다.

vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-2
vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-1
vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-1
vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-2

 

그럼 이제 externalTrafficPolicy 옵션을 사용해보자.

apiVersion: v1
kind: Service
metadata:
  name: svc-3
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080
    nodePort: 30000
  type: NodePort
  externalTrafficPolicy: Local

 

externalTrafficPolicy 옵션을 Local로 지정했기 때문에 해당 노드에 해당하는 pod에만 통신이 되는 것을 확인할 수 있다.

vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-1
vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-1
vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-1
vagrant@kube-control1:~/tmp$ curl 192.168.100.21:30000/hostname
Hostname : pod-1
vagrant@kube-control1:~/tmp$ curl 192.168.100.22:30000/hostname
Hostname : pod-2
vagrant@kube-control1:~/tmp$ curl 192.168.100.22:30000/hostname
Hostname : pod-2
vagrant@kube-control1:~/tmp$ curl 192.168.100.22:30000/hostname
Hostname : pod-2
vagrant@kube-control1:~/tmp$ curl 192.168.100.22:30000/hostname
Hostname : pod-2

 

마지막으로 Load Balancer 타입이다.

type이 LoadBalancer로 지정된 새로운 서비스를 생성해보자.

외부 플러그인이 설치돼있지 않다면 type 다음 줄에 externalIPs를 추가한다.

vagrant@kube-control1:~/tmp$ cat lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-3
spec:
  selector:
    app: pod
  ports:
  - port: 9000
    targetPort: 8080
  type: LoadBalancer
  externalIPs:
  -  192.168.0.10

 

생성된 로드밸런서를 확인한다.

vagrant@kube-control1:~/tmp$ kubectl get svc | grep svc-3
svc-3        LoadBalancer   10.110.22.180    192.168.0.10   9000:30429/TCP   5m29s

 

로드 밸런서와 통신 시 pod-1과 pod-2가 번갈아가면서 통신이 되는 것을 확인할 수 있다.

vagrant@kube-control1:~/tmp$ curl 192.168.0.10:9000/health
pod-1 is Running
vagrant@kube-control1:~/tmp$ curl 192.168.0.10:9000/health
pod-2 is Running
vagrant@kube-control1:~/tmp$ curl 192.168.0.10:9000/health
pod-2 is Running
vagrant@kube-control1:~/tmp$ curl 192.168.0.10:9000/health
pod-2 is Running
vagrant@kube-control1:~/tmp$ curl 192.168.0.10:9000/health
pod-1 is Running

Volume

1. emptyDir

2. hostPath

3. PVC / PV

 

먼저 emptyDir는 컨테이너들끼리 데이터를 공유하기 위해 볼륨을 사용하는 것이다.

최초 이 볼륨은 비어있기 때문에 emptyDir이라고 불린다.

이 볼륨은 Pod 안에 생성되기 때문에 Pod가 삭제되면 이 볼륨은 사라진다.(일시적인 데이터만 사용할 때)

 

아래 yaml 파일을 통해 파드를 생성한다.

vagrant@kube-control1:~/tmp$ cat empty.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-1
spec:
  containers:
  - name: container1
    image: kubetm/init
    volumeMounts:
    - name: empty-dir
      mountPath: /mount1
  - name: container2
    image: kubetm/init
    volumeMounts:
    - name: empty-dir
      mountPath: /mount2
  volumes:
  - name : empty-dir
    emptyDir: {}

 

container1에 접속해보자.

vagrant@kube-control1:~/tmp$ kubectl exec --stdin --tty pod-volume-1 -c container1 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@pod-volume-1 /]#

 

mount 명령어를 통해 mount1 디렉토리가 마운트 돼있는 것을 확인할 수 있다.

[root@pod-volume-1 /]# ls
anaconda-post.log  boot  etc   lib    media  mount1  proc  run   srv  tmp  var
bin                dev   home  lib64  mnt    opt     root  sbin  sys  usr

[root@pod-volume-1 /]# mount | grep mount1
/dev/sda1 on /mount1 type ext4 (rw,relatime)

 

마운트 디렉토리로 들어가서 예제 파일을 하나 생성하자.

[root@pod-volume-1 mount1]# echo "hello file" >> file.txt
[root@pod-volume-1 mount1]# ls
file.txt

 

`ctrl + p + q` 명령어를 통해 container1에서 나온 후 container2로 접속해보자.

vagrant@kube-control1:~/tmp$ kubectl exec --stdin --tty pod-volume-1 -c container2 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
[root@pod-volume-1 /]#

 

아래와 같이 mount2 디렉토리에도 조금 전 만들었던 file.txt라는 파일이 들어있는 것을 확인한다.

[root@pod-volume-1 /]# ls
anaconda-post.log  boot  etc   lib    media  mount2  proc  run   srv  tmp  var
bin                dev   home  lib64  mnt    opt     root  sbin  sys  usr

[root@pod-volume-1 /]# cd mount2/

[root@pod-volume-1 mount2]# ls
file.txt

 

이렇게 emptyDir이 잘 동작하는 것을 확인했다.

이제 pod를 지우고 다시 만들었을 때 어떻게 동작하는지 확인해보자.

vagrant@kube-control1:~/tmp$ kubectl delete pod pod-volume-1
pod "pod-volume-1" deleted

vagrant@kube-control1:~/tmp$ kubectl create -f empty.yaml
pod/pod-volume-1 created

 

pod를 다시 생성했으니 container1 혹은 container2에 접속한다.

mount 디렉토리는 존재하나, pod가 지워지면서 데이터도 함께 지워졌기 때문에 현재의 mount 디렉토리는

빈 디렉토리이다.

vagrant@kube-control1:~/tmp$ kubectl exec --stdin --tty pod-volume-1 -c container2 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
error: unable to upgrade connection: container not found ("container2")

vagrant@kube-control1:~/tmp$ kubectl exec --stdin --tty pod-volume-1 -c container2 /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.

[root@pod-volume-1 /]# ls
anaconda-post.log  boot  etc   lib    media  mount2  proc  run   srv  tmp  var
bin                dev   home  lib64  mnt    opt     root  sbin  sys  usr

[root@pod-volume-1 /]# cd mount2/

[root@pod-volume-1 mount2]# ls

hostPath는 pod가 올라가있는 node의 path를 볼륨으로써 사용한다.

pod는 이 볼륨을 마운트하여 사용하기 때문에 Pod가 죽어도 볼륨은 유지된다는 장점이 있다.

그러나 한 가지 문제점은 pod가 재생성될 때이다.

Node-1의 볼륨을 마운트하고 있던 pod가 재생성될 때 스케줄러에 의해 Node-2에 생성된다면

Node-1의 볼륨을 마운트할 수 없는 문제점이 있다.

hostPath는 파드의 데이터를 저장하는 용도가 아닌, Node에 있는 데이터를 pod에서 쓰기 위한 용도이다.

 

 

PVC / PV

< 출처 : KUBETM BLOG >

Volume에는 로컬도 있지만 볼륨을 직접 만들고 관리할 수 있는 여러 솔루션들이 있다.(git, NFS ..)

이러한 볼륨을 생성하고 이를 PersistentVolume이라는 이름으로 쿠버네티스에 등록한다.

이후 파드를 생성할 때 볼륨 정의 부분에 PVC를 지정하여 PV와 연결한다.

PVC를 두는 이유는 볼륨의 종류는 많고 각각의 설정값이 다르기 때문에 이를 전문적으로 다루는 영역은

Admin으로 구분하고 User는 이를 사용하기 위해 PVC를 만든다.

 

관리자가 생성한 볼륨을 쿠버네티스 클러스터에 표현한 것이 PV이고, Pod의 볼륨과 이 PV를 연결하는 관계가

PVC이다.