본문 바로가기
[DevOps]/Kubernetes

CKA 기출 문제 복기 및 접근법 정리[24.11.24 응시]

by 팡펑퐁 2024. 11. 27.
728x90

🥸 들어가기 전에

모든 문제를 완벽히 복기할 수 없으므로 대략적인 내용을 정리합니다.

아마 문제를 읽고 대략적으로 어떻게 접근하면 풀 수 있겠다 싶으면 풀 수 있는 겁니다.

시험 정책이 크게 바뀌지 않는 한 어렵게 꼬아버리는 문제는 없는 것 같습니다.

문제 풀 당시 저의 접근법도 함께 정리해 두었으니 참고하면 좋을 것 같습니다.(올바른 방법이 아닐 수 있습니다.)

문제 순서와는 관계 없으며 기억에 남은 문제만 정리하였습니다.

17문제 중에 절반 정도는 kodekloud의 문제를 다 풀 수 있다면 쉽다고 느낄 수준의 문제입니다.

 

1. Ingress 만들기

1. ping이라는 ingress를 만드는데 namespace는 Ing-intenal이며
/hello 엔드포인트로 요청이 들어오면 hello 서비스 5678 포트로 라우팅 해라.
curl -kL {internal-ip}/hello로 테스트 가능하며 성공 시 hello가 출력된다.

 

관련 공식 문서

https://kubernetes.io/docs/concepts/services-networking/ingress/#the-ingress-resource

 

대략적인 풀이

# yaml 파일 생성
vi xx.yaml

# 값 입력
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ping <- 이름
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /hello <- 엔드포인트
        pathType: Prefix
        backend:
          service: 
            name: hello <- 서비스명
            port:
              number: 5678 <- 포트
   
# yaml 실행
k apply -f xx.yaml

# curl 명령어를 위한 노드 internal-ip 조회
k get node -o wide

# 나온 노드의 <internal-ip>로 명령어 입력
curl -kL <internal-ip>/hello
  • curl -kL은 보안 인증서 검증을 무시하면서 리디렉션을 따라 최종 데이터를 가져오는 명령입니다
  • 저의 경우 node가 3개 있었습니다.
  • 아무 생각 없이 워커 노드 두 개의 internal ip를 대입하여 테스트하다가 한 곳에서 hello 출력이 나와서 넘겼으나, 지금 생각해 보면 ingress controller pod가 실행되고 있는 노드의 internal-ip로 하는 것이 맞지 않나 생각이 듭니다.

 

2. etcd Backup & Restore

1. master-node에 들어가서 sudo -i 권한으로 etcdctl 명령어를 사용하여 데이터베이스 스냅샷을 save해라.
2. 미리 지정된 경로에 previous-snapshot.db가 있는데 이걸로 etcd를 restore 해라.

 

관련 공식 문서

https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#backing-up-an-etcd-cluster

https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/#restoring-an-etcd-cluster

 

대략적인 풀이

# 마스터 노드 접속
ssh master-node(예시)

# 루트 권한 획득
sudo -i

# 명령어로 옵션 확인
ETCDCTL_API=3 etcdctl -h 

# snapshot save(해당 경로는 문제에서 주어짐)
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
--cacert=<trusted-ca-file> --cert=<cert-file> --key=<key-file> \
snapshot save <backup-file-location>

# snapshot restore(--data-dir 경로는 새로 만듬, previous-snapshot.db 경로는 문제에서 주어짐)
ETCDCTL_API=3 etcdctl --data-dir /var/lib/etcd-backup snapshot restore <previous-snapshot.db>

# etcd.yaml 편집 들어가기
vi /etc/kubernetes/manifests/etcd.yaml

