'Server/AWS'에 해당하는 글 48건

EKS 버전 업그레이드 (1.28 -> 1.31) 후에 대표 관리자를 제외한 부 관리자들이 EKS 모니터링 실행에 실패하는 현상이 나타났고, 실패 로그는 아래와 같았다.

 

Proxy request for clusterId="11115f91f1f9e3f0c97e4c3692f41111" to url="/apis/metrics.eks.amazonaws.com/v1" has statusCode=401
Proxy request for clusterId="11115f91f1f9e3f0c97e4c3692f41111" to url="/apis/metrics.eks.amazonaws.com/v1" failed with UNAUTHORIZED

 

aws-auth ConfigMap 에는 기존 버전 그대로 해당 사용자들의 권한이 명시되어 있었다.

 

  mapUsers: |
    - groups:
      - system:masters
      userarn: arn:aws:iam::111151101111:user/honggildong

 

 

다른 모든 api 권한은 문제가 없는데, 제어 플레인 (control plane) 메트릭 가져오는 api 만 인증되지 않았다는게 당최 어디서 설정을 해야 하는건지...

 

그렇게 찾다보니, EKS 액세스 관리 제어에 관련된 AWS 기술 블로그를 찾았다.
https://aws.amazon.com/ko/blogs/tech/a-deep-dive-into-simplified-amazon-eks-access-management-controls/

 

간소화된 Amazon EKS 액세스 관리 제어 톺아보기 | Amazon Web Services

본 블로그 포스트는 Sheetal Joshi, Rodrigo Bersa, Mike Stefaniak 님의 영문 블로그를 원문으로 한글 번역된 블로그 입니다.  소개 초기 Amazon Elastic Kubernetes Service (Amazon EKS) 출시 이후 클러스터에서 인증할

aws.amazon.com

 

기존의 액세스 권한 부여 방식이 복잡했기 때문에, 액세스 관리 제어 기능을 통해 AuthN(인증) / AuthZ(권한) 부분을 간소화 하였다는 내용이다.

 

EKS 관리 제어에 두가지 용어가 추가됐다.
- 액세스 항목(access entries) : IAM 사용자나 역할에 연결되어 EKS 클러스터를 인증 (AuthN)
- 액세스 정책(access policy) : 특정 클러스터 작업에 대한 EKS 만의 권한 부여 (AuthZ)

 

액세스 항목 + 액세스 정책 대신 기존의 RBAC(Role-Based Access Control: 역할 기반 액세스 제어) 의 권한 부여(ClusterRoleBinding) 와 결합하는 것도 가능하다.

 

 

 

특정 클러스터에의 사용자에게 권한을 주려면 액세스 항목에 IAM 사용자나 역할로 생성하고, 정책을 할당하여 특정 권한을 부여하는 프로세스 이다. (기존에는 위 예제처럼 ConfigMap 에 IAM 정보와 권한을 부여할 group 을 설정했었다.) 이 기능이 2024년 7월 경 오픈되었고 이 날 이후에 업그레이드된 클러스터에서는 인증/권한 설정에 대해 기존의 CONFIG_MAP, 새로운 API, 두가지 모두 사용 가능한 API_AND_CONFIG_MAP 모드를 선택하게 됐다. 이 문서에서는 기존 클러스터를 API_AND_CONFIG_MAP 인증 모드로 설정하고, 기존의 aws-auth configMap 에서 사용된 동일한 ID / 그룹을 지정하여 동등한 액세스 항목을 생성할 것을 권장하고 있다. access_entries / aws-auth 모두 설정되어 있을 경우, 우선순위는 액세스 항목 > ConfigMap 순이다. 또한 클러스터 뿐아닌 네임스페이스 레벨의 권한도 설정이 가능하다.

명령) 특정 클러스터에 IAM ARN 인증 및 권한 설정

 

$ aws eks create-access-entry --cluster-name <CLUSTER_NAME> \
  --principal-arn <IAM_PRINCIPAL_ARN>

$ aws eks associate-access-policy --cluster-name <CLUSTER_NAME> \
  --principal-arn <IAM_PRINCIPAL_ARN> \
  --policy-arn arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy
  --access-scope type=cluster

 

