https://computingforgeeks.com/run-teleport-in-docker-docker-compose/

 

https://github.com/gravitational/teleport#docker

 

https://gallery.ecr.aws/gravitational/teleport

TELEPORT_DOCKER_IMAGE=public.ecr.aws/gravitational/teleport:12

mkdir -p ~/teleport/{config,data}

TELEPORT_HOSTNAME=" teleport.example.com"

###아래의 Docker run은 실제 Docker를 실행하는게 아니고 설정파일을 만드는과정으로 빠지면 안됨
docker run --hostname ${TELEPORT_HOSTNAME} --rm \
  --entrypoint=/bin/sh \
  -v ~/teleport/config:/etc/teleport \
  ${TELEPORT_DOCKER_IMAGE} -c "teleport configure > /etc/teleport/teleport.yaml"


[root@ip-10-32-1-156 teleport]# cat docker-compose.yaml
version: '3.7'
services:
  teleport:
    image: "quay.io/gravitational/teleport:12.2.5-amd64"
    container_name: teleport
    restart: always
    hostname: "teleport.sabo.sbx.infograb.io"
    volumes:
      - ./config:/etc/teleport
      - ./data:/var/lib/teleport
    ports:
      - 3023:3023
      - 3024:3024
      - 3025:2025
      - 3080:3080
      


$ docker exec teleport tctl users add admin --roles=editor,access --logins=root,ubuntu,ec2-user

 

그리고 webpage.co.kr:3080 접속하면 계정 생성 페이지로 접속된다.

 

이후 MFA 설정 하고 로그인하면 된다.

 

 

위와같이 기본적으로 localhost 연결이 가능하고 이외에 애플리케이션, 대시보드등 접근이 가능하다.

위와같이 web 브라우져에서 바로 접속이 가능하다.(인터넷만 되는 환경에서 급한 작업 있을때 유용할듯 ?)

일단 애플리케이션(웹페이지)로의 접근은 필요성이 있을것같은데 서버 관리에 필요한 ssh 접근은 흠... 세션 레코딩 기능이 참 매력적이긴 한데...

 

일단 세션 레코딩만해도 큰 메리트가 있으니까 일단 접속해보자.

macos는 brew install teleport 명령어로 teleport 설치하고 tsh 명령어로 접근이 가능하다.
근데
The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security. We recommend the use of our own Teleport packages.
라고 하니 

https://goteleport.com/download/?os=mac 에서 직접 설치해주자.

Download the MacOS .pkg installer (tsh client only, signed) and double-click to run it.

4주차는 EKS observability 이다.

 

시작.

 

로깅 대상은 컨트롤 플레인, node, 애플리케이션이 있다.

 

먼저 컨트롤 플레인 로깅이다.

현재 모든 로깅은 꺼져있는 상태

위와같이 enable 해주면

On 확인

 

# EC2 Instance가 NodeNotReady 상태인 로그 검색
fields @timestamp, @message
| filter @message like /**NodeNotReady**/
| sort @timestamp desc

# kube-apiserver-audit 로그에서 userAgent 정렬해서 아래 4개 필드 정보 검색
fields userAgent, requestURI, @timestamp, @message
| filter @logStream ~= "kube-apiserver-audit"
| stats count(userAgent) as count by userAgent
| sort count desc

#
fields @timestamp, @message
| filter @logStream ~= "**kube-scheduler**"
| sort @timestamp desc

#
fields @timestamp, @message
| filter @logStream ~= "**authenticator**"
| sort @timestamp desc

#
fields @timestamp, @message
| filter @logStream ~= "kube-controller-manager"
| sort @timestamp desc

log insights 에서 필터링하여 로그를 확인할수 있다.

 

위와같이 프로메테우스 메트릭 형태로도 볼수있다.

 

그외에도 아래 내용을 참고하여 컨트롤플래인단 로그를 확인할수 있다.

# How to monitor etcd database size? >> 아래 10.0.X.Y IP는 어디일까요? >> 아래 주소로 프로메테우스 메트릭 수집 endpoint 주소로 사용 가능한지???
**kubectl get --raw /metrics | grep "etcd_db_total_size_in_bytes"**
etcd_db_total_size_in_bytes{endpoint="<http://10.0.160.16:2379>"} 4.665344e+06
etcd_db_total_size_in_bytes{endpoint="<http://10.0.32.16:2379>"} 4.636672e+06
etcd_db_total_size_in_bytes{endpoint="<http://10.0.96.16:2379>"} 4.640768e+06