# etcd.yaml 수정
spec:
  containers:
  	- command:
    	- etcd
        - --data-dir=/var/lib/etcd-backup <- 수정
        ...
        
      volumeMounts:
    	- mountPath: /var/lib/etcd-backup <- 수정
      	  name: etcd-data
    	- mountPath: /etc/kubernetes/pki/etcd
          name: etcd-certs
      readOnly: true
  hostNetwork: true
  priorityClassName: system-cluster-critical
  volumes:
    - hostPath:
        path: /var/lib/etcd-backup <- 수정
        type: DirectoryOrCreate
      name: etcd-data
      ...
  • 주어진 경로에 snapshot save를 합니다.
  • 그리고 미리 저장되어 있는 Previous-snapshot을 restore 합니다.
  • /etc/kubernetes/manifests 경로의 etcd.yaml 파일에 들어가 파일을 수정하였는데 Pending이 떴고 해결하지 못한 채 시험이 끝났습니다.(유일하게 못 푼 문제ㅜ)
  • kodeloud에서는 위와 같이 풀었을 때 항상 맞았는데 왜 Pending인지 모르겠습니다.(혹시 아시면 댓글로 알려주세요 ㅠ)

 

3. TroubleShooting

worker node가 NotReady 상태이다. 이를 Ready 상태로 만들어라.

 

대략적인 풀이

# 문제가 있는 노드 확인
k get node

# 해당 노드로 ssh 접속
ssh worker-node

# 루트 권한 설정
sudo -i

# kubelet 상태 확인(저의 경우 incative였습니다.)
systemctl status kubelet
(inactive)

# kubelet restart
systemctl restart kubelet

# kubelet 상태 재확인
systemctl status kubelet
(active)

# 마스터노드로 돌아오기
exit

# 노드 재확인(Ready로 변경)
k get node
  • 쉬운 문제입니다. 만약 active 상태인데 NotReady인 경우 kodekloud에서 나온 다른 유형 정도 수준 아닐까 싶네요. 여러 번 반복하면 문제없이 풀 수 있을 것 같습니다.
  • journal -u kubelet | grep -i error <- 이 명령어로 kubelet 동작 시의 로그 중 error만 추출하여 어떤 문제인지 확인할 수 있습니다.

 

4. 마스터 노드 kubeadm, kubelet, kubectl 업그레이드

마스터 노드를 1.30.0에서 1.30.1로 업그레이드하라.
워커노드는 업그레이드하지 말고 마스터 노드만 업그레이드하라.

 

관련 공식 문서

https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/

 

대략적인 풀이

  • 위 공식문서를 보며 그대로 마스터 노드만 업그레이드하면 됩니다.
  • linux 환경에서 공식문서에 나온 명령어를 복사하여 붙여 넣고 실행할 때 3줄 정도의 '&&'로 결합된 명령어는 제대로 안 먹는 문제가 있었습니다.
  • 그래서 명령어를 전부 나눠서 처리했습니다. 이 부분만 신경 쓰면 될듯하네요.
  • kodekloud의 문제 유형과 똑같으므로 어렵지 않게 풀 수 있었습니다.

 

5. Pod Log

특정 파드 log에서 Error 메시지만 주어진 경로의 파일에 저장하라.

 

# logs는 특정 파드의 로그를 조회하는 명령어이며, -i는 대소문자 구분을 하지 않는 옵션
k logs <pod-name> | grep -i error > /문제에서/주어진/경로

 

 

6. side car multi container

기존 파드가 기록하는 log 파일에 접근 가능한 sidecar container를 추가하여 sidecar로 로그를 확인하고 주어진 경로에 로그를 저장하라.(저장하라고까지 했는지 정확히 기억이 안 남)

 

관련 공식 문서

https://kubernetes.io/docs/concepts/cluster-administration/logging/#cluster-level-logging-architectures

 

대략적인 풀이

# 공식 문서의 예시
apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
  volumes:
  - name: varlog
    emptyDir: {}

# 공식 문서를 참고하여 sidecar container 추가
apiVersion: v1
kind: Pod
metadata:
  name: counter