하지만 다 필요없고, EKS 대시보드에서 아주 간편하게 액세스 관리 제어를 설정할 수 있다...

 

 

EKS 액세스 항목에 부 관리자 IAM 설정하고, 정책(AmazonEKSClusterAdminPolicy) 연결해서 문제는 해결됐다. 하지만 위의 오류가 발생했던 이유는, 지금도 잘 모르겠다. 버전 업데이트 후에 액세스 관리 제어 설정이 안되어 있어서 configMap 에만 의존하고 있었을 것이고, ConfigMap 에 설정된 system:masters 권한이라면 기존과 동일하게 api 권한의 문제는 없었어야 했는데, 다른 api 는 다 되고 metric api 만 거부됐다는게...

 

몰라몰라~~

 

이제 aws-auth ConfigMap 에서 사용자 권한을 편집할 필요가 없어졌다. 추후 EKS 에서 ConfigMap 이 제거된다고 하니 액세스 관리 제어의 사용은 필수...

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

AWS WAF setting

Server/AWS 2024. 11. 25. 02:53

웹 공격, 특히 DDoS 대응으로 방화벽을 설치하라고 한다. (난 안전불감증으로, WAF 설치의 필요성은 못느끼고 있다.)

AWS 에서는 WAF 라는 웹 어플리케이션 방화벽 서비스를 제공한다. 고급 사양으로는 DDoS 방어에 특화된 AWS Shield, 여러 계정/리소스 관리를 간소화 하는 AWS Firewall Manager 가 있지만 생략한다. (여유자금 있으면 쓰면됨)

십수 년 전 suhosin 사용했을 때도 그렇지만, 설정을 빡세게 할수록 방화벽의 기능을 십분 활용할 수 있지만, 그렇게까지 할 필요가 있나 싶다. 공격을 완벽하게 막기란 쉽지 않고, 까딱 잘못하면 정상적인 요청마저 거부할 수도 있고, 슬프지만 내가 개발한 서비스가 누군가의 타겟이 될 정도로 인기 있지도 않기 때문이다. 참고로 20년 동안 방화벽에 대한 필요성을 느낀 적이 단 한번도 없었다. 그래도 방화벽을 달아야 하는 상황이라 아주 기본적인 설정만 해보려고 한다.

WAF 는 기본적으로, AWS 리소스 일부를 보호할 수 있으며, HTTP(S) 요청에 대한 IP / 국가 / 헤더 / 요청횟수 등으로 접근 허용이나 거부를 할 수 있다. (SQL Injection / XSS 생략) 프론트 단의 CloudFront 와 백엔드의 API 서버 중 alb 에만 방화벽을 설치해 보았다. 가장 기본적인 규칙들만 몇 개 적용하고 Bot Control / Capcha 등은 사용하지 않았다.

 

 

1. 서버 접근 패턴 파악

 

우선은 방어 전략을 짜기 전에, 해당 서버에 로그를 수집하여 패턴을 파악해 봐야 한다. 물론 처음부터 빡세게 제한하는 것도 좋지만, 이미 운영중일 경우는 기존 서비스에 장애가 발생하지 않도록 면밀히 분석해야 한다.

 

다행스럽게도 서버 대부분은 해외IP 로부터 SQL Injection / XSS 접근이 전부여서 Source IP 가 해외인 접근만 차단하는 것으로 완벽 차단이 가능했다. 사실 그것보다는 DDoS 공격에 대비하는 것이 목표라, 해외IP 차단 + 국내IP 에서 초당 100개 요청시 IP 차단 하는 Rule 로 처리하기로 했다.  

 

 

 

 

2. Rule 세팅 및 리소스 적용

 

  • Rule : 제어 규칙 생성
  • Rule Group : 재사용 가능한 사용자 정의 Rule Group 을 생성할 수 있고, AWS Marketplace 에서 유/무료 관리형 규칙 그룹을 선택할 수도 있다. (규칙 수, 복잡도에 따라 요금 증가)
  • Web ACL(제어목록) : 특정 규칙집합을 만들고 AWS 리소스를 연결하여 요청 제어 수행
    ㄴ 기본동작 (Allow / Block) 설정
    ㄴ 규칙 우선순위는 화면 위에서 아래, 낮은 숫자에서 높은 숫자 순

 

 

 

 

