안녕하세요!

특정 서비스에서 NLB + ALB를 사용하여 고정 IP 및 타켓 라우팅 규칙을 사용하는 예시를 공유 드립니다. 

(구조에 리스닝, 타켓을 개념을 잘 분리해서 작업하면됩니다)

 

저는 처음에 아래 구조를 보면서 고정IP는 사용이 가능하지만 라우팅 규칙을 사용이 불가능 할 것이라고 생각했습니다..

이유는 NLB L4 에서는 도메인 호스트 (test80.test.com, test81.test.com)을 인식할 수 없다고 생각하여 루프가 발생하는게 아닌가 했습니다.....

 

하지만 공식 문서에서 지원을 하다고 되어 있습니다! (추정하는것 보다는 테스트 정답 같습니다 ㅠㅠ)

 

구조

  Router 53 대상(NLB)→ NLB → ALB → 서버 (Nginx 2개 81, 80)

NLB 구조

   리스닝 : 80, 443

   타켓그룹: ALB 80, 443

 

ALB 구조

   리스닝 :

      80 규칙:

        모든 요청 https 라우팅

 

      443 규칙:

        test80.test.com → 서버 80 포트

        test81.test.com → 서버 81 포트

'AWS > EC2' 카테고리의 다른 글

AMI → EC2 생성 중 네트워크 이슈  (0) 2024.03.07

개인적으로 테스트한 내용으로 틀린 정보가 있을 확률이 매우 높습니다. 

운영에 적용 전 따로 테스트가 필요합니다.

배포로인한 서비스 연속성(인바운드 트래픽 유실, 아웃바운드 트래픽 유실, 어플리케이션 안정성)에 이슈가 발생하지 않게 하는 것이 중요합니다.

 

하기 내용은 AWS 환경에서 동작한다는 기준으로 작성했습니다.

 

배포 진행 시 이슈 (502, 504 발생)

 

1. 신규 파드에 느린 어플리케이션 시작 (트래픽을 받을 상태가 아닌 상황)

2. 기존 파드에 종료 ( 타켓그룹에서 계속 트래픽을 전달함, 기존 어플리케이션에 정상적인 종료가 안된 상태)

 

위에 이슈를 조치하기위해 ReadinessGates 를 사용해야됩니다. (aws alb controller사용한다는 기준)

자세한 가이드 (https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.8/deploy/pod_readiness_gate/)
 

ReadinessGates를 사용할 경우 (트래픽을 받을 상태가 아닌 상황, 타켓그룹에서 계속 트래픽을 전달함)을 조치할 수 있습니다. 

 

하지만 "기존 어플리케이션에 정상적인 종료가 안된 상태"는 조치가 되지 않습니다.

위에 이슈를 조치하는 방법은 preStop, terminationGracePeriodSeconds, alb.ingress.kubernetes.io/target-group-attributes: deregistration_delay.timeout_seconds= 30 예시

 

 

참고 블로그 

https://waspro.tistory.com/682

 

Amazon EKS 제로 다운타임 배포환경 구현하기

서론 Amazon EKS는 Kubernetes를 기반으로 동작하는 PaaS 플랫폼으로 Kubernetes가 제공하는 Rolling Update 방식을 그대로 적용하여 기본 제로 다운타임 배포를 구현할 수 있다. 다만, EKS 자체의 제로 다운타

waspro.tistory.com

https://pmh.codes/kube/

Cloudfront 멀티 index.html 설정 방법을 기록해보겠습니다.

 

cloudfront 함수를 사용하고 구현합니다.

 

함수

https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/example-function-add-index.html

 

파일 이름이 포함되지 않는 요청 URL에 index.html 추가 - Amazon CloudFront

파일 이름이 포함되지 않는 요청 URL에 index.html 추가 다음 뷰어 요청 함수는 URL에 파일 이름이나 확장자를 포함하지 않는 요청에 index.html를 추가합니다. 이 함수는 Amazon S3 버킷에서 호스팅되는

docs.aws.amazon.com

 

 

구성 방법

Cloudfront 함수 생성 -> JavaScript runtime 2.0 으로 구성 -> 배포(Cloudfront 선택) -> 뷰어 요청에 생성한 함수 연결 -> 끝 

 

 

