쿠버네티스 교육/강의 내용 정리

220628_4_k8s_볼륨_hostPath

kimhope 2022. 6. 28. 17:20
728x90

hostPath


hostPath란

파드가 실행된 호스트의 파일이나 디렉토리를 파드에 마운트

  • 호스트에 있는 실제 파일이나 디렉토리를 마운트함
  • 파드를 재시작하더라도 호스트에 데이터가 남아있음
  • 호스트의 중요 디렉토리를 컨테이너에 마운트해서 사용할 수 있음
  • 쿠버네티스 클러스터 노드에 로그 파일을 저장하거나 CA 인증서 및 토큰을 파드에 제공하기 위한 용도로 사용 가능
  • 도커 시스템용 디렉토리를 컨테이너에서 사용할 때나 시스템용 디렉토리를 마운트해서 시스템을 모니터링하는 용도로 사용 가능

 


 

hostPath 실습

사전 작업

  • kube-node1 노드에 접속
  • /web_contents 디렉토리 생성
  • 디렉토리 안에 index.html 파일 생성
vagrant@kube-master1:~$ ssh vagrant@192.168.56.21

vagrant@kube-node1:~$ sudo mkdir /web_contents

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

 

hostPath 구성

  • 레플리카셋 생성 파일
  • 1. .spec.containers[].volumeMounts: 볼륨 마운트 설정
  • .name: web-content 볼륨 이름 지정
  • .mountPath: 볼륨을 컨테이너의 /usr/share/nginx/html 디렉토리에 마운트하도록 설정
  • 2. .spec.volumes: 볼륨 설정
  • .name: 볼륨 이름 설정
  • . type: 설정한 경로 타입
  • .hostPath.path: 호스트의 볼륨 디렉토리 설정
vagrant@kube-master1:~/hostPath$ cat myapp-rs-hp.yml
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:	#----------------------------1
        - name: web-content
          mountPath: /usr/share/nginx/html
        ports:
        - containerPort: 80
      volumes:	#----------------------------2
      - name: web-content
        hostPath:
          type: Directory
          path: /web_contents

 

  • 서비스 생성 파일
vagrant@kube-master1:~/hostPath$ cat myapp-svc-hp.yml
apiVersion: v1
kind: Service
metadata:
  name: myapp-svc-hp
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: myapp-rs-hp

 

  • 레플리카셋, 서비스 생성
vagrant@kube-master1:~/hostPath$ kubectl create -f myapp-rs-hp.yml -f myapp-svc-hp.yml
replicaset.apps/myapp-rs-hp created
service/myapp-svc-hp created

 

실행 결과

  • myapp-rs-hp 파드 2개 생성
  • myapp-rs-hp 레플리카셋 생성
  • myapp-svc-hp 로드밸런서 생성
  • 오류 발생: 한 개의 파드가 제대로 실행되지 않음 (CotainerCreating 상태가 지속됨)
vagrant@kube-master1:~/hostPath$ kubectl get all
NAME                         READY   STATUS              RESTARTS   AGE
pod/myapp-rs-hp-6bcn8        0/1     ContainerCreating   0          10s
pod/myapp-rs-hp-thfgp        1/1     Running             0          10s

NAME                        TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
service/myapp-svc-hp        LoadBalancer   10.233.46.71    192.168.56.201   80:31404/TCP   10s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/myapp-rs-hp        2         2         1       10s

 

  • 실행되지 않는 파드의 이벤트 확인
  • 볼륨 마운트에 실패함
vagrant@kube-master1:~/hostPath$ kubectl describe pods myapp-rs-hp-6bcn8
Events:
  Type     Reason       Age                   From               Message
  ----     ------       ----                  ----               -------
  Normal   Scheduled    8m46s                 default-scheduler  Successfully assigned default/myapp-rs-hp-6bcn8 to kube-node2
  Warning  FailedMount  4m26s                 kubelet            Unable to attach or mount volumes: unmounted volumes=[web-content], unattached volumes=[default-token-wl2vl web-content]: timed out waiting for the condition
  Warning  FailedMount  2m8s (x2 over 6m44s)  kubelet            Unable to attach or mount volumes: unmounted volumes=[web-content], unattached volumes=[web-content default-token-wl2vl]: timed out waiting for the condition
  Warning  FailedMount  33s (x12 over 8m47s)  kubelet            MountVolume.SetUp failed for volume "web-content" : hostPath type check failed: /web_contents is not a directory

 

  • 실행되고 있는 파드의 이벤트 확인
  • 마운트에 실패한 파드의 이벤트와 비교