spec:
  containers:
  - name: count
    image: busybox:1.28
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        echo "$i: $(date)" >> /var/log/1.log;
        echo "$(date) INFO $i" >> /var/log/2.log;
        i=$((i+1));
        sleep 1;
      done      
    volumeMounts:
    - name: varlog
      mountPath: /var/log
 ####################################################### 추가, 문제에 주어진 조건으로 변경    
  - name: count-log-1
    image: busybox:1.28
    args: [/bin/sh, -c, 'tail -n+1 -F /var/log/1.log']
    volumeMounts:
    - name: varlog
      mountPath: /var/log
 #######################################################  
  volumes:
  - name: varlog
    emptyDir: {}

# 기존 파드 삭제
k delete po <pod-name> --force

# sidecar 추가한 yaml파일로 파드 생성
k apply -f /경로/sidecar.yaml

# sidecar 컨테이너로 접근하여 /var/log에 기존 컨테이너의 로그가 저장되어있는지 확인
k exec -it <pod-name> -c <container-name> -- /bin/bash

# 컨테이너 내에서 로그 복사
tail -f /var/log/xxx.log # 로그 파일 들어가 로그 복사 후

# 파드에서 빠져 나와 주어진 경로에 vi 수정 모드로 복사 붙여넣기
  • 시험이 끝나고 생각해 보니 k log <pod-name> <container-name>을 입력하면 되는 문제였네요.
  • k log <pod-name> <container-name> > /문제에서/주어진/경로 <- 이렇게 풀면 될 것 같습니다.

 

7. 주어진 조건의 Node 개수 찾기

ready 상태인 node 중에 taint가 없는 node의 개수를 구하여 주어진 경로의 파일에 저장하라

 

관련 공식 문서

https://kubernetes.io/docs/reference/kubectl/quick-reference/#viewing-and-finding-resources

 

대략적인 풀이

# kubectl Quick Reference 참고, Ready 상태의 노드 개수 확인 -> 모든 노드 Ready였음
# Check which nodes are ready with custom-columns
kubectl get node -o custom-columns='NODE_NAME:.metadata.name,STATUS:.status.conditions[?(@.type=="Ready")].status'

# Ready면서 taint가 없는 노드 개수 확인
k describe node | grep -i taint

# 모든 노드 개수에서 taint : <None>인 노드 개수 찾기 -> 2개 였음

# 주어진 경로 저장
echo "2" > /문제에서/주어진/경로
  • quick-reference는 두세 번 훑고 어떤 내용이 있는지 숙지하는 것을 권장드립니다.

 

8. 주어진 조건의 Pod 이름 찾기

특정 namespace에서 <key>:<value> label을 가진 Pod 중 CPU 사용률이 가장 높은 pod의 이름을 주어진 경로의 파일에 저장하라

 

관련 공식 문서

https://kubernetes.io/docs/reference/kubectl/quick-reference/#interacting-with-running-pods

 

대략적인 풀이

// top 명령어와 --sort-by 옵션 활용
k top po -n <name-space> -l <key>:<value> --sort-by=cpu

// echo "<pod-name>" > /문제에서/주어진/경로/
  • 이 문제 역시 quick-reference에서 봤다면 쉽게 풀 수 있는 문제였습니다.

 

9. NetworkPolicy

NetworkPolicy를 생성하여 특정 namspace의 Pod의 요청만 정해진 포트를 통해 들어올 수 있도록 하라.(ingress)

 

관련 공식 문서

https://kubernetes.io/docs/concepts/services-networking/network-policies/#networkpolicy-resource

 

대략적인 풀이

# 공식문서에서 가져온 예시
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy -> 문제에서 주어진대로 수정
  namespace: default -> 문제에서 주어진대로 수정
spec:
  podSelector:
    matchLabels:
      role: db -> 문제에서 주어진대로 수정
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: myproject -> 문제에서 주어진대로 수정
    - podSelector:
        matchLabels:
          role: frontend -> 문제에서 주어진대로 수정
    ports:
    - protocol: TCP
      port: 6379  -> 문제에서 주어진대로 수정
  • networkpolicy 리소스에 대해 잘 이해하고 있다면 어렵지 않게 풀 수 있는 문제였습니다.

 

정확한 복기가 아니므로 어디까지나 참고입니다! 1트에 합격하세여🤗

728x90