**kubectl get --raw=/metrics | grep apiserver_storage_objects |awk '$2>100' |sort -g -k 2**

# CW Logs Insights 쿼리
fields @timestamp, @message, @logStream
| filter @logStream like /**kube-apiserver-audit**/
| filter @message like /**mvcc: database space exceeded**/
| limit 10

# How do I identify what is consuming etcd database space?
**kubectl get --raw=/metrics | grep apiserver_storage_objects |awk '$2>100' |sort -g -k 2**
**kubectl get --raw=/metrics | grep apiserver_storage_objects |awk '$2>50' |sort -g -k 2**
apiserver_storage_objects{resource="clusterrolebindings.rbac.authorization.k8s.io"} 78
apiserver_storage_objects{resource="clusterroles.rbac.authorization.k8s.io"} 92

# CW Logs Insights 쿼리 : Request volume - Requests by User Agent:
fields userAgent, requestURI, @timestamp, @message
| filter @logStream like /**kube-apiserver-audit**/
| stats count(*) as count by userAgent
| sort count desc

# CW Logs Insights 쿼리 : Request volume - Requests by Universal Resource Identifier (URI)/Verb:
filter @logStream like /**kube-apiserver-audit**/
| stats count(*) as count by requestURI, verb, user.username
| sort count desc

# Object revision updates
fields requestURI
| filter @logStream like /**kube-apiserver-audit**/
| filter requestURI like /pods/
| filter verb like /patch/
| filter count > 8
| stats count(*) as count by requestURI, responseStatus.code
| filter responseStatus.code not like /500/
| sort count desc

#
fields @timestamp, userAgent, responseStatus.code, requestURI
| filter @logStream like /**kube-apiserver-audit**/
| filter requestURI like /pods/
| filter verb like /patch/
| filter requestURI like /name_of_the_pod_that_is_updating_fast/
| sort @timestamp

 

이번엔 컨테이너 로깅이다..

# 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 < 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 = "
curl -s 
kubectl logs deploy/nginx -f

# 반복 접속
while true; do curl -s  -I | head -n 1; date; sleep 1; done

# (참고) 삭제 시
helm uninstall nginx

 

위와같이 진행한다. 다만 ACM 은 인증서 따로 추가해줘야 한다.

CERT_ARN=$(aws acm list-certificates --query 'CertificateSummaryList[].CertificateArn[]' --output text) echo $CERT_ARN
이부분

 

 

위와같이 배포 완료

 

컨테이너도 위와같이 로깅을 확인할수있다.

 

이번에는 외부에서 로그를 수집하도록 하는 방법이다.

# 설치
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 -**

# 설치 확인
kubectl get-all -n amazon-cloudwatch
kubectl get ds,pod,cm,sa -n amazon-cloudwatch
kubectl describe **clusterrole cloudwatch-agent-role fluent-bit-role**                          # 클러스터롤 확인
kubectl describe **clusterrolebindings cloudwatch-agent-role-binding fluent-bit-role-binding**  # 클러스터롤 바인딩 확인
kubectl -n amazon-cloudwatch logs -l name=cloudwatch-agent -f # 파드 로그 확인
kubectl -n amazon-cloudwatch logs -l k8s-app=fluent-bit -f    # 파드 로그 확인
for node in $N1 $N2 $N3; do echo ">>>>> $node <<<<<"; ssh ec2-user@$node sudo ss -tnlp | grep fluent-bit; echo; done

# cloudwatch-agent 설정 확인
**kubectl describe cm cwagentconfig -n amazon-cloudwatch**
{
  "agent": {
    "region": "ap-northeast-2"
  },
  "logs": {
    "metrics_collected": {
      "kubernetes": {
        "cluster_name": "myeks",
        "metrics_collection_interval": 60
      }
    },
    "force_flush_interval": 5
  }
}

# CW 파드가 수집하는 방법 : Volumes에 HostPath를 살펴보자! >> / 호스트 패스 공유??? 보안상 안전한가? 좀 더 범위를 좁힐수는 없을까요?
**kubectl describe -n amazon-cloudwatch ds cloudwatch-agent**
...
ssh ec2-user@$N1 sudo tree /dev/disk
...

# Fluent Bit Cluster Info 확인
**kubectl get cm -n amazon-cloudwatch fluent-bit-cluster-info -o yaml | yh**
apiVersion: v1
data:
  cluster.name: myeks
  http.port: "2020"
  http.server: "On"
  logs.region: ap-northeast-2
  read.head: "Off"
  read.tail: "On"
