STUDY/Data Engineering

[CKA] 실습/개념 정리

wonpick 2024. 1. 20. 19:56

다음은 CKA 시험 준비를 하면서 따배쿠/kodekloud 실습한 내용을 정리한 자료이다.

관련된 개념은 계속해서 추가해볼 예정이다.

1. pv hostpath 볼륨 마운트 (2점)

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany
	hostPath:
		path: /tmp/app-config

2. 기존 팟 수정해서 볼륨에 로그 저장하는 사이드카 컨테이너 붙이기 (커맨드 추가) (5점)

질문

 

웹서버 nginx 컨테이너를 동작시켜보자

  • nginx는 사용자가 접속하게 되면 /var/log/html 안에 access/error로그가 남겨진다.
  • 기본은 컨테이너안에서만 로그가 남겨지는데 별도의 쿠버네티스 볼륨을 만들었다.
  • varlog 라는 볼륨을 마운트 시킨다.(read write가 가능하도록)
  • html에 쌓이게 되는 access error로그가 볼륨에 쌓이게 된다.

이제부터 하나의 컨테이너를 더 만들어서 볼륨에 있는 데이터를 가공분석하고싶음

  • 웹 로그를 분석하는 애플리케이션 컨테이너
  • data 디렉토리에 있는 로그를 가져다가 로그 분석을 해야함
  • 그러려면 data 디렉토리에 웹로그가 있어야함
  • 볼륨을 data 디렉토리에 read on 이 가능하게 마운트 시킴
  • 웹서버가 로그를 만들어주면 이 로그분석 프로그램은 그걸 가져다가 가공해주는 사이드카 컨테이너가 된다.

하나의 파드안에서 두개의 컨테이너와 저장소 볼륨이 같이 만들어져서 도는게 사이드카 컨테이너다.

  • 기존에 있던 컨테이너 안에 사이드카를 추가해서 집어넣어달라
    • 이미존재하는 eshop-cart-app에 추가하기
  • 컨테이너 2개
    • cart-app와 sidecar가 /var/log/cart-app.log를 같이 공유하고 있다.
    • sidecar 컨테이너를 이용해서 메인 컨테이너가 만든 데이터를 외부에 노출시킬 수 있게 만듦
kubectl get pods eshop-cart-app -o yaml > sidecar.yaml
vi sidecar.yaml

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: price
   image: busybox
   args: /bin/sh, -c, 'tail -n+1 -F /'] 
   volumeMounts:
   - name: varlog
     mountPath: /var/log

  volumes:
  - name: varlog
    emptyDir: {}
 #나오면 성공
Kubectl exec 파드명 -c sidecar --cat /var/log/파드명.log

3. etcd 복구 

ETCD는 저장소이다. api를 통해 동작되는 쿠버의 모든 운영 정보를 담고 있음.

ETCD는 하나의 파드 형태이고, 이 파드가 쿠버에서 운영하는 정보를 데이터저장소에 담아줌.

snapshot 파일을 남겨주는 것. 데이터한테는 snapshot 저장이 됨.

 

마스터 장비에는 etcd 는 데이터 저장소가 있다.

  • 현재 api통해 동작되는 쿠버의 모든 운영정보가 etcd에 담겨져있음
  • 파드 형태임
  • 키 벨류 타입의 저장소이다.
  • /var/lib/etcd 경로로 감
  • 백업
    • 그래서 백업을 하게 된다. → 저장소 공간을 별도의 파일로 백업할 수 있다.
    • etcd를 백업하는걸 snapshot했다고 칭함.
    • /data/etcd-snapshot.db → 백업
  • 리스토어
    • /data/etcd-snapshot-previous.db
    • 이 파일을 데이터베이스에 옮겨줘야한다. 이때 사용되는 디렉토리는 기존 etcd 디렉토리랑 달라야함
      • /var/lib/etcd- xxxx → 다른 디렉토리로
    • 그다음 경로를 etcd pod에 데이터 저장소 새 경로를 알려줘야함
    • etcd pod는 static pod이기 때문에 컨피그레이션을 변경만 하면 알아서 리스토어 해줌

