Run The Bridge

k8s 4일차 본문

Cloud/k8s

k8s 4일차

anfrhrl5555 2021. 8. 11. 17:22
728x90

0. Persistent volume(PV)과 Persistent Volume Claim(PVD)

  • 포드의 데이터를 영구적으로 저장하기 위한 방법
  • 쿠버네티스는 여러 워커 노드를 사용하고, 어떤 노드에서 접근하더라도 사용할 수 있는 공용 볼륨 필요

  • 호스트의 디렉토리를 포드와 공유해 데이터 저장
  • 포드가 있는 노드에서만 생성되기 때문에 장애 발생 시에는 문제
  • 모든 노드에서 필요한 특수한 포드의 경우 유용하게 사용할 수 있다

1. 워커 노드의 로컬 디렉토리를 볼륨으로 사용 : hostPath

# vi hostpath-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hostpath-pod
spec:
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      volumeMounts:
      - name: my-hostpath-volume  # 아래의 volumes-name과 맞아야한다.
        mountPath: /etc/data  # container안에 mount 할 위치

  volumes:
    - name: my-hostpath-volume
      hostPath:  # volume의 type
        path: /tmp  # node에서 생성할 폴더
kubectl apply -f hostpath-pod.yaml  # pod 실행

 

이제 pod에 직접 접속해서 /etc/data에 'tocuh mydata'로 임시파일을 만든다.

kubectl exec -it hostpath-pod -- bash

pod 내부
worker node

worker1번에서 mydata가 생성된 것을 알 수 있다.


2. 포드 내의 컨테이너 간 임시 데이터 공유 : emptyDir

  • 포드가 실행되는 도중에만 필요한 휘발성 데이터를 각 컨테이너가 함께 사용할 수 있는 임시 저장공간
  • 포드가 생성되면 비어있는 상태로 생성되고 포드가 삭제되면 저장된 데이터도 함께 삭제

3. 네트워크 볼륨

  • 모든 노드에서 접근 가능하고 데이터를 공유하기 위해서는 네트워크 볼륨이 필요하다
  • 쿠버네티스에서는 다양한 종류의 네트워크 볼륨을 지원
  • NFS, iSCSI, GlusterFS, Ceph, AWS EBS 등

우리가 제일 쉽게 사용할 수 있는 네트워크 볼륨: NFS

 

VM에 NFS 서버 만들기

yum install -y nfs-utils  # 모든 node에서 실행

vi /etc/exports
/nfs *(rw,fsid=0,insecure,no_root_squash)

mkdir /nfs

systemctl start nfs-server

systemctl enable nfs-server

exportfs -r  # export 설정

showmount -e  # 구성보기

exportfs -v

mkdir /nfs/vol1
mkdir /nfs/vol2

worker node에서 확인
worker node에서 확인

# vi nfs-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nfs-pod
spec:
  containers:
    - name: my-container
      image: busybox
      args: ['tail', '-f', '/dev/null']
      volumeMounts:
      - name: my-nfs-volume
        mountPath: /etc/data

  volumes:
    - name: my-nfs-volume
      nfs:
        path: /nfs
        server: 192.168.100.140

nfs-pod : kube-worker2

 

k apply -f nfs-pod.yaml
k exec it nfs-pod -- bash  # 접속

cd /etc/data

touch file1
touch file2

확인가능

worker2에서 node가 파일을 만들었는데, master에서 파일이 만들어졌다.

 

 

다음의 명령을 worker node 1, 2에 입력한다.

mount -t nfs -o sync 192.168.100.140:/nfs /mnt

cd /mnt 로 이동 후 파일을 생성하면 모든 node에서 파일을 볼 수 있다.


4. PV와 PVC 사용하기

# vi nfs-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  persistentVolumeReclaimPolicy: Retain
  nfs:
    server: 192.168.100.140
    path: /nfs/PersistentVolume
k apply -f nfs-pv.yaml

 

용량을 5Gi라고 쓰는 이유?

1k = 1000(현실)

1ki = 1024(컴퓨터 세상)

 

 

# vi nfs-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-nfs-pvc
spec:
  storageClassName: ""
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
# vi nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nfs-mount-container
spec:
  containers:
  - name: nfs-mount-container
    image: busybox
    args: ["tail", "-f", "/dev/null"]
    volumeMounts:
    - name: nfs-volume
      mountPath: /mnt
  volumes:
  - name: nfs-volume
    persistentVolumeClaim:
      claimName: my-nfs-pvc

