IT STUDY LOG
Sprint - 모니터링 시스템 구축 본문
#해결 과제
💡 Prometheus Operator가 설치된 환경에서 nginx 인그레스 컨트롤러를 설치
💡 cozserver (v2)의 디플로이먼트 및 서비스를 배포하고, 인그레스를 만들어서 nginx를 통해 서비스에 접근하도록 설정
💡 Prometheus에서 쿼리를 통해 주요 메트릭을 확인
💡 Grafana에 이미 존재하는 대시보드들을 살펴보고, 어떤 쿼리를 사용하는지 확인
#과제 항목별 진행 상황
✏️ helm을 이용해 nginx 인그레스 컨트롤러 설치
- nginx 인그레스 컨트롤러가 프로메테우스용 메트릭을 노출할 수 있도록 환경 설정 (참고 레퍼런스 : 레퍼런스, 레퍼런스2)
Step 1 : helm 패키지 매니저로 nginx ingress controller 설치
# nginx controller를 helm repo를 이용해 다운로드
$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
$ helm repo update
# 프로메테우스 메트릭스 노출 설정 후 nginx 설치
$ helm install ingress-nginx ingress-nginx/ingress-nginx \
--set controller.metrics.enabled=true \
--set controller.metrics.serviceMonitor.enabled=true
NAME: ingress-nginx
LAST DEPLOYED: Fri Jun 2 17:21:12 2023
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
The ingress-nginx controller has been installed.
It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status by running 'kubectl --namespace default get services -o wide -w ingress-nginx-controller'
An example Ingress that makes use of the controller:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example
namespace: foo
spec:
ingressClassName: nginx
rules:
- host: www.example.com
http:
paths:
- pathType: Prefix
backend:
service:
name: exampleService
port:
number: 80
path: /
# This section is only required if TLS is to be enabled for the Ingress
tls:
- hosts:
- www.example.com
secretName: example-tls
If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided:
apiVersion: v1
kind: Secret
metadata:
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls
Step 2 : 프로메테우스 웹 UI (http://localhost:9090)에서 ingress-nginx-controller가 Target으로 설정되었는지 확인
- 사전에 kubectl 명령어를 통해 port-forward 필요
# 프로메테우스 노출
$ kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
# 그라파나 노출
$ kubectl --namespace monitoring port-forward svc/grafana 3000
✏️ 인그레스 생성
Step 0 : 아키텍처
Step 1 : 디플로이먼트, 서비스 배포 후 ingress 생성
(1) 디플로이먼트, 서비스, 인그레스 yaml 파일 작성
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: cozserver
namespace: default
labels:
app: cozserver
spec:
selector:
matchLabels:
app: cozserver
replicas: 3
minReadySeconds: 10
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: cozserver
spec:
containers:
- name: nodejs
image: sebcontents/cozserver:2.0
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: cozserver
namespace: default
spec:
selector:
app: cozserver
type: ClusterIP # NOT LoadBalancer
ports:
- name: cozserver
protocol: TCP
port: 8055
targetPort: 8080
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cozserver
annotations:
kubernetes.io/ingress.class: "nginx" # ingress class를 명시해주어야 함
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: localhost # nginx ingress controller에서 인그레스 리소스를 정의할 때 이 host필드는 필수
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: cozserver
port:
number: 8055
(2) 디플로이먼트, 서비스, 인그레스 배포
# 디플로이먼트 배포
$ kubectl apply -f cozserver-deployment-v2.yaml --record
deployment.apps/cozserver created
# 서비스 배포
$ kubectl apply -f cozserver-service.yaml
service/cozserver created
# 인그레스 배포
$ kubectl apply -f cozserver-ingress.yaml
ingress.networking.k8s.io/cozserver created
Step 2 : 포트포워딩을 통해 호스트 PC에서 인그레스에 접근 허용
$ sudo kubectl port-forward service/ingress-nginx-controller 80 &
Step 3 : 해당 네임스페이스의 클러스터에 실행된 디플로이먼트, 서비스, 인그레스 확인
$ kubectl get all,ingresses --namespace="default"
NAME READY STATUS RESTARTS AGE
pod/cozserver-7dcc7c99b7-ffpc9 1/1 Running 0 18m
pod/cozserver-7dcc7c99b7-l9622 1/1 Running 0 18m
pod/cozserver-7dcc7c99b7-sbwwx 1/1 Running 0 18m
pod/ingress-nginx-controller-5988bbb6b-r2v56 1/1 Running 0 22m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cozserver ClusterIP 10.105.185.120 <none> 8055/TCP 17m
service/ingress-nginx-controller LoadBalancer 10.100.241.249 <pending> 80:32213/TCP,443:31440/TCP 22m
service/ingress-nginx-controller-admission ClusterIP 10.101.10.117 <none> 443/TCP 22m
service/ingress-nginx-controller-metrics ClusterIP 10.96.128.235 <none> 10254/TCP 22m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 32m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/cozserver 3/3 3 3 18m
deployment.apps/ingress-nginx-controller 1/1 1 1 22m
NAME DESIRED CURRENT READY AGE
replicaset.apps/cozserver-7dcc7c99b7 3 3 3 18m
replicaset.apps/ingress-nginx-controller-5988bbb6b 1 1 1 22m
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/cozserver <none> localhost 80 10m
sprint-k8s-rollout-reference $ git:(reference) $ Handling connection for 80
✏️ 인그레스 접속 로그가 찍히는지 프로메테우스를 통해 확인
Step 1 : http://localhost로 접속해 인그레스를 통해 cozserver에 접속
Step 2 : 프로메테우스 웹 UI Graph 에서 각종 쿼리 수행 (SRE의 네 가지의 황금 시그널을 보기 위해 필요한 메트릭 조회)
(1) nginx_ingress_controller_requests : 트래픽, 오류 확인
(2) nginx_ingress_controller_request_duration_seconds_count : 대기 시간
(3) nginx_ingress_controller_request_duration_seconds_bucket : 대기 시간
(4) node_cpu_seconds_total : 포화 수준
Step 3 : 프로메테우스가 지원하는 PromQL을 통해 다음과 같이 복잡한 지표를 표현 가능
(1) 1시간 동안 인그레스 컨트롤러를 통해 들어온 요청의 누적 비율
sum(rate(
nginx_ingress_controller_requests[1h]
))
by (ingress)
(2) 1시간 동안 모든 요청 중 400번대 에러의 비율
sum(rate(
nginx_ingress_controller_requests{
status=~"4.."
}[1h]
))
by (ingress) /
sum(rate(
nginx_ingress_controller_requests[1h]
))
by (ingress)
✏️ Grafana의 대시보드 살펴보기
Step 1 : grafana의 대시보드에서 쿼리 수행
Step 2 : 커뮤니티에서 만들어놓은 대시보드를 Import 해보기
(0) grafana dash 보드 import하는 방법
- 대시보드에서 new > import
- json 파일을 업로드하거나, grafana.com의 dashboard id를 입력하거나, 직접 json을 입력해 dashboard 로드
- data source로 프로메테우스를 선택 후 import
#TROUBLE SHOOTING LOG
📝 문제 1 : nginx 404 not found
- 원인 : ingress class name을 명시적으로 지정해주지 않아 발생한 문제
- 해결 방안 : ingress.yaml 파일에 ingress-controller pod의 class name과 동일한 ingress class name을 명시
$ kubectl describe pod ingress-nginx-controller-5988bbb6b-r2v56
Name: ingress-nginx-controller-5988bbb6b-r2v56
Namespace: default
# ... 중략 ... #
Containers:
controller:
Container ID: docker://bb3d562c924cb3b9570cb7de4dd1fd6d401d2e1ea3ac53b3c6c3a71ac40beb1c
Image: registry.k8s.io/ingress-nginx/controller:v1.8.0@sha256:744ae2afd433a395eeb13dc03d3313facba92e96ad71d9feaafc85925493fee3
Image ID: docker-pullable://registry.k8s.io/ingress-nginx/controller@sha256:744ae2afd433a395eeb13dc03d3313facba92e96ad71d9feaafc85925493fee3
Ports: 80/TCP, 443/TCP, 10254/TCP, 8443/TCP
Host Ports: 0/TCP, 0/TCP, 0/TCP, 0/TCP
Args:
/nginx-ingress-controller
--publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
--election-id=ingress-nginx-leader
--controller-class=k8s.io/ingress-nginx
--ingress-class=nginx # ingress-class명
--configmap=$(POD_NAMESPACE)/ingress-nginx-controller
--validating-webhook=:8443
--validating-webhook-certificate=/usr/local/certificates/cert
--validating-webhook-key=/usr/local/certificates/key
# ... 하략 ... #
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cozserver
annotations:
kubernetes.io/ingress.class: "nginx" # ingress class를 명시
# ... 하략 ...#
- 참고
- 쿠버네티스 1.18에 IngressClass 리소스 및 ingressClassName 필드가 추가되기 전에 인그레스 클래스는 인그레스에서 kubernetes.io/ingress.class 어노테이션으로 지정되었으나 앞으로 사라질 어노테이션임
- kubernetes.io/ingress.class 어노테이션은 일반적으로 인그레스를 구현해야 하는 인그레스 컨트롤러의 이름을 참조하는 데 사용됨
- 인그레스의 최신 ingressClassName 필드는 kubernetes.io/ingress.class 어노테이션을 대체하나 완전 동등한 것은 아님
- ingressClassName 필드는 인그레스 컨트롤러의 이름을 포함하는 추가 인그레스 구성이 포함된 인그레스 클래스 리소스를 참조
- ingressClassName을 생략하려면, 기본 인그레스 클래스가 정의되어 있어야 함(즉, 기본 인그레스 클래스가 정의되어있지 않으면 생략 불가능)
#References
https://kubernetes.io/ko/docs/concepts/services-networking/ingress/#default-ingress-class
https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressBackend
https://prometheus.io/docs/visualization/grafana/
https://grafana.com/docs/grafana/latest/dashboards/manage-dashboards/
https://grafana.com/grafana/dashboards/9614-nginx-ingress-controller/
'devops bootcamp 4 > pair/team log' 카테고리의 다른 글
Sprint - 성능 테스트를 위한 서비스 모니터링(advanced) (0) | 2023.06.08 |
---|---|
Sprint - aws EC2와 K6를 이용한 성능테스트 (0) | 2023.06.07 |
Sprint - Auto Scaling + CloudWatch를 이용한 알림 (0) | 2023.06.02 |
Sprint - 새 버전이 망가졌어요 (0) | 2023.05.19 |
Sprint - Terraform x AWS (0) | 2023.05.17 |