💡 Kubernetes 이해

  • 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있다.
  • 확장가능한 오픈소스 플랫폼이다.
  • 쿠버네티스는 선언적 구성 (desired state)과 자동화를 모두 용이하게 한다.
  • 쿠버네티스는 크고, 빠르게 성장하는 생태계를 가지고 있다.
  • 구글이 2014년에 쿠버네티스 프로젝트를 오픈소스화 했다.

⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

사용자가 node들에 명령을 내리는게 아니다.

명령을 API 서버에 두고 node들이 API 서버로 사용자가 뭐래요? 라고 물어본다.

해당 명령을 스케쥴러 (kube-scheduler) 를 통해 pod들에게 준다.

⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

💥아키텍쳐 화살표 유의💥

💡 Control Plane Component

  • 클러스터에 관한 전반적인 결정을 수행 (스케쥴링 => Pod에 대한 배치)
  • 클러스터 이벤트를 감지하고 반응한다. (replicas 필드 = desired state (자아치유)에 대한 요구조건이 충족되지 않을 경우)

💡 kube-apiserver; like Master

  • 거대한 배의 선장 => like 잭스 스패로우 🚢
  • 쿠버네티스 컨트롤 플레인 컴포넌트
  • 컨트롤 플레인의 프론트엔드
  • 수평적으로 확장되도록 디자인

💡 etcd

  • 모든 클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 일관성-고가용성 키-값 저장소 (KVS => NoSQL).
  • 쿠버네티스 클러스터에서 etcd를 뒷단의 저장소로 사용한다면, 이 데이터를 백업하는 계획은 필수
  • etcd라 부름 => NoSQL => key=value 형식을 사용 => KVS
  • 쿠버네티스 데이터베이스로써 컨트롤 플레인에 일어나는 모든 데이터를 저장

💡 kube-scheduler

  • 노드가 배정되지 않는 새로 생성된 pod를 감지
  • 실행할 노드를 선택하는 컨트롤 컴포넌트, 스케쥴링 결정을 위해서 고려되는 요소는 리소스 (CPU, RAM)에 대한 개별 및 총체적 요구 사항 등을 포함하지만 주로 리소스를 기반으로 한다.

💡 kube-controller-manager

  • Very Busy 젤 바쁜 친구
  • 컨트롤러를 구동하는 마스터 상의 컴포넌트
  • 논리적으로, 각 컨트롤러는 개별 프로세스이지만, 복잡성을 낮추기 위해 모두 단일 바이너리로 컴파일되고 단일 프로세스 내에서 실행
  • 스케쥴러와 컨트롤러 매니저는 유기적으로 통신

✅ 이들 컨트롤러는 다음을 포함

  • 노드 컨트롤러 : 노드가 다운되었을 때 통지와 대응에 관한 책임을 가짐
  • 레플리케이션 컨트롤러 : 시스템의 모든 레플리케이션 컨트롤러 오브젝트에 대해 알맞은 수의 파드들을 유지시켜 주는 책임을 가짐 (복제를 일으키는 컨트롤러)
  • 엔드포인트 컨트롤러 : 엔드포인트 오브젝트를 채운다 (즉, 서비스와 파드를 연결, 접속을 관리)
  • 서비스 어카운트 & 토큰 컨트롤러 : 토큰을 부여해서 접근 제한을 해준다.

💡 Cloud-Controller-Manger

  • 클라우드 벤더사 별 컨트롤 로직을 포함하는 쿠버네티스 컨틀로 플레인 컴포넌트이다.
  • 퍼블릭 클라우드에서 제공해주는 컴포넌트
  • 클라우드 제공자가 제공해주는 거라 학습환경에서는 CCM이 없다.

💡 Node-Component

  • 동작 중인 pod를 유지시키고 쿠버네티스 런타임 환경을 제공하며, 모든 노드 상에서 동작한다.
  • Master Node에도 pod를 위치시킬 수 있지만 바쁜 친구라 권장은 하지 않음

💡 kubelet

  • 능동적 빵셔틀 느낌
  • 작고 귀여운 통통배 선장 ⛵
  • 클러스터의 각 노드에서 실행되는 에이전트
  • kube-apiserver의 명령을 듣는게 아니라 시키지 않아도 kube-apiserver에게 찾아가서 물어본 후 수행
    => API에 몇 개의 pod가 필요한지 알아내서 pod를 만드는 친구
  • pod 안에 컨테이너가 있다.
  • pod를 생성 후에도 master가 죽어도 kube-apiserver 에게 물어봐서 유지 가능