STATUS가 Bound이므로 이제 사용하면 된다. (Pod에서 사용)

 

이제 Pod로 접속해서 /mnt 위치로 이동 후, 아무 파일이나 생성하면 된다.

 

그러면 nfs에 위치한 디렉토리에 파일이 생성되는 것을 볼 수 있다.

 

PVC에서 주로 사용하는 조건

  • accessMode 종류
  • 볼륨 크기
  • 라벨
  • 스토리지 클래스

ReadWriteOnce가 사용하는 node가 1개여야한다.

ReadOnlyMany는 여러 node에서 사용가능

ReadWriteMany는 all-in-one

 

 

PV의 Reclaim Policy 종류 따른 상태 변화

Pod를 삭제해도 Bound 상태는 변하지 않지만, pvc가 삭제하면 Released로 바뀐다.

 

이제 이 PV는 재사용이 되지않는다.

 

 

다시 생성해도 Pending상태로 유지된다.


5. StorageClass와 Dynamic Provisioning

  • 볼륨의 특성을 파악해야 하고 PVC에서 요구하는 조건의 PV를 미리 혹은 매번 만들어 주는 것은 번거로운 일이다
  • Dynamic Provisioning은 사용자가 PVC를 만들면 자동으로 PV와 외부 스토리지를 provisioning(제공) 해주는 기능
  • StorageClass는 dynamic provisioning이 가능한 외부 스토리지 정보를 명시한 오브젝트
    → StorageClass여러가지 스토리지 유형을 표현하는 것으로 사전에 정의한 유형으로 동적 프로비저닝을 하는데 사용

 

(실습) NFS를 이용한 StorageClass 구현하기

강사님이 구한 파일로 실습을 해보았다.

# vi nfs-prov-sa.yaml

kind: ServiceAccount
apiVersion: v1
metadata:
  name: nfs-pod-provisioner-sa
---
kind: ClusterRole # Role of kubernetes
apiVersion: rbac.authorization.k8s.io/v1 # auth API
metadata:
  name: nfs-provisioner-clusterRole
rules:
  - apiGroups: [""] # rules on persistentvolumes
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-provisioner-rolebinding
subjects:
  - kind: ServiceAccount
    name: nfs-pod-provisioner-sa # defined on top of file
    namespace: default
roleRef: # binding cluster role to service account
  kind: ClusterRole
  name: nfs-provisioner-clusterRole # name defined in clusterRole
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-pod-provisioner-otherRoles
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-pod-provisioner-otherRoles
subjects:
  - kind: ServiceAccount
    name: nfs-pod-provisioner-sa # same as top of the file
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: nfs-pod-provisioner-otherRoles
  apiGroup: rbac.authorization.k8s.io
# vi deployment-provision-nfs.yaml

kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-pod-provisioner
spec:
  selector:
    matchLabels:
      app: nfs-pod-provisioner
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-pod-provisioner
    spec:
      serviceAccountName: nfs-pod-provisioner-sa # name of service account
      containers:
        - name: nfs-pod-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-provisioner-v
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME # do not change
              value: nfs-test # SAME AS PROVISIONER NAME VALUE IN STORAGECLASS
            - name: NFS_SERVER # do not change
              value: 192.168.100.140 # Ip of the NFS SERVER
            - name: NFS_PATH # do not change
              value: /nfs/dynamic  # path to nfs directory setup
      volumes:
       - name: nfs-provisioner-v # same as volumemouts name
         nfs:
           server: 192.168.100.140  # 이 부분만 변경
           path: /nfs/dynamic  # 이 부분만 변경 및 dynamic dir 추가
# vi storageclass-nfs.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storageclass  # PVC에 storageClass 부분에 이 이름을 주어야한다.
provisioner: nfs-test  
reclaimPolicy: Retain
parameters:
  archiveOnDelete: "false"

storageclasses 보는법

 

# vi test-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc-test
spec:
  storageClassName: nfs-storageclass # SAME NAME AS THE STORAGECLASS, 여기여기
  accessModes:
    - ReadWriteMany #  must be the same as PersistentVolume
  resources:
    requests:
      storage: 1Gi

pv가 알아서 만들어져서 Bound 되어있다.


 

 

728x90
Comments