kind: ConfigMap
...

# Fluent Bit 로그 INPUT/FILTER/OUTPUT 설정 확인 - [링크](<https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/Container-Insights-setup-logs-FluentBit.html#ContainerInsights-fluentbit-multiline>)
## 설정 부분 구성 : application-log.conf , dataplane-log.conf , fluent-bit.conf , host-log.conf , parsers.conf
**kubectl describe cm fluent-bit-config -n amazon-cloudwatch
...
application-log.conf**:
----
[**INPUT**]
    Name                tail
    Tag                 **application.***
    Exclude_Path        /var/log/containers/cloudwatch-agent*, /var/log/containers/fluent-bit*, /var/log/containers/aws-node*, /var/log/containers/kube-proxy*
    **Path                /var/log/containers/*.log**
    multiline.parser    docker, cri
    DB                  /var/fluent-bit/state/flb_container.db
    Mem_Buf_Limit       50MB
    Skip_Long_Lines     On
    Refresh_Interval    10
    Rotate_Wait         30
    storage.type        filesystem
    Read_from_Head      ${READ_FROM_HEAD}

[**FILTER**]
    Name                kubernetes
    Match               application.*
    Kube_URL            <https://kubernetes.default.svc:443>
    Kube_Tag_Prefix     application.var.log.containers.
    Merge_Log           On
    Merge_Log_Key       log_processed
    K8S-Logging.Parser  On
    K8S-Logging.Exclude Off
    Labels              Off
    Annotations         Off
    Use_Kubelet         On
    Kubelet_Port        10250
    Buffer_Size         0

[**OUTPUT**]
    Name                cloudwatch_logs
    Match               application.*
    region              ${AWS_REGION}
    **log_group_name      /aws/containerinsights/${CLUSTER_NAME}/application**
    log_stream_prefix   ${HOST_NAME}-
    auto_create_group   true
    extra_user_agent    container-insights
**...**

# Fluent Bit 파드가 수집하는 방법 : Volumes에 HostPath를 살펴보자!
**kubectl describe -n amazon-cloudwatch ds fluent-bit**
...
ssh ec2-user@$N1 sudo tree /var/log
...

# (참고) 삭제
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 delete -f -

우선 위와같이 설치를 진행한다.  

정상적으로 설치 완료

 

 

위와같이 fluent bit로 어떻게 가공 과정을 볼수있다.

 

 

콘솔에서도 로그 확인

Insights 항목에서도 여러 항목 모니터링 가능

 

이번에는 모니터링을하기위한 메트릭수집 도구들을 알아볼것이다.

 

 

# 배포
**kubectl apply -f <https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml**>

# 메트릭 서버 확인 : 메트릭은 15초 간격으로 cAdvisor를 통하여 가져옴
kubectl get pod -n kube-system -l k8s-app=metrics-server
kubectl api-resources | grep metrics
kubectl get apiservices |egrep '(AVAILABLE|metrics)'

# 노드 메트릭 확인
kubectl top node

# 파드 메트릭 확인
kubectl top pod -A
kubectl top pod -n kube-system --sort-by='cpu'
kubectl top pod -n kube-system --sort-by='memory'

메트릭서버 설치방법(만 알아본다.)

 

kwatch라는것도 있다. 이걸로 slack 웹훅을 걸어줄수있다.

 

# configmap 생성
cat < ~/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: '**<https://hooks.slack.com/services/T03G23CRBNZ/sssss/sss**>'
        title: $NICK-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**>

botube라는 도구도 있다.

 

 

# repo 추가
helm repo add botkube <https://charts.botkube.io>
helm repo update

# 변수 지정
export ALLOW_KUBECTL=true
export ALLOW_HELM=true
export SLACK_CHANNEL_NAME=webhook3

#
cat < 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
# 연결 상태, notifications 상태 확인
**@Botkube** ping
**@Botkube** status notifications

# 파드 정보 조회
**@Botkube** k get pod
**@Botkube** kc get pod --namespace kube-system
**@Botkube** kubectl get pod --namespace kube-system -o wide

# Actionable notifications
**@Botkube** kubectl

botkube의 장점은 슬랙과 연동하여 @Botkube로 슬랙의 지정채널에서 파드의 정보를 불러오는등 슬랙에서 클러스터 정보 확인이 가능한장점이 있다. 

 

자 이제 마지막으로 프로메테우스&그라파나이다.

 

프로메테우스 오퍼레이터 : 프로메테우스 및 프로메테우스 오퍼레이터를 이용하여 메트릭 수집과 알람 기능 실습
https://malwareanalysis.tistory.com/566

Thanos 타노드 : 프로메테우스 확장성과 고가용성 제공
https://hanhorang31.github.io/post/pkos2-4-monitoring/

 

 

프로메테우스란

  •  

제공 기능

  • a multi-dimensional data model with time series data(=TSDB, 시계열 데이터베이스) identified by metric name and key/value pairs
  • PromQL, a flexible query language to leverage this dimensionality
  • no reliance on distributed storage; single server nodes are autonomous
  • time series collection happens via a pull model over HTTP
  • pushing time series is supported via an intermediary gateway
  • targets are discovered via service discovery or static configuration
  • multiple modes of graphing and dashboarding support

설치 방법은 아래와 같다.

# 모니터링
kubectl create ns monitoring
watch kubectl get pod,pvc,svc,ingress -n monitoring

# 사용 리전의 인증서 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 < 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

# alertmanager:
#   ingress:
#     enabled: true
#     ingressClassName: alb
#     hosts: 
#       - alertmanager.$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'
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

# 확인
~~## alertmanager-0 : 사전에 정의한 정책 기반(예: 노드 다운, 파드 Pending 등)으로 시스템 경고 메시지를 생성 후 경보 채널(슬랙 등)로 전송~~
## grafana : 프로메테우스는 메트릭 정보를 저장하는 용도로 사용하며, 그라파나로 시각화 처리
## prometheus-0 : 모니터링 대상이 되는 파드는 ‘exporter’라는 별도의 사이드카 형식의 파드에서 모니터링 메트릭을 노출, pull 방식으로 가져와 내부의 시계열 데이터베이스에 저장
## node-exporter : 노드익스포터는 물리 노드에 대한 자원 사용량(네트워크, 스토리지 등 전체) 정보를 메트릭 형태로 변경하여 노출
## operator : 시스템 경고 메시지 정책(prometheus rule), 애플리케이션 모니터링 대상 추가 등의 작업을 편리하게 할수 있게 CRD 지원
## kube-state-metrics : 쿠버네티스의 클러스터의 상태(kube-state)를 메트릭으로 변환하는 파드
helm list -n monitoring
kubectl get pod,svc,ingress -n monitoring
kubectl get-all -n monitoring
**kubectl get prometheus,servicemonitors -n monitoring**
~~~~**kubectl get crd | grep monitoring**

 

위와같이 설치 완료

 

프로메테우스 메트릭 수집정보를 확인해보자.

노드의 정보를 가져오는 노드 익스포터라는 파드가 올라온것을 확인할수있다.

 

위 메트릭들을 수집한다.

 

프로메테우스가 수집할 타겟들

 

아까 봤떤 노드 익스포터

 

그라파나 확인

다른 사용자가 만들어둔 여러가지 대시보드들이 있다.

공식 대시보드 가져오기 - 링크 추천

  • [Kubernetes / Views / Global] Dashboard → New → Import → 15757 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • [1 Kubernetes All-in-one Cluster Monitoring KR] Dashboard → New → Import → 13770 or 17900 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • [Node Exporter Full] Dashboard → New → Import → 1860 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • kube-state-metrics-v2 가져와보자 : Dashboard ID copied! (13332) 클릭 - 링크
    • [kube-state-metrics-v2] Dashboard → New → Import → 13332 입력 후 Load ⇒ 데이터소스(Prometheus 선택) 후 Import 클릭
  • [Amazon EKS] **AWS CNI Metrics 16032 - 링크

 

 

위 항목에서 Dashboard 임폴트가 가능하다.

 

임폴트한 대시보드 화면

 

그럼 마지막으로 아까 배포한 Nginx 파드의 여러가지 정보를 모니터링해보자.

 

# 모니터링
watch -d kubectl get pod

# 파라미터 파일 생성 : 서비스 모니터 방식으로 nginx 모니터링 대상을 등록하고, export 는 9113 포트 사용, nginx 웹서버 노출은 AWS CLB 기본 사용
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

# 확인
kubectl get pod,svc,ep
kubectl get servicemonitor -n monitoring nginx
kubectl get servicemonitor -n monitoring nginx -o json | jq

# 메트릭 확인 >> 프로메테우스에서 Target 확인
NGINXIP=$(kubectl get pod -l app.kubernetes.io/instance=nginx -o jsonpath={.items[0].status.podIP})
curl -s <http://$NGINXIP:9113/metrics> # nginx_connections_active Y 값 확인해보기
curl -s <http://$NGINXIP:9113/metrics> | grep ^nginx_connections_active

# nginx 파드내에 컨테이너 갯수 확인
kubectl get pod -l app.kubernetes.io/instance=nginx
kubectl describe pod -l app.kubernetes.io/instance=nginx

# 접속 주소 확인 및 접속
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

 

추가 참고.

 

kubecost - k8s 리소스별 비용 현황 가시화 도구

# 
cat < 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

**# kubecost chart 에 프로메테우스가 포함되어 있으니, 기존 프로메테우스-스택은 삭제하자 : node-export 포트 충돌 발생**
**helm uninstall -n monitoring kube-prometheus-stack**

# 배포
kubectl create ns kubecost
helm install kubecost oci://public.ecr.aws/kubecost/cost-analyzer --version **1.103.2** --namespace kubecost -f cost-values.yaml

# 배포 확인
kubectl get-all -n kubecost
kubectl get all -n kubecost

# 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) 활용 - [링크](<https://www.redhat.com/sysadmin/getting-started-socat>)
yum -y install socat
socat TCP-LISTEN:80,fork TCP:$CAIP:9090
웹 브라우저에서 bastion EC2 IP로 접속

설치 방법

 

위와같이 kubecost를 통해 리소스별 비용 확인이 가능하다.

 

 

 

오픈텔레메트리

 

https://opentelemetry.io/docs/what-is-opentelemetry/ 참고

 

 

 

'job > eks' 카테고리의 다른 글

eks 6주차  (0) 2023.05.31
eks 5주차  (0) 2023.05.23
3주차 eks 스터디  (0) 2023.05.13
eks 2주차  (0) 2023.05.02
eks 교육 1  (0) 2023.04.24

3주차 eks 스터디는 스토리지 및 노드 관리이다.

 

 

3주차 실습 환경 구성은 앞선 2주차와 마찬가지로 클라우드 포메이션을 통해 배포를 진행한다.

2주차

https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick.yaml

3주차

https://s3.ap-northeast-2.amazonaws.com/cloudformation.cloudneta.net/K8S/eks-oneclick2.yaml

 

2주차 3주차 각각 다운받아서 diff로 비교해보면 efs 쪽 설정이 추가된것을 확인할수있다.

  • Amazon EKS 윈클릭 배포 (EFS 생성 추가) & 기본 설정
    • 기본 설정 및 EFS 확인
    # default 네임스페이스 적용
    **kubectl ns default**
    
    # (옵션) context 이름 변경
    NICK=<각자 자신의 닉네임>
    **NICK=gasida**
    kubectl ctx
    kubectl config rename-context admin@myeks.ap-northeast-2.eksctl.io **$NICK@myeks**
    
    # EFS 확인 : AWS 관리콘솔 EFS 확인해보자
    mount -t nfs4 -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport ***<자신의 EFS FS ID>***.efs.ap-northeast-2.amazonaws.com:/ **/mnt/myefs**
    **df -hT --type nfs4**
    mount | grep nfs4
    **echo "efs file test" > /mnt/myefs/memo.txt**
    cat /mnt/myefs/memo.txt
    **rm -f /mnt/myefs/memo.txt**
    
    # 스토리지클래스 및 CSI 노드 확인
    kubectl get sc
    kubectl get sc gp2 -o yaml | yh
    kubectl get csinodes
    
    # 노드 정보 확인
    kubectl get node --label-columns=node.kubernetes.io/instance-type,eks.amazonaws.com/capacityType,topology.kubernetes.io/zone
    ****eksctl get iamidentitymapping --cluster myeks
    ****
    # 노드 IP 확인 및 PrivateIP 변수 지정
    N1=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2a -o jsonpath={.items[0].status.addresses[0].address})
    N2=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2b -o jsonpath={.items[0].status.addresses[0].address})
    N3=$(kubectl get node --label-columns=topology.kubernetes.io/zone --selector=topology.kubernetes.io/zone=ap-northeast-2c -o jsonpath={.items[0].status.addresses[0].address})
    echo "export N1=$N1" >> /etc/profile
    echo "export N2=$N2" >> /etc/profile
    echo "export N3=$N3" >> /etc/profile
    echo $N1, $N2, $N3
    
    # 노드 보안그룹 ID 확인
    NGSGID=$(aws ec2 describe-security-groups --filters Name=group-name,Values=*ng1* --query "SecurityGroups[*].[GroupId]" --output text)
    aws ec2 authorize-security-group-ingress --group-id $NGSGID --protocol '-1' --cidr 192.168.1.100/32
    
    # 워커 노드 SSH 접속
    ssh ec2-user@$N1 hostname
    ssh ec2-user@$N2 hostname
    ssh ec2-user@$N3 hostname
    
    # 노드에 툴 설치
    ssh ec2-user@$N1 sudo yum install links tree jq tcpdump sysstat -y
    ssh ec2-user@$N2 sudo yum install links tree jq tcpdump sysstat -y
    ssh ec2-user@$N3 sudo yum install links tree jq tcpdump sysstat -y
    
    • AWS LB/ExternalDNS, kube-ops-view 설치
    # AWS LB Controller
    helm repo add eks <https://aws.github.io/eks-charts>
    helm repo update
    helm install aws-load-balancer-controller eks/aws-load-balancer-controller -n kube-system --set clusterName=$CLUSTER_NAME \\
      --set serviceAccount.create=false --set serviceAccount.name=aws-load-balancer-controller
    
    # ExternalDNS
    MyDomain=<자신의 도메인>
    **MyDomain=gasida.link**
    MyDnzHostedZoneId=$(aws route53 list-hosted-zones-by-name --dns-name "${MyDomain}." --query "HostedZones[0].Id" --output text)
    echo $MyDomain, $MyDnzHostedZoneId
    curl -s -O <https://raw.githubusercontent.com/gasida/PKOS/main/aews/externaldns.yaml>
    MyDomain=$MyDomain MyDnzHostedZoneId=$MyDnzHostedZoneId envsubst < externaldns.yaml | kubectl apply -f -
    
    # kube-ops-view
    helm repo add geek-cookbook <https://geek-cookbook.github.io/charts/>
    helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set env.TZ="Asia/Seoul" --namespace kube-system
    kubectl patch svc -n kube-system kube-ops-view -p '{"spec":{"type":"LoadBalancer"}}'
    kubectl **annotate** service kube-ops-view -n kube-system "external-dns.alpha.kubernetes.io/hostname=**kubeopsview**.$MyDomain"
    echo -e "Kube Ops View URL = http://**kubeopsview**.$MyDomain:8080/#scale=1.5"
    
    • 설치 정보 확인
    # 이미지 정보 확인
    **kubectl get pods --all-namespaces -o jsonpath="{.items[*].spec.containers[*].image}" | tr -s '[[:space:]]' '\\n' | sort | uniq -c**
    
    # eksctl 설치/업데이트 addon 확인
    **eksctl get addon --cluster $CLUSTER_NAME**
    
    # IRSA 확인
    **eksctl get iamserviceaccount --cluster $CLUSTER_NAME**
    

 

 