3. 모니터링 및 알람 설정

모니터링으로 요청에 대한 규칙 및 필터링 확인을 마쳤다면, CloudWatch 에서 특정 메트릭(예: 차단된 요청 수 - BlockedRequests)이 기준치를 초과할 때 SNS 알림을 트리거하도록 설정하여 운영하도록 한다. (알람 세팅 생략...)

 

 

 

4. 요금

(예, 관리형 규칙X, 사용자 규칙 19)

  • 웹 ACL 요금 = 5.00 USD * 1 = 5.00 USD
  • 규칙 요금 = 1.00 USD * 19(규칙) = 19.00 USD
  • 요청 요금 = 1백만 건당 0.60 USD * 1천만 건 = 6.00 USD
  • 결합된 총 요금 = 월별 30.00 USD

WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

약 1년 정도 EKS fargate + grafana 로 모니터링과 알람을 사용했다. 이왕 설치했으니까, 나름 피곤한 세팅 해가면서, 이쁘게 커스텀 잘 해왔는데, 보안 점검때마다 EKS 와 plugin 을 최신버전으로 올리는 바람에 그 때마다 Node 날아가고 전부 새로 설치+세팅 해야 한다는 점... 한번은 그냥 기분 좋게 했었는데, 두번은 못하겠다. 이게 다 fargate 를 사용해서...? AWS 의 EKS 인 만큼, AWS 안에서 모니터링과 알람을 만드는 것이 옳다고 생각하고 방법을 찾아봤다.

 

CPU / MEM / Traffic 모니터링은 기본이고, 배포시(혹은 장애시) 슬랙 알림 전송이 목표이며, 유일하게 AWS CloudWatch Container Insights 를 찾았다.

 