💡 kube-proxy

  • Load Balance 기능을 가지고 있다.
  • 실질적으로 worker node에서 외부로의 연결을 담당
  • Master Node 엔드포인트 컨트롤러의 따까리
  • 클러스터 바깥에서 pod로 네트워크 통신을 할 수 있게 해줌.

💡 Container-runtime (Docker)

  • 컨테이너 실행을 담당하는 소프트웨어

💡 pod

  • 쿠버네티스에서 배포할 수 있는 가장 작은 단위
  • 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가진다.
  • pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근할 수 있다.
  • 컨테이너를 하나만 사용하는 경우도 반드시 pod로 감싸서 관리한다.
  • ECS, Swarm => task
  • Kube => pod
  • 대부분의 경우가 1pod = 1컨테이너, 1스토리지
  • 물론 1pod에 여러 컨테이너가 들어갈 순 있지만 굳이 복잡하게 여러 컨테이너를 넣을 필요는 없음

💡 SVC (Service)

  • 네트워크와 관련된 리소스
  • pod를 외부 네트워크와 연결해주고 여러 개의 pod를 바라보는 내부 로드밸런서를 생성할 때 사용
  • 내부 DNS에 서비스 이름을 도메인으로 등록하기 때문에 서비스 디스커버리 역할도 한다.

🔆 Kubernetes 설치 [CentOS7] 🔆

💡 Minikube 설치

# curl -fsSL https://get.docker.com/ | sudo sh
# systemctl enable --now docker
# yum install -y conntrack git
# curl -Lo minikube https://storage.googleapis.com/minikube/releases/v1.23.2/minikube-linux-amd64 && chmod +x minikube
# mkdir -p /usr/local/bin/
# install minikube /usr/local/bin/
# minikube version
# minikube start --driver=none
# minikube status

💡 kubectl 설치

# curl -LO https://dl.k8s.io/release/v1.22.2/bin/linux/amd64/kubectl
# install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# source <(kubectl completion bash)
# echo "source <(kubectl completion bash)" >> ~/.bashrc
- kubectl CLI 자동완성

# exit
# kubectl version
# kubectl get svc

💡 pod 생성

# mkdir workspace && cd $_
# kubectl run nginx-pod2 --image=nginx
- nginx로 만든 pod를 생성

# kubectl get pod
- pod list

💡 Cluster IP

# kubectl expose pod nginx-pod --name clusterip --type=ClusterIP --port 80
  • 접속 서비스 : expose
  • nginx-pod 이라는 pod를 ClusterIP 라는 접속유형으로 host port는 80으로 하여 expose 한다.

  • cluster ip는 pod들 간 내부에서만 가능한 통신; like private cloud?
  • proxy가 없다면 외부 user는 clusterip로 접근 불가

💡 NodePort

# kubectl expose pod nginx-pod --name nodeport --type=NodePort --port 80


  • Cluster IP의 기능도 지원
  • 외부(호스트) 포트 31670을 열어줘서 외부랑 통신이 가능한 Type
  • 내부에서는 80으로 curl을 통해 접속이 가능하고 외부에서는 kube의 ip:31670으로 접속 가능
  • NodePort 범위 30,000 ~ 32,787

💡 LoadBalancer

# kubectl expose pod nginx-pod --name loadbalancer --type=LoadBalancer --external-ip 192.168.0.182 --port 80

  • NodePort의 기능도 지원
  • 80포트와, 3만대 포트를 사용해서 두 개의 입구
  • NodePort의 기능도 지원
    💦 접속 유형 3가지 [ 접속유형 틀리면 안됨. 정해진 것 ]
  • ClusterIP : 내부만
  • NodePort : 포트사용해서 외부와 내부
  • LoadBalancer : 80과 포트와 내부
# kubectl get pod
# kubectl get svc
# kubectl get all
# kubectl delete svc --all
# kubectl delete pod nginx

💡 pod 명령어

# kubectl get pod
- pod들을 출력

# kubectl get svc
- service들을 출력

# kubectl get all
- 싹 다 출력

# kubectl exec -it nginx-pod -- bash
- pod 터미널로 접속

# kubectl get pod -o wide
- kube-scheduler가 어디에 node 배치했는지 물어보는 것