2주차와 마찬가지(efs 및 2주차에서 실습 진행했떤 ALB등은 추가돼있음)로 위와같이 진행하면 3주차 실습 준비 완료

 

 

첫번째 사진처럼 파드안의 컨테이너 내 tmpFS가 있는경우 컨테이너가 종료되면 tmpFS내 데이터도 삭제된다.

마찬가지로 두번째 사진처럼 파드내에 볼륨이 있고 두개의 컨테이너가 해당 볼륨을 공유해서 사용하여도 파드가 종료되면 볼륨내 데이터도 삭제가 된다.

따라서 컨테이너, 파드의 종료여부와 상관없이 데이터를 보존하기 위해 PV/PVC가 필요하다.

앞서 PV/PVC를 이용하지 않는다면(즉 컨테이너 내에 임시의 파일시스템을 이용한다면)데이터가 보존되지 않는다고했는데 이를 실제로 확인해보면 아래와 같다.

10초간격으로 date를 찍는 busybox를 deployment로 배포하고 pod-out.txt 확인하면 10초에 한번씩 찍힌것을 볼수있다.

이후 busybox 파드를 종료후 다시 확인해보면 이전에 찍혔던 date(즉 기존 데이터)는 보존되지 않은것을 확인할수있다.

 

이번에는 local-path-provisioner 스트리지 클래스를 사용하여 데이터 보존성을 확인해보자.