Container Insights 는 ECS/EKS 의 EC2/Fargate 에서 컨테이너 어플리케이션의 지표 및 로그를 수집하고 집계할 수 있다. 일반적으로 워커노드의 kubelet 이 /metrics/cadvisor 엔드포인트에서 CPU, 메모리, 디스크, 네트워크 사용량 등의 리소스 지표를 노출하는데, EKS Fargate 네트워킹 구조상 이 kubelet 에 접근이 안되기 때문에 프록시 역할을 할 ADOT(AWS Distro for OpenTelemetry 수집기를 사용하여, 워커노드의 지표 및 로그(CPU, 메모리, 트래픽) 들을 CloudWatch 로 전달한다. 그럼에도 CloudWatch 의 [향상된 관찰 기능] 은 지원되지 않는다.

 

 

 

 

ADOT Pod 생성

 

1. fargate profile 생성

 

$ kubectl create namespace fargate-container-insights
namespace/fargate-container-insights created

 

 

2. 서비스 계정 생성

 

ADOT 수집기에는 성능 로그 이벤트를 CloudWatch로 보내려면 IAM 권한이 필요하다. AWS 관리형 정책 CloudWatchAgentServerPolicy 와 연결할 역할(EKS-Fargate-ADOT-ServiceAccount-Role)을 만들고, EKS 의 서비스계정(adot-collector) 을 생성하여 연결하는 스크립트이다. YOUR-EKS-CLUSTER-NAME 과 YOUR-EKS-CLUSTER-REGION 을 적절히 수정한다.

 

$ ##!/bin/bash
CLUSTER_NAME=YOUR-EKS-CLUSTER-NAME
REGION=YOUR-EKS-CLUSTER-REGION
SERVICE_ACCOUNT_NAMESPACE=fargate-container-insights
SERVICE_ACCOUNT_NAME=adot-collector
SERVICE_ACCOUNT_IAM_ROLE=EKS-Fargate-ADOT-ServiceAccount-Role
SERVICE_ACCOUNT_IAM_POLICY=arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

$ eksctl utils associate-iam-oidc-provider \
--cluster=$CLUSTER_NAME \
--approve

$ eksctl create iamserviceaccount \
--cluster=$CLUSTER_NAME \
--region=$REGION \
--name=$SERVICE_ACCOUNT_NAME \
--namespace=$SERVICE_ACCOUNT_NAMESPACE \
--role-name=$SERVICE_ACCOUNT_IAM_ROLE \
--attach-policy-arn=$SERVICE_ACCOUNT_IAM_POLICY \
--approve

2023-11-27 22:09:08 [ℹ]  eksctl version 0.75.0
2023-11-27 22:09:08 [ℹ]  using region ap-northeast-2
2023-11-27 22:09:09 [ℹ]  1 iamserviceaccount (fargate-container-insights/adot-collector) was included (based on the include/exclude rules)
2023-11-27 22:09:09 [!]  serviceaccounts that exist in Kubernetes will be excluded, use --override-existing-serviceaccounts to override
2023-11-27 22:09:09 [ℹ]  1 task: {
    2 sequential sub-tasks: {
        create IAM role for serviceaccount "fargate-container-insights/adot-collector",
        create serviceaccount "fargate-container-insights/adot-collector",
    } }2023-11-27 22:09:09 [ℹ]  building iamserviceaccount stack "eksctl-test-addon-iamserviceaccount-fargate-container-insights-adot-collector"
2023-11-27 22:09:10 [ℹ]  deploying stack "eksctl-test-addon-iamserviceaccount-fargate-container-insights-adot-collector"
2023-11-27 22:09:10 [ℹ]  waiting for CloudFormation stack "eksctl-test-addon-iamserviceaccount-fargate-container-insights-adot-collector"
2023-11-27 22:09:26 [ℹ]  waiting for CloudFormation stack "eksctl-test-addon-iamserviceaccount-fargate-container-insights-adot-collector"
2023-11-27 22:09:43 [ℹ]  waiting for CloudFormation stack "eksctl-test-addon-iamserviceaccount-fargate-container-insights-adot-collector"
2023-11-27 22:09:43 [ℹ]  created serviceaccount "fargate-container-insights/adot-collector"

 

 

3. ADOT StatefulSet 배포

 

https://github.com/aws-observability/aws-otel-collector/blob/main/deployment-template/eks/otel-fargate-container-insights.yaml

 

파일을 다운받아, YOUR-EKS-CLUSTER-NAME 과 region=us-east-1 을 적절히 수정하여 배포한다.

 

$ kubectl apply -f eks-fargate-container-insights.yaml
clusterrole.rbac.authorization.k8s.io/adotcol-admin-role created
clusterrolebinding.rbac.authorization.k8s.io/adotcol-admin-role-binding created
configmap/adot-collector-config created
service/adot-collector-service created
statefulset.apps/adot-collector created

 

 

4. CloudWatch Log Group 확인

 

몇 분이 지나면 CloudWatch 로그 그룹에 로그가 쌓이는 것을 확인할 수 있다.
/aws/containerinsights/CLUSTER_NAME/performance

 

 

5. CloudWatch 대시보드 생성

 

Metrics > ContainerInsights 지표를 활용하여 CPU, 메모리, 트래픽 정도의 대시보드를 구현할 수 있다.
(배포 알림은 ContainerInsights 가 아닌 ALB target-group 의 HealthyHostCount 로 측정하였음. PromQL 가 없으니 잇몸으로...)

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

 

말 그대로 인스턴스를 미리 예약(구매)하는 것이다. 내가 사용할 인스턴스를 1년 이상 약정하고 그 만큼의 할인 혜택(최대75%)을 받는 것이다. 인스턴스 서비스를 제공하는 Amazon EC2, RDS, ElastiCache, OpenSearch, Redshift 등이 대상이다. 일단 인스턴스를 미리 생성해서 사용하다가, CPU/MEM 등이 적절한 인스턴스 사양을 찾아 최대한 빨리 RI 를 적용하는 것이 이득이다. 1년도 사용하지 않을 계획이라면 쳐다도 보지 않는 것이 좋다;

 

 

RI 설정

 

해당 서비스의 대시보드에 들어가면 좌측 메뉴에 예약 인스턴스(Reserved Instance), 예약 노드 등이 있는데 이곳에서 RI 를 생성하면 된다. 부수적인 옵션이 각각 있지만, 공통적으로 사용할 인스턴스 사양, 결제방법 등이 중요하다.

 

결제방법 (1년/3년)

  • 선결제 없음 : 매달 할인 받은 금액으로 결제
  • 부분 선결제 : 반 선결제 하고, 매달 할인 받은 금액 결제
  • 전체 선결제 : 즉시 전체 결제하고 1년/3년 사용

 

전체 선결제는 즉시 결제이므로 3가지 결제방법 중 할인율이 가장 크다. 선결제 없음은 초기 비용이 발생하지 않지만 3가지 결제방법 중 할인율이 가장 적다. 1년/3년을 무조건 사용할 예정이라면 전체 선결제를 선택하면 되고, 그 안에 사양 업그레이드 등 변화가 예상되는 경우는 선결제 없음을 선택하는 것이 좋다. 사용하던 하지 않던 구매하는 순간 요금은 발생되므로 주의해야... 해당 RI 가 만료되면 온디맨드 요금으로 변경되므로, 수동 재계약. (예약 구매 가능)

 

 

EC2 RI 사용 예)

 

