Kubernetes/07. 쿠버네티스 볼륨

[쿠버네티스] hostPath 볼륨

Jaden Park 2021. 6. 22. 13:43

들어가며

hostPath 볼륨 생성

hostPath 볼륨에 사용할 노드의 디렉토리 준비

hostPath 볼륨을 사용하는 레플리카셋 생성

hostPath 볼륨을 사용하는 리소스 변경

hostPath 볼륨을 사용하는 리소스 재확인


들어가며:

 

emptyDir 볼륨은 아무 데이터도 없는 빈 디렉토리를 제공하는 볼륨이였고 동일한 파드 내의 컨테이너 간에 데이터를 공유할 때 유용하게 사용할 수 있었습니다.

 

hostPath 볼륨파드가 동작하는 쿠버네티스 클러스터의 노드(host)의 로컬 파일시스템의 파일 및 디렉토리를 파드가 사용할 수 있는 볼륨으로 제공해줍니다.

 

 

같은 노드에 배치된 파드 및 컨테이너에게 공유 디렉토리를 제공할 목적으로 사용될 수 있지만, 다른 노드에 배치된 파드 및 컨테이너에는 데이터를 공유할 수 없습니다. 즉, 각 노드마다 볼륨이 생성됩니다.

 

또한, 기존에 A 노드에 작동하고 있던 X 파드가, B 노드로 이동하면 더 이상 데이터를 접근할 수 없게 됩니다.

 

k8s 클러스터 내부에서 사용 용도는 k8s 클러스터 노드에 로그 파일을 저장하거나 CA 인증서 및 토큰을 파드에 제공하기 위한 용도가 있습니다.


hostPath 볼륨 생성

volumes:
- name: <VOL-NAME>
  hostPath:
    type: <TYPE>
    path: <PATH>
  • .volumes.hostPath.type: 볼륨의 종류 지정
    • DirectoryOrCreate: 지정된 경로의 디렉토리 사용 (없으면 만들어줌)
    • Directory: 지정된 경로의 디렉토리 사용 (존재해야 함)
    • FileOrCreate: 지정된 경로의 파일 사용 (없으면 만들어줌)
    • File: 지정된 경로의 파일 사용 (존재해야 함)
    • Socket: 지정된 경로의 UNIX 소켓 사용 (존재해야 함)
    • CharDevice: 지정된 경로의 캐틱터 장치 사용 (존재해야 함)
    • BlockDevice: 지정된 경로의 블록 장치 사용 (존재해야 함)

 

  • .volumes.hostPath.path: 공유할 볼륨의 호스트 경로 지정

hostPath 볼륨에 사용할 노드의 디렉토리 준비

kube-node1에 hostPath 볼륨에 사용할 디렉토리를 생성해보겠습니다.

 

컨트롤 플레인에서 kube-node1으로 접속한 후 /web_contents 디렉토리를 생성, index.html 파일을 생성합니다.

그런 뒤 다시 컨트롤플레인으로 돌아옵니다.

vagrant@kube-control1:~$ ssh kube-node1
Password: 

vagrant@kube-node1:~$ sudo mkdir /web_contents
vagrant@kube-node1:~$ echo "hello hostPath Volumes" | sudo tee /web_contents/index.html
hello hostPath Volumes
vagrant@kube-node1:~$ exit

vagrant@kube-control1:~$

hostPath 볼륨을 사용하는 레플리카셋 생성

다음은 hostPath 볼륨을 사용하는 레플리카셋 오브젝트 정의 파일입니다.

vagrant@kube-control1:~/ch7$ cat myapp-rs-hp.yaml 
---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp-rs-hp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: myapp-rs-hp
  template:
    metadata:
      labels:
        app: myapp-rs-hp
    spec:
      containers:
      - name: web-server
        image: nginx:alpine
        volumeMounts:
        - name: web-content
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
        volumes:
        - name: web-content
          hostPath:
            type: Directory
            path: /web_contents

.spec.template.spec.volumes 필드에 web-contents hostPath 볼륨을 지정했으며, web-server 컨테이너가 해당 볼륨을 사용합니다.

레플리카셋 컨트롤러에 의해 web-server 파드는 2개의 복제본을 가집니다. 즉, 2개의 파드에 같은 웹 컨텐츠를 제공해줍니다.

다음은 hostPath 볼륨을 사용하는 레플리카셋을 위한 서비스 오브젝트 입니다.

 

 

vagrant@kube-control1:~/ch7$ cat myapp-svc-hp.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc-hp
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: myapp-rs-hp

 

레플리카셋과 서비스를 생성한 뒤 확인해보겠습니다.

$ kubectl create -f myapp-rs-hp.yaml -f myapp-svc-hp.yaml 
replicaset.apps/myapp-rs-hp created

myapp-rs-hp-f52rd 는 kube-node2에 배치된 것을 확인할 수 있습니다. kube-node2는 볼륨을 연결할 수 없어서 준비되고 있지 않는 것을 추정할 수 있습니다.

 

준비되지 않은 파드의 정보를 kubectl describe 로 더 자세히 살펴보면

이벤트항목에서 볼륨을 마운트 할 수 없다고(FailedMount) 보고를 확인할 수 있습니다.


hostPath 볼륨을 사용하는 리소스 변경

레플리카셋 컨트롤러를 삭제한 뒤 오브젝트를 수정하겠습니다.

$ kubectl delete -f myapp-rs-hp.yaml 

replicaset.apps "myapp-rs-hp" deleted

.spec.template.spec.nodeName 필드를 추가해줍니다. nodeName 필드는 데몬셋으로 살펴본 .spec.template.spec.nodeSelector 필드와 비슷한 기능으로 nodeSelector 는 노드의 레이블을 매핑 시키지만, nodeName 필드는 배치할 노드를 직접 지정할 수 있습니다.

 

다시 레플리카셋 컨트롤러를 생성한 뒤 파드의 배치를 확인해보겠습니다.

두 파드 모두 kube-node1 이 배치된 것을 확인할 수 있고, 볼륨을 마운트 할 수 있기 때문에 준비된 상태로 보고하고 있습니다.


hostPath 볼륨을 사용하는 리소스 재확인

두 파드의 index.html 파일의 내용이 같은지 확인해보겠습니다.

같은 볼륨을 마운트 하고있기 때문에 같은 내용이 출력되는 것을 확인할 수 있습니다.

 

 

서비스에도 접근해보도록 하겠습니다.

로드밸런싱되어도 당연히 같은 볼륨을 마운트하고 있기에 같은 내용이 출력되는 것을 확인할 수 있습니다.