본문 바로가기
IT 기술/k8s

[cka] killer.sh 문제풀이 - (1-5)

by Geunny 2024. 9. 14.
반응형

cka 시험을 앞두고 시험환경을 적응하기 위해 LF (Linux Foundation) 에서 제공하는 모의고사 시험 killer.sh 을 치뤗다.

 

정리에 앞서서 해당 시험을 리뷰하자면

 

난이도는 엄청 극악이다.

한문제 한문제 처음보는 조건들도 있었으며 아무리 docs 를 보면서 풀더라도 주어진 시험시간 2시간 내에는 절대 풀수 없다 생각든다.

 

하지만 해당환경을 통해서 시험에서 필요한 환경적응등을 해볼수 있어서 매우 좋았다.

특히 문제마다 context 를 변경하는 과정은 필수적으로 진행해야 한다.

Use context: kubectl config use-context k8s-c3-CCC

 

 

또한 한가지 불편했던 점은 필자는 mac 환경에서 진행하는데 복사 붙여넣기가 계속 cmd + c/v 에서 ctrl + shift + c/v 로 진행해야 하는것이 많이 햇갈린다.

 

문제가 주어진 환경에서는 명령어를 클릭으로 복사가 가능하지만 한번에 복사가 잘 되진 않는다. 두세번 정도는 눌러야 복사가 된다.

이러한 환경을 적응하기에는 좋았던것 같다. 해당 모의고사 없이 시험에서 해당 환경을 마주쳤다면 많이 당황해서 시험을 치루기에 영향을 많이 줬을것 같다.

 

시험 후에 비교를 한번 해봐야 겠다.

 

1-1. You have access to multiple clusters from your main terminal through kubectl contexts. Write all those context names into /opt/course/1/contexts.

 

해당 문제는 kubectl 에서 config 명령어를 사용하여 찾아야 하는 문제이다.

# 1.1
k config get-contexts # copy manually
k config get-contexts -o name > /opt/course/1/contexts

 

해당 문제를 통해 다시한번 돌아본 옵션들 

kubectl 에서 -o 옵션을 통해 가져올수 있는 값들을 알수 있었다.

# kubectl -o 로 가져올수 있는 값들

kubectl get pods -o yaml
kubectl get pods -o json
kubectl get pods -o name
kubectl get pods -o wide
kubectl get pods -o custom-columns

ex)
kubectl config get-contexts -o custom-columns=NAME:.name,CLUSTER:.context.cluster

 

1-2. Next write a command to display the current context into /opt/course/1/context_default_kubectl.sh, the command should use kubectl.

 

kubectl config 를 이용한 지금 context 를 확인하는 방법이다.

kubectl config current-context

 

해당 커맨드를 위 경로로 저장하면된다.

 

1-3. Finally write a second command doing the same thing into /opt/course/1/context_default_no_kubectl.sh, but without the use of kubectl.

# /opt/course/1/context_default_no_kubectl.sh
cat ~/.kube/config | grep current | sed -e "s/current-context: //"

 

kubectl config 값들이 저장되는 파일경로다 ~/.kube/config 파일에 존재한다.

 

2.  Use context: kubectl config use-context k8s-c1-H

Create a single Pod of image httpd:2.4.41-alpine in Namespace default. The Pod should be named pod1 and the container should be named pod1-container. This Pod should only be scheduled on controlplane nodes. Do not add new labels to any nodes.

 

단순하게 pod를 만드는 문제이다. 하지만 생성하는데 조건들을 잘 파악해야 한다.

만들어야 하는 pod 조건

  1. pod 이미지 : httpd:2.4.41-alpine

  2. pod name 명시 : pod1

  3. container name 명시 : pod1-container

  4. controlplane node 에서 동작해야 한다.

  5. 라벨을 추가하면 안된다.

문제를 자세히 읽어 조건을 확실하게 파악한 후에 생성을 해야한다.

 

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod1
  name: pod1 ## 조건 2