예1) 1일부터 c5.xlarge 를 이용해오다, 15일에 해당 서비스의 ri 를 구매할 경우
 - 적용시간부터 ri 요금이 적용된다.

예2) 1일부터 c5.xlarge 를 이용해오다, 15일에 c5.2xlarge 로 교체할 경우 (인스턴스 크기 유연성: 같은 리전의 정규화 시간당 유닛만큼 할인)
 - 15일부터 사용하는 c5.2xlarge(16) 의 요금중, 기존 사용중인 c5.xlarge 의 정규화 시간당 유닛(8)만큼 할인 받고, 나머지 c5.xlarge(8) 의 온디맨드 요금 발생

예3) RI 구매했지만 서비스를 그만 사용할 경우
 - Marketplace 에 등록하여 남은 사양만큼을 타인에게 판매.

 

표준 타입이 아닌 컨버터블 타입의 RI 를 사용한다면, 다른 인스턴스 패밀리(m, x, r...), 운영 체제 또는 테넌시를 변경할 수 있는 여러가지 옵션들이 있으며 다른 RI 와 병합도 가능하다. (비싼 요금에서 싼 요금으로의 변경은 불가능하다...) 컨버터블 타입의 경우, 요구조건이 까다로워서 AWS 문서를 확인하는 편이 확실할 듯 하다. EC2 가 아닌 다른 대부분의 다른 서비스 RI 는 수정/삭제가 불가능하므로, 마찬가지로 주의해서 생성해야 한다. RDS, ElastiCache, OpenSearch, Redshift...

 

 

요금 비교

 

권한이 있다면(ViewBilling,ViewAccount, ...), 비용(Cost) 대시보드에서는 최근 사용해 온 서비스 들로부터 RI 권장사항도 확인할 수 있다. 또는, 본인이 사용하는 서비스의 인스턴스 사양의 온디맨드 요금과 예약 인스턴스 요금을 구글에서 검색해 본다.


예) ec2 ri 요금

 

 

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

 

Fargate 에서 실행 중인 pods 를 모니터링 할 수는 있을까.

 

초창기에 EKS 를 fargate 로 세팅한 후에 모니터링을 위해 prometheus 까지 만들어 놓으려다가, 실패하고 이제야 설치를 해봤다. 기억으로는 아마도 fargate 때문이었다. 그때까지만 해도 대부분 문서들이 전부 EC2 기반이라 삽질 조금 하다가 깔끔하게 접었었다.

 

지금은 Fargate / EC2 상관없이 AWS 에서 제공하는 AMP(Amazon Managed Service for Prometheus) 를 이용하면 쉽게 연동이 가능할 것 같은데, 역시나 서울 리전은 아직 해당 서비스를 제공하지 않는다. 그리하여 짬 내서 다시 한번 시도해 보았다.

 

일단 나는 EC2 를 쓸 생각이 없었는데, Prometheus 는 Fargate 로 설치할 수 없다. Prometheus 의 시계열 데이터베이스가 컨테이너 재시작 중에 손실되지 않도록 영구 볼륨(Persistent Volumes) 을 사용하여 Prometheus 에 지속성을 제공해야 한다. 그러려면 우선 EKS 에서 EC2 노드 그룹 (Node Group) 을 생성해야 한다.

 

 

 

