컨테이너 오케스트레이션을 위한 Kubernetes (22.05.23)

박민선·2022년 5월 24일
0

Volume

spec.volumes.*: 볼륨 유형

emptyDir

임시로 사용할 빈 볼륨, 파드 삭제 시 볼륨 같이 삭제
디스크 기반의 병합 종류와 같은 스크레치 공간
충돌로부터 복구하기위해 긴 계산을 검사점으로 지정
웹 서버 컨테이너가 데이터를 처리하는 동안 컨텐츠 매니저 컨테이너가 가져오는 파일을 보관
medium을 momery로 쓰면 램메모리 사용가능

apiVersion: v1
kind: Pod
metadata:
  name: myweb-pod
spec:
  containers:
    - name: myweb1
      image: httpd
      volumeMounts:
        - name: emptyvol
          mountPath: /empty
    - name: myweb2
      image: ghcr.io/c1t1d0s7/go-myweb:alpine
      volumeMounts:
        - name: emptyvol
          mountPath: /empty
  volumes:
    - name: emptyvol
      emptyDir: {}
kubectl create -f myweb-pod.yaml
kubectl exec -it myweb-pod -c myweb1 -- bash

> cd /empty
> touch a b c
kubectl exec -it myweb-pod -c myweb2 -- sh

> ls /empty
kubectl describe po myweb-pod  #같은 볼륨을 서로 공유

gitRepo(사용 중지) --> initContainer(초기화 컨테이너)

pod 생성 시 딱 1번만 실행되고 종료됨

https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/

apiVersion: v1
kind: Pod
metadata:
  name: init-pod
spec:
  initContainers:
    - name: gitpull
      image: alpine/git
      args:
        - clone
        - -b
        - v2.18.1
        - https://github.com/kubernetes-sigs/kubespray.git
        - /repo
      volumeMounts:
        - name: gitrepo
          mountPath: /repo
  containers:
    - name: gituse
      image: busybox
      args:
        - tail
        - -f
        - /dev/null
      volumeMounts:
        - name: gitrepo
          mountPath: /kube
  volumes:
    - name: gitrepo
      emptyDir: {}

hostPath

/mnt/web_contents/index.html

<h1> Hello hostPath </h1>

참고
로컬 스토리지: 다른 호스트에 스토리지 볼륨을 제공할 수 X

  • emptyDir
  • hostPath
  • gitRepo
  • local

vi myweb-rs-hp.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myweb-rs-hp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: httpd
          volumeMounts:
            - name: web-contents
              mountPath: /usr/local/apache2/htdocs/
      volumes:
        - name: web-contents
          hostPath:
            type: Directory
            path: /web_contents
sudo mkdir /web_contents
sudo echo :hellohostPath" | sudo tee /web_contents/index.html
cat /web_contents/index,html
kubectl create -f myweb-rs-hp.yaml
kubectl get rs,po -o wide

node1은 생성되지만 node2,3은 생성되지 않는걸 확인 할 수 있음

emptyDir, hostPath는 local storage임
network storage가 아님

ssh node2 sudo kidir /seb_contents
ssh node2 echo "hello hostPath" | sudo tee /web_contents/index.html
ssh node3 sudo kidir /seb_contents
ssh node3 echo "hello hostPath" | sudo tee /web_contents/index.html
kubectl delete po myweb-   #생성안된 파드 삭제
kubectl get po

PV & PVC

  • PersistentVolume: 스토리지 볼륨 정의
  • PersistentVolumeClaim: PV를 요청

pv, pvc 예제

Pod

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
    - name: mypod
      image: httpd
      volumeMounts:
        - name: myvol
          mountPath: /tmp
  volumes:
	- name: myvol
	  persistentVolumeClaim:
	    name: mypvc

PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  volumeName: mypv
  ...

PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv
spec:
  hostPath:
    path: /web_contents
    type: DirectoryOrCreate

PV, PVC 생명주기

