노드가 3개인 Kubernetes 클러스터를 살펴 보겠습니다. 각 노드에는 사용 가능한 CPU 메모리와 디스크 리소스가 있습니다.
모든 파드(Pod)은 리소스 집합(이 경우 CPU 2개, 메모리 1개, 디스크 공간 일부)을 사용합니다. Pod가 노드에 배치될 때마다 해당 노드에서 사용할 수 있는 리소스를 소비합니다.
이전에 논의한 것처럼 Pod가 이동할 노드를 결정하는 것은 Kubernetes 스케줄러입니다. 스케줄러는 파드에 필요한 리소스와 노드에서 사용 가능한 리소스의 양을 고려합니다.
이 경우 스케줄러는 노드2에서 새 파드를 사용해야 합니다. 노드에 충분한 리소스가 없으면 스케줄러는 해당 노드에 파드를 배치하지 않습니다. 대신 충분한 리소스를 사용할 수 있는 곳에 파드를 배치합니다. 노드에서 사용할 수 있는 리소스가 충분하지 않은 경우 Kubernetes는 Pod 예약을 보류합니다.
우리는 보류(Pending) 상태의 파드를 확인할 수 있으며, 이벤트 섹션을 보면 보류가 된 이유를 알 수 있습니다. 여기서는 CPU 부족이라고 확인됩니다.
이제 각 파드의 리소스 요구 사항에 초점을 맞추겠습니다. 이 블록은 무엇이며 그 값은 무엇입니까?
디폴트로 Kubernetes는 파드 또는 파드 내의 컨테이너에 0.5 CPU 와 256mebibyte의 메모리가 필요하다고 가정합니다. 이를 컨테이너에 대한 리소스 요청이라고 합니다. 컨테이너에 요청되는 최소 CPU 또는 메모리 양입니다.
스케줄러가 파드를 노드에 배치하려고 할 때 이 숫자를 사용하여 사용 가능한 리소스가 충분한 노드를 식별합니다.
이제 애플리케이션에 이보다 더 많은 것이 필요하다는 것을 알고 있는 경우, 파드 또는 deployment definition 파일에서 값을 수정할 수 있습니다.
이 간단한 파드 Definition 파일에서 요청을 추가하고 메모리 및 CPU 사용량에 대한 새 값을 지정합니다.이 경우에는 1GB의 메모리와 1개의 vCPU로 설정했습니다.
그렇다면 CPU의 1 카운트가 실제로 의미하는 것은 무엇일까요?
이 블록은 설명 목적으로만 사용된다는 점을 기억하십시오.
0.5 단위로 증가할 필요는 없습니다. 0.1 처럼 작은 값도 지정할 수 있습니다. 0.1 CPU는 100m로 표시할 수도 있습니다. 여기서 m은 밀리를 나타냅니다. 1m까지 내려갈 수 있지만 그보다 작아서는 안 됩니다.
CPU 1개는 vCPU 1개, 즉 AWS의 vCPU 1개, GCP 또는 Azure의 코어 1개 또는 하이퍼 스레드 1개와 같습니다.
노드에 충분한 리소스가 있는 경우 컨테이너에 대해 더 많은 수의 CPU를 요청할 수 있습니다.
메모리도 마찬가지로 Mi 접미사를 사용하여 256mebibyte바이트를 지정하거나 이와 같이 메모리에 동일한 값을 지정할 수 있습니다.
또는 기가바이트에 대해 접미사 G를 사용합니다.
G와 Gi의 차이점에 유의하십시오.
G는 기가바이트로 1000메가바이트를 의미하고, 기(Gi)는 기비바이트로 1024mebibyte를 의미한다.
메가바이트와 킬로바이트에도 동일하게 적용됩니다.
이제 노드에서 실행되는 컨테이너를 살펴보겠습니다.
도커 세계에서 도커 컨테이너는 노드에서 사용할 수 있는 리소스에 제한이 없습니다.
컨테이너가 노드에 있는 하나의 vCPU로 시작한다고 가정하면, 노드에 있는 기본 프로세스나 다른 리소스 컨테이너를 질식시키는 데 필요한 만큼의 리소스를 사용할 수 있습니다.
그러나 이러한 파드에서 리소스 사용량에 대한 제한을 설정할 수 있습니다. 디폴트로, Kubernetes는 컨테이너에 하나의 vCPU 제한을 설정합니다. 따라서 명시적으로 지정하지 않으면 컨테이너는 노드에서 하나의 vCPU만 사용하도록 제한됩니다.
메모리도 마찬가지입니다. 디폴트로 Kubernetes는 컨테이너에 대해 512메비바이트의 제한을 설정합니다.
기본 제한이 마음에 들지 않으면 파드(Pod) Definition 파일의 resouces
섹션 아래에 limits
섹션을 추가하여 변경할 수 있습니다. 이와 같이 메모리 및 CPU에 대한 새 제한을 지정합니다.
파드가 생성되면 Kubernetes는 컨테이너에 대한 새로운 제한을 설정합니다. 파드 내의 각 컨테이너에 대해 제한 및 요청이 설정된다는 점을 기억하세요.
그렇다면 Pod가 지정된 제한을 초과하는 리소스를 초과하려고 하면 어떻게 될까요? CPU의 경우 Kubernetes는 지정된 제한을 초과하지 않도록 CPU를 조절합니다. 컨테이너는 제한보다 더 많은 CPU 리소스를 사용할 수 없습니다.
그러나 메모리의 경우는 아닙니다. 컨테이너는 한도보다 더 많은 메모리 리소스를 사용할 수 있습니다.
따라서 파드가 지속적으로 한도보다 더 많은 메모리를 사용하려고 하면 파드가 종료됩니다.
이미 존재하는 파드의 specification은 아래 외에는 수정할 수 없습니다.
spec.containers[*].image
spec.initContainers[*].image
spec.activeDeadlineSeconds
spec.tolerations
예를 들어 실행 중인 파드의 환경 변수, 서비스 계정, 리소스 제한(모두 나중에 설명함)을 편집할 수 없습니다. 하지만 정말로 원한다면 두 가지 옵션이 있습니다.
변경 사항이 포함된 파일의 복사본이 위와 같이 임시 위치에 저장됩니다.
그런 다음 다음 명령을 실행하여 기존 파드를 삭제할 수 있습니다.
kubectl delete pod webapp
그런 다음 임시 파일을 사용하여 변경 사항으로 새 파드를 만듭니다.
kubectl create -f /tmp/kubectl-edit-ccvrq.yaml
그런 다음 편집기(vi 편집기)를 사용하여 내보낸 파일을 변경합니다. 변경 사항을 저장하세요.
vi my-new-pod.yaml
그런 다음 기존 파드를 삭제하십시오.
kubectl delete pod webapp
그런 다음 편집된 파일로 새 파드를 만듭니다.
kubectl create -f my-new-pod.yaml
deployments를 사용하면 POD 템플릿의 모든 필드/속성을 쉽게 편집할 수 있습니다. 파드 템플릿은 deployment spec의 하위 항목이므로 변경 사항이 있을 때마다 deployment가 자동으로 삭제되고 새 변경 사항이 포함된 새 파드가 생성됩니다. 따라서 deployment의 POD 부분 속성을 편집하라는 메시지가 표시되면 다음 명령을 실행하여 간단히 수행할 수 있습니다.
kubectl edit deployment my-deployment
테스트 통과 완료
DaemonSets은 Replicasets처럼 Pod의 여러 인스턴스를 배포하는 데 도움을 줍니다. 그러나 클러스터의 각 노드에서 하나의 파드(Pod) 사본을 실행합니다.
DaemonSet을 만드는 것은 ReplicaSet을 만드는 것과 매우 유사합니다.
ReplicaSet과 kind만 다릅니다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: monitoring-daemon
labels:
app: nginx
spec:
selector:
matchLabels:
app: monitoring-agent
template:
metadata:
labels:
app: monitoring-agent
spec:
containers:
- name: monitoring-agent
image: monitoring-agent
definition file로 daemonsets만드는 방법은 아래 커맨드를 입력하면 됩니다.
kubectl create -f daemon-set-definition.yaml
daemonsets 조회
kubectl get daemonsets
For more details of the daemonsets
kubectl describe daemonsets monitoring-daemon
테스트 통과 완료
파드에 대한 정보를 저장하도록 지정된 서버의 디렉터리에서 파드 정의 파일을 읽도록 kubelet을 구성할 수 있습니다.
지정된 디렉토리를 호스트의 모든 디렉토리가 될 수 있으며, 해당 디렉토리의 위치는 서비스를 실행하는 동안 옵션으로 kubelet에 전달됩니다.
kubelet.service 파일에서 직접 옵션을 지정하는 대신, config 옵션을 사용하여 다른 config 파일에 대한 경로를 제공하고 파일에서 디렉토리 경로를 staticPodPath로 정의할 수 있습니다.
static pods 조회
docker ps
Static Pods는 노드 기반 실행이며 컨트롤 플레인과는 직접적으로 상호 작용하지 않습니다.
DaemonSets는 노드 기반 실행이며 컨트롤 플레인과 상호 작용하여 클러스터 레벨에서 파드 배포와 관리를 수행합니다.
테스트에 관련된 문제를 정리해보겠다.
ls /etc/kubernetes/manifests
에 static pod yaml 이 있음.
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: static-busybox
name: static-busybox
spec:
containers:
- image: busybox
name: static-busybox
command:
- sleep
- "1000"
mv test.yaml /etc/kubernetes/manifests/
(node01 에 배치되어 있는 스태틱 파드를 지우는 문제)
kubectl get pods -o wide
으로 스태틱 파드가 어디 node에 있는지 확인
kubectl get nodes -o wide
으로 해당 node IP 확인
ssh 192.9.41.6
으로 해당 node 접속
cat /var/lib/kubelet/config.yaml | grep "staticPodPath"
config 파일 에서 staticPodPath 확인
rm -rf /etc/just-to-mess-with-you/greenbox.yaml
삭제
테스트 통과 완료