1. Add Node Group

 

노드 그룹을 생성할 때는, 노드 IAM 역할(role) 을 필요로 한다.

 

IAM 대시보드에서 아래 두가지 정책을 포함하는 역할(ex. EksEC2nodeGroupRole) 을 만든다.
- AmazonEKSWorkerNodePolicy
- AmazonEC2ContainerRegistryReadOnly

 

또한, 쿠버네티스의 서비스계정에서 IAM 역할을 사용할 수 있도록 Amazon VPC CNI plugin 을 구성한다.

 

# aws-node 서비스계정 생성/업데이트
$ eksctl create iamserviceaccount \
    --name aws-node \
    --namespace kube-system \
    --cluster my-cluster \
    --role-name "AmazonEKSVPCCNIRole" \
    --attach-policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
    --override-existing-serviceaccounts \
    --approve
    
2023-01-31 17:42:15 [ℹ]  eksctl version 0.75.0
2023-01-31 17:42:15 [ℹ]  using region ap-northeast-2
2023-01-31 17:42:16 [ℹ]  1 iamserviceaccount (kube-system/aws-node) was included (based on the include/exclude rules)
2023-01-31 17:42:16 [!]  metadata of serviceaccounts that exist in Kubernetes will be updated, as --override-existing-serviceaccounts was set
2023-01-31 17:42:16 [ℹ]  1 task: {
    2 sequential sub-tasks: {
        create IAM role for serviceaccount "kube-system/aws-node",
        create serviceaccount "kube-system/aws-node",
    } }2023-01-31 17:42:16 [ℹ]  building iamserviceaccount stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-aws-node"
2023-01-31 17:42:16 [ℹ]  deploying stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-aws-node"
2023-01-31 17:42:16 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-aws-node"
2023-01-31 17:42:33 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-aws-node"
2023-01-31 17:42:49 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-aws-node"
2023-01-31 17:43:09 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-aws-node"
2023-01-31 17:43:26 [ℹ]  waiting for CloudFormation stack "eksctl-my-cluster-addon-iamserviceaccount-kube-system-aws-node"
2023-01-31 17:43:26 [ℹ]  serviceaccount "kube-system/aws-node" already exists
2023-01-31 17:43:26 [ℹ]  updated serviceaccount "kube-system/aws-node"

 

role 과 serviceAccounts 설정을 마쳤으면 eks 대시보드에서 노드 그룹을 추가/확인 한다. (node 수는 1개만 설정했다. 100G)

 

$ kubectl get pods -w -n kube-system
NAME                                            READY   STATUS    RESTARTS   AGE
aws-node-q123f                                  1/1     Running   0          4h5m
kube-proxy-abcmh                                1/1     Running   0          4h5m
...

 

EKS 콘솔의 추가기능에서 Amazon EBS CSI 드라이버(v1.23 버전부터 EC2 노드그룹 사용시 필요) 를 설치해야 하는데 IAM 역할을 미리 생성 해준다. (해당 권한이 올바로 설치되지 않으면 아래 storage 가 생성되지 못한다.)

 

$ eksctl create iamserviceaccount \
  --name ebs-csi-controller-sa \
  --namespace kube-system \
  --cluster my-cluster \
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy \
  --approve \
  --role-only \
  --role-name AmazonEKS_EBS_CSI_DriverRole

 

 

2. Prometheus 설치

 

# prometheus install
$ helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

$ helm install prometheus prometheus-community/prometheus \
     --namespace prometheus \
     --set alertmanager.persistentVolume.storageClass="gp2" \
     --set server.persistentVolume.storageClass="gp2"

NAME: prometheus
LAST DEPLOYED: Tue Jan 31 13:04:08 2023
NAMESPACE: prometheus
STATUS: deployed
REVISION: 1
NOTES:
The Prometheus server can be accessed via port 80 on the following DNS name from within your cluster:
prometheus-server.prometheus.svc.cluster.local


Get the Prometheus server URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace prometheus port-forward $POD_NAME 9090


The Prometheus alertmanager can be accessed via port  on the following DNS name from within your cluster:
prometheus-%!s(<nil>).prometheus.svc.cluster.local


