kubectl delete pod nginx
kubectl get nodes
NAME STATUS ROLES AGE VERSION
controlplane Ready control-plane 28m v1.30.0
node01 Ready <none> 27m v1.30.0
cat nginx.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
nodeName: node01
containers:
- image: nginx
name: nginx
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 15s 10.244.1.2 node01 <none> <none>
혹은
kubectl replace --force -f nginx.yaml
Labels and Selectors
레이블: 각 객체에 부착된 속성으로 키-값 형태로 정의되며 객체를 그룹화하고 분류할 수 있다.
셀렉터: 특정 조건을 만족하는 레이블을 가진 객체들을 필터링하는 방법으로 특정 속성을 가진 객체들을 쉽게 찾을 수 있다.
대부분의 객체(파드, 서비스, 레플리카셋, 디플로이먼트)에 적용된다.
ReplicaSet에서 Selector를, Pod 정의 파일에서 Labels를 추가하면 사용 가능하며
ReplicaSet 정의 파일에서 template 내 label에는 pod의 라벨을, ReplicaSet의 최상위 label에는 ReplicaSet의 라벨을 넣어주면 된다.
Annotation
Label은 객체를 그룹화하는데 사용, Annotation은 부가 정보를 기록하는 용도
ex) 빌드 정보 연락처 등등
문제풀이2
label이 dev인 pod의 갯수는: 7개
kubectl get pods --selector selector=dev
bu가 finance 비즈니스 유닛의 pod의 갯수: 6
kubectl get pods --selector bu=finance --no-headers | wc -l
env가 prod인 모든 object의 갯수: 7
kubectl get all --selector env=prod --no-headers | wc -l
env가 prod, bu=finance, tier=frontend
kubectl get all --selector env=prod,bu=finance,tier=frontend
Create a new pod with the nginx image and pod name as mosquito.
kubectl create -f nginx-pod.yaml
pod가 pending 상태에 있는 이유: pod가 배치될 수 있는 node가 존재하지 않아서
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 88s default-scheduler 0/2 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 1 node(s) had untolerated taint {spray: mortein}. preemption: 0/2 nodes are available: 2 Preemption is not helpful for scheduling.
Create another pod named bee with the nginx image, which has a toleration set to the taint mortein: operator: Equal은 key, value가 모두 일치해야 하고, Exists는 key만 체크함
taint toleration 설정을 하면 각각의 pod가 node에 배치되도록 설정한다. 벌레기피제와 특정 향기를 좋아하는 벌레 비유와 같이
taint를 node에 뿌리면 해당 설정을 좋아하는 pod가 붙게된다. 하지만 해당 상황에서는 내가 배치하고자 하는 pod가 taint가 없는 node에 붙을 수 있다.
이 때 Node Affinity를 이용해 pod를 node에 특정할 수 있다. 하지만 해당 상황에서는 또 내가 배치하고자 하는 pod가 아닌 pod가 오면 안되는 node에 붙을 수 있다.
이럴 떄 taint, toleration과 Node Affinity를 섞어서 이용하면 특정 node에 pod가 배치되도록 강제할 수 있다.
문제풀이5
A pod called rabbit is deployed. Identify the CPU requirements set on the Pod
Another pod called elephant has been deployed in the default namespace. It fails to get to a running state. Inspect this pod and identify the Reason why it is not running.
kubectl describe pod elephant
State: Waiting
Reason: CrashLoopBackOff
Last State: Terminated
Reason: OOMKilled
Exit Code: 1
Started: Wed, 05 Mar 2025 09:14:47 +0000
Finished: Wed, 05 Mar 2025 09:14:47 +0000
Ready: False
Restart Count: 2
The status OOMKilled indicates that it is failing because the pod ran out of memory. Identify the memory limit set on the POD.
Limits:
memory: 10Mi
Requests:
memory: 5Mi
The elephant pod runs a process that consumes 15Mi of memory. Increase the limit of the elephant pod to 20Mi.
# 해당 명령어로 현재 pod 정보로 elephant.yaml 파일 출력
kubectl get pod elephant -o yaml > elephant.yaml
# memory limits를 20Mi로 수정
# 기존의 elephant.yaml을 대체
kubectl replace -f elephant.yaml --force
Daemon Sets
kube-porxy, weave-net 같은 네트워킹 컴포넌트들이 DaemonSet으로 띄워져있다.
모든 pod에 기본적으로 띄워져야 하는 어플리케이션들이 DaemonSet으로 만들어진다.
kubectl get daemonsets
kubectl describe daemonsets monitoring-daemon
위의 명령어로 확인 가능하다.
문제풀이6
모든 namespaces에서 떠 있는 Daemonsets의 갯수
kubectl get daemonsets --all-namespaces
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-flannel kube-flannel-ds 1 1 1 1 1 <none> 4m13s
kube-system kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 4m14s
kube-proxy가 떠있는 namespace: kube-system
On how many nodes are the pods scheduled by the DaemonSetkube-proxy?
kubectl describe daemonset kube-proxy --namespace=kube-system
Name: kube-proxy
Selector: k8s-app=kube-proxy
Node-Selector: kubernetes.io/os=linux
Labels: k8s-app=kube-proxy
Annotations: deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 1
Current Number of Nodes Scheduled: 1
Number of Nodes Scheduled with Up-to-date Pods: 1
Number of Nodes Scheduled with Available Pods: 1
Number of Nodes Misscheduled: 0
Pods Status: 1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Static pods
기본적으로 worker node는 master node의 kube-apiserver, kube-scheduler, etcd cluster, controller-manager 등에 의해 통제되지만 만약 Master Node가 존재하지 않는다면 Worker Node
Pod 상세 정보를 제공할 API 서버가 존재하지 않는다 이 때 기본적으로 etc/kubernetes/manifests 디렉토리에 pod 정의 파일을 넣으면 kubelet이 주기적으로 해당 파일을 읽고 호스트를 만든다.
이걸 static pod라고 하며 replicaset이나 deployment는 생성할 수 없다.
kubelet.service의 --pod-manifest-path 항목을 보면 경로를 확인할 수 있다.
.service 파일에 직접 입력할 수도 있고, config 파일을 제공해서 이용할 수도 있다.
![[Pasted image 20250310182736.png]]
kubectl 명령어는 kube-apiserver에서 입력받기 때문에 docker ps 등 컨테이너 서비스의 명령어를 사용해야 한다.
kubelet에서는 kube-api에서 명령하는 pod와 static pod 두 가지 모두 공존 가능하며 kube-api에서 static pod도 readonly로 정보를 읽을 수 있다.
각각의 node에 static pod를 이용해 controller manager, apiserver, etce cluster 등등 모든 요소를 띄워놓고 독립적으로 사용 가능하다.
static pod, daemonsets 둘 다 kube-scheduler에서 자유롭다.
문제풀이 7
How many static pods exist in this cluster in all namespaces? 4, static pod는 기본적으로 -controlplane으로 네이밍 된다.
What is the path of the directory holding the static pod definition files? ps aux | grep kubelet
해당 명령어를 입력하면 --config 파일 위치가 나오는데 해당 파일을 열어서 staticPodPath를 사용하면 static pod 파일 위치가 확인 가능하다.
Create a static pod named static-busybox that uses the busybox image and the command sleep 1000
6. We just created a new static pod named **static-greenbox**. Find it and delete it.
This question is a bit tricky. But if you use the knowledge you gained in the previous questions in this lab, you should be able to find the answer to it.
### 문제풀이 8
1. What is the name of the POD that deploys the default kubernetes scheduler in this environment?
controlplane ~ ✖ k get pods -n kube-system
NAME READY STATUS RESTARTS AGE
coredns-7484cd47db-46hwv 1/1 Running 0 5m39s
coredns-7484cd47db-ldwlb 1/1 Running 0 5m39s
etcd-controlplane 1/1 Running 0 5m44s
kube-apiserver-controlplane 1/1 Running 0 5m44s
kube-controller-manager-controlplane 1/1 Running 0 5m44s
kube-proxy-nx25b 1/1 Running 0 5m39s
kube-scheduler-controlplane 1/1 Running 0 5m44s
```
2. Let's create a configmap that the new scheduler will employ using the concept of ConfigMap as a volume. We have already given a configMap definition file called my-scheduler-configmap.yaml at /root/ path that will create a configmap with name my-scheduler-config using the content of file /root/my-scheduler-config.yaml.
k create -f /root/my-scheduler-configmap.yaml
```
3. Deploy an additional scheduler to the cluster following the given specification.
Use the manifest file provided at `/root/my-scheduler.yaml`. Use the same image as used by the default kubernetes scheduler.
```bash
vi my-scheduler.yaml, image를 registry.k8s.io/kube-scheduler:v1.32.0로 변경
k create -f my-scheduler.yaml 실행
```
4. A POD definition file is given. Use it to create a POD with the new custom scheduler. File is located at `/root/nginx-pod.yaml`
```bash
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
schedulerName: my-scheduler
containers:
- image: nginx
name: nginx
```
## Scheduler Profiles
스케줄링은
Scheduling Queue - Filtering - Scoring - Binding 순서로 이뤄진다.
1. Scheduling
- PriorityClass kind로 정의 가능하며 pod-definition에는 priorityClassName으로 매칭해줄 수 있다.
- 이 과정에서 높은 priority를 가진 POD가 Queue에서 먼저 배치된다.
- PrioritySort Plugin
2. Filtering
- pod의 조건에 맞지 않는 node를 제거한다
- NodeResourcesFit, NodeName, NodeUnschedulable Plugin
3. Scoring
- 배치 후 남은 노드의 리소스양을 계산한 후 가장 많은 리소스가 남게 되는 node가 선택되어 Binding된다.
- NodeResourcesFit ImageLocality Plugin
4. Binding
- pod를 적합한 node에 배치하는 과정
- DefaultBinder Plugin
각 과정에서는 필요한 플러그인들이 있으며 각각의 플러그인들은 Scheduling Queue, Filtering, Scoreing, Binding의 Extension들에 binding된다. queueSort, preFilter, filter, postFilter, preScore 등의 Extension들이 있고 필요한 플러그인들을 연결할 수 있다.
1.18 이후 여러 스케줄러가 하나의 config에서 설정될 수 있다.
## RBAC
```bash developer-role.yaml
apiVersion: rbac.autorization.k8s.io/v1
kind: Role
metadata:
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["create"]
resourceNames: ["blue", "orange"]
사이에 껴 있는데 인증과정 후에 NamespaceAutoProvision 등과 같이 존재하지 않는 namespace로 명령이 들어왔을 때 자동으로 생성하는 등 기능을 가진 Controller들이 존재한다
문제풀이 9
admission controller의 역할이 아닌 것은: 사용자 인증
Which admission controller is not enabled by default?
Which admission controller is enabled in this cluster which is normally disabled?
grep enable-admission-plugins /etc/kubernetes/manifests/kube-apiserver.yaml
--enable-admission-plugins=NodeRestriction
/etc/kubernetes/manifest/kubeapi-server.yaml에서 수정하면 admission controller 수정 가능
✅ Validating Admission Controller (검증)
• 요청을 검증(Validate)한 후, 허용하거나 거부(Allow/Deny)
• 예: NamespaceExists
• 요청한 네임스페이스가 존재하는지 확인하고, 없으면 요청 거부
✅ Mutating Admission Controller (수정)
• 요청을 수정(Mutate)하여 적용
• 예: DefaultStorageClass
• PVC(Persistent Volume Claim) 요청 시 StorageClass가 없으면 기본값을 자동 추가
✅ Validating + Mutating Admission Controller
• 요청을 수정 후 검증하는 Admission Controller
• 예:
• NamespaceAutoProvisioning → 네임스페이스가 없으면 생성 (Mutating)
• NamespaceExists → 존재 여부 검증 (Validating)
• 순서 중요: Mutating → Validating 순으로 실행되어야 정상 동작
📌 기본 내장 Admission Controller 외에, 사용자 정의 Admission Controller를 추가 가능
• Kubernetes에서는 MutatingAdmissionWebhook, ValidatingAdmissionWebhook을 제공하여 외부 웹훅(Webhook) 기반 Admission Controller를 만들 수 있음
✅ Admission Webhook 동작 방식
클러스터 내 또는 외부에 Admission Webhook 서버 배포
Kubernetes 요청이 기본 Admission Controller를 통과한 후, Webhook을 호출
Webhook 서버는 요청을 AdmissionReview JSON 객체로 수신
Webhook 서버는 요청을 검토하고, allowed: true(허용) 또는 allowed: false(거부) 응답
✅ Webhook 서버 개발 (예: Python)
• validate() → 요청을 검증하고 특정 조건이 맞으면 거부
• mutate() → 요청을 수정하여 특정 값을 자동 추가
• JSON Patch 형식으로 요청 객체를 수정할 수도 있음
• 개발 후 Kubernetes 클러스터 내부 또는 외부에서 실행 가능
문제풀이 10
Which of the below combination is correct for Mutating and validating admission controllers
mutating 먼저 그 다음 validating 실행된다
Create TLS secretwebhook-server-tls for secure webhook communication in webhook-demo namespace.
kubectl create secret tls webhook-server-tls --cert=/root/keys/webhook-server-tls.crt --key=/root/keys/webhook-server-tls.key -n webhook-demo