위와같이 local-path-provisioner 사용하기 위해 localpth claim 을 생성해주고

위와같이 앞서 생성한 PVC를 마운트하여 파드를 실행하고 아까와같이 파드를 재시작하여 데이터 보존유무를 확인해보자.

위와같이 파드를 종료하여도 데이터가 없어지지않고 기존 데이터가 보존되는것을 확인할수있다.

실제 데이터는 node1에 저장돼있는것을 확인할수있다.

 

여기까지 eks 클러스터내의 파드를 이용한 볼륨 마운트를 알아보았는데 지금부터는 AWS EBS 마운트를 알아보도록 하자.

 

```bash
# 아래는 **aws-ebs-csi-driver** 전체 버전 정보와 기본 설치 버전(True) 정보 확인
**aws eks describe-addon-versions \\
    --addon-name aws-ebs-csi-driver \\
    --kubernetes-version 1.24 \\
    --query "addons[].addonVersions[].[addonVersion, compatibilities[].defaultVersion]" \\
    --output text**
v1.18.0-eksbuild.1
Tru
v1.17.0-eksbuild.1
False
...

# ISRA 설정 : AWS관리형 정책 AmazonEBSCSIDriverPolicy 사용
eksctl create **iamserviceaccount** \\
  --name **ebs-csi-controller-sa** \\
  --namespace kube-system \\
  --cluster ${CLUSTER_NAME} \\
  --attach-policy-arn arn:aws:iam::aws:policy/service-role/**AmazonEBSCSIDriverPolicy** \\
  --approve \\
  --role-only \\
  --role-name **AmazonEKS_EBS_CSI_DriverRole**

# ISRA 확인
kubectl get sa -n kube-system ebs-csi-controller-sa -o yaml | head -5
**eksctl get iamserviceaccount --cluster myeks**
NAMESPACE	    NAME				            ROLE ARN
kube-system 	ebs-csi-controller-sa		**arn:aws:iam::911283464785:role/AmazonEKS_EBS_CSI_DriverRole**
...

# Amazon EBS CSI driver addon 추가
eksctl create **addon** --name aws-ebs-csi-driver --cluster ${CLUSTER_NAME} --service-account-role-arn arn:aws:iam::${ACCOUNT_ID}:role/**AmazonEKS_EBS_CSI_DriverRole** --force

# 확인
**eksctl get addon --cluster ${CLUSTER_NAME}**
kubectl get deploy,ds -l=app.kubernetes.io/name=aws-ebs-csi-driver -n kube-system
kubectl get pod -n kube-system -l 'app in (ebs-csi-controller,ebs-csi-node)'
kubectl get pod -n kube-system -l app.kubernetes.io/component=csi-driver

# ebs-csi-controller 파드에 6개 컨테이너 확인
**kubectl get pod -n kube-system -l app=ebs-csi-controller -o jsonpath='{.items[0].spec.containers[*].name}' ; echo**
ebs-plugin csi-provisioner csi-attacher csi-snapshotter csi-resizer liveness-probe

# csinodes 확인
kubectl get csinodes

# gp3 스토리지 클래스 생성
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'
  #fsType: ext4 # 기본값이 ext4 이며 xfs 등 변경 가능 >> 단 스냅샷 경우 ext4를 기본으로하여 동작하여 xfs 사용 시 문제가 될 수 있음 - 테스트해보자
EOT
**kubectl apply -f gp3-sc.yaml**
kubectl get sc
kubectl describe sc gp3 | grep Parameters
```

