본문 바로가기
네트워크/k8s

[k8s] 27. Volume - 실습

by Lauren X Ming 2021. 2. 21.

Volume 실습

image

  • 동적으로 PV를 생성하는 것을 하려면 Dynamic Provisioning 솔루션을 지원하는 StorageOS를 설치해야 함

1. StorageOS 설치

설치

kubectl apply -f https://github.com/storageos/cluster-operator/releases/download/1.5.0/storageos-operator.yaml

설치 확인

kubectl get all -n storageos-operator

image

Deployment 수정

kubectl edit deployments.apps storageos-cluster-operator -n storageos-operator

spec.containers.env의 DISABLE_SCHEDULER_WEBHOOK의 Value를 true로 설정

spec:
  containers:
  - command:
    - cluster-operator
    env:
    - name: DISABLE_SCHEDULER_WEBHOOK
      value: "false"    # true 로 변경
    image: storageos/cluster-operator:1.5.0
    imagePullPolicy: IfNotPresent

image

  • 이거 안하면 StorageClassName에 ""을 넣으면 PV를 못찾고 에러가 나서 변경함

관리 계정을 위한 Secret 생성 (username 및 password를 Base64 문자로 만들기)

echo -n "admin" | base64
echo -n "1234" | base64

image

apiUsernameapiPassword 부분에 위 결과로 나온 문자 넣기

kubectl create -f - <<END
apiVersion: v1
kind: Secret
metadata:
  name: "storageos-api"
  namespace: "storageos-operator"
  labels:
    app: "storageos"
type: "kubernetes.io/storageos"
data:
  apiUsername: YWRtaW4=  # admin
  apiPassword: MTIzNA==  # 1234
END

StorageOS 설치 트리거 생성

kubectl apply -f - <<END
apiVersion: "storageos.com/v1"
kind: StorageOSCluster
metadata:
  name: "example-storageos"
  namespace: "storageos-operator"
spec:
  secretRefName: "storageos-api" # Reference the Secret created in the previous step
  secretRefNamespace: "storageos-operator"  # Namespace of the Secret
  k8sDistro: "kubernetes"
  images:
    nodeContainer: "storageos/node:1.5.0" # StorageOS version
  resources:
    requests:
    memory: "512Mi"
END

설치 확인

kubectl get all -n storageos

image

  • 파드들이 만들어지고 있음 (ㅋㅋ 1개 만들어졌네 taint 때메 나중에 수정하면 2개임)
    • image
  • 서비스도 만들어짐
  • 파드는 Daemonset에 의해서 만들어짐
  • 스캐줄러 역할을 하는 deployment와 replicaset도 만들어짐
  • 서비스를 통해서 StorageOS 대시보드에 접속할 수 있음
  • EXTERNAL IP에 값을 줘서 외부에서 접속 가능하게 할 것

Dashboard 접속을 위한 Service 수정

kubectl edit service storageos -n storageos

spec에 externalIPs와 MasterIP 추가

spec:
  clusterIP: 10.98.109.153
  externalIPs:     # 추가
  - 192.168.35.30   # Master IP 추가
  ports:

image

image

  • ExternalIP 추가 됐당

접속

http://192.168.35.30:5705/

image

안 되는데요... --> 방법 2로 ㄱㄱ

Dashboard 접속을 위한 Service 수정(방법 2)

kubectl edit service storageos -n storageos

type을 NodePort로 변경

spec:
  ports:
  - name: storageos
    port: 5705
    protocol: TCP
    targetPort: 5705
    nodePort: 30705  # port 번호 추가
  type: NodePort     # type 변경

image

image

접속

http://192.168.35.30:30705/

이번에도 접속 안 되면 실습 안 함 접음 ㅅㄱ

image

image

이전 실습 Taint 때문임

image

Pod - Node Scheduling - 실습

node02의 taint 제거

[root@k8s-master ~]# kubectl taint node k8s-node2 out-of-disk=True:NoExecute-
node/k8s-node2 untainted

기존에 실행되지 않던 Pod 하나가 이제 돌아감!

image

그럼 이제 접속 쌉가능 ㅇㅈ?

이거랑 똑같은 상황으로 해결 못함

  • 그냥 http://192.168.35.31:5705/로 접속해서 실습하겠음

image

  • admin/1234

Default StorageClass 추가

kubectl apply -f - <<END
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: default
  annotations: 
    storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/storageos
parameters:
  adminSecretName: storageos-api
  adminSecretNamespace: storageos-operator
  fsType: ext4
  pool: default
END
  • annotation 덕분에 storageclass가 default로 작용할 수 있음

StorageClass 확인

kubectl get storageclasses.storage.k8s.io

image

  • default는 방금 만든 storageClass
  • fast는 storageOS를 설치하면서 생성된 storageClass

사전 준비 끝!


2. Dynamic Provisioning

image

  • hostPath PV 2개 만들 예정 용량만 다르게
  • StorageClass에 ""를 넣어서 PVC와 연결할 예정
  • PVC 때, StorageClassName에 fast, 생략한 값도 넣어볼 예정

PersistentVolume - hostpath1

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-hostpath1
spec:
  capacity:
    storage: 1G
  accessModes:
  - ReadWriteOnce
  hostPath:
    path: /mnt/hostpath
    type: DirectoryOrCreate

PersistentVolume - hostpath2

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-hostpath2
spec:
  capacity:
    storage: 2G
  accessModes:
  - ReadWriteOnce
  hostPath:
    path: /mnt/hostpath
    type: DirectoryOrCreate