# kubectl describe pod nginx-pod
- 해당 pod의 상세정보

# kubectl describe svc clusterip-service-pod
- 해당 svc 상세 정보

# kubectl edit svc clusterip-service-pod
- edit 하고싶을 때 사용
- 수정이 모두 다 가능하진 않다.

# kubectl delete pods <pod> --grace-period=0 --force
- kubectl 버전 >= 1.5를 사용하여 파드를 강제로 삭제

# kubectl delete pods <pod> --grace-period=0
- kubectl <= 1.4 버전을 사용하는 경우, --force 옵션을 생략하고 다음을 사용해야 한다.

💡 Service

nginx-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx-pod
spec:
  containers:
  - name: nginx-pod-container
    image: nginx
  • labels:
    app: nginx-pod
    ✏ => service와 연결되는 연결고리라고 할 수 있음
# kubectl apply -f nginx-pod.yaml
# kubectl get pod -o wide
# kubectl describe pod nginx-pod

💡 clusterip-pod.yaml

# vi clusterip-pod.yaml

apiVersion: v1
kind: Service
metadata:
  name: clusterip-service-pod
spec:
  type: ClusterIP
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  • nginx-pod.yaml의 labels 부분에 정의되어 있는 것을 selector에 입력
    port => 호스트 포트
    targetPort => 컨테이너 포트
# kubectl apply -f clusterip-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-pod

💡 nodeport-pod.yaml

# vi nodeport-pod.yaml
apiVersion: v1
kind: Service
metadata:
  name: nodeport-service-pod
spec:
  type: NodePort
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080
  • targetPort: 80 => 컨테이너 포트
# kubectl apply -f nodeport-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-pod

💡 loadbalancer-pod.yaml

apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-pod
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.0.182
  selector:
    app: nginx-pod
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
# kubectl apply -f loadbalancer-pod.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-pod

💡 ReplicaSet

replicaset.yaml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-replicaset
spec:
  replicas: 3 # desired state (kube-controller-manager), 선언적 API, 🔔 자가치유 🔔
  selector:
    matchLabels:
      app: nginx-replicaset

  template:
    metadata:
      name: nginx-replicaset
      labels:
        app: nginx-replicaset
    spec:
      containers:
      - name: nginx-replicaset-container
        image: nginx
        ports:
        - containerPort: 80

3개 desired state가 있고 문제가 생기면 밑에 있는 label을 selector로 참조해서 다시 만든다.
⭐ labels와 selector의 matchLabels가 같아야 참조 가능하므로 이름이 꼭 같아야 한다 ⭐
template는 시작 템플릿 같은거다.

# kubectl apply -f replicaset.yaml
# kubectl get replicasets.apps -o wide
# kubectl describe replicasets.apps nginx-replicaset

🔆 ReplicaSet 🔆

💡 clusterip-replicaset.yaml

apiVersion: v1
kind: Service
metadata:
  name: clusterip-service-replicaset
spec:
  type: ClusterIP
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
# kubectl apply -f clusterip-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-replicaset

💡 nodeport-replicaset.yaml

apiVersion: v1
kind: Service
metadata:
  name: nodeport-service-replicaset
spec:
  type: NodePort
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080
# kubectl apply -f nodeport-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-replicaset

💡 loadbalancer-replicaset.yaml

apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-replicaset
spec:
  type: LoadBalancer
  externalIPs:
    - 172.25.0.137
  selector:
    app: nginx-replicaset
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
# kubectl apply -f loadbalancer-replicaset.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-replicaset

🔆 Master Kube 설치 🔆

# hostnamectl set-hostname master
# curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
# sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/docker-ce.repo
# yum --enablerepo=docker-ce-stable -y install docker-ce-19.03.15-3.el7
# mkdir /etc/docker
# cat <<EOF | sudo tee /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF
# systemctl enable --now docker
# systemctl daemon-reload
# systemctl restart docker
# systemctl disable --now firewalld
# setenforce 0
# sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config

# swapoff -a
# sed -i '/ swap / s/^/#/' /etc/fstab
# mkdir /etc/docker
# cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

# sysctl --system
# reboot
  • swap이 사용중이면 쿠버네티스를 사용할 수 없어 잠시 중지 시켜놓는다
# cat <<'EOF' > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF

