Scooter-2022 / AI-HPA

딥러닝 기반 Kubernetes Autoscaler 성능 개선 프로젝트
1 stars 3 forks source link

Init 컨테이너로 검사하기 #23

Closed bconfiden2 closed 2 years ago

bconfiden2 commented 2 years ago

내용

스케일러가 동작하기 위해서는 메트릭서버가 정상 작동하고 있어야 함 yaml 파일에서 init 컨테이너 둬서 메트릭 서버 동작 확인한 뒤에 스케일러 실행시키기

작업 내용

참고 사항

https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

hellouz818 commented 2 years ago

init 컨테이너를 통해 스케일러 동작 전에 메트릭 서버 컨테이너가 미리 실행될수 있도록 환경설정을 해놓아야 한다는건가? 아직 사용법이나 목적을 잘 모르겠어서 일단 init 컨테이너 관련해서 읽어보고 궁금한 사항이나 진행 상황 생기는대로 남기겠습니다!

bconfiden2 commented 2 years ago

맞아맞아 땡큐! 👍

hellouz818 commented 2 years ago
  1. 메트릭 서버 설치 (Collect/metrics-server.yaml)
  2. 스케일러 실행 전 init container를 Update/test-scaler.yaml에 추가 2-1. 이때 init container는 metric servers에 api요청 날리는 명령 수행 후 정상적이면 test-scaler.yaml의 기존 애플리케이션 컨테이너 수행

이렇게 진행되는것이 맞을까요? 2-1에서 메트릭 서버 동작 확인 부분이 어떻게 해야할지 조금 헷갈립니다..

hellouz818 commented 2 years ago

그리고 Update 폴더 내의 파일들도 사용법을 md 문서로 작성해놓으면 나중에 이해하기 편할거 같아요! 왜냐면,, 저에겐 모델 관련한 부분은 조금 낯설기 때문에,, 하핫

bconfiden2 commented 2 years ago

Update 아래에 있는 test-scaler.yaml 말고 최상단 디렉토리에 yaml 파일 하나 추가해서 진행하는건 어때?? 그렇게 생각하고 이름을 test-scaler 라고 지어놓긴 해서.. ㅋㅋㅋㅋ 최상단 디렉토리에 스케일러랑 모델 등 우리가 개발한 내용들이 담긴 yaml 파일을 추가하고, 그 파일에 메트릭서버 동작을 검사하는 init container를 추가하는거지,,,,

2-1 에서 메트릭 서버 동작 확인 부분은 뭐 api 요청 결과를 기준으로 확인해보면 되지 않으려나?? 메트릭 서버가 떠있을때랑 없을 때 어떻게 다르게 반환되는지 보고 기준을 정하면 될 듯??

hellouz818 commented 2 years ago

아하,, 나는 말그대로 init이기때문에 어느파일 안에 무조건 들어간다음 초기화를 먼저 해야하지 않을까라고 생각했는데, test-scaler.yaml랑 관련없이 분리 될 수 있도록 작업 해보겠습니닷,, (그러니까 init container가 우리가 개발한 내용의 yaml 파일이랑 다른 파일에 써도 되고 나중에 합쳐도 되는 방식으로,,) 그리고 메트릭 서버 동작 확인부분은 따로 정해진게 없고 그냥 결과 기준으로 판단해서 하면 되는거구나 나는 다른 방법이 있는줄 알았으

답변 고마워 땡큐! 하다가 이상하면 다시 남길게~~

bconfiden2 commented 2 years ago

음... 나중에 이거 보면 내가 뭔 생각으로 말했는지 알 수 있을듯?? https://www.youtube.com/watch?v=ChArV14J6Ek

hellouz818 commented 2 years ago

프로젝트 전반에서 해당 내용(메트릭서버 상태 확인)이 먼저 선행되어야하는 이유로 루트 디렉토리에 밑에 파일을 추가하는 것에는 동의하지만, 아직 해당 파일이 미완성이라고 생각되어 test-scaler.yaml에 init container내용을 추가하여 PR 보내겠습니다. 감사합니둥~

