(시리즈4) 쿠버네티스 코드 분석하기 : kubectl apply -f nginx.yaml 을 입력하면 일어나는 일(2) - kubectl

msyhu·2021년 7월 3일
1
post-thumbnail

이번 시간에는 저번 청사진에 이어 'kubectl apply -f 를 입력하면 일어나는 일' 입구에 해당하는 kubectl 부분을 알아보겠습니다.

kubectl

1.client에서 api-server로 kubectl apply 명령을 내린다.

Kubectl은 쿠버네티스 클러스터를 제어하기 위한 커맨드 라인 도구이다. 구성을 위해, kubectl 은 config 파일을 $HOME/.kube 에서 찾는다. KUBECONFIG 환경 변수를 설정하거나 --kubeconfig 플래그를 설정하여 다른 kubeconfig 파일을 지정할 수 있다.
https://kubernetes.io/ko/docs/reference/kubectl/overview/

쿠버네티스 hello-world에 가까운 nginx 이미지를 deployment해 보겠다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

staging/src/k8s.io/kubectl/pkg/cmd

Kubectl 뒤에 오는 명령어들 별로 폴더가 구분되어있고, 그 안에 실행시킬 코드들이 정리되어 있다.

staging/src/k8s.io/kubectl/pkg/cmd/apply/apply.go : NewCmdApply

Apply 관련 로직이 모여있는 함수.
180~184 라인에 실제 돌아가는 로직이 있다.
실제 작동 로직이 들어있는 184 라인 o.Run()을 살펴보았다.

Run() -> GetObjects()

GetObject() 함수에 실제로 내가 정의한 yaml 파일과 기타 resource 정보를 모아주는 로직이 모여있었다.

Builder 패턴
Builder 패턴은 복잡한 객체의 생성 과정과 표현 방법을 분리하여 개발자가 메서드별로 명확하게 하는 일을 파악할 수 있게 해 주는 디자인 패턴이다.
여기서는 각 메서드가 Builder 구조체를 수정 후 포인터를 반환하고 다음 메서드가 그걸 받아서 쓰는 형식을 통해서 메서드별로 그 목적에 맞게 builder 구조체를 수정한다.
( 출처 : https://johngrib.github.io/wiki/builder-pattern/ )

Do()

앞에는 각종 전처리 및 에러체크이므로, 핵심 로직이 있는 Do 함수를 알아보았다.
이 함수는 Result 객체를 반환하는데, 여기에 실제 어플리케이션을 생성하는 핵심 정보들이 들어간다.

Visitor 패턴
Visitor 패턴은 실제 로직을 가지고 있는 객체(Visitor)가 로직을 적용할 객체(Element)를 방문하면서 실행하는 패턴이다. 즉, 로직과 구조를 분리하는 패턴이라고 볼 수 있다. 로직과 구조가 분리되면 구조를 수정하지 않고도 새로운 동작을 기존 객체 구조에 추가할 수 있다. 실제로 여기서 생성된 visitor가 나중에 리소스 정보를 획득한다.
( 출처 : https://thecodinglog.github.io/design/2019/10/29/visitor-pattern.html )

Visitor가 visit하면서 리소스 정보를 출력하는 부분이다. 실제로 Infos 객체를 찍어본 결과 정의한 yaml파일 정보를 얻어오는 것을 확인했다.

다시 Run 함수로 돌아와서 보면 앞에서 visitor가 얻은 infos를 순회하면서 하나씩 apply한다.

applyOneObject() 함수의 일부이다.
리소스가 없을시 kubectl create로 연결되어 객체를 생성하며, 그 외에도 modify 부분이 있었다.
또 info.GET() 은 api-server를 호출해서 해당 info가 있는지 rest get 호출로 확인해보는 로직이다.

kubectl 에서 API-Server로 자원 생성을 요청하는 곳까지 내려와서, 한번 로그를 찍어 본 모습이다. 하나씩 자세히 파악하지 않아도 기본 yaml 파일 정보에 기타 정보들이 추가되어 있는 모습을 볼 수 있다.

Do함수 내부로 들어가 url과 요청, 응답 body를 출력해보았다.
6443포트는 api서버의 기본 포트이다.


다음 글에서는 API-Server에서 etcd에 저장하는 부분을 알아보도록 하겠습니다.
잘못된 부분이 있으면 댓글 남겨주시면 감사하겠습니다!!

profile
컨테이너, k8s, 마이크로서비스 등 클라우드 네이티브 환경에 관심이 많습니다.

0개의 댓글