# yum -y install kubeadm-1.19.16-0 kubelet-1.19.16-0 kubectl-1.19.16-0 --disableexcludes=kubernetes
# systemctl enable kubelet

✅ Docker Hub를 사용할 수 없을 때

  • Docker Hub에서 이미지를 받을 수 없는 경우 사설 레지스트리를 이용할 수 있다.
  • Master [ 레지스트리 이미지 실행 ]
# docker run -d -p 5000:5000 --restart=always --name private-docker-registry registry
  • Node
# vi /etc/docker/daemon.json

{ "insecure-registries":["192.168.1.183:5000"] }


- 실행 순서를 위해 daemon.json 파일에 overlay2 뒷 부분에 추가한다.
- 사설 레지스트리 주소로 이미지를 push 한다.
- replicaset.yaml 파일의 이미지를 사설 레지스트리 이미지 주소로 입력한다.

curl localhost:5000/v2/_catalog
curl localhost:5000/v2/nginx/tags/list
curl localhost:5000/v2/web-site/tags/list


- 사설 레지스트리에 올라간 파일을 볼 수 있음


## 🔆 Deployment 🔆 
### 💡 deployment.yaml
#### ✅ yaml파일로 만든 선언적 API = manifest file 이라고도 함. 

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx-deployment
template:
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment-container
image: nginx
ports:
- containerPort: 80

💡 clusterip-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: clusterip-service-deployment
spec:
  type: ClusterIP
  selector:
    app: nginx-deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
# kubectl apply -f clusterip-deployment.yaml
# kubectl get svc -o wide
# kubectl describe svc clusterip-service-deployment

💡 nodeport-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: nodeport-service-deployment
spec:
  type: NodePort
  selector:
    app: nginx-deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30080
# kubectl apply -f nodeport-deployment.yaml
# kubectl get svc -o wide
# kubectl describe svc nodeport-service-deployment

💡 loadbalancer-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: loadbalancer-service-deployment
spec:
  type: LoadBalancer
  externalIPs:
  - 192.168.0.143
  selector:
    app: nginx-deployment
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
# kubectl apply -f loadbalancer-deployment.yaml
# kubectl get svc -o wide
# kubectl describe svc loadbalancer-service-deployment
# kubectl get all
# kubectl delete pod,svc --all
# kubectl delete replicaset,svc --all
# kubectl delete deployment,svc --all

💡 Deployment 롤링 업데이트 제어

# kubectl set image deployment.apps/nginx-deployment nginx-deployment-container=nginx:1.9.1
# kubectl get all
# kubectl rollout history deployment nginx-deployment
# kubectl rollout history deployment nginx-deployment --revision=2 # 리비전2 상세보기
# kubectl rollout undo deployment nginx-deployment # 롤백(전 단계로 복원)
# kubectl rollout undo deployment nginx-deployment --to-revision=2 # 해당 revision으로 롤백
# kubectl get all
# kubectl rollout history deployment nginx-deployment
# kubectl rollout history deployment nginx-deployment --revision=3 # 리비전3 상세보기
  • replicaset과 다르게 업데이트를 할 수 있다.
  • revision 으로 해당 수정된 버젼을 볼 수 있다. # 숫자가 낮을 수록 오래된 것
curl localhost:5000/v2/_catalog
curl localhost:5000/v2/nginx/tags/list
curl localhost:5000/v2/web-site/tags/list
  • 사설 레지스트리에 뭐가 올라간지 확인한다.

Ingress

# git clone https://github.com/hali-linux/_Book_k8sInfra.git
# kubectl apply -f /root/_Book_k8sInfra/ch3/3.3.2/ingress-nginx.yaml
# kubectl get pods -n ingress-nginx
# mkdir ingress && cd $_
# vi ingress-deploy.yaml

-n 옵션 => 별도의 namespace 지정

ingress-deploy.yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: foods-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: foods-deploy
  template:
    metadata:
      labels:
        app: foods-deploy
    spec:
      containers:
      - name: foods-deploy
        image: 192.168.1.183:5000/test-home:v0.0
---
apiVersion: v1
kind: Service
metadata:
  name: foods-svc
spec:
  type: ClusterIP
  selector:
    app: foods-deploy
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sales-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sales-deploy
  template:
    metadata:
      labels:
        app: sales-deploy
    spec:
      containers:
      - name: sales-deploy
        image: 192.168.1.183:5000/test-home:v0.0