-

2주차때 했던것처럼 IRSA 설정해서 AWS EBS와 EKS 클러스터간에 통신이 가능하도록 해줘야 한다. 

ebs 테스트 준비 완료

 

이제 아까처럼 pv/pvc 로 마운트하여 테스트해보자.

기존

위와같이 pvc 생성하고 해당 pvc를 마운트하는 파드를 새로 생성하면 아래와같이 새로운 볼륨이 생성된것을 확인할수있다.

이와같이 파드에 EBS를 마운트하여 사용할수있다. 또한 기존 aws ebs와 마찬가지로 용량 증설도 가능하다.(반대로 축소는 불가능)

 

이번엔 볼륨 스냅샷에 대해 알아보자. 이또한 EKS의 개념이 아닌 aws내 ebs 의 스냅샷 기능을 이용하는것.

 

```bash
# (참고) EBS CSI Driver에 snapshots 기능 포함 될 것으로 보임
kubectl describe pod -n kube-system -l app=ebs-csi-controller

# Install Snapshot CRDs
curl -s -O <https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshots.yaml>
curl -s -O <https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml>
curl -s -O <https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/client/config/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml>
kubectl apply -f snapshot.storage.k8s.io_volumesnapshots.yaml,snapshot.storage.k8s.io_volumesnapshotclasses.yaml,snapshot.storage.k8s.io_volumesnapshotcontents.yaml
kubectl get crd | grep snapshot
kubectl api-resources  | grep snapshot

# Install Common Snapshot Controller
curl -s -O <https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml>
curl -s -O <https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/master/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml>
kubectl apply -f rbac-snapshot-controller.yaml,setup-snapshot-controller.yaml
kubectl get deploy -n kube-system snapshot-controller
kubectl get pod -n kube-system -l app=snapshot-controller

# Install Snapshotclass
curl -s -O <https://raw.githubusercontent.com/kubernetes-sigs/aws-ebs-csi-driver/master/examples/kubernetes/snapshot/manifests/classes/snapshotclass.yaml>
kubectl apply -f snapshotclass.yaml
kubectl get vsclass # 혹은 volumesnapshotclasses
```

 위와같이 준비 진행

 