NayeonKeum commented 2 years ago

이거 의존성 있는 오브젝트 실행 여부 확인해서 실행시키는 이미지 있어서 그거 쓰면 될 것 같은데 늦게 봐서 미안

stackanetes/kubernetes-entrypoint

이거 찾아봐!

NayeonKeum commented 2 years ago

container 실행 전에 initContainer로 의존성 있는 파드, 서비스 이름 등으로 서비스 디스커버리 하면 그 파드가 완전히 Ready 되어서 Running 될 때까지 initialized에 머물러있다가 ready 시작함!

사용 예시)

initContainers:
  - command:
    - kubernetes-entrypoint
    name: init-dependency-check
    env:
    - name: POD_NAME
      value: cluster-mysql-0
    - name: NAMESPACE
      value: mysql-artiference
    - name: DEPENDENCY_POD_JSON # 필수 아님
      value: '[{"labels":{"app.kubernetes.io/name":"mysql"}}]'
    - name: COMMAND
      value: echo done
    image: projects.registry.vmware.com/tcx/snapshot/stackanetes/kubernetes-entrypoint:latest
    securityContext:
      privileged: true
      runAsUser: 0

관련 깃헙 레포로 가면 저런 변수 설정 다 있으니까 참고하면 좋을듯!

bconfiden2 commented 2 years ago

오 괜찮은듯!!

hellouz818 commented 2 years ago

앗 고마워! 나 안그래도 저거 레디일때 안되는거 예외처리같은걸 해줘야하나 고민하고 있었거든.. 일단 initContainer 관련 pr은 올렸어서 해당 pr에 이어서 보내준 내용 확인하고 수정해보도록 할게잇!

hellouz818 commented 2 years ago

의존성 있는 네임스페이스나 서비스이름 라벨명 등을 각각 넣고빼고하면서 실행해봤는데 잘 되지 않아,, 위에서 기입하라고 알려준 의존성 있는 파드는 이름은 항상 변하기 때문에 (deployment로 생성하기때문에 metrics-server-*** 이런식으로 만들어짐) 하나로 지정되지 않아서 그런거 아닐까 싶은데 다들 어떻게 생각해? 혹시 이상한 부분이 있다면 알려줘!

이건 추가하려는 initContainer 부분

# metrics-server Running check in advance
  initContainers:
  - command:
    - kubernetes-entrypoint
    name: init-dependency-check
    env:
    - name: NAMESPACE
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
    - name: DEPENDENCY_SERVICE
      value : metrics-server
    - name:  DEPENDENCY_POD_JSON
      value : '[{"namespace": "kube-system", "name": "metrics-server"}, {"labels": {"k8s-app": "metrics-server"}}]'
    image: projects.registry.vmware.com/tcx/snapshot/stackanetes/kubernetes-entrypoint:latest
    securityContext:
      privileged: true
      runAsUser: 0

아래는 kubectl describe -f metrics-server.yaml -n kube-system의 일부야!


Name:         metrics-check-pod
Namespace:    kube-system
Priority:     0
Node:         testpool-w-1gp2/192.168.123.9
Start Time:   Sun, 17 Jul 2022 22:23:28 +0900
Labels:       app=metrics-check
Annotations:  <none>
Status:       Pending
IP:           198.18.0.24
IPs:
  IP:  198.18.0.24
Init Containers:
  init-dependency-check:
    Container ID:  containerd://dcce0ce7085bd268e395edbbe52a71b6d0e16aba51aa30317951d8b4a1581fea
    Image:         projects.registry.vmware.com/tcx/snapshot/stackanetes/kubernetes-entrypoint:latest
    Image ID:      projects.registry.vmware.com/tcx/snapshot/stackanetes/kubernetes-entrypoint@sha256:73d017557367c658bb69276763a1e3b6c0ffccddbfffc7441d1ab76dee61258d
    Port:          <none>
    Host Port:     <none>
    Command:
      kubernetes-entrypoint
    State:          Running
      Started:      Sun, 17 Jul 2022 22:23:30 +0900
    Ready:          False
    Restart Count:  0
    Environment:
      NAMESPACE:            kube-system (v1:metadata.namespace)
      DEPENDENCY_SERVICE:   metrics-server
      DEPENDENCY_POD_JSON:  [{"namespace": "kube-system", "name": "metrics-server"}, {"labels": {"k8s-app": "metrics-server"}}]
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-p69xb (ro)

