Run The Bridge
k8s 4일차 본문
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
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
# 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
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"
# 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
'Cloud > k8s' 카테고리의 다른 글
k8s 5일차 (0) | 2021.08.13 |
---|---|
Secert과 tls 타입의 시크릿 생성 후 mysql, wordpress, nginx 적용 (0) | 2021.08.11 |
wordpess-mysql 환경변수를 configmap으로 올리기, nginx 관련 실습 (0) | 2021.08.10 |
mysql, wordpress, tomcat, python/flask를 pod, replicaset, deployment로 올리고 서비스 생성하기 (0) | 2021.08.10 |
k8s 3일차 (0) | 2021.08.10 |
Comments