--data-dir 옵션을 제외한 나머지 옵션은 etcd 프로세스 실행시 사용된 값들이기 때문에 위에서 설명한 내용만 숙지했으면 큰 문제는 없을것이다. --data-dir 옵션에는 etcd 프로세스 사용시 --data-dir 옵션에 사용되었던 값은 /var/lib/etcd 대신 /var/lib/etcd_backup 으로 설정함으로써 restore 시에는 현재 사용중인 Data 파일을 덮어씌우지 않게 했다.

kubectl config current-context
ssh k8s-master
whoami #권한 확인
sudo tree /var/lib/etcd #etcd 파일 확인
etcdctl version

sudo ETCDCTL_API=3 etcdctl \\
  --endpoints=https://127.0.0.1:2379 \\
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \\
  --cert=/etc/kubernetes/pki/etcd/server.crt  \\ 
  --key=/etc/kubernetes/pki/etcd/server.key \\
  snapshot save /data/etch-snapshot.db

sudo ls -l /data/etcd-snapshot.db #백업 확인

sudo ETCDCTL_API=3 etcdctl \\
  --data-dir /var/lib/etcd-previous \\
  snapshot restore /data/etcd-previous.db
sudo tree /var/lib/etcd-previous

#etcd에게 변경된 데이터 저장소 위치 
kubectl get pod -n kube-system
cd /etc/kubernetes/manifests/
sudo vi /etc/kubernetes/manifests/etcd.yaml
#hostpath 변경
/var/lib/etcd-previous

#docker 명령어로 up 상태 확인
sudo docker ps -a | grep etcd
  • CA에서 발급한 root certificate
  • 서버에서 발급한 server certificate
  • 클라이언트에서 발급한 client certificate

4. 워커노드 트러블슈팅(kubelet)

  • 한번만이 아니라 영구적으로 유지될 수 있게 해라
  • 문제에 대한 진단을 어떻게 해야하는지 확인할 것임
  • 워커노드가 가지고 있는 컴포넌트이고 이 순으로 작업되야됨
    • 도커엔진이 러닝중인가? Kueblet 데몬이 러닝중인가? → 여기까지만 돼도 러닝은 됨
    • kube-proxy 파드가 러닝중인가?
    • CNI 러닝중인가?(컨테이너간의 소통을 위해)

→ 4가지 서비스 운영 필요

  •  진단이나 서비스 명 볼 때 루트권한이 필요하다.
  • 큐블렛 데몬이 죽어있는걸 볼 수 있음. 다음번 실행에도 실행되지 않게 되어있고

그래서 서비스 동작시키고 다음 부팅에도 실행될 수 있게명령어 씀

명령어 —now를 통해 다음에도 동작되게

  • 큐브 프록시 /CNI 확인

exit로 확인 cni나 큐브프록시는 수도에서 빠져나가서 콘솔창에서 확인해야함

ssh worker node
systemctl status kubelet
systemctl enable --now kubelet
exit 
kubectl get ndoes # active확인

5. pod 특정 레이블 중 top cpu 파드 이름 저장

리소스 확인할때 top이라는 명령어를 쓴다!

##overloaded-cpu 레이블을 가지고 사용되는 파드들 중에 cpu 사용량이 가장 많은거
kubectl top pods -l name=overloaded-cpu --sort-by=cpu > /var/CKA2022/cpu_load_pod.txt

6. taint된 노드 개수

k describe nodes | grep -i taint 

7. ingress 재작 후 curl 테스트 (7점)

질문

인그레스는 클러스터 외부에서 클러스터 내부 서비스로 HTTP와 HTTPS 경로를 노출한다. 트래픽 라우팅은 인그레스 리소스에 정의된 규칙에 의해 컨트롤된다.

클러스터 외부에서 클러스터 내부로 서비스를 노출 시켜주는 api

ingress룰을 만들 수 있는지가 문제다.

#포트번호는 아래 명령어로 확인한걸로 수정하기 
kubectl get svc -n ingress-nginx 명령어로 확인한 포트

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
	namespace: ingress-nginx
  name: app-ingress
  annotations:
		nginx.ingress.kubernetes.io/ingress.class: nginx
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: nginx
            port:
              number: 80
      - path: /app
        pathType: Prefix
        backend:
          service:
            name: appjs-service
            port:
              number: 80

kubectl describe ingress app-ingress -n ingress-nginx
curl k8s-worker1:30080
curl k8s-worker1:30080/app

8. 멀티컨테이너 파드 만들기 (2점)

