ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [AWS] EKS - Observability(스터디 4주차)
    Infra/Cloud 2023. 5. 15. 20:50

    이번주 스터디 주제는 EKS Observability이다.

     

    각종 로그들을 어떻게 활용하느냐에 따라 운영의 효율이 달라질 수 있다고 생각하는 사람으로써, 이것 저것 많은 기능이 존재하는

     

    Kubernetes Cluster 운영에서 가장 중요하면서 필요한 부분중 하나라고도 생각한다. 이번주 스터디를 진행하면서 익숙한 것만

     

    사용하기 보다는 새롭게 나오는 다양한 편리한 기능들을 많이 알아두는 것도 굉장히 중요하다는 생각도 들었다. 


    EKS Console 살펴보기

    - Overview tap

    => Overview를 통해 EKS에 어떤 IAM이 부여되어있는지 ARN을 알려주며 해당 ARN을 클릭하면 어떤 권한들이 부여되어 있는지도 확인이 가능하다. 

     

     

     

    - Resource Tap

    =>  eks console의 Resource Tap에서는 kubernetes apiserver를 통해 각각의 resource 정보를 확인할 수 있다. 참고로 해당 Resource를 클릭하면 좀더 자세한 세부사항도 확인이 가능하다. Pod의 경우 Labels, Annotations, Events, Container(env, mount info, 사용 ports 등) 정보 등 굉장히 세세한 부분까지 볼 수 있다.

     

     

     

     

    EKS Controlplane Logging - CloudWatch

    EKS Logging Tap -> Controlplane Log 정보

    # CloudWatch Logs 활성화
    aws eks update-cluster-config --region $AWS_DEFAULT_REGION --name $CLUSTER_NAME \
        --logging '{"clusterLogging":[{"types":["api","audit","authenticator","controllerManager","scheduler"],"enabled":true}]}'
        
        
    # CloudWatch Logs 비활성화
    eksctl utils update-cluster-logging --cluster $CLUSTER_NAME --region $AWS_DEFAULT_REGION --disable-types all --approve

    => 해당 Tap에서 Controlplane의 API Server, Schduler, Audit, Controller, Authenticator의 Log를 활성화 시킬 수 있다. 수정하고 조금 기다리면 활성화 된다(위와 같이 aws-cli로도 활성화가 가능하다)

     

     

     

    - CloudWatch를 이용한 Log 확인

    => 위의 설정을 진행하게되면 CloudWatch에 자동으로 Log Group이 생성된다. 생성된 CloudWatch의 Log group을 통해 수집된 Log 확인이 가능하며 Log insights에서 query를 통해 필터링된 Log 조회도 가능하다.

     

     

     

     

    - 그렇다면 실제로 로그가 수집되는지 테스트해보자

    test-pod 생성

    => 위와같이 test-pod라는 이름의 Pod를 kubectl 명령을 통해 생성하게되면 인증 config를 이용하여 kube-apiserver에 request를 날릴 것이다. 즉, apiserver log에 관련 request log가 남을 것이다.

     

     

     

    - CloudWatch Log Insights

    apiserver log에서 create pod request log 확인

    => 위에서 우리가 생성한 test-pod 관련 request 관련 audit log를 확인할 수 있었다. query만 잘 작성한다면 필요 log만 수집하여 사용하는데 도움이 될 것같다. On-premise 환경의 Kubernetes에서는 이러한 log 수집 설정이나 수집 level도 apiserver manifest file에서 직접 옵션을 지정해줘야한다. 또한 설정하더라도 방대한 log에 대해 query를 통한 filtering을 기본적으로 지원하지는 않는 걸로 알고있는데, EKS는 편리하게 확인할 수 있도록 query를 이용한 log 조회 기능을 CloudWatch를 통해 제공해주고 있었다.

     

     

    - Clean UP

    # CloudWatch Log group 삭제
    aws logs delete-log-group --log-group-name /aws/eks/$CLUSTER_NAME/cluster

     

     

    - Controlplane에 대한 다양한 정보 확인

    kubectl get --raw [요청할 resource 또는 endpoint]
    kubectl get --raw /api/v1/pods
    kubectl get --raw /api/v1/namespaces

    => kubectl 명령에 --raw 옵션을 사용하면 원시(무처리) API 출력을 받을 수 있다. 

     

     

     

    - metrics와 etcd database size 정보 확인

     

    Metrics For Kubernetes System Components

    System component metrics can give a better look into what is happening inside them. Metrics are particularly useful for building dashboards and alerts. Kubernetes components emit metrics in Prometheus format. This format is structured plain text, designed

    kubernetes.io

     

    kubernetes metrics:

    Cluster와 그 내부의 resource(node, pod 등)에 대한 성능 및 상태를 수집하고 표시하기 위해 사용되는 측정 지표이다. 이를 이용하여 kubernetes cluster의 monitoring과 성능분석을 진행한다.

     

    kubectl get --raw /metrics | more
    kubectl get --raw /metrics | grep -i "etcd_db_total_size_in_bytes"

    => Controlplane의 metric 정보는 위의 명령을 사용하면 확인이 가능하며(Prometheus 출력 패턴과 비슷) 해당 내용에서 etcd database size또한 확인이 가능하다. 위의 IP와 Port는 etcd에 대한 endpoint이다.

     

     


     

    Container Logging

    - AWS Certificate Manager를 통한 인증서 생성

    certificates request

    => 해당 내용 진행전 SSL 통신에 사용될 certificate가 필요했다. 다행히 AWS의 Certificate Manager로 생성한 인증서는 무료라고한다. 나는 Route 53을 통해 Domain을 구매해놨기 때문에 해당 Domain으로 request 해두었다!! 시간이 조금 걸린다(대략 10~15분??)

     

     

    => 짜잔 발급이 완료되었다.

     

     

     

    - 그럼 해당 인증서와 Domain을 이용해서 Nginx 웹서버를 배포해보겠다.

    # NGINX 웹서버 배포
    helm repo add bitnami https://charts.bitnami.com/bitnami
    
    # 사용 리전의 인증서 ARN 확인
    CERT_ARN=$(aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text)
    echo $CERT_ARN
    
    # 도메인 확인
    echo $MyDomain
    
    # 파라미터 파일 생성
    cat <<EOT > nginx-values.yaml
    service:
        type: NodePort
    
    ingress:
      enabled: true
      ingressClassName: alb
      hostname: nginx.$MyDomain
      path: /*
      annotations: 
        alb.ingress.kubernetes.io/scheme: internet-facing
        alb.ingress.kubernetes.io/target-type: ip
        alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
        alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
        alb.ingress.kubernetes.io/success-codes: 200-399
        alb.ingress.kubernetes.io/load-balancer-name: $CLUSTER_NAME-ingress-alb
        alb.ingress.kubernetes.io/group.name: study
        alb.ingress.kubernetes.io/ssl-redirect: '443'
    EOT
    cat nginx-values.yaml | yh
    
    # 배포
    helm install nginx bitnami/nginx --version 14.1.0 -f nginx-values.yaml
    
    # 확인
    kubectl get ingress,deploy,svc,ep nginx
    kubectl get targetgroupbindings # ALB TG 확인
    
    # 접속 주소 확인 및 접속
    echo -e "Nginx WebServer URL = https://nginx.$MyDomain"
    curl -s https://nginx.$MyDomain
    kubectl logs deploy/nginx -f
    
    # 반복 접속
    while true; do curl -s https://nginx.$MyDomain -I | head -n 1; date; sleep 1; done
    
    # (참고) 삭제 시
    helm uninstall nginx

    alb.ingress.kubernetes.io/load-balancer-name: $CLUSTER_NAME-ingress alb -> LoadBalancer 이름 설정 

    alb.ingress.kubernetes.io/group.name: study -> LoadBalancer Group 설정

    alb.ingress.kubernetes.io/ssl-redirect: '443' -> SSL Redirection 설정

     

     

     

    - 정상 배포 확인

    => Nginx 관련 resource들이 정상 배포되었다.

     

     

     

    - AWS GUI에서 LoadBalancer 확인

    => 위에서 생성한 ALB가 생성된 것을 확인할 수 있었으며 annotation을 통해 Redirection이 설정된 것 또한 볼 수 있었다. 나는 써본지 얼마안되서 잘몰랐지만 LoadBalancer Controller Version Up이 되면서 annotation에 명시하는 것만으로 자동적으로 80 Listener가 설정되고 Redirection도 자동으로 걸어준다고 한다.

     

     

     

    - MyDomain을 이용한 접속 시도

    접속 시도
    kubeclt logs로 접속 로그 확인

    => 정상적으로 접속이되는 것을 볼 수 있었으며 발급한 인증서 또한 Amazon에서 발급한 내용임을 확인할 수 있었다. kubeclt logs 명령을 통해 access log 또한 확인이 가능했다.

     

     

    - 하지만 어떻게 바로 access log 확인이 가능한 것일까???

     

    View container logs

     

    docs.docker.com

     

    GitHub - nginxinc/docker-nginx: Official NGINX Dockerfiles

    Official NGINX Dockerfiles. Contribute to nginxinc/docker-nginx development by creating an account on GitHub.

    github.com

    By default, docker logs shows the command’s STDOUT and STDERR. To read more about I/O and Linux, see the Linux Documentation Project article on I/O redirection.

    The official nginx image creates a symbolic link from /var/log/nginx/access.log to /dev/stdout, and creates another symbolic link from /var/log/nginx/error.log to /dev/stderr, overwriting the log files and causing logs to be sent to the relevant special device instead. See the Dockerfile.

    => container로 그를 kubectl log로 볼 수 있다는 것은 모두다 알고 있는 내용이다. 그렇다면 이게 가능한 이유는 무엇일까?? 이와 관련된 몇 가지 내용을 위에 적어두었다. 요약하자면, docker log 명령은 STDOUT, STDERR로 표시된다고 한다. 또한 nginx의 image의 경우 /var/log/nginx/access.log에서 /dev/stdout으로 심볼링 링크를 생성하고 /var/log/nginx/error.log에서 /dev/stderr로 심볼릭링크를 생성해 로그를 덮어쓴다고한다. 

     

    => 그렇다면 nginx image에 해당 내용이 존재할 것이다.

     

     

     

    Nginx image와 Dockerfile 살펴보기

    kubectl run test --image=nginx
    kubectl exec -it test -- ls -al /var/log/nginx

    생성된 nginx container 내의 STDOUT, STDERR 심볼릭링크 확인

     

    Docker 공식문서에서 말한 것 처럼 심볼릭링크가 걸려있었다. 이번에는 Dockerfile을 확인해보자. Docker history로도 대략적인 file을 확인할 수 있다. 아래는 내가 만든 스크립트이다. 

     

    GitHub - k8s-ho/k8s_Kubernetes: [ 2022.11.22 Start ] Research & Dev Tools

    [ 2022.11.22 Start ] Research & Dev Tools. Contribute to k8s-ho/k8s_Kubernetes development by creating an account on GitHub.

    github.com

    => 만든 목적은 Kubernetes 환경 내의 node / pod / image 등 기본정보 매핑 출력 및 image의 취약성 수준 간략 출력, image에 대한 Dockerfile 생성 및 image 파일 생성을 통한 manifest file 내 취약성 확인을 위한 용도지만 어쨌던 우리가 필요한 image에 대한 Dockerfile을 생성할 수 있다.

     

     

    - Nginx docker file(위의 스크립트 결과로 나온 Dockerfile)

    Analyzing nginx
    Docker Version: 20.10.23
    GraphDriver: overlay2
    Environment Variables
    |PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    |NGINX_VERSION=1.23.4
    |NJS_VERSION=0.7.11
    |PKG_RELEASE=1~bullseye
    
    Open Ports
    |80
    
    Image user
    |User is root
    
    Potential secrets:
    Dockerfile:
    CMD ["bash"]
    LABEL maintainer=NGINX Docker Maintainers <docker-maint@nginx.com>
    ENV NGINX_VERSION=1.23.4
    ENV NJS_VERSION=0.7.11
    ENV PKG_RELEASE=1~bullseye
    RUN set -x  \
    
    	...
        생략
        ...
    
    	&& ln -sf /dev/stdout /var/log/nginx/access.log  \
    	&& ln -sf /dev/stderr /var/log/nginx/error.log  \
    	&& mkdir /docker-entrypoint.d
        
    COPY file:7b307b62e82255f040c9812421a30090bf9abf3685f27b02d77fcca99f997911 in /
    	docker-entrypoint.sh
    
    COPY file:5c18272734349488bd0c94ec8d382c872c1a0a435cca13bd4671353d6021d2cb in /docker-entrypoint.d
    	docker-entrypoint.d/
    	docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
    
    	...
        생략
        ...
        
    ENTRYPOINT ["/docker-entrypoint.sh"]
    EXPOSE 80
    STOPSIGNAL SIGQUIT
    CMD ["nginx" "-g" "daemon off;"]

    docker history

    => 결론적으로 추후 뭔가 중요 로그들을 볼 수 있도록 image를 만들 때 위의 내용처럼 STDOUT, STDERR에 심볼링 링크를 걸어서 Build하면 도움이 될 것이다.

     

     


     

    CloudWatch + Fluent Bit 

     

    Fluent DaemonSet Bit를 A로 설정하여 Logs에 CloudWatch 로그 전송 - 아마존 CloudWatch

    이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

    docs.aws.amazon.com

     

    사전 조건 확인 - 아마존 CloudWatch

    이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

    docs.aws.amazon.com

    => EKS는 CloudWatch와 Fluent Bit를 이용하여 Pod Logging이 가능하다. Fluent Bit를 Daemonset으로 배포해서 각각의 Node에 동작하도록 한다. 당연히 이게 가능하려면 IAM policy를 통한 권한이 필요하며 CloudWatchAgentServerPolicy를 사용하면 된다(AWS 공식 페이지 참고)

     

     

     

    Fluent Bit 배포하기

    kubectl apply -f https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/cloudwatch-namespace.yaml
     

    파이널라이저

    파이널라이저는 쿠버네티스가 오브젝트를 완전히 삭제하기 이전, 삭제 표시를 위해 특정 조건이 충족될 때까지 대기하도록 알려주기 위한 네임스페이스에 속한 키(namespaced key)이다. 파이널라이

    kubernetes.io

    => 해당 내용은 amazon-cloudwatch라는 namespace를 생성해준다. namespace yaml file을 보다 새롭게 알게된점은 finalizer이다. namespace 삭제 시, terminating에서 멈춰있을 때를 종종 겪어봤을텐데 이러한 이유는 잔존하는 Resource들이 해당 namespace에 아직 존재하기 때문이다. 보통은 해당 Resource들 역시 Terminating 중이며 무언가 삭제 순서가 꼬여서 발생하는 것이라고 한다.

     

     

     

    - 배포하기(위의 namespace도 포함된 YAML file) - 이걸로 배포하면됨

    FluentBitHttpServer='On'
    FluentBitHttpPort='2020'
    FluentBitReadFromHead='Off'
    FluentBitReadFromTail='On'
    curl -s https://raw.githubusercontent.com/aws-samples/amazon-cloudwatch-container-insights/latest/k8s-deployment-manifest-templates/deployment-mode/daemonset/container-insights-monitoring/quickstart/cwagent-fluent-bit-quickstart.yaml | sed 's/{{cluster_name}}/'${CLUSTER_NAME}'/;s/{{region_name}}/'${AWS_DEFAULT_REGION}'/;s/{{http_server_toggle}}/"'${FluentBitHttpServer}'"/;s/{{http_server_port}}/"'${FluentBitHttpPort}'"/;s/{{read_from_head}}/"'${FluentBitReadFromHead}'"/;s/{{read_from_tail}}/"'${FluentBitReadFromTail}'"/' | kubectl apply -f -

    수집한 Log를 CloudWatch로 전송함 -> Log Groups가 생성된 것을 확인할 수 있음

    => 공식홈페이지의 내용을 현재 생성되어있는 EKS의 환경변수에 맞게 수정한 것이다. 이를 통해 configMap과 Fluent Bit 데몬 세트를 배포한다. configMap, ClusterRole,Binding, SA, Daemonset 등이 배포되는 것을 확인할 수 있었다. 정상적으로 배포가 되었다면 각각의 Node 마다 하나씩 생성된 fluent-bit Pod를 확인할 수 있다(또한 CloudWatch에는 Fluent bit가 수집해서 전송한 로그로 LogGroup이 생성된 것도 확인이 가능했다.)

     

     

     

    - 각각의 Log Group들이 수집하는 내용은 다음과 같다.

    => 따라서 여기에 맞게 필요한 로그를 확인하면 될 것 같다. 우리는 Pod 로깅을 할 것이기 때문에 Application Group에서 확인하면 된다.

     

     

     

    - Container 로그 확인

    Pod를 생성하고 관련 Container 로그를 확인
    cloudWatch의 다양한 기능

    => 위에서 처럼 Fluent Bit가 로그를 수집해서 CloudWatch로 전송하는 설정은 배포한 내용중 configMap에서 확인이 가능하다. 또한 Worker Node에 배포된 Pod 관련로그들은 node내 /var/log/container/에 존재하게된다. 각각의 log file을 열어서 확인해보면 container내에서 동작한 로그들을 볼 수 있었다. CloudWatch GUI에서는 CLI에서 본 동일한 내용을 좀 더 보기좋게 정렬해서 볼 수 있으며 Container Insights를 통해 Container들을 구성도처럼 볼 수도 있다(자원사용률, Tx/RX 등 확인가능)

     

     


     

    [참고] Fluent bit Pod 살짝 살펴보기(설정에 취약한 부분이?!??!)

    => 짧게만 짚고 넘어가자면 Fluent bit Pod는 3주차 Storage에 언급했던 위험한 행위가 존재했다. 바로 hostPath로 "/" 디렉터리를 적용한 것이다. 하지만 그 뿐만이 아닌 docker.sock까지 mount 하고 있었다. host에서 사용하는 docker.sock가 Pod에 mount 되어있는 상태에서 악의적인 사용자가 해당 Pod에 docker만 설치할 수 있다면, mount된 dock.sock을 이용하여 host의 docker에 명령을 보낼 수 있게 된다(docker가 client-server 구조이기 때문에 가능).이는 container escape라고도 할 수 있다.

    => 예외적으로 Fluent bit Pod의 docker.sock mount에 대해서는 Pod Container에 대한 정보수집을 위해서 존재하는 부분인 것 같지만 다른 Pod였다면 위와같은이유로 여지없지 취약하다고 볼 것 같다

     

     


     

    [ kubernetes 운영 시, 배포해서 유용하게 사용할 수 있는 여러가지 기능 ]

    Kwatch 활용하기

     

    kwatch 0.8.3 · abahmed/kwatch

    monitor all changes in your Kubernetes(K8s) cluster, detects crashes in your running apps in realtime, and publishes notifications to your channels (Slack, Discord, etc.) instantly

    artifacthub.io

    # configmap 생성
    cat <<EOT > ~/kwatch-config.yaml
    apiVersion: v1
    kind: Namespace
    metadata:
      name: kwatch
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: kwatch
      namespace: kwatch
    data:
      config.yaml: |
        alert:
          slack:
            webhook: '[Slack link]'
            title: IMyoungho-EKS
            #text:
        pvcMonitor:
          enabled: true
          interval: 5
          threshold: 70
    EOT
    kubectl apply -f kwatch-config.yaml
    
    # 배포
    kubectl apply -f https://raw.githubusercontent.com/abahmed/kwatch/v0.8.3/deploy/deploy.yaml

    잘못된 Pod image를 배포한 뒤, Slack의 알림 확인

    => Kwatch는 Kubernetes Cluster의 모든 변경 사항을 모니터링하고, 실행 중인 앱의 충돌을 실시간으로 감지하며, 채널(Slack, Discord 등)에 즉시 알림을 게시하는데 사용되는 굉장히 유용한 기능이다. 추후 Kubernetes에 보안관련 개발,배포나 구축 시에 편리하게 사용할 수 있을 것 같다.

     

     

     

    BotKube 활용하기

     

    Botkube.io

    Introducing Botkube v1.0 - the future of Kubernetes Troubleshooting May 4, 2023 Something new is coming to the Botkube universe...

    botkube.io

    # repo 추가
    helm repo add botkube https://charts.botkube.io
    helm repo update
    
    # 변수 지정
    export ALLOW_KUBECTL=true
    export ALLOW_HELM=true
    export SLACK_CHANNEL_NAME=[slack 채널명]
    
    #
    cat <<EOT > botkube-values.yaml
    actions:
      'describe-created-resource': # kubectl describe
        enabled: true
      'show-logs-on-error': # kubectl logs
        enabled: true
    
    executors:
      k8s-default-tools:
        botkube/helm:
          enabled: true
        botkube/kubectl:
          enabled: true
    EOT
    
    # 설치
    helm install --version v1.0.0 botkube --namespace botkube --create-namespace \
    --set communications.default-group.socketSlack.enabled=true \
    --set communications.default-group.socketSlack.channels.default.name=${SLACK_CHANNEL_NAME} \
    --set communications.default-group.socketSlack.appToken=${SLACK_API_APP_TOKEN} \
    --set communications.default-group.socketSlack.botToken=${SLACK_API_BOT_TOKEN} \
    --set settings.clusterName=${CLUSTER_NAME} \
    --set 'executors.k8s-default-tools.botkube/kubectl.enabled'=${ALLOW_KUBECTL} \
    --set 'executors.k8s-default-tools.botkube/helm.enabled'=${ALLOW_HELM} \
    -f botkube-values.yaml botkube/botkube
    
    # 참고 : 삭제 시
    helm uninstall botkube --namespace botkube

    Slack을 통해 Kubernetes에 배포된 내용 확인가능...후덜덜..

    => BotKube 실습을 처음 접했을 때 굉장히 놀랬다. 위의 Kwatch도 굉장히 유용하지만 BotKube는 Slack을 이용해서 kubectl 명령을 보낼 수도 있게된다.. 접근성이 너무좋다... 단점이 있다면 편리한 만큼 보안 hole이 될 수도 있겠다는 생각이 들었다. 이건 위험할 수 있는 설정을 충분히 고려해보고 사용하는 것이 좋을 것 같다(하지만 너무 편할거같아...냐미다..)

     

     


     

    메트릭 시스템

     

     

    pkos 스터디 4주차 - 메트릭 오픈소스 프로메테우스

    4주 차에서는 메트릭 오픈소스인 프로메테우스 오퍼레이터를 공부했습니다. 프로메테우스 오퍼레이터를 이용하여 메트릭 수집방법과 알림기능 실습했습니다. 이번 주차에는 github copilot도움을

    malwareanalysis.tistory.com

    나는 서버나 클라우드 운영을 실무에서 해본적은 없지만 보안운영 경험이 있어 인프라팀과의 협업으로 간접적으로나마 장애에 대해 경험할 수 있었다(물론 보안솔루션에 대한 장애 경험도 있다). 때문에 이번 주차에서 진행한 모니터링, 메트릭 시스템에 대한 구축은 내가 미처 인지하지 못한 장애나, 조치가 필요한 장애를 조금 더 빠르고 편리하게 알 수 있을 것 같다.

     

    특히 Kubernetes나 Cloud 같은 MSA 아키텍처들은 굉장히 많은 종류의 리소스들과 서비스가 연동되어있어 복잡하다고 느꼈는데 장애 포인트들도 잘 잡아줄 수 있을 것 같고 성능 분석이나 확장, 축소면에서도 도움이 될 것 같다.

     

     

     

     

     

    Prometheus - stack으로 배포

    * 포함내용

     

    Push vs Pull - 모니터링 데이터 수집 방식

    모니터링 시스템은 크게 Pull/Push 방식이 있다.Push: 데이터를 가진 곳에서, 필요한 곳으로 보내준다.Pull: 데이터가 필요한 곳에서, 가진 곳에 접속하여 데이터를 긁어간다.메트릭은 중앙에서 정의

    velog.io

    Prometheus  Kubernetes Cluster와 node 등의 metrics를 수집하여 저장한다. 수집한 메트릭 데이터를 TSDB 형식으로 저장하여 PromQL로 쿼리할 수 있다.
    Prometheus target(정보를 가져오는 대상)들이 exporter를 이용해 정보를 수집해갈 수 있게 하면 Prometheus Server가 Pull 방식으로 매트릭을 수집해 TSDB에 저장한다.
    Grafana 데이터 시각화 및 대시보드 도구로, Prometheus와 같은 데이터 소스에서 가져온 메트릭을 시각적으로 표시하고 분석할 수 있으며 다양한 그래프와 대시보드를 생성하여 모니터링 데이터를 시각화하는 기능을 가지고 있다.
    Alertmananger Prometheus와 함께 사용되며 수집된 메트릭을 분석하여 경고 rule 생성, 임계값 초과시 경고 및 알림 등의 역할. Slack이나 PagerDuty 등 다양한 채널로 경고를 전송 할 수 있다.
    Prometheus Operator Kubernetes 환경에서 Prometheus와 관련된 리소스를 쉽게 관리하기 위한 도구로 Prometheus, Alertmanager, Grafana 등의 컴포넌트를 구성하고, 관리하며, 운영하기 위한 Kubernetes Custom Resource Definitions (CRDs)를 제공하는 역할을 한다.
    # 사용 리전의 인증서 ARN 확인
    CERT_ARN=`aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text`
    echo $CERT_ARN
    
    # repo 추가
    helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
    
    # 파라미터 파일 생성
    cat <<EOT > monitor-values.yaml
    prometheus:
      prometheusSpec:
        podMonitorSelectorNilUsesHelmValues: false
        serviceMonitorSelectorNilUsesHelmValues: false
        retention: 5d
        retentionSize: "10GiB"
    
      ingress:
        enabled: true
        ingressClassName: alb
        hosts: 
          - prometheus.$MyDomain
        paths: 
          - /*
        annotations:
          alb.ingress.kubernetes.io/scheme: internet-facing
          alb.ingress.kubernetes.io/target-type: ip
          alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
          alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
          alb.ingress.kubernetes.io/success-codes: 200-399
          alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
          alb.ingress.kubernetes.io/group.name: study
          alb.ingress.kubernetes.io/ssl-redirect: '443'
    
    grafana:
      defaultDashboardsTimezone: Asia/Seoul
      adminPassword: prom-operator
    
      ingress:
        enabled: true
        ingressClassName: alb
        hosts: 
          - grafana.$MyDomain
        paths: 
          - /*
        annotations:
          alb.ingress.kubernetes.io/scheme: internet-facing
          alb.ingress.kubernetes.io/target-type: ip
          alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
          alb.ingress.kubernetes.io/certificate-arn: $CERT_ARN
          alb.ingress.kubernetes.io/success-codes: 200-399
          alb.ingress.kubernetes.io/load-balancer-name: myeks-ingress-alb
          alb.ingress.kubernetes.io/group.name: study
          alb.ingress.kubernetes.io/ssl-redirect: '443'
    
    defaultRules:
      create: false
    kubeControllerManager:
      enabled: false
    kubeEtcd:
      enabled: false
    kubeScheduler:
      enabled: false
    alertmanager:
      enabled: false
    EOT
    cat monitor-values.yaml | yh
    
    helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --version 45.27.2 \
    --set prometheus.prometheusSpec.scrapeInterval='15s' --set prometheus.prometheusSpec.evaluationInterval='15s' \
    -f monitor-values.yaml --namespace monitoring

    =>   모니터링에 필요한 Prometheus, grafana, Prometheus rule 등이 포함된 단일 chart, 즉 stack으로 제공해준다. 따라서 helm을 통해 설치 후 배포하면 된다.

     

     

    - 배포 확인

    prometheus와 grafana
    ALB와 Rule 확인

    HTTP 80으로 inbound시 HTTPS로 redirect되며 alb HTTPS:443 rule에 따라 prometheus.[domain], grafana.[domain]로 분류해서 정의되어있다.

     

     

    두 ALB 모두 위에서 작성한 파라미터 값 중, Annotations에 동일한 group을 사용했기 때문에 두 개의 ADDRESS 값이 같게된다.

     

     

    exporter 정보

    위에서 "Prometheus target들이 exporter를 이용해 정보를 수집해갈 수 있게 하면 Prometheus Server가 Pull 방식으로 매트릭을 수집해 TSDB에 저장한다."라고 한 것처럼 위에서 확인된 node의 메트릭들을 Prometheus가 수집해간다

    => node의 9100port의 /metrics를 노출시켜 http get 방식으로 수집해갈 수 있게함

     

     

     

    1- avg(rate(node_cpu_seconds_total{mode="idle"}[1m]))

    Status -> Service Discovery를 통해 자동으로 Prometheus target 대상들 발견해 정보를 수집하는 것을 확인할 수 있었으며 PromQL을 통해 전체 cluster node의 CPU 사용량 합계를 조회해 graph로도 확인해볼 수 있었다.

     

     

     


     

     

    Grafana

    직접 데이터자체를 저장하지는 않으며 다양한 데이터소스들을(prometheus 등) 시각화 해준다 - 가시화가 목적!!

    # 기본 계정
    admin / prom-operator

    grafana connection 확인
    nslookup으로 해당 url 확인

    => 현재 Prometheus 데이터 소스가 기본적으로 연동되어있는 것을 확인할 수 있었고 Prometheus 아래에 작성된 주소는 Grafana가 Prometheus를 바라보는 service object(clusterIP)의 Domain 주소인 것도 확인할 수 있었다.

     

     

     

    다양한 Grafana Dashboard 적용하기

     

    dotdc Dashboards | Grafana Labs

    Data visualization & monitoring with support for Graphite, InfluxDB, Prometheus, Elasticsearch and many more databases

    grafana.com

    Grafana Dashboad에 ID:15757 Dashboad 적용화면

    => Grafana 대시보드 적용은 굉장히 간단한게 만들어져있다. 공식 대시보드 페이지에서 원하는 대시보드의 ID만 입력하면 위의 사진처럼 적용이 가능하다.

     

     

     

    Nginx 웹 서버 배포 및 애플리케이션 모니터링 설정 및 접속

    cat <<EOT > ~/nginx_metric-values.yaml
    metrics:
      enabled: true
    
      service:
        port: 9113
    
      serviceMonitor:
        enabled: true
        namespace: monitoring
        interval: 10s
    EOT
    
    helm upgrade nginx bitnami/nginx --reuse-values -f nginx_metric-values.yaml

    => Nginx는 위의 Container Logging 실습에서 사용했던 것을 가지고 진행하였다. 기존의 설정으로는 모니터링 Dashboard를 이용할 수 없어서 nginx helm chart의 metrics 기능을 enable 해주고 helm upgrade를 진행해주었다.

     

     

     

    => 생성된 Pod를 살펴보면 기존에 1개였던 container가 2개인 것을 볼 수 있는데 kubectl describe로 자세히 확인해보자.

     

     

     

    Pod Container를 통한 exporter 확인 및 prometheus target 확인 
    grafana Dashboard(12708)

    => 이는 sidecar 패턴의 Pod로 Promethues가 metrics를 수집할 수 있게해주는 exporter container임을 알 수 있었다. 이를 통해 Prometheus의 Service Discovery가 확인하고 Prometheus GUI의 status -> targert에 잡혀있는 것 또한 확인할 수 있었다. grafana에서도 ID 12708 nginx 모니터링 DashBoard로 확인이 가능하다.

     

     

     

     

    Kubecost

    kubernetes Resource별 비용 분석 및 분류 가시화를 제공해주는 기능을 가진 오픈소스 도구이다.

     

    Amazon EKS Integration - Kubecost Documentation

    On the Amazon EKS cluster with mixed processor architecture worker nodes (AMD64, ARM64), this parameter can be used to schedule Kubecost deployment on ARM-based worker nodes: --set nodeSelector."beta\\.kubernetes\\.io/arch"=arm64

    docs.kubecost.com

    kubectl get sc
    cat <<EOT > gp3-sc.yaml
    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      name: gp3
    allowVolumeExpansion: true
    provisioner: ebs.csi.aws.com
    volumeBindingMode: WaitForFirstConsumer
    parameters:
      type: gp3
      allowAutoIOPSPerGBIncrease: 'true'
      encrypted: 'true'
    EOT
    kubectl apply -f gp3-sc.yaml
    kubectl get sc
    
    
    cat <<EOT > cost-values.yaml
    global:
      grafana:
        enabled: true
        proxy: false
    
    priority:
      enabled: false
    networkPolicy:
      enabled: false
    podSecurityPolicy:
      enabled: false
    
    persistentVolume:
        storageClass: "gp3"
    
    prometheus:
      kube-state-metrics:
        disabled: false
      nodeExporter:
        enabled: true
    
    reporting:
      productAnalytics: true
    EOT
    
    
    # 배포
    kubectl create ns kubecost
    helm install kubecost oci://public.ecr.aws/kubecost/cost-analyzer --version 1.103.2 --namespace kubecost -f cost-values.yaml
    
    
    # kubecost-cost-analyzer 파드 IP변수 지정 및 접속 확인
    CAIP=$(kubectl get pod -n kubecost -l app=cost-analyzer -o jsonpath={.items[0].status.podIP})
    curl -s $CAIP:9090
    
    
    # 외부에서 bastion EC2 접속하여 특정 파드 접속 방법 : socat(SOcket CAT) 활용
    yum -y install socat
    socat TCP-LISTEN:80,fork TCP:$CAIP:9090
    웹 브라우저에서 bastion EC2 IP로 접속

    => 나의 경우 직무상 클라우드나 kubernetes 실무를 경험해보지 못했지만 스터디를 같이 하시는 실무자 분들이 자주 하시는 말들 중 하나가 바로 비용 절감이다. Kubecost는 비용 측정, 비용예상, 비용절감까지 실시간으로 제시를 해주고 있다. 때문에 예산에 대해서도 어느정도 측정할 수 있어 뭔가 마음이 편안해지는(?) 좋은 오픈소스를 get 한 것 같다!!ㅎㅎ

    반응형

    댓글

Designed by Tistory.