RDS 인증서 교체 작업이 있어 확인한 내용을 기록합니다.

변경 가능한 리스트 인증서 및 유효기간

  • rds-ca-rsa2048-g1
  • rds-ca-rsa4096-g1
  • rds-ca-ecc384-g1

무중단 수정 가능 확인 (재 기동)

SupportsCertificateRotationWithoutRestart 값이 true일 경우 RDS 재시작이 필요없습니다.

 

import boto3
import csv
import subprocess


# RDS 클라이언트 생성
region_name = 'ap-northeast-2'
session = boto3.Session(profile_name='test')
rds = session.client('rds', region_name=region_name)


response = rds.describe_db_instances()


# CSV 파일 열기
with open('rds_instances.csv', mode='w', newline='') as file:
    writer = csv.writer(file)

    # 헤더 행 작성
    writer.writerow(['엔진 버전', '인스턴스 이름', '엔드포인트', '엔진 정보'])

    # 각 RDS 인스턴스에 대한 정보 작성
    for db_instance in response['DBInstances']:
        engine = db_instance['Engine']
        if engine == 'docdb':  # DocumentDB 인스턴스 건너뛰기
            continue

        engine_version = db_instance['EngineVersion']
        db_instance_name = db_instance['DBInstanceIdentifier']
        endpoint = db_instance['Endpoint']['Address']
        region = 'ap-northeast-2'  # 필요한 경우 리전을 변경하세요

        command = f"aws rds describe-db-engine-versions --profile test --engine {engine} --engine-version {engine_version} --include-all --region {region}"
        result = subprocess.run(command, shell=True, executable='/bin/zsh',  capture_output=True, text=True)
        if result.stderr:
            print(f"Error: {result.stderr}")
        else:
            engine_info = result.stdout
            jq_filter = '.DBEngineVersions[] | "EngineName: \(.Engine), EngineVersion: \(.EngineVersion), SupportsCertificateRotationWithoutRestart: \(.SupportsCertificateRotationWithoutRestart), SupportedCAs: \(.SupportedCACertificateIdentifiers | join(\", \"))"'
            engine_info = subprocess.run(['jq', '-r', jq_filter], input=engine_info, text=True, capture_output=True).stdout
            writer.writerow([engine_version, db_instance_name, endpoint, engine_info])

 

TLS 통신하는 RDS, 계정 확인 (Mysql)

-- SSL/TLS
SELECT id, user, host, connection_type
FROM performance_schema.threads pst
INNER JOIN information_schema.processlist isp
ON pst.processlist_id = isp.id;

 

 

인증서 교체 전 어플리케이션 이슈 검토

제가 확인한 내용으로 잘못된 정보가 있을 확률이 매우 높습니다. 

 

1. 기존 TLS 통신을 하는 서비스에는 이슈가 없다. 

 - 이유: 신뢰 인증저장소에 AWS Root CA가 등록되어 있는 상태임으로 rds-ca-rsa2048-g1로 교체 해도 이슈는 없다.

2. 만약 외부 인터넷과 통신이 어려운 서비스는 AWS 번들을 신뢰 저장소에 등록이 필요할 것으로 예상 합니다.(완전 추정)

 

교체

순단 이슈는 검토 했지만 따로 기록하지 않겠습니다.

웹 콘솔에서 작업 또는 aws cli 중 선택해서 진행하면 됩니다.

 

참고로 테스트 당시 인증서 교체에 약 26초 정도 걸렸습니다.

현재 Github action self hosted runner 구성은 서버에 프로세스 형태로 구성하기 또는 쿠버네티스에 ARC 로 구성하는 방법이 있습니다.

 

참고 : 

 ARC : https://tech.buzzvil.com/blog/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4%EC%97%90%EA%B2%8C-github-actions-%EC%84%A4%EC%B9%98%EC%97%90-%EB%8C%80%ED%95%B4-%EB%AC%BB%EB%8B%A4/

 

 

GitHub Actionsでself-hosted runnersをDockerで作る - Qiita

https://docs.github.com/ja/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self…

qiita.com

 

 

저는 특정 상황 때문에 이미지 파일로 구성하려고 합니다. 

 

도커 파일 

FROM ubuntu:22.04