spec:
  containers:
  - image: httpd:2.4.41-alpine # 조건 1
    name: pod1-container                       # 조건 3
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
  tolerations:                                 # 조건 4
  - effect: NoSchedule                         
    key: node-role.kubernetes.io/control-plane 
  nodeSelector:                                
    node-role.kubernetes.io/control-plane: ""  # 조건 4
status: {}

 

여기서 중요한 것은 control-plane 노드에서만 동작 시키려면 control-plane 노드에 설정된 Taints 에 대한 Toleration 을 설정하는 것과 경우에 따라 다른노드에서 실행될수 있기에 nodeSelector 를 통해 지정한 노드에서만 실행할수 있도록 설정하는 것이 중요하다.

 

nodeSelector 에서는 실행중인 노드의 label 값을 입력함으로써 노드를 지정할 수 있다. 

control-plane 의 유니크한 label 값을 입력함으로써 control-plane 노드를 지정하여 pod 를 배포할 수 있게 되었다.

 

3. Use context: kubectl config use-context k8s-c1-H

There are two Pods named o3db-* in Namespace project-c13. C13 management asked you to scale the Pods down to one replica to save resources.

 

3번 문제는 현재 동작중인 o3db 로 시작하는 pods 의 scale 을 변경하는 문제이다.

단순히 해당 pod 가 동작중인 deployment (또는 replicasets) 를 찾아내어 scale 명령어를 통해 해당 값을 변경해 주면 되는 문제이다.

 

해당 문제에서는 deployment 도 replicasets 도 아닌 statefulsets 에 해당 파드에 대한 정보가 담겨 있었다.

➜ k -n project-c13 get pod | grep o3db
o3db-0                                  1/1     Running   0          52s
o3db-1                                  1/1     Running   0          42s

➜ k -n project-c13 get deploy,ds,sts | grep o3db
statefulset.apps/o3db   2/2     2m56s

https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/

 

StatefulSets

A StatefulSet runs a group of Pods, and maintains a sticky identity for each of those Pods. This is useful for managing applications that need persistent storage or a stable, unique network identity.

kubernetes.io

 

StatefulSet과 Deployment의 차이점

 

Deployment는 상태가 없는 애플리케이션(예: 웹 서버 등)을 다루는 데 주로 사용됩니다. Deployment의 파드는 고유한 네트워크 식별자나 스토리지와 관계없이 랜덤하게 생성되고 교체될 수 있습니다.

반면 StatefulSet은 상태가 중요한 애플리케이션(예: 데이터베이스, Kafka 등)을 다루는 데 적합합니다. 파드의 순서, 네트워크 ID, 스토리지가 매우 중요하기 때문에 StatefulSet은 이를 보장해 줍니다.

 

➜ k -n project-c13 scale sts o3db --replicas 1
statefulset.apps/o3db scaled

➜ k -n project-c13 get sts o3db
NAME   READY   AGE
o3db   1/1     4m39s

 

 

문제에서 주어진 조건은 해당 o3db-* POD 를 동작시킨 o3db statefulset 을 scale 명령어를 사용하여 replicas 수를 감소시켜주면 된다.

 

4. Use context: kubectl config use-context k8s-c1-H

4-1. Do the following in Namespace default. Create a single Pod named ready-if-service-ready of image nginx:1.16.1-alpine. Configure a LivenessProbe which simply executes command true. Also configure a ReadinessProbe which does check if the url http://service-am-i-ready:80 is reachable, you can use wget -T2 -O- http://service-am-i-ready:80 for this. Start the Pod and confirm it isn't ready because of the ReadinessProbe.

4-2. Create a second Pod named am-i-ready of image nginx:1.16.1-alpine with label id: cross-server-ready. The already existing Service service-am-i-ready should now have that second Pod as endpoint.

Now the first Pod should be in ready state, confirm that.

 

해당 문제는 pods 를 생성할때 Probe 를 설정하는 문제이다.

 

https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/

 

Configure Liveness, Readiness and Startup Probes

This page shows how to configure liveness, readiness and startup probes for containers. For more information about probes, see Liveness, Readiness and Startup Probes The kubelet uses liveness probes to know when to restart a container. For example, livenes

