버전 비교

  • 이 줄이 추가되었습니다.
  • 이 줄이 삭제되었습니다.
  • 서식이 변경되었습니다.
목차

...

1. Resource Policies

2.1 Request / Limit (최소요구사항/최대 사용량)

  • 쿠버네티스에서 파드를 어느 노드에 배포할지 스케쥴링 할 때, 스케쥴링이 될 노드에 해당 파드가 동작할 수 있는 충분한 자원이 확보가 되어야 합니다.

  • 쿠버네티스에서 파드(컨테이너)에 필요한 리소스 양을 명시 할 수 있도록 설정을 지원합니다.

  • cpu/memory와 같은 컴퓨트 리소스 외에도 gpu/storage 리소스에 대한 쿼터도 지정 할 수 있습니다.

  • CPU는 m(밀리코어, 1코어=1000밀리코어) 단위로 지정하며, 해당 컨테이너에 어느정도의 CPU를 할당할 것인지를 지정합니다.

  • 메모리는 Mi(Mib)를 사용합니다.

...

코드 블럭
root@k8s-master01:~# kubectl -n kube-system top pod | sort -n -k 2
NAME                                       CPU(cores)   MEMORY(bytes)
nginx-proxy-k8s-worker01                   1m           16Mi
nginx-proxy-k8s-worker02                   1m           17Mi
dns-autoscaler-59b8867c86-hjkvs            2m           7Mi
kube-controller-manager-k8s-master02       4m           19Mi
kube-controller-manager-k8s-master03       4m           19Mi
nodelocaldns-rdkbl                         4m           15Mi
coredns-588bb58b94-9qcvw                   5m           16Mi
kube-scheduler-k8s-master02                5m           20Mi
nodelocaldns-sd99v                         5m           10Mi
coredns-588bb58b94-zcnvc                   6m           14Mi
kube-proxy-h584h                           7m           22Mi
kube-scheduler-k8s-master03                7m           19Mi
nodelocaldns-9vlvr                         7m           9Mi
nodelocaldns-b8gpm                         7m           9Mi
metrics-server-6f77f96b88-v5jjs            8m           17Mi
nodelocaldns-r4sjf                         8m           16Mi
kube-scheduler-k8s-master01                9m           21Mi
kube-proxy-x8gcq                           12m          22Mi
calico-kube-controllers-75748cc9fd-gqdzw   13m          21Mi
kube-proxy-w87v4                           13m          15Mi
kube-proxy-96tsm                           20m          15Mi
kube-proxy-tj8pv                           24m          14Mi
kube-controller-manager-k8s-master01       36m          52Mi
calico-node-87g22                          42m          85Mi
calico-node-kk5vn                          51m          84Mi
calico-node-wckv7                          51m          85Mi
calico-node-8278d                          64m          91Mi
etcd-k8s-master02                          70m          89Mi
calico-node-4hzx4                          71m          109Mi
kube-apiserver-k8s-master02                77m          303Mi
etcd-k8s-master03                          81m          84Mi
kube-apiserver-k8s-master01                94m          349Mi
etcd-k8s-master01                          99m          95Mi
kube-apiserver-k8s-master03                111m         310Mi

2.2 ResourceQuota

  • 쿠버네티스 운영 시 특정 팀에서 많은 리소스를 요구할 경우 ResourceQuota를 이용하여 네임스페이스별로 사용할 수 있는 리소스의 양을 정하고, 컨테이너 마다 사용 할 수 있는 양을 지정할 수 있습니다.

...

코드 블럭
root@k8s-master01:~# kubectl get pod
NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-5bccc488d-bqkvz   1/1     Running   0          18h
nginx-deployment-5bccc488d-r4s5d   1/1     Running   0          18h
nginx-deployment-5bccc488d-z29wp   1/1     Running   0          18h

root@k8s-master01:~# kubectl get quota
NAME      AGE   REQUEST                                         LIMIT
default   32s   cpu: 750m/1k, memory: 192Mi/200Gi, pods: 3/10

