Kubernetes 이야기

올바른 Kubernetes manifest 작성하기 본문

Kubernetes/일반

올바른 Kubernetes manifest 작성하기

kmaster 2022. 5. 5. 18:43
반응형

올바른 Dockerfile 작성하기 글을 올린적이 있는데 https://kmaster.tistory.com/52

 

올바른 Dockerfile 작성하기

DockerHub에는 다양한 Docker Image가 존재한다. Official한 이미지를 사용하면 좋겠지만, 때로는 Official 이미지에 다양한 라이브러리와 개발된 라이브러리등을 넣어서 본인만의 Docker Image를 만들어야 하

kmaster.tistory.com

이번에는 올바른 Kubernetes manifest 작성하는 방법을 알아보자.

 

오픈소스중 trivy나 datree 같은 Tool을 사용하면 사용자가 만든 yaml 의 문제점을 파악해준다. 올바른 yaml 방법을 사용하여 배포하면 장애나 보안에 적절하게 대응할 수 있다.

 

Liveness, Readiness and Startup Probes 설정

 

  • Liveness Probe : 컨테이너가 동작 중인지 여부를 나타낸다. 만약 활성 프로브(liveness probe)에 실패한다면, kubelet은 컨테이너를 죽이고, 해당 컨테이너는 재시작 정책의 대상이 된다. 만약 컨테이너가 활성 프로브를 제공하지 않는 경우, 기본 상태는 Success 이다.
  • Readiness Probe : 컨테이너가 요청을 처리할 준비가 되었는지 여부를 나타낸다. 만약 준비성 프로브(readiness probe)가 실패한다면, 엔드포인트 컨트롤러는 파드에 연관된 모든 서비스들의 엔드포인트에서 파드의 IP주소를 제거한다. 준비성 프로브의 초기 지연 이전의 기본 상태는 Failure 이다. 만약 컨테이너가 준비성 프로브를 지원하지 않는다면, 기본 상태는 Success 이다.
  • Startup Probe : 컨테이너 내의 애플리케이션이 시작되었는지를 나타낸다. 스타트업 프로브(startup probe)가 주어진 경우, 성공할 때까지 다른 나머지 프로브는 활성화되지 않는다. 만약 스타트업 프로브가 실패하면, kubelet이 컨테이너를 죽이고, 컨테이너는 재시작 정책에 따라 처리된다. 컨테이너에 스타트업 프로브가 없는 경우, 기본 상태는 Success 이다.

예제

ports:
- name: port
  containerPort: 8080
  hostPort: 8080

  livenessProbe:
    httpGet:
      path: /healthz
      port: liveness-port
    failureThreshold: 1
    periodSeconds: 10

  readinessProbe:
    httpGet:
      path: /healthz
      port: liveness-port
    initialDelaySeconds: 5
    periodSeconds: 10
      
  startupProbe:
    httpGet:
      path: /healthz
      port: liveness-port
    failureThreshold: 30
    periodSeconds: 10

 

리소스 요청 및 제한 설정

 

프로덕션 클러스터에 애플리케이션을 배포하는 것은 해당 클러스터에서 사용 가능한 리소스가 제한되어 실패할 수 있다. 이는 Kubernetes 클러스터 작업 시 일반적인 문제이며 리소스 요청 및 제한이 설정되지 않은 경우에 발생한다.

리소스 요청 및 제한 없이 클러스터의 포드는 필요한 것보다 더 많은 리소스를 활용하기 시작할 수 있다. 포드가 노드에서 더 많은 CPU 또는 메모리를 사용하기 시작하면 스케줄러가 새 포드를 배치하지 못할 수 있으며 노드 자체가 충돌할 수도 있다.

 

또한, Pod에는 QoS라는 것이 있다. 이 QoS의 포드는 축출을 수행할 때 마지막 선택된다.

 

예제

  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

 

Label 입력

 

Kubernetes에서는 거의 모든 개체에 레이블을 추가할 수 있다. Label은 Kubernetes Service를 사용하여 애플리케이션에 액세스할 때 트래픽을 전달하는 데 중요한 역할을 하고, 사용자가 개체를 그룹화/목록화하려는 경우에도 필요하다.

 

예제

apiVersion: v1
kind: Pod
metadata:
  name: label-demo
  labels:
    environment: production
    app: nginx

 

AutomountServiceAccountToken 비활성화

 

기본적으로 사용자가 포드에 serviceAccounts를 지정하지 않으면 default service account가 포드에 탑재된다. 이 service token을 이용해 Kubernetes API 서버와 통신할 수 있다. 이것은 보안 위험하다.

 

예제

apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-robot
automountServiceAccountToken: false
...

또는

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  serviceAccountName: build-robot
  automountServiceAccountToken: false
  ...

 

HA설정

 

Pod가 장애날 것을 대비하여 최소 2개이상의 replicas를 권장한다. 그리고 동일한 Node에 배포될 수 있기 때문에

적절한 Node Affinity등을 통해 분산 배치되도록 해야 한다.

이 글을 참고한다. https://kmaster.tistory.com/42

 

Pod 스케줄링

Kubernetes 에는 Pod가 어느 노드에 생성되어야 하는지 결정할 수 있는 다양한 방법이 있다. 이 중 대표적으로 아래와 같은 방법이 있다. Assingning Pods to Nodes ( nodeSelector / Affinity and anti-affinity..

kmaster.tistory.com

 

hostPort

 

반드시 필요한 것이 아니라면 파드에 hostPort 를 명시하지 않는다. <hostIP, hostPort, protocol> 조합은 유일해야 하기 때문에, hostPort로 바인드하는 것은 파드가 스케줄링될 수 있는 위치의 개수를 제한한다. 만약 hostIP와 protocol을 뚜렷히 명시하지 않으면, 쿠버네티스는 hostIP의 기본 값으로 0.0.0.0를, protocol의 기본 값으로 TCP를 사용한다.

동일한 이유로 hostNetwork도 사용을 피한다.

 

Service Type 확인

 

서비스를 NodePort나 LoadBalancer 로 하는 경우 클러스터 외부의 네트워크에서 도달할 수 있는 모든 노드의 포트를 열게된다.  이는 보안에 크게 위험할 수 있으니 꼭 필요한 서비스인지 확인해야 한다.

 

 

참고

https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/

https://kubernetes.io/docs/concepts/scheduling-eviction/pod-priority-preemption/

https://kubernetes.io/ko/docs/concepts/configuration/manage-resources-containers/

https://kubernetes.io/ko/docs/concepts/overview/working-with-objects/labels/

https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

 

반응형
Comments