목차 |
---|
...
...
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를 사용합니다.
...
코드 블럭 |
---|
root@k8s-master01:~# cat LimitRange.yaml apiVersion: v1 kind: LimitRange metadata: name: cpu-min-max-demo-lr namespace: default spec: limits: - max: cpu: "800m" min: cpu: "200m" type: Pod #Container root@k8s-master01:~# more nginx-deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.19 ports: - containerPort: 80 resources: requests: memory: "64Mi" cpu: "1000m" limits: memory: "128Mi" cpu: "1500m" |
경고 |
---|
root@k8s-master01:~# # kubectl get event --sort-by='lastTimestamp' |
...
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. 쿠버네티스 볼륨
PV(PersistentVolume): PV는 관리자가 프로비저닝했거나 스토리지 클래스를 사용해 동적으로 프로비저닝한 클러스터의 스토리지입니다. PV는 볼륨과 같은 볼륨 플러그인이지만 PV를 사용하는 개별 Pod와 독립적인 수명 주기를 가집니다.
PVC(PersistentVolumeClaim): PVC는 사용자가 볼륨을 사용하기 위해 PV에 하는 스토리지 요청입니다. Pod와 유사하게 Pod는 노드 리소스를 소비하고, PVC는 PV 리소스를 소비합니다.
3.1 PV의 Lifecycle
...
...
(1
...
) Provisioning
PV를 생성하는 단계로 프로비저닝 방법에는 두 가지가 있습니다.
정적 프로비저닝
정적 프로비저닝은 클러스터 관리자가 미리 적정 용량의 PV를 만들어 두고 사용자의 요청이 있을 시 미리 만들어 둔 PV를 할당하는 방식입니다.
사용할 수 있는 스토리지 용량에 제한이 있을 때 유용합니다.
동적 프로비저닝
동적 프로비저닝은 사용자가 PVC를 거쳐서 PV를 요청했을 때 생성해 제공합니다.
클러스터에 사용자가 원하는 만큼의 스토리지 용량이 있다면, 원하는 용량만큼을 생성해서 사용할 수 있습니다.
...
(2) Binding
바인딩은 프로비저닝으로 생성된 PV를 PVC와 연결하는 단계입니다. PVC에서 원하는 스토리지 용량과 접근방법을 명시해서 용청하면 거기에 맞는 PV가 할당됩니다. PV와 PVC의 매핑은 1대1 관계입니다.
(3
...
) Using
PVC는 Pod에 설정되고, Pod는 PVC를 볼륨으로 인식해서 사용합니다. 클러스터는 PVC를 확인하여 바인딩된 PV를 찾고 해당 볼륨을 Pod에서 사용할 수 있도록 해줍니다. 할당된 PVC는 파드를 유지하는 동안 계속 사용되며, 시스템에서 임의로 삭제할 수 없습니다.
...
(4) Reclaiming
사용이 끝난 PVC는 삭제되고, PV를 초기화(reclaim)하는 과정을 거칩니다. PV는 기존에 사용했던 PVC가 아니더라도 다른 PVC로 재활용이 가능합니다.
PV 초기화 정책
Retain: PV의 데이터를 그대로 보존합니다.
Recycle: 재사용하게 될 경우 기존의 PV 데이터들을 모두 삭제 후 재사용합니다.
Delete: 사용이 종료되면 해당 볼륨을 삭제합니다.
3.2 PV 생성
코드 블럭 |
---|
apiVersion: v1 kind: PersistentVolume metadata: name: test-pv labels: name: test-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteMany hostPath: path: "/test/volume" # Value - capacity: 사용할 용량을 설정합니다. - accessModes:특정 접근 모드를 선택합니다. - hostPath: 노드에 저장되는 디렉토리를 설정합니다. # 적용하기 kubectl apply -f test-pv.yaml # PV 조회 kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE test-pv 1Gi RWX Retain Available 15s |
3.3 PVC 생성
코드 블럭 |
---|
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi kubectl apply -f test-pvc.yaml # PV, PVC 조회 kubectl get pv,pvc NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/test-pv 1Gi RWX Retain Bound default/test-pvc 2m22s NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/test-pvc Bound test-pv 1Gi RWX 18s => PV와 PVC가 연결되어 PV가 Bound 상태로 변경된 것을 확인할 수 있습니다. |
3.4 PVC를 사용할 Pod 생성
코드 블럭 |
---|
apiVersion: v1 kind: Pod metadata: name: test-nginx2 spec: containers: - name: test-nginx2 image: nginx:1.19 ports: - containerPort: 80 volumeMounts: - mountPath: "/test/volume" name: test-pv volumes: - name: test-pv persistentVolumeClaim: claimName: test-pvc # 옵션 - volumeMounts.mountPath: 볼륨 마운트할 컨테이너 안의 경로를 작성합니다. - volumes:.persistentVolumeClaim: 컨테이너에서 사용할 PV의 이름을 가져오고, PV와 연결되어 있으며 요청을 보낼 PVC를 지정합니다. # 적용하기 kubectl apply -f test-nginx2.yaml # 확인해보기 # 외부에서 확인 # kubectl describe pod test-nginx2 | grep -A1 Mounts Mounts: /test/volume from test-pv (rw) # 컨테이너 내부에서 확인 kubectl exec -it test-nginx2 -- bash root@test-nginx2:/# df -Th | grep volume /dev/vda1 xfs 50G 3.7G 47G 8% /test/volume => 지정한 경로에 볼륨이 마운트된 것을 확인할 수 있습니다. # 컨테이너 내부에서 test용 파일 생성 root@test-nginx2:/# touch /test/volume/test.txt # PV 생성 시 설정한 노드의 경로에서도 확인이 가능합니다. [root@worker-node ~]# ls -al /test/volume/ total 0 drwxr-xr-x 2 root root 22 Mar 10 06:22 . drwxr-xr-x 3 root root 20 Mar 10 06:18 .. -rw-r--r-- 1 root root 0 Mar 10 06:22 test.txt |
4. 컨피그맵
Key-Value 쌍으로 기밀이 아닌 데이터를 저장하는 데 사용하는 API 오브젝트입니다.
컨테이너 이미지에서 환경 별 구성을 분리하여, 애플리케이션을 쉽게 이식할 수 있습니다.
개발/운영 환경의 컨테이너는 동일하게 구성하고, 컨피그맵 설정을 다르게 적용하여 서비스를 관리할 수 있습니다.
파드와 컨피그맵은 동일한 네임스페이스에 있어야 합니다.
4.1 컨피그맵 사용
4.1.1 컨피그맵을 생성합니다.
코드 블럭 |
---|
apiVersion: v1
kind: ConfigMap
metadata:
name: prod-account
namespace: default
data:
ID: prod-user
PASSWORD: prod-pass
LOG_LEVEL: info |
4.1.2 컨테이너에서 prod-account 컨피그맵의 LOG_LEVEL값을 가지고 오도록 설정합니다.
코드 블럭 |
---|
piVersion: apps/v1
kind: Deployment
metadata:
name: configmap-test
labels:
app: prod
spec:
replicas: 1
selector:
matchLabels:
app: prod
template:
metadata:
labels:
app: prod
spec:
containers:
- name: testapp
image: nginx:1.19
ports:
- containerPort: 8080
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: prod-account
key: LOG_LEVEL |
4.1.3 설정이 제대로 되었는지 파드 안에서 확인합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# kubectl get pod
NAME READY STATUS RESTARTS AGE
configmap-test-779ff45747-f4969 1/1 Running 0 80s
root@k8s-master01:~/kb# kubectl exec -it configmap-test-779ff45747-f4969 -- bash
root@configmap-test-779ff45747-f4969:/# env | grep LOG_LEVEL
LOG_LEVEL=info |
5. 시크릿
비밀번호, OAuth 토큰, ssh 키와 같은 민감한 정보를 저장하는 용도로 사용됩니다.
시크릿 생성 시 데이터는 base64로 인코딩되어 저장됩니다.
컨피그맵은 보안/암호화를 제공하지 않기 때문에, 저장하려는 데이터가 기밀인 경우, Secret을 사용하여 데이터를 비공개로 유지합니다.
시크릿은 ETCD에 암호화되지 않은 상태로 저장되기 때문에, API 접근 권한이 있는 모든 사용자는 시크릿을 조회/수정 할 수 있습니다.
TLS 인증서를 시크릿으로 저장하여 사용하는 경우도 많습니다.
secret 리소스의 type 필드로 타입을 명시 할 수 있습니다.
...
빌트인 타입
...
사용처
...
Opaque
...
임의의 사용자 정의 데이터
...
kubernetes.io/service-account-token
...
서비스 어카운트 토큰
...
kubernetes.io/dockercfg
...
직렬화 된(serialized) ~/.dockercfg
파일
...
kubernetes.io/dockerconfigjson
...
직렬화 된 ~/.docker/config.json
파일
...
kubernetes.io/basic-auth
...
기본 인증을 위한 자격 증명(credential)
...
kubernetes.io/ssh-auth
...
SSH를 위한 자격 증명
...
kubernetes.io/tls
...
TLS 클라이언트나 서버를 위한 데이터
...
bootstrap.kubernetes.io/token
...
부트스트랩 토큰 데이터
5.1 불투명(Opaque) 시크릿 사용
5.1.1 명령어로 시크릿 생성
코드 블럭 |
---|
root@k8s-master01:~/kb# cat prod-user.txt
prod-user
root@k8s-master01:~/kb# cat prod-pass.txt
prod-pass
root@k8s-master01:~/kb# kubectl create secret generic prod-user --from-file=./prod-user.txt --from-file=./prod-pass.txt
secret/prod-user-secret created
root@k8s-master01:~/kb# kubectl get secrets
NAME TYPE DATA AGE
prod-user-secret Opaque 2 4s
root@k8s-master01:~/kb# kubectl get secrets prod-user-secret -o yaml
apiVersion: v1
data:
prod-pass.txt: cHJvZC1wYXNzCg==
prod-user.txt: cHJvZC11c2VyCg==
kind: Secret
metadata:
creationTimestamp: "2023-03-13T02:35:54Z"
name: prod-user-secret
namespace: default
resourceVersion: "1226226"
uid: 41a2cb2d-97f2-41bc-824f-c0c2783ec678
type: Opaque
*원래 값 확인방
root@k8s-master01:~/kb# echo cHJvZC11c2VyCg== | base64 --decode
prod-user
|
5.1.2 yaml 파일로 시크릿 생성
yaml 파일로 생성시 필요 값들을 base64로 인코딩된 값을 넣어야 합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# echo -n "prod-user" | base64
cHJvZC11c2Vy
root@k8s-master01:~/kb# echo -n "prod-pass" | base64
cHJvZC1wYXNz |
시크릿을 생성합니다.
코드 블럭 |
---|
apiVersion: v1
kind: Secret
metadata:
name: prod-user
type: Opaque
data:
username: cHJvZC11c2Vy
password: cHJvZC1wYXNz |
생성된 시크릿을 확인합니다.
코드 블럭 |
---|
root@k8s-master01:~/kb# kubectl apply -f prod-user-secret.yaml
root@k8s-master01:~/kb# kubectl get secrets
NAME TYPE DATA AGE
prod-user Opaque 2 5s
root@k8s-master01:~/kb# kubectl get secrets prod-user -o yaml
apiVersion: v1
data:
password: cHJvZC1wYXNz
username: cHJvZC11c2Vy
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"cHJvZC1wYXNz","username":"cHJvZC11c2Vy"},"kind":"Secret","metadata":{"annotations":{},"name":"prod-user","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2023-03-13T02:49:45Z"
name: prod-user
namespace: default
resourceVersion: "1228228"
uid: a5eff12c-2329-4697-92f7-f252a4f724ba
type: Opaque
|
5.1.3 시크릿 사용
코드 블럭 |
---|
apiVersion: apps/v1
kind: Deployment
metadata:
name: secretapp
labels:
app: secretapp
spec:
replicas: 1
selector:
matchLabels:
app: secretapp
template:
metadata:
labels:
app: secretapp
spec:
containers:
- name: testapp
image: nginx:1.19
ports:
- containerPort: 8080
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: prod-user
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: prod-user
key: password |
...