vagrant@kube-master1:~/hostPath$ kubectl describe pods myapp-rs-hp-thfgp
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  11m   default-scheduler  Successfully assigned default/myapp-rs-hp-thfgp to kube-node1
  Normal  Pulling    11m   kubelet            Pulling image "nginx:alpine"
  Normal  Pulled     10m   kubelet            Successfully pulled image "nginx:alpine"
  Normal  Created    10m   kubelet            Created container web-server
  Normal  Started    10m   kubelet            Started container web-server

 

  • 파드가 생성된 노드의 위치 확인
  • 정상 실행 중인 파드는 kube-node1에 생성됨
  • 마운트에 실패한 파드는 kube-node2에 생성된 것을 확인
  • kube-node2에 /web_contents 디렉토리가 존재하지 않아 마운트에 실패했다는 것을 알 수 있음
vagrant@kube-master1:~/hostPath$ kubectl get pods -o wide
NAME                     READY   STATUS              RESTARTS   AGE    IP              NODE         NOMINATED NODE   READINESS GATES
myapp-rs-hp-6bcn8        0/1     ContainerCreating   0          14m    <none>          kube-node2   <none>           <none>
myapp-rs-hp-thfgp        1/1     Running             0          14m    10.233.101.92   kube-node1   <none>           <none>

 

오류 해결

  • 파드를 kube-node1 노드에 생성하여 볼륨을 공유하도록 구성
  • 리플리카셋 생성 파일에서 파드를 생성할 노드 지정
  • .spec.template.spec.nodename=kube-node1 추가
vagrant@kube-master1:~/hostPath$ cat myapp-rs-hp.yml
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:
      nodeName: kube-node1	# 추가
      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

 

  • 레플리카셋 삭제 후 다시 생성
vagrant@kube-master1:~/hostPath$ kubectl delete -f myapp-rs-hp.yml
replicaset.apps "myapp-rs-hp" deleted

vagrant@kube-master1:~/hostPath$ kubectl create -f myapp-rs-hp.yml
replicaset.apps/myapp-rs-hp created

 

  • 생성된 파드 정보 확인
  • 두 개의 파드 모두 kube-node1 노드에 생성되어 정상 실행되고 있음
vagrant@kube-master1:~/hostPath$ kubectl get svc,pods -o wide
NAME                        TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE     SELECTOR
service/myapp-svc-hp        LoadBalancer   10.233.46.71    192.168.56.201   80:31404/TCP   23m     app=myapp-rs-hp

NAME                         READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
pod/myapp-rs-hp-lpfq6        1/1     Running   0          2m36s   10.233.101.93   kube-node1   <none>           <none>
pod/myapp-rs-hp-vg98c        1/1     Running   0          2m36s   10.233.101.94   kube-node1   <none>           <none>

 

  • 각 파드에서 동일한 볼륨에 마운트되었는지 확인
vagrant@kube-master1:~/hostPath$ kubectl exec myapp-rs-hp-lpfq6 -- cat /usr/share/nginx/html/index.html
hello hostPath Volumes

vagrant@kube-master1:~/hostPath$ kubectl exec myapp-rs-hp-vg98c -- cat /usr/share/nginx/html/index.html
hello hostPath Volumes

# 로드밸런서 연결 확인
vagrant@kube-master1:~/hostPath$ kubectl run nettool -it --image=c1t1d0s7/network-multitool --rm=true bash
If you don't see a command prompt, try pressing enter.
bash-5.0#
bash-5.0# curl http://myapp-svc-hp
hello hostPath Volumes
bash-5.0# curl http://10.233.46.71
hello hostPath Volumes
bash-5.0# curl http://192.168.56.201
hello hostPath Volumes
728x90