2.3 LimitRange

  • ResourceQuota를 사용하면 네임스페이스의 리소스를 제한하고, LimitRange는 네임스페이스 내 파드(컨테이너)의 리소스를 제한합니다.

  • 사용자가 컨테이너 리소스를 너무 크게 사용하면 특정 컨테이너가 많은 리소스를 점유하는 것을 방지할 수 있기 때문에 LimitRange를 사용합니다.

...

경고

# kubectl get event --sort-by='lastTimestamp'
LAST SEEN TYPE REASON OBJECT MESSAGE
78s Warning FailedCreate replicaset/nginx-deployment-8579d7f98c Error creating: pods "nginx-deployment-8579d7f98c-mxw8q" is forbidden: maximum cpu usage per Pod is 800m, but limit is 1500m

...

2. Label & Selector

  • Label

    • Label은 Pod와 같은 객체에 연결된 키/값 쌍입니다.

    • 리소스를 논리적인 그룹으로 나누거나, 식별의 편의를 위해 붙이는 이름표입니다.

    • Label은 생성 시 객체에 첨부할 수 있으며 나중에 언제든지 추가 및 수정할 수 있습니다.

  • Selector

    • 특정 Label에 해당하는 객체를 식별하고 검색할 수 있습니다.

2.1 Node Label

...

코드 블럭
# Node Label 확인
kubectl get nodes --show-labels

# Node Label 추가
kubectl label nodes k8s-worker01 svc=web

2.2 Pod Selector

pod-label.yml

코드 블럭
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    svc: web

...

3. 쿠버네티스 볼륨

지금까지 우리는 많은 실습을 통해 Pod를 배포하고 Service를 만들어 접속 할 수 있게 되었습니다.

...

이러한 데이터의 유지를 위하여 volume을 사용 합니다.

3.1 emptyDir

  • emptyDir 볼륨은 파드가 노드에 할당될 때 처음 생성되며, 해당 노드에서 파드가 실행되는 동안에만 존재합니다.

  • 이름에서 알 수 있듯이 emptyDir 볼륨은 처음에는 비어있습니다.

  • 파드 내 모든 컨테이너는 emptyDir 볼륨에서 동일한 파일을 읽고 쓸 수 있지만, 해당 볼륨은 각각의 컨테이너에서 동일하거나 다른 경로에 마운트 될 수 있습니다.

  • 노드에서 파드가 제거되면 emptyDir 의 데이터가 영구적으로 삭제됩니다.

  • emptyDir은 주로 Pod내부에서 실행 중인 애플리케이션 간의 휘발성 파일을 공유할 때 유용하게 사용 됩니다.

  • 공유가 필요 없는 볼륨이라면 굳이 emptyDir를 사용 할 필요는 없습니다 명시하지 않은 모든 볼륨의 데이터는 휘발성입니다 (이미지에 존재하지 않는 mountpath생성을 위한 용도로는 사용할 될 수 있습니다)

...

코드 블럭
languagebash
kubectl apply -f 012.nginx-vol-2.yml
pod/nginx-vol-2 created
 
kubectl get pod
NAME          READY   STATUS    RESTARTS   AGE
nginx-vol-2   2/2     Running   0          8s
 
# 확인하면 포드내 컨테이너가 2개로 보입니다
# 생성된 컨테이너를 확인합니다
 