PV <--1:1--> PVC

  1. 프로비저닝
  2. 바인딩
  3. 사용
  4. 회수/반환(Reclaim)
    • Retain: 보존 - PV를 삭제하지 않음(Release <- PVC가 연결 X)
    • Delete: 삭제 - PV를 삭제 / 실제 스토리지 내용 삭제
    • Recycle: 재사용(X) - 실제 스토리지 내용을 비우고, PV를 사용 가능한 상태(Available)

접근 모드(Access Mode)

  • ReadWriteOnce: RWO
  • ReadWriteMany: RWX
  • ReadOnlyMant: ROW

NFS를 사용한 정적 프로비저닝(Static Provision)

node1: NFS 서버

sudo apt install nfs-kernel-server -y
sudo mkdir /nfsvolume
echo "<h1> Hello NFS Volume </h1>" | sudo tee /nfsvolume/index.html
sudo chown -R www-data:www-data /nfsvolume

/etc/exports

/nfsvolume 192.168.100.0/24(rw,sync,no_subtree_check,no_root_squash)
sudo systemctl restart nfs-kernel-server
systemctl status nfs-kernel-server

active(exited) 상태 확인

node1, node2, node3

sudo apt install nfs-common -y 

또는

ansible all -i ~/kubespray/inventory/mycluster/inventory.ini -m apt -a 'name=nfs-common' -b

PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv
spec:
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 1G
  persistentVolumeReclaimPolicy: Retain
  nfs:
    path: /nfsvolume
    server: 192.168.100.100

PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1G
  storageClassName: '' # For Static Provisioning
  volumeName: mypv

RS

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myweb-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: httpd
          volumeMounts:
            - name: myvol
              mountPath: /usr/local/apache2/htdocs
      volumes:
        - name: myvol
          persistentVolumeClaim:
            claimName: mypvc

SVC

apiVersion: v1
kind: Service
metadata:
  name: myweb-svc-lb
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: web

안될 시 (권한변경)
node1으로 이동
ls -ld /nfsvolume
sudo chown nobody:hogroup -R /nfsvolume
sudo chmod 770 -R /nfsvolume
sudo exportfs -arv

파드가 삭제되고 생성되어도 동일한 pvc에 연결됨
pvc와 pv 연결된 상태에서 pv는 삭제 안됨
릴리즈 상태의 pv에 연결 안됨

동적 프로비저닝

Vagrant 스냅샷:
스냅샷 생성: vagrant snapshot save before-rook
스냅샷 복구: vagrant snapshot restore before-rook

NFS Dynamic Provisioner 구성

https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

git clone https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner.git
cd nfs-subdir-external-provisioner/deploy
kubectl create -f rbac.yaml

deployment.yaml

...
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.100.100
            - name: NFS_PATH
              value: /nfsvolume
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.100.100
            path: /nfsvolume
kubectl create -f deployment.yaml
kubectl create -f class.yaml

mypvc-dynamic.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc-dynamic
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1G
  storageClassName: 'nfs-client'  #변경
kubectl create -f mypvc-dynamic.yaml
sudo ls -l /nfsvolume
sudo ls -l /nfsvolume/default~~
echo "<h1> Hello NFS Dynamic Provision </h1>" | sudo tee /nfsvolume/XXX/index.html

myweb-rs-dynamic.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myweb-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: myweb
          image: httpd
          volumeMounts:
            - name: myvol
              mountPath: /usr/local/apache2/htdocs
      volumes:
        - name: myvol
          persistentVolumeClaim:
            claimName: mypvc-dynamic
kubectl create -f myweb-rs-dynamic.yaml

기본 스토리지 클래스

~/nfs-subdir-external-provisioner/deploy/class.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
  annotations:
    storageclass.kubernetes.io/is-default-class: "true"  #추가
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"
kubectl apply -f class.yaml
kubectl get sc

NAME                   ...
nfs-client (default)   ...
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc-dynamic
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1G

Default Storage를 지정해두면
vi mypvc.yaml 에서 storageClassName을 적지 않아도 Default StorageClass로 지정이됨

profile
클라우드신생아

0개의 댓글