Get the Alertmanager URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus,component=" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace prometheus port-forward $POD_NAME 9093
#################################################################################
######   WARNING: Pod Security Policy has been disabled by default since    #####
######            it deprecated after k8s 1.25+. use                        #####
######            (index .Values "prometheus-node-exporter" "rbac"          #####
###### .          "pspEnabled") with (index .Values                         #####
######            "prometheus-node-exporter" "rbac" "pspAnnotations")       #####
######            in case you still need it.                                #####
#################################################################################


The Prometheus PushGateway can be accessed via port 9091 on the following DNS name from within your cluster:
prometheus-prometheus-pushgateway.prometheus.svc.cluster.local


Get the PushGateway URL by running these commands in the same shell:
  export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus-pushgateway,component=pushgateway" -o jsonpath="{.items[0].metadata.name}")
  kubectl --namespace prometheus port-forward $POD_NAME 9091

For more information on running Prometheus, visit:
https://prometheus.io/

 

모니터링은 내부에서만 사용할 예정이라 기본사양인 gp2 EBS 볼륨을 사용했으며, alertmanager 용 2G / server 용 8G 볼륨이 생성된다.

 

# check prometheus pods
$ kubectl get all -n prometheus
NAME                                                    READY   STATUS    RESTARTS   AGE
pod/prometheus-alertmanager-0                           1/1     Running   0          85s
pod/prometheus-kube-state-metrics-7cdcf7cc98-m7n9q      1/1     Running   0          85s
pod/prometheus-prometheus-node-exporter-552n8           0/1     Pending   0          85s
pod/prometheus-prometheus-node-exporter-5hkjp           0/1     Pending   0          84s
pod/prometheus-prometheus-node-exporter-5k54s           0/1     Pending   0          85s
pod/prometheus-prometheus-node-exporter-77gsb           1/1     Running   0          84s
pod/prometheus-prometheus-node-exporter-9ckh5           1/1     Running   0          85s
pod/prometheus-prometheus-node-exporter-gtvht           0/1     Pending   0          85s
pod/prometheus-prometheus-node-exporter-hxkn6           0/1     Pending   0          84s
pod/prometheus-prometheus-node-exporter-rxl4b           0/1     Pending   0          85s
pod/prometheus-prometheus-node-exporter-xr468           0/1     Pending   0          85s
pod/prometheus-prometheus-node-exporter-zqxrm           0/1     Pending   0          85s
pod/prometheus-prometheus-pushgateway-9d598d466-844ct   1/1     Running   0          85s
pod/prometheus-server-6487b794-qtddq                    2/2     Running   0          85s

NAME                                          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
service/prometheus-alertmanager               ClusterIP   172.20.40.182    <none>        9093/TCP   85s
service/prometheus-alertmanager-headless      ClusterIP   None             <none>        9093/TCP   85s
service/prometheus-kube-state-metrics         ClusterIP   172.20.106.187   <none>        8080/TCP   85s
service/prometheus-prometheus-node-exporter   ClusterIP   172.20.144.95    <none>        9100/TCP   85s
service/prometheus-prometheus-pushgateway     ClusterIP   172.20.17.45     <none>        9091/TCP   85s
service/prometheus-server                     ClusterIP   172.20.39.89     <none>        80/TCP     85s

NAME                                                 DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/prometheus-prometheus-node-exporter   10        10        2       10           2           <none>          85s

NAME                                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/prometheus-kube-state-metrics       1/1     1            1           85s
deployment.apps/prometheus-prometheus-pushgateway   1/1     1            1           85s
deployment.apps/prometheus-server                   1/1     1            1           85s

NAME                                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/prometheus-kube-state-metrics-7cdcf7cc98      1         1         1       86s
replicaset.apps/prometheus-prometheus-pushgateway-9d598d466   1         1         1       86s
replicaset.apps/prometheus-server-6487b794                    1         1         1       86s

NAME                                       READY   AGE
statefulset.apps/prometheus-alertmanager   1/1     86s

 

만약 alertmanager 가 Pending 상태라면 prometheus uninstall 후에, 해당 EBS 볼륨(아마도 2G)도 직접 삭제하고, pvc 도 조회하여 삭제한다. (kubectl delete pvc name -n namespace)... prometheus uninstall 때 기존 alertmanager 관련 볼륨정보가 삭제되지 않는듯... 여러번 설치테스트 하다가 이것 때문에 삽질 좀 했다.

 