---
apiVersion: v1
kind: Service
metadata:
  name: sales-svc
spec:
  type: ClusterIP
  selector:
    app: sales-deploy
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: home-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: home-deploy
  template:
    metadata:
      labels:
        app: home-deploy
    spec:
      containers:
      - name: home-deploy
        image: 192.168.1.183:5000/test-home:v0.0
---
apiVersion: v1
kind: Service
metadata:
  name: home-svc
spec:
  type: ClusterIP
  selector:
    app: home-deploy
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
# kubectl apply -f ingress-deploy.yaml
# kubectl get all

ingress-config.yaml

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /foods
        backend:
          serviceName: foods-svc
          servicePort: 80
      - path: /sales
        backend:
          serviceName: sales-svc
          servicePort: 80
      - path:
        backend:
          serviceName: home-svc
          servicePort: 80
  • backend는 like Target Group
  • path에 따라 ex) /foods의 경로로 들어온 트래픽은 foods-svc로 ~

ingress-service.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
spec:
  ports:
  - name: http
    protocol: TCP
    port: 80
    targetPort: 80
  - name: https
    protocol: TCP
    port: 443
    targetPort: 443
  selector:
    app.kubernetes.io/name: ingress-nginx
  type: LoadBalancer
  externalIPs:
  - 192.168.1.183

# kubectl apply -f ingress-service.yaml

pv/pvc


PV 및 PVC 는 컨트롤러 및 파드와 별개의 쿠버네티스 리소스이며, 파드의 생명주기와 별개로 작동한다.

  • PV 리소스
    쿠버네티스 클러스터 외부 스토리지와 연결을 담당하는 리소스이다.
  • PVC
    PV와 파드를 연결하기 위한 리소스다.
관리자개발자
스토리지 <-> PV <--> PVC <-> 파드

PV와 Pod는 연결이 되지않기 때문에 가교역할을 하는 PVC를 만들어 PV와 Pod를 연결해준다.

역할을 나눈다면, 스토리지 지식이 있는 쿠버네티스 클러스터 관리자 또는 스토리지 관리자는 PV 리소스를 생성해 스토리지와 연결해 두고, 파드 개발자는 PVC를 생성해 자신의 파드 및 관리자가 제공해 준 PV와 연결해 파드에서 볼륨을 사용할 수 있게 해준다.

즉, 개발자는 스토리지의 지식이 없어도 PVC를 작성해 사용할 PV를 지정하면 원하는 볼륨을 제공받을 수 있다.

또한, 파드의 생명주기와 별도로 볼륨 생명주기를 가지게 된다.

# pv-pvc-pod.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 10Mi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Mi
  selector:
    matchLabels:
      type: local
---
apiVersion: v1
kind: Pod
metadata:
  name: task-pv-pod
  labels:
    app: task-pv-pod
spec:
  volumes:
    - name: task-pv-storage
      persistentVolumeClaim:
        claimName: task-pv-claim
  containers:
    - name: task-pv-container
      image: nginx
      ports:
        - containerPort: 80
          name: "http-server"
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: task-pv-storage
  • kind: PersistentVolume
    => PV생성

  • capacity:
    storage: 10Mi
    => 용량은 10m

  • kind: PersistentVolumeClaim
    => PVC 생성

  • resources:
    requests:
    storage: 10Mi
    => 10m만 사용할 수 있게 요청

accessModes 종류

  • ReadWriteOnce
    하나의 노드에서 해당 볼륨이 읽기-쓰기로 마운트 될 수 있다. ReadWriteOnce 접근 모드에서도 파드가 동일 노드에서 구동되는 경우에는 복수의 파드에서 볼륨에 접근할 수 있다.

  • ReadOnlyMany
    볼륨이 다수의 노드에서 읽기 전용으로 마운트 될 수 있다.

  • ReadWriteMany
    볼륨이 다수의 노드에서 읽기-쓰기로 마운트 될 수 있다.

  • ReadWriteOncePod
    볼륨이 단일 파드에서 읽기-쓰기로 마운트될 수 있다. 전체 클러스터에서 단 하나의 파드만 해당 PVC를 읽거나 쓸 수 있어야하는 경우 ReadWriteOncePod 접근 모드를 사용한다. 이 기능은 CSI 볼륨과 쿠버네티스 버전 1.22+ 에서만 지원된다.

0개의 댓글