PersistentVolumeClaim - hostpath1

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-hostpath1
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1G
  storageClassName: ""

PersistentVolumeClaim - fast1

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-fast1
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1G
  storageClassName: "fast"

PersistentVolumeClaim - default1

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-default1
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2G

실습 과정

  1. PV - hostpath1 생성
  2. PV - hostpath2 생성
    image
  3. PVC - hostpath1 생성 --> PV - hostpath1과 연결됨
    image
  4. PVC - fast1 생성 --> 바로 Volume과 연결이 됨
    image
    image
  5. PVC - default 생성 (StorageClassName 생략)
    image
    image
    StorageOS 대시보드에서도 Volume 확인 가능

PV를 직접 만든 것과 Dynamic Provisioning의 차이

  • PV를 직접 만들어서 PVC와 연결했을 때, Volume은 만들어지지 않음, 경로만 존재
    • 파드가 생성될 때 Volume이 만들어짐
  • PV가 StorageOS와 같이 Dynamic Provisioning 되면 Volume이 직접 만들어짐

3. PV Status, ReclaimPolicy

image

image

  • 최초 PV를 만들 땐, Available
  • PVC와 연결된 PV는 Bound
  • Pod가 PVC와 연결되어야 Volume이 만들어짐(PV를 직접 만든 경우)
  • 직접 만든 PV의 ReclaimPolicy는 Retain, StorageClass로 만든 PV는 Delete

Pod - hostpath

apiVersion: v1
kind: Pod
metadata:
  name: pod-hostpath1
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node1
  terminationGracePeriodSeconds: 0
  containers:
  - name: container
    image: kubetm/init
    volumeMounts:
    - name: hostpath
      mountPath: /mount1
  volumes:
  - name: hostpath
    persistentVolumeClaim:
      claimName: pvc-hostpath1

Persistent Volume - Recycle

image

  • Deprecated된 Recycle 실습
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-recycle1
spec:
  persistentVolumeReclaimPolicy: Recycle
  capacity:
    storage: 3G
  accessModes:
  - ReadWriteOnce
  hostPath:
    path: /tmp/recycle
    type: DirectoryOrCreate
  • persistentVolumeReclaimPolicy: Recycle
  • path: /tmp/recycle

PersistentVolumeClaim - Recycle

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-recycle1
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 3G
  storageClassName: ""

Pod - Recycle

apiVersion: v1
kind: Pod
metadata:
  name: pod-recycle1
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node1
  terminationGracePeriodSeconds: 0
  containers:
  - name: container
    image: kubetm/init
    volumeMounts:
    - name: hostpath
      mountPath: /mount1
  volumes:
  - name: hostpath
    persistentVolumeClaim:
      claimName: pvc-recycle1

실습 과정

  1. Pod - hostpath 생성
  2. Pod의 shell에 들어가서 다음 명령어 실행하여 데이터 넣기
    cd /mount1
    touch file.txt
    파드가 node1에 생성돼서 node1에 file.txt가 생성됨
    image
    PV를 먼저 만들고, 파드가 연결되는 시점에 실제 볼륨이 생성되는지 확인한 실습
  3. Pod - hostpath 삭제
  4. PVC - hostpath 삭제
    image
    PV - hostpath가 Released가 됨 --> 직접 지워야 삭제됨
    image
    Volume도 직접 node1에 들어가서 삭제해줘야 함
  5. PVC - default 삭제
  6. PV - default가 바로 삭제됐는지 확인
    PVC - default 삭제 전 PV - default
    image
    PVC - default 삭제 후 PV - default
    image
    image
  7. Deprecated된 PV - Recycle 생성
  8. Deprecated된 PVC - Recycle 생성
  9. Deprecated된 Pod - Recycle 생성
  10. Deprecated된 Pod - Recycle 쉘에 들어가서 다음 명령어로 파일 생성
    cd /mount1
    touch file.txt
  11. Deprecated된 Pod - Recycle과 PVC - Recycle 지우기
    Deprecated된 PV - Recycle이 Available이 됨
    실제 노드의 볼륨도 지워짐, 근데 어차피 Deprecated임
    image

StorageClass 만들 때 참고할 YAML

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: default
  annotations:
    # Default StorageClass로 선택 
    storageclass.kubernetes.io/is-default-class: "true" 
# 동적으로 PV생성시 PersistentVolumeReclaimPolicy 선택 (Default:Delete)
reclaimPolicy: Retain, Delete, Recycle
provisioner: kubernetes.io/storageos
# provisioner 종류에 따라 parameters의 하위 내용 다름 
parameters:
  • ReclaimPolicy: Retain --> 삭제될 때 바로 안 지워짐, 마치 직접 만든 PV마냥

Get All Objects In Namespaces

kubectl get all -n storageos-operator
  • 여러 플러그인을 사용하다보면 네임스페이스 단위로 모든 자원을 조회할 때 사용

Force Deleteion

kubectl delete persistentvolumeclaims pvc-fast1 --namespace=default --grace-period 0 --force
kubectl delete persistentvolume pvc-b53fd802-3919-4fb0-8c1f-02221a3e4bc0 --grace-period 0 --force
  • PV나 PVC를 사용하면서 삭제했는데 잘 안 지워질 때 강제로 삭제하는 명령어
  • 일반적으로 delete하는 명령 뒤에 --force를 줌
  • PV, PVC 이외 Pod를 삭제할 때도 사용 가능

HostPath(Deprecated된 내용)

  • Deprecated된 Recycle 정책은 /tmp/로 시작하는 Path에서만 됨

출처

인프런 - 대세는 쿠버네티스