apiVersion: v1
kind: Pod
metadata:
	name: eshop-frontend
spec:
	containers:
	- image: nginx
		name: nginx
	- image: redis
		name: redis
	- image: memcached
		name: memcached
	- image: consul
		name: consul

9. 조건에따라 networkpolicy 만들기 (특정 네임스페이스, 포트, 파드로 가는 트래픽 허용) (7점)

질문

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-web-from-customera
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: poc
  policyTypes:
    - Ingress
  ingress:
        - namespaceSelector:
            matchLabels:
              partition: customera
        - podSelector:
            matchLabels:
              role: customera
      ports:
        - protocol: TCP
          port: 80

kubectl get networkpolicies #띄운게 나와야함

10. 마스터 노드 업그레이드 (7점)

질문

ssh 마스터 노드
sudo -i

apt update
apt-cache madison kubeadm

apt-mark unhold kubeadm && \\
apt-get update && apt-get install -y kubeadm=1.23.3-00 && \\
apt-mark hold kubeadm

kubeadm version
kubeadm upgrade plan v1.23.3
kubeadm upgrade apply v1.23.3

exit
kubectl drain hk8s-m --ignore-daemonsets

ssh 마스터노드
sudo -i

apt-mark unhold kubelet kubectl && \\
apt-get update && apt-get install -y kubelet=1.23.3-00 kubectl=1.23.3-00 && \\
apt-mark hold kubelet kubectl

systemctl daemon-reload
systemctl restart kubelet

exit
kubectl uncordon 마스터노드

kubectl get nodes

11. 디플로이먼트 expose 하는 nodeport 타입 서비스 만들기 (3점)

kubectl get deployments.apps front-end
kubectl expose deployment front-end --name front-end-nodesvc --port=80 --target-port=80 --type NodePort --dry-run=client -o yaml > front-svc.yaml
vi front-svc.yaml
kubectl apply -f front-svc.yaml
kubectl get svc
curl k8s-worker1:30200

12.  nodeSelector

nodeSelector는 노드 선택 제약사항의 가장 간단하면서도 추천하는 형태이다. 파드 스펙에 nodeSelector 필드를 추가하고, 타겟으로 삼고 싶은 노드가 갖고 있는 노드 레이블을 명시한다. 쿠버네티스는 사용자가 명시한 레이블을 갖고 있는 노드에만 파드를 스케줄링한다.

gpu가 있는 장치가 있는곳에서 실행하는 작업이 많은 머신러닝을 한다고 할때

수많은 워크노드중 어떤 노드가 gpu가 있는 장비일까?

그거는 쿠버네티스가 구분을 할 수 없다.

  • 엔지니어가 알려줘야함 (시스템 어드민스레이트에 gpu가 있는건 별도로 label을 설정함)
  • 마스터 api에서 파드 실행할 때 node selector를 gpu:true라는 조건이 있는 시스템만 실행해줘
  • 워커노드에 node lable 사용 (키벨류 형태) → 노드 셀렉터에 키벨류 넣어줌
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

13. 디플로이먼트 파드 스케일링 (presentation이라는 디플로이먼트를 5개로 늘리기) (3점)

kubectl scale deployment/presentation --replicas=5

14. svc 생성 후 클러스터롤 , 바인딩하기 (5점)

질문

k create serviceaccount 서비스명 -n 네임스페이스!!!
kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods,deployment,statefulSet,daemonSet
kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root -n 네임스페이스!!!

15. 워커 노드 비우기, 드레인 했다가 uncordon (2점)

k drain 노드명 --ignore-daemonsets --force

16. pod error log 확인 후 저장

kubectl logs custom-app | grep -i 'file not found' > /var/CKA2022/custom-app-log

17. pvc만들고 만든 뒤에 capacity 늘리기

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: task-pv-claim
spec:
  accessModes:
     -ReadWriteOnce
  resources:
    requests:
storage: 10Mi

kubectl edit pvc pv-volume --record

18. deployment 수정

kubectl set image deployment/busybox-deploy busybox=busybox123 

 

 


1차 시험을 보았는데, 기출을 제대로 안봐서 인지 6점차로 떨어져서 

2차 시험은 제대로 준비해서 볼 예정이다!

시험 환경도 경험했고 2차는 안붙으면 이상할거 같다. 

이 다음 글은 시험 합격 후기로 돌아오겠다!