kubernetes.io

probe 는 pod 의 상태를 주기적으로 확인하는 매커니즘이며 LivenessProbe , ReadinessProbe , StartupProbe 3개가 존재한다.

 

1. Liveness Probe

 

역할: 컨테이너가 정상적으로 살아있는지 확인합니다.

만약 liveness probe가 실패하면, Kubernetes는 해당 컨테이너를 재시작합니다.

컨테이너가 일정 시간 동안 응답하지 않거나 교착 상태(Deadlock)에 빠졌을 때 이 프로브가 유용합니다. 컨테이너가 재시작을 통해 다시 정상 상태로 복구될 수 있을 때 사용하는 프로브입니다

 

2. Readiness Probe

 

역할: 컨테이너가 트래픽을 받을 준비가 되었는지 확인합니다.

Readiness Probe가 실패하면 Kubernetes는 해당 컨테이너에 대한 트래픽을 중지합니다. 즉, 컨테이너가 서비스의 엔드포인트에서 제외되므로 외부 트래픽이 컨테이너로 전달되지 않습니다.

컨테이너가 시작되었더라도, 애플리케이션이 충분히 준비되지 않아 외부 요청을 처리할 수 없는 경우에 이 프로브를 사용합니다.

 

3. Startup Probe

 

역할: 애플리케이션이 정상적으로 시작되었는지 확인합니다.

Startup Probe는 컨테이너의 초기 시작 상태를 점검합니다. 만약 컨테이너가 일정 시간 내에 시작하지 못하면, 컨테이너는 실패로 간주되고 재시작됩니다.

애플리케이션의 시작 시간이 오래 걸리는 경우에 유용합니다. Startup Probe가 성공한 후에는 liveness probe가 적용됩니다.

 

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: ready-if-service-ready
  name: ready-if-service-ready
spec:
  containers:
  - image: nginx:1.16.1-alpine
    name: ready-if-service-ready
    resources: {}
    livenessProbe:                                      # add from here
      exec:
        command:
        - 'true'
    readinessProbe:
      exec:
        command:
        - sh
        - -c
        - 'wget -T2 -O- http://service-am-i-ready:80'   # to here
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

 

주어진 조건에 맞게 pod를 정의해 준다.

 

이후 해당 pod 를 확인해 보면 아직 service-am-i-ready 에 접근할수 없어 ready 상태로 주어지게 된다.

이제 두번째 조건인 pod를 생성하면 해당 pod 는 정상으로 동작중인 상태가 된다.

 

➜ k get pod ready-if-service-ready
NAME                     READY   STATUS    RESTARTS   AGE
ready-if-service-ready   0/1     Running   0          7s


k run am-i-ready --image=nginx:1.16.1-alpine --labels="id=cross-server-ready"


➜ k get pod ready-if-service-ready
NAME                     READY   STATUS    RESTARTS   AGE
ready-if-service-ready   1/1     Running   0          53s

 

5. Use context: kubectl config use-context k8s-c1-H

5-1. There are various Pods in all namespaces. Write a command into /opt/course/5/find_pods.sh which lists all Pods sorted by their AGE (metadata.creationTimestamp).

5-2. Write a second command into /opt/course/5/find_pods_uid.sh which lists all Pods sorted by field metadata.uid. Use kubectl sorting for both commands.

 

단순한 조회 문제이나 조건이 달린 문제이다. 

모든 namespace 를 조회하는 -A(--all-namespace) 와 조회시 정렬을 해주는 --sort-by 옵션을 이용하여 정리할 수 있다.

# /opt/course/5/find_pods.sh
kubectl get pod -A --sort-by=.metadata.creationTimestamp

# /opt/course/5/find_pods_uid.sh
kubectl get pod -A --sort-by=.metadata.uid

 

다행이 정렬할 컬럼값을 문제에서 주어줬으니 해당값을 복사하여 사용하면 된다.

해당 값들을 확인하려면 -o json 을 통해 댑스를 확인하여도 된다.

 

 

댓글