ARG PERSONAL_ACCESS_TOKEN
ARG HOST=https://github.com
ARG ORGANIZATION
ARG REPOSITORY

ENV BINARY_URL=https://github.com/actions/runner/releases/download/v2.315.0/actions-runner-linux-x64-2.315.0.tar.gz

ENV RUNNER_NAME=myRunner
ENV RUNNER_GROUP=Default
ENV RUNNER_LABELS="self-hosted,Linux"
ENV RUNNER_WORKDIR=_work

RUN apt-get update && \
    apt-get install -y dotnet-sdk-6.0 curl sudo && \
    apt-get clean && rm -rf /var/lib/apt/lists/*

SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN useradd runner && \
    echo "runner:runner" | chpasswd && \
    chsh -s /usr/bin/bash runner && \
    usermod -aG sudo runner && \
    mkdir /actions-runner && \

    chown runner:runner /actions-runner

USER runner
WORKDIR /actions-runner

RUN curl -fsSL -o actions-runner-linux-x64-2.315.0.tar.gz -L $BINARY_URL && \
    tar xf ./actions-runner-linux-x64-2.315.0.tar.gz && \
    rm actions-runner-linux-x64-2.315.0.tar.gz && \
    rm actions-runner.tar.gz && \
    echo $PERSONAL_ACCESS_TOKEN && \
    ./config.sh \
        --unattended \
        --url $HOST/$ORGANIZATION/$REPOSITORY \
        --pat $PERSONAL_ACCESS_TOKEN \
 #      --token $PERSONAL_ACCESS_TOKEN \
        --name $RUNNER_NAME \
        --runnergroup $RUNNER_GROUP \
        --labels $RUNNER_LABELS \
        --work $RUNNER_WORKDIR

CMD ["nohup","./run.sh", "&"]

작업 : AMI → EC2 생성

 

원인 : cloud-init와 관련된 python2.7 내의 종속성 문제 추정하고 있습니다. 

  

이슈 감지 :

   AMI로 EC2 (A) 생성

   EC2 상태 “인스턴스 상태 검사” 실패 확인 및 서버 접속 불가

 

로그 확인:

 

EC2 직렬콘솔로 부팅 화면확인

   Failed to start LSB: Bring up/down networking error message 에러 발생

    추정 (cloud-init 동작에 문제가 발생되어 IP를 할당 실패)

 

1차 조치 진행 후 [cloud-initFAILED[607]: ] File "/usr/bin/cloud-init", line 9, in <module>Failed to start Initial cloud-init job (pre-networking). 에러 발생

   추정 (문제는 cloud-init와 관련된 python2.7 내의 종속성 문제로. pip 및 yum을 통해 요청 및 urllib3을 제거한 다음 yum을 통해 다시 설치)

 

 

조치 (1차) -실패

https://repost.aws/questions/QU8L6L6c7HRRqU0-SajiAc5A/aws-instance-failed-to-start-lsb-bring-up-down-networking-error-message

위에 글을 참고하여 신규 ec2 (B) 생성 문제 EBS(A)를 신규 ec2에 연결

1. Stop the impaired instance and detach the root volume.
2. Attach the root volume on another rescue instance (which is running in the same availability zone).
3. Check the disk/volume attached and mount it.

            $ sudo lsblk
            $ sudo lsblk -f
            $ mkdir /rescue
            $ mount /dev/xvdf1 /rescue

4. Mount the required pseudo filesystems and chroot into the environment.

            $ for i in proc sys dev run; do mount --bind /$i /rescue/$i ; done
            $ chroot /rescue

5. Check the cloud-init configurations and the cloud-init package, if it is installed.

            $ ls -l /etc/cloud/
            $ sudo rpm -qa | grep cloud-init
            $ sudo yum install cloud-init

6. Exit from the chroot environment and unmount the filesystems.

            $ exit
            $ for i in proc sys dev run; do umount /rescue/$i ; done
            $ umount /rescue

8. Detach the root volume from the rescue instance and attach it to the original instance.

 9. Start the instance.

 

 

조치 (2차) - 성공

 

   AMI 로 다시 EC2 (C) 생성 볼륨 분리 후 EC2(B) 에 연결

   조치 1차 4번 까지 진행 후 하기 명령어 실행

   sudo pip uninstall urllib3

   sudo pip install urllib3

   조치 1차 5번 진행

     5. Check the cloud-init configurations and the cloud-init package, if it is installed.

   sudo yum update cloud-init

   조치 1차 6번 진행

     6. Exit from the chroot environment and unmount the filesystems.

   EBS 분리 후 EC2 (C)에 연결 후 서버 기동

 

 

후기 :

  ami 생성 후 원본서버가 기동 상태에서 ami로 서버가 잘 올라오는지 확인 후 원본 서버를 삭제가 필요합니다 ㅠㅠ

 

'AWS > EC2' 카테고리의 다른 글

NLB + ALB (고정 퍼블릭 IP  (0) 2024.08.26

 

EKS 안에 프로메테우스, 그라파나를 구성하여 사용하고 있습니다. 

 

기본적으로 pod의 메트릭은 수집되고 있지만 그 외 EC2의 메트릭은 수집되고 있지 않았습니다.

 

Node exporter 를 EC2에 구성 후 프로메테우스 설정 (job)에 등록하여 배포 (수동)으로 진행 중 

 

ec2_sd_configs 라는 것을 알게되어 구성해보았습니다. 

 

 

1. 프로메테우스 pod 에 AmazonEC2ReadOnlyAccess 권한을 부여하였습니다.

https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/associate-service-account-role.html

 

IAM 역할을 수임하도록 Kubernetes 서비스 계정 구성 - Amazon EKS

역할 또는 서비스 계정이 이미 있는 경우 이전 명령이 실패할 수 있습니다. eksctl에는 이러한 상황에서 제공할 수 있는 다양한 옵션이 있습니다. 자세한 내용을 알아보려면 eksctl create iamserviceaccou

docs.aws.amazon.com

 

 

2. 프로메테우스 헬름 설정 추가

 

설정을 설명하면

 

prometheus-ec2-role 는 위에 1번에서 생성한 SA를 입력해주면 됩니다. ( ec2 tag 확인 및 메타데이터 확인 용도)

 

ec2_exporter 는 메트릭 수집 대상을 인식하기 위한 설정 및 라벨 수정에 사용됩니다.

 

serviceAccounts:
  server:
    create: false
    name: "prometheus-ec2-role"
    
    
 - job_name: ec2_exporter
    relabel_configs:
      - source_labels: [__meta_ec2_tag_Name]
        target_label: instance
      - source_labels: [__meta_ec2_private_ip]
        target_label: ip
    ec2_sd_configs:
      - region: ap-northeast-2
        port: 9100
        filters: 
          - name: tag:prometheus
            values: 
              - prometheus

 

 

기존 프로세스 

- ec2 node expoter 설치 -> 프로메테우스 설정 수정 -> 배포 -> 그라파나 확인 

 

변경 프로세스

- ec2 node expoter 설치 -> ec2 Tag 설정 -> 그라파나 확인

 

 

주의사항: 

- 프로메테우스에서 바로 ec2를 인식하지 않습니다.  (대충 5분에 한번?)

- 잠시 생성되고 삭제되는 서비스가 있으면 eks crontjob를 검토 필요 (사실 잘모르겠습니다 ㅠㅠ)

 

 

 

 

참고 블로그

 

https://koudingspawn.de/prometheus-aws-discovery/

https://prometheus.io/docs/prometheus/2.41/configuration/configuration/

https://blog.bespinglobal.com/post/prometheus-설정-가이드/

'AWS > EKS' 카테고리의 다른 글

무중단 배포 (EKS)  (0) 2024.07.07
alb aws-load-balancer-controller error  (1) 2023.11.21
EKS 업데이트 참고하면 좋은 tool  (0) 2023.09.19
eks worknode 서브넷 그룹 변경 (비용)  (2) 2023.08.12
fargate + eks 네트워크 이슈  (0) 2023.03.06

안녕하세요 

 

eks 1.24 -> 1.25 업데이트를 진행하면서 발생한 문제점을 공유 드립니다.

 

참고로 무중단 업그레이드 방식이 아닌것으로 추정하고 있습니다. 

 

작업 전 검토 : 

 

kubent 툴을 활용하여 사용 중인  API를 확인 

https://github.com/doitintl/kube-no-trouble

 

GitHub - doitintl/kube-no-trouble: Easily check your clusters for use of deprecated APIs

Easily check your clusters for use of deprecated APIs - GitHub - doitintl/kube-no-trouble: Easily check your clusters for use of deprecated APIs

github.com

 

 

cni 버전 확인 (공식 문서를 읽는것을 추천드립니다!)

 

kube-proxy 버전 확인 (공식 문서를 읽는것을 추천드립니다!)

 

 

 

조치 :

 

1. psp 같은 경우  eks.privileged 만 사용하고 있어 따로 작업이 불 필요했습니다.

2. cni, kube-proxy 는 버전에 맞게 수정해주었습니다.

3. 필수 참고를 꼭 읽어주세요!

 

 

 

 

 

==========

필수 참고 : https://marcincuber.medium.com/amazon-eks-upgrade-journey-from-1-24-to-1-25-e1bcccc2f384

 

개인 AWS 에서 EKS 테스트를 자주 진행하고 있었습니다. 

 

EKS 생성은 하기 링크를 사용했습니다. 

 

https://gasidaseo.notion.site/Amazon-EKS-23-6-6-16ed4098c3314802a1e4dbf12a9d1da8

 

Amazon EKS 윈클릭 배포 가이드 (’23.6.6 업데이트)

구성 환경

gasidaseo.notion.site

 

alb 생성은 공식 문서를 보고 진행했고 계속 실패를 했습니다 

 

에러 예시

 

1 existing iamserviceaccount(s) (kube-system/aws-load-balancer-controller) will be excluded
1 iamserviceaccount (kube-system/aws-node) was included (based on the include/exclude rules)
1 iamserviceaccount (kube-system/aws-load-balancer-controller) was excluded (based on the include/exclude rules)
metadata of serviceaccounts that exist in Kubernetes will be updated, as --override-existing-serviceaccounts was set

 

 

원인은 제가 동일한 이름에 정책, 롤 (lb 컨트롤러)를 생성한것이 문제였습니다.

(기타 문제 : 과거 테스트에서 생성한 oidc가 등록되어 있음... )

 

조치 :

 

Clodformation 에서 컨트롤러 생성 스택 제거 

 

모니터링 중앙화 ?

 

쿠버네틱스 안에 프로메테우스가 있고 외부에 있는 서버의 메트릭 프로메테우스로 가지고 오기

 

k8s (프로메테우스 ) - 외부 서브넷에 있는 서버 (Cadvisor)

 

 

--------------------------------------------

현재 상태 : Prometheus, Grafana Helm 으로 구성

 

1. 추가 서버에서 cadvisor 설치 (컨테이너 실행 or 바이너리 파일로 실행)

참고 : os 별 (https://github.com/google/cadvisor/blob/master/docs/running.md)

컨테이너 실행이나 바이너리 파일 실행도 서버 재기동을 생각해서 docker restart, systemd 에 등록이 필요합니다.

sudo docker run -d --restart always --volume=/:/rootfs:ro --volume=/var/run:/var/run:ro --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --volume=/dev/disk/:/dev/disk:ro --publish=8080:8080 --detach=true --name=cadvisor --privileged --device=/dev/kmsg gcr.io/cadvisor/cadvisor:latest

2. 프로메테우스 설정 파일에 하기 내용 추가

extraScrapeConfigs: |
  - job_name: 'test-api'  
    scrape_interval: 5s  
    static_configs:  
    - targets: ['172.3.61.111:8080']
      labels:
        type: AWS-EC2

 

3. 프로메테우스 target 에서 수집이 잘되는지 확인

 

모니터링 구성 (import 13946)- 그라파나 버전에 따라 많은 수정이 필요합니다.

 

 

 

 

혹시 몰라서 테스트

 

kube-prometheus-stack 에서 동일하게 구성하기

https://malwareanalysis.tistory.com/566
https://www.jacobbaek.com/1540

프로메테우스 설정 파일에 하기 내용 추가 (헬름)

prometheus:
  prometheusSpec:
    additionalScrapeConfigs:
      - job_name: "test-api"
        scrape_interval: 5s
        static_configs:
          - targets: ["172.3.61.111:8080"]
            labels:
              type: AWS-EC2

 

 

+ Recent posts