...

Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  7s    default-scheduler  Successfully assigned kube-system/metrics-check-pod to testpool-w-1gp2
  Normal  Pulling    6s    kubelet            Pulling image "projects.registry.vmware.com/tcx/snapshot/stackanetes/kubernetes-entrypoint:latest"
  Normal  Pulled     5s    kubelet            Successfully pulled image "projects.registry.vmware.com/tcx/snapshot/stackanetes/kubernetes-entrypoint:latest" in 152.48649ms
  Normal  Created    5s    kubelet            Created container init-dependency-check
  Normal  Started    5s    kubelet            Started container init-dependency-check

https://github.com/stackanetes/kubernetes-entrypoint 이건 참고한 깃헙이야!

bconfiden2 commented 2 years ago

음 나도 테스트 해보고 있을게!!

NayeonKeum commented 2 years ago

원래 이름으로는 그래서 하면 안 되고, 해당 파드 desribe하면 나오는 정보 중에 DEPENDENCY_POD_JSON 명시해주면 됨! 내가 예시로 적은 저 label은 불변값이어서 사용했었엉 그리고 혹시 권한 없다고 나오면 ClusterRole 추가해줘야함!

hellouz818 commented 2 years ago

계속 해보았는데, 잘 안되어서,, 혹시 잘못하고 있다면 알려줘! @NayeonKeum

일단 컨테이너, 데몬셋은 podname이라는 변수가 꼭 필요하다고하여(This dependency requires a POD_NAME environment variable) podname은 계속 바뀌니까 이 환경변수는 빈칸으로 설정했고, 말해준대로 DEPENDENCY_POD_JSON과 namespace를 항목을 넣고 service는 넣어보기도했고 빼보기도해서 만든 파일이야 참고로, init-myservice는 init이 순차적으로 되는지 상태를 확인하고자 첫번째로 기본세팅들을 busybox 이미지로 다운받을 수 있도록 해놓았고, 두번째가 metrics-server를 실행여부를 검사하는거야!

initcontainer.yaml

kind: Pod
metadata:
  name: metrics-check-pod
  namespace: kube-system
  labels:
    app: metrics-check
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']

  # metrics-server Running check in advance
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "echo busybox"]
  - name: init-dependency-check
    command: ['kubernetes-entrypoint']
    image: projects.registry.vmware.com/tcx/snapshot/stackanetes/kubernetes-entrypoint:latest
    securityContext:
      privileged: true
      runAsUser: 0
    env:
    - name: NAMESPACE
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
    - name: DEPENDENCY_CONTAINER
    - name: DEPENDENCY_SERVICE
      value: metrics-server
    - name: DEPENDENCY_DAEMONSET
    - name: DEPENDENCY_POD_JSON
      value: '[{"labels":{"k8s-app":"metrics-server", "pod-template-hash":"689f8f6b6"}}]'

metrics-server가 실행되는 파드 describe해서 나온 결과값은 아래와 같아! 그래서 json값으로 해당 라벨에서 나온 값인 value: '[{"labels":{"k8s-app":"metrics-server", "pod-template-hash":"689f8f6b6"}}]'을 추가해주었어 pod-template-hash는 여러번 생성해도 동일하게 나왔고! (이것도 뺐다 넣었다 해보긴했어)

kubectl describe pods metrics-server-~ -n kube-system