위와같이 볼륨 스냅샷을 apply하면 아래와같이 스냅샷이 생성된것을 확인할수있다.

 

 

그럼 장애를 재연해서 스냅샷으로 복원해보도록 하자.

위와같이 실수록 삭제한 상황에서

우선 위와같이 datasource를 ebs볼륨 스냅샷을 가지고 pvc를 생성해주고

위와같이 스냅샷을 이용하여 생성한 pvc를 가지고 파드를 생성해주면 

위와같이 기존에 가지고 있떤 스냅샷을 가지고 ebs를 생성된것이 확인된다.

 

이번엔 efs에 대해 진행할것이다.

우선 efs의 구성 및 아키텍쳐는 다음과 같다.

(처음 efs 에 대해 공부할때 AWS에 있는 NFS로 이해했었다.)

 

# EFS 정보 확인 
aws efs describe-file-systems --query "FileSystems[*].FileSystemId" --output text

# IAM 정책 생성
curl -s -O <https://raw.githubusercontent.com/kubernetes-sigs/aws-efs-csi-driver/master/docs/**iam-policy-example.json**>
aws iam create-policy --policy-name **AmazonEKS_EFS_CSI_Driver_Policy** --policy-document file://iam-policy-example.json

# ISRA 설정 : 고객관리형 정책 AmazonEKS_EFS_CSI_Driver_Policy 사용
eksctl create **iamserviceaccount** \\
  --name **efs-csi-controller-sa** \\
  --namespace kube-system \\
  --cluster ${CLUSTER_NAME} \\
  --attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/AmazonEKS_EFS_CSI_Driver_Policy \\
  --approve