# 컨테이너가 2개 이상인경우 get pod 명령어를 활용해서 컨테이너를 식별하고 제어하지 못합니다.
$ kubectl describe pod/nginx-vol-2
......
Containers:
  nginx:
    Container ID:   containerd://a9eac4ae13b2a8f052fe9bf6eca53c93e95c0de7ce4352cf1e77a0c4d2e1c5bb
    Image:          nginx
    Image ID:       docker.io/library/nginx@sha256:6926dd802f40e5e7257fded83e0d8030039642e4e10c4a98a6478e9c6fe06153
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 13 Sep 2023 11:05:21 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /cache from cache-volume (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pjccg (ro)
  fortune:
    Container ID:   containerd://6e343b738170e0b1d0b0fa18fe641c0cd0b1257ae3cab9d7fc75fff041f09084
    Image:          luksa/fortune
    Image ID:       docker.io/luksa/fortune@sha256:814dd72ecc4b431560ca6ede8649fc4862c401ba5b6d37520e6672e0657deea9
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Wed, 13 Sep 2023 11:05:33 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /cache from cache-volume (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pjccg (ro)
 
Volumes:
  cache-volume:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  <unset>
 

# 두번째 yml을 보면 volume type을 EmptyDir로 선언하는것을 생략하였습니다 아무런 type이 없으면 기본값으로 EmptyDir를 사용 하게 됩니다
  .....
 
 
# nginx와 fortune 2개의 컨테이너가 생성된것을 확인 할수 있습니다
# rw로 마운트된 fortune에서 파일을 생성하고 nginx컨테이너에서 파일을 볼수 있는지 실습 해봅시다
 
 
# pod내 컨테이너 선택은 -c옵션을 이용합니다
# fortune 컨테이너에서 만든 파일을 같은 pod내에 있는 nginx컨테이너테서 확인 할 수 있습니다.
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c fortune  -- bash -c ' echo "test" > /cache/test.txt '
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c fortune  -- ls -l /cache
total 4
-rw-r--r--. 1 root root 5 Sep 13 02:19 test.txt
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c nginx  -- ls -l /cache
total 4
-rw-r--r--. 1 root root 5 Sep 13 02:19 test.txt
 
# 아래와 같이 nginx는 ro권한밖에 없으므로, 실제 write는 불가능합니다.
[root@m-k8s vagrant]# kubectl exec nginx-vol-2 -c nginx  -- bash -c 'echo "test" > /cache/test2.txt'
bash: line 1: /cache/test2.txt: Read-only file system
command terminated with exit code 1
 
# 실습환경을 정리합니다. 
kubectl delete -f 012.nginx-vol-2.yml
pod "nginx-vol-2" deleted
 
 
*기본적으로 emptydir은 worker노드에 디스크(파일시스템)에 생성되지만 상황에따라 memory나 fc disk등에 생성 할 수도 있습니다.

3.2 hostpath

  • hostPath 볼륨은 호스트 노드의 파일시스템에 있는 파일이나 디렉터리를 파드에 마운트 합니다.

  • emptydir과 달리 pod를 삭제하여도 워커노드의 파일은 삭제되지 않습니다.

  • 각 워커노드의 파일이 다를 수 있으므로 사용에 주의하도록 합니다.

    • node seletor를 이용하여 필요한 볼륨이 있는 node만 스케줄되게 하거나 모든 node가 동일한 파일을 가지거나 등의 조치를 하지 않고 배포 시 문제가 발생 할 수 있습니다.

...

코드 블럭
languagebash
# yaml 파일을 적용합니다.
kubectl apply -f 012.nginx-vol-3.yml
 
# 생성된 파드에서 마운트 된 경로의 파일을 확인합니다.
kubectl exec -it nginx-vol-3 -- ls -l /usr/share/nginx/html
total 4
-rw-r--r-- 1 root root 9 Apr 28 01:17 index.html

# 파일 내용을 확인합니다.
kubectl exec -it nginx-vol-3 -- cat /usr/share/nginx/html/index.html
hihihihi
 

[root@m-k8s vagrant]# kubectl get pod -o wide
NAME          READY   STATUS    RESTARTS   AGE    IP               NODE     NOMINATED NODE   READINESS GATES
nginx-vol-3   1/1     Running   0          107s   172.16.221.185   w1-k8s   <none>           <none>
[root@m-k8s vagrant]# 
[root@m-k8s vagrant]# curl 172.16.221.185
hihihihi
 
 
# node에서 생성한 파일이 pod에 hostpath를 이용해 마운트 된것을 확인 할 수 있습니다. 
# hostpath의 경우 권한이 다르면 사용할수 없으므로 컨테이너 내 사용자로 권한을 바꾸거나 root사용자로 구동되도록 하여야 합니다.
 
 
# 실습을 위해 실습환경을 정리합니다.
[root@m-k8s vagrant]# kubectl delete -f 012.nginx-vol-3.yml
pod "nginx-vol-3" deleted

3.3 NFS

  • NFS를 volume으로 사용할 수 있습니다.

  • NFS를 이용하면 여러 pod에 동일한 volume을 마운트 할 수 있고, 여러 노드가 읽고 쓸 수 있으므로 파일 공유에 많은 이점이 있습니다.

...

코드 블럭
kubectl apply -f 012.nginx-vol-4.yaml
pod/nginx-vol-4 created
 
[root@m-k8s vagrant]# k get pod -o wide
NAME          READY   STATUS    RESTARTS   AGE   IP               NODE     NOMINATED NODE   READINESS GATES
nginx-vol-4   1/1     Running   0          53s   172.16.221.186   w1-k8s   <none>           <none>
 
[root@m-k8s vagrant]# curl 172.16.221.186
hiihi
 
kubectl exec -it nginx-vol-4 -- df -h
Filesystem      Size  Used Avail Use% Mounted on
...
w2-k8s:/nfs                   37G  4.4G   33G  12% /usr/share/nginx/html
...
 
 
# pod가 구동중인 worker1의 마운트 상태 확인
[root@w1-k8s /]# df -h
Filesystem      Size  Used Avail Use% Mounted on
 
w2-k8s:/nfs                   37G  4.4G   33G  12% /var/lib/kubelet/pods/23229ac8-acb5-4aa0-b
0f1-6d8f36236366/volumes/kubernetes.io~nfs/nfs-volume 
 
#hostpath의 경우 해당파일이 존재하는 워커노드에서만 수행되도록 설정하였으나 nfs사용시에는 어느 노드에서 구동되어도 상관이 없습니다
 
 
# 다음 실습을 위해 실습환경을 정리 합니다.
kubectl delete -f 012.nginx-vol-4.yml
pod "nginx-vol-4" deleted

3.4 Persistent Volume(PV)

  • PV(PersistentVolume): PV는 관리자가 프로비저닝했거나 스토리지 클래스를 사용해 동적으로 프로비저닝한 클러스터의 스토리지입니다. PV는 볼륨과 같은 볼륨 플러그인이지만 PV를 사용하는 개별 Pod와 독립적인 수명 주기를 가집니다.

  • PVC(PersistentVolumeClaim): PVC는 사용자가 볼륨을 사용하기 위해 PV에 하는 스토리지 요청입니다. Pod와 유사하게 Pod는 노드 리소스를 소비하고, PVC는 PV 리소스를 소비합니다.

...

코드 블럭
# 파드를 생성합니다.
kubectl apply -f 012.nginx-vol-6.yml
pod/nginx-vol-6 created
 
# 컨테이너 안에서 마운트 상태를 확인합니다.
kubectl exec -it nginx-vol-6 -- df -h
 
Filesystem      Size  Used Avail Use% Mounted on
w2-k8s:/nfs                   37G  4.4G   33G  12% /vol
 
 
# 정상적으로 마운트 된것을 확인 할수 있습니다
 
## 실습 환경을 정리 합니다
# 파드 삭제
kubectl delete pod nginx-vol-6
pod "nginx-vol-6" deleted
 
# PVC 삭제 
kubectl delete pvc/nginx-pvc-1
persistentvolumeclaim "nginx-pvc-1" deleted
 
# PV 삭제 
kubectl delete pv/nginx-vol-pv-5
persistentvolume "nginx-vol-pv-5" deleted

3.5 동적 프로비저닝 + 프로덕션 환경 테스트

정보

Dynamic 프로비저닝을 하려면 CSI를 제공하는 스토리지가 필요합니다. 보통 운영환경에서는 모두 이 방식을 사용합니다.

동적 프로비저닝의 의미는 PV를 PVC요청에 따라 동적으로 할당 한다는 것을 의미 합니다.

...