0/9 nodes are available: 1 node(s) had volume node affinity conflict, 8 node(s) had taint {eks.amazonaws.com/compute-type: fargate}, that the pod didn't tolerate.

 

또한 node-exporter 는 ec2 노드에서 작동하는 daemonset 으로 실행되지만 이미 생성된 fargate 노드들이 daemonset 을 지원하지 않기 때문에 fargate 에서 schedule 을 수행할 수 없다. node-exporter 의 역할은 실행중인 node에 배치되어 해당 호스트의 low-level 매트릭(vCPU, Mem, Network, Disk) 수집을 담당하는데, kube-state-metrics 가 이 메트릭을 대신 수집해 주어 node-exporter 없이도 지표 수집이 가능한 것 같아, node-exporter 를 전부 삭제했다.

 

# node-exporter 삭제
$ kubectl delete daemonset prometheus-prometheus-node-exporter -n prometheus

 

 

3. prometheus URL 접속 확인 (선택)

 

# Prometheus server URL
$ export POD_NAME=$(kubectl get pods --namespace prometheus -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}")
# 127.0.0.1:9090
$ kubectl --namespace prometheus port-forward $POD_NAME 9090

# Alertmanager URL
$ export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=alertmanager" -o jsonpath="{.items[0].metadata.name}")
# 127.0.0.1:9093
$ kubectl --namespace prometheus port-forward $POD_NAME 9093

# PushGateway URL 
$ export POD_NAME=$(kubectl get pods --namespace prometheus -l "app.kubernetes.io/name=prometheus-pushgateway" -o jsonpath="{.items[0].metadata.name}")
# 127.0.0.1:9091
$ kubectl --namespace prometheus port-forward $POD_NAME 9091

 

 

 

4. Grafana 설치

 

$ vi grafana.yaml
datasources:
  datasources.yaml:
    apiVersion: 1
    datasources:
    - name: Prometheus
      type: prometheus
      url: http://prometheus-server.prometheus.svc.cluster.local
      access: proxy
      isDefault: true


# grafana install
$ helm repo add grafana https://grafana.github.io/helm-charts
$ helm install grafana grafana/grafana \
    --namespace prometheus \
    --set persistence.storageClassName="gp2" \
    --set persistence.enabled=true \
    --set adminPassword='admin_password' \
    --values ./grafana.yaml \
    --set service.type=LoadBalancer

W0131 18:50:26.890856   44556 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0131 18:50:27.492718   44556 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
NAME: grafana
LAST DEPLOYED: Tue Jan 31 18:50:26 2023
NAMESPACE: prometheus
STATUS: deployed
REVISION: 1
NOTES:
1. Get your 'admin' user password by running:

   kubectl get secret --namespace prometheus grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo

2. The Grafana server can be accessed via port 80 on the following DNS name from within your cluster:

   grafana.prometheus.svc.cluster.local

   Get the Grafana URL to visit by running these commands in the same shell:
   NOTE: It may take a few minutes for the LoadBalancer IP to be available.
        You can watch the status of by running 'kubectl get svc --namespace prometheus -w grafana'
     export SERVICE_IP=$(kubectl get svc --namespace prometheus grafana -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
     http://$SERVICE_IP:80

3. Login with the password from step 1 and the username: admin

 

 

grafana 설치 확인

 

# Grafana URL 
$ kubectl get svc --namespace prometheus grafana -o jsonpath='{.status.loadBalancer.ingress[0].hostname}'
abc29d87564994207b5dfb965886a11e-1234385928.ap-northeast-2.elb.amazonaws.com

 

 

 

[ dashboard id: 12006 ]

 

 

 

# 만약 망했으면 uninstall 하고 처음부터 다시 try...
$ helm uninstall prometheus --namespace prometheus
$ helm uninstall grafana --namespace prometheus

 

삭제되지 않은 볼륨들도 모두 삭제한다.

 

대부분의 쿠버네티스 스펙이 helm 으로 한방에 설치되니까 편하긴 한듯...

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,