****# ISRA 확인
kubectl get sa -n kube-system efs-csi-controller-sa -o yaml | head -5
****eksctl get iamserviceaccount --cluster myeks

# EFS Controller 설치
helm repo add aws-efs-csi-driver <https://kubernetes-sigs.github.io/aws-efs-csi-driver/>
helm repo update
helm upgrade -i aws-efs-csi-driver aws-efs-csi-driver/aws-efs-csi-driver \\
    --namespace kube-system \\
    --set image.repository=602401143452.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/eks/aws-efs-csi-driver \\
    --set controller.serviceAccount.create=false \\
    --set controller.serviceAccount.name=efs-csi-controller-sa

# 확인
helm list -n kube-system
kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"

LB나 EBS와 마찬가지로 IRSA 셋팅해준다.

이제 efs를 마운트한 파드를 배포해보자.

 

위와같이 EFS가 연결돼있는 PV/PVC를 생성해주고

 

위와같이 파드 2개를 생성해준다.

위와같이 2개의 파드와 맨 처음 해당 실습을 진행했을때 배스천호스트에 마운트해놨던 efs까지 확인할수있다.

 

즉 현재 방금 배포한 2개의 파드와 실습용ec2 인스턴스는 한개의 efs 볼륨을 공유해서 사용하고있는상황
(예전 온프레미스 환경에서 NFS는 실시간 동기화필요할때(업로드 디렉토리처럼) 많이 사용했었음)

 

'job > eks' 카테고리의 다른 글

eks 6주차  (0) 2023.05.31
eks 5주차  (0) 2023.05.23
4주차 eks 스터디  (0) 2023.05.16
eks 2주차  (0) 2023.05.02
eks 교육 1  (0) 2023.04.24

+ Recent posts