Name:                 metrics-server-689f8f6b6-k2d9n
Namespace:            kube-system
Priority:             2000000000
Priority Class Name:  system-cluster-critical
Node:                 testpool-w-1hyo/192.168.123.9
Start Time:           Sun, 24 Jul 2022 16:28:13 +0900
Labels:               k8s-app=metrics-server
                      pod-template-hash=689f8f6b6
Annotations:          <none>
Status:               Running
IP:                   198.18.1.249
IPs:
  IP:           198.18.1.249
Controlled By:  ReplicaSet/metrics-server-689f8f6b6
Containers:
  metrics-server:
    Container ID:  containerd://b0405874c8459c41dfc408d26dbba7eb917d6a4e64f4cafaa6d4e32cc244ea63
    Image:         k8s.gcr.io/metrics-server/metrics-server:v0.6.1
    Image ID:      k8s.gcr.io/metrics-server/metrics-server@sha256:5ddc6458eb95f5c70bd13fdab90cbd7d6ad1066e5b528ad1dcb28b76c5fb2f00
    Port:          4443/TCP
    Host Port:     0/TCP
    Args:
      --cert-dir=/tmp
      --kubelet-insecure-tls
      --secure-port=4443
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
      --kubelet-use-node-status-port
      --metric-resolution=90s
    State:          Running
      Started:      Sun, 24 Jul 2022 16:28:18 +0900
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:        100m
      memory:     200Mi
    Liveness:     http-get https://:https/livez delay=0s timeout=1s period=10s #success=1 #failure=3
    Readiness:    http-get https://:https/readyz delay=20s timeout=1s period=10s #success=1 #failure=3
    Environment:  <none>
    Mounts:
      /tmp from tmp-dir (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-vzm62 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  tmp-dir:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     
    SizeLimit:  <unset>
  kube-api-access-vzm62:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Burstable
Node-Selectors:              kubernetes.io/os=linux
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Scheduled  6m11s                  default-scheduler  Successfully assigned kube-system/metrics-server-689f8f6b6-k2d9n to testpool-w-1hyo
  Normal   Pulling    6m10s                  kubelet            Pulling image "k8s.gcr.io/metrics-server/metrics-server:v0.6.1"
  Normal   Pulled     6m7s                   kubelet            Successfully pulled image "k8s.gcr.io/metrics-server/metrics-server:v0.6.1" in 3.32834254s
  Normal   Created    6m6s                   kubelet            Created container metrics-server
  Normal   Started    6m6s                   kubelet            Started container metrics-server
  Warning  Unhealthy  4m41s (x8 over 5m41s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 500

하지만 왜 안되는지 모르겠다.. 조언 부탁해..!!

일단 기존 커밋 내용은 작동해서 따로 수정하진 않았고일단은 다른 부분 보고 있을게!

참고했던 github https://github.com/stackanetes/kubernetes-entrypoint https://github.com/yogeshlonkar/pod-dependency-init-container

NayeonKeum commented 2 years ago

내가 예시로 줬던 것 중에

- name: DEPENDENCY_POD_JSON # 필수 아님
      value: '[{"labels":{"app.kubernetes.io/name":"mysql"}}]'

여기서 labels 값을 metadata로 지정해줄 수 있거든?! deployment의 spec 부분 중에 pod에 대한 template에

... 어쩌구 저쩌구
metadata:
  labels:
    app.kubernetes.io/name: {파드 이름}

이렇게 해놓고 맨 위에 환경변수 값을 yaml에 추가해봐!!

NayeonKeum commented 2 years ago

음... role에 관한 에러를 못 보긴 했는데 Role이 없어서 생긴 문제일 수도 있거든?? api 그룹은 다를 것 같긴한데 일단 이런 느낌이여

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: {대상}
  name: role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: {대상}
  name: roleBinding
subjects:
- kind: ServiceAccount
  name: {대상에 접근하는}
  namespace: {대상에 접근하는}
roleRef:
  kind: Role 
  name: role
  apiGroup: rbac.authorization.k8s.io
---
hellouz818 commented 2 years ago

role 문제는 아닌것 같아..!!