[쿠버네티스] - AWS EC2 를 이용한 kubenetes 클러스터 구성 & 클러스터 스케일링

2024. 10. 31. 12:13현대 오토에버 SW 스쿨 - 클라우드/쿠버네티스

SMALL

1. EC2 를 이용한 쿠버네티스 클러스터 구성

EC2 인스턴스 생성

  • 외부에서 접속을 했을 떄는 일정 시간 동안 입력이 없으면 자동으로 세션이 해제
  • Master Node
  • CPU 가 2개 이상 
    • Core 가 1개이면 설치는 성공 -> master node 로 실행하려고 할 때 에러 발생
  • 포트 개방
    • API Server : 6443
    • etcd Server : 2379, 2380
    • kubelet API : 10250
    • kube scheduler: 10251
    • kube controller manager: 10252
    • Flannel CNI 플러그인에 대한 포트 : 8285, 8472
  • Worker Node
  • 하드웨어 제약 없음
  • 포트 개방
    • API Server: 6443
    • kube-proxy 가 서비스를 로드밸런싱하기 위해서 사용하는 포트 : 26443
    • Flannel CNI 플로그인에 대한 포트 : 8285, 8472
    • NodePort 로 사용할 포트 : 30000-32767

2) Ubuntu 24.04

# 패키지 정보 업데이트
sudo apt update && sudo apt upgrade -y
# 런타임 설치
sudo apt install -y docker.io
# 런타임 확인
sudo docker --version
  • 쿠버네티스 저장소 등록
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
  • kubenetes 클러스터 구성을 위한 패키지 설치
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
  • 패키지의 용도
    • kubeadm: 클러스터 구성을 위한 패키지
    • kubelet: 노드 에이전트 (Pod 생성, 실행, 모니터링)
    • kubectl: 명령 수행 도구 (CLI)
  • 버전 고정
sudo apt-mark hold kubelet kubeadm kubectl
  • Memory Swap 비활성화: 가상 메모리 사용으로 인한 문제점을 제거
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

확인: sudo free -m 과 sudo swapon -s

3) 마스터 노드에서 클러스터 생성

  1. kubeadm을 초기화하고 pod의 네트워크 대역을 설정
    1. sudo kubeadm init --pod-network-cidr=10.244.0.0/16
  2. 워커노드에서 마스터 노드를 연결하기 위한 코드
    1. sudo kubeadm token list
    2. openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' 
  3. 쿠버네티스 환경 설정 파일 생성
    mkdir -p $HOME/.kube
    
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
  4. 노드 확인
    kubectl get nodes
  5. 방화벽 중지
    sudo systemctl stop ufw
    sudo systemctl disable ufw
  6. Cloud 서비스는 기본적으로 port 에 대한 보안을 별도록 설정하도록 되어 있음 -> 보안 그룹에 가서 인바운드 규칙에 추가를 해줌
# 토큰 확인
kubeadm token list

# 토큰 생성
kubeadm token create

# 해시값 확인
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt

 

3) 워커 노드에서 마스터 노드에 연결

  • kubeadm join 172.31.1.97:6443 --token f1dop8.fcqs8gricz2az5ye \ --discovery-token-ca-cert-hash sha256:8a806679be5851bbb2778662a0ca454188ef8fa4d446c6829ab9836ed564b462'
  • 교재 소스 : https://github.com/gilbutITbook/kiamol

 

2. 스케일링

1) 개요

  • 성능을 높이거나 낮추는 작업
  • Scale up
  • 하드웨어 성능을 높이는 것
  • 초기 단계의 서비스나 하드웨어 업그레이드 전략으로 충분히 성능 향상이 가능한 경우에 적합한 전략
  • 확장의 한계에 도달 시 추가적인 성능 향상이 어려워 장지적으로 사용한느 서비스에는 부적합
  • kubenentes 의 매니페스트에서 resource 의 제한을 가할 수 있음 
    • 해당 부분 수정시 scale up 과 유사한 효과를 나타낼 수 있음
  • Scale out
  • 컴퓨터의 대수를 늘리는 전략
  • 서비스 성장에 따라 서버를 추가로 확장할 수 있음
  • 하나의 서버에 문제가 발생하더라도 다른 서버가 역할을 대신 수행
  • 서버의 수가 증가하게 되면 네트워크가 복잡해지고 관리 비용이 증가
  • kubenetes 에서는 replica 를 조정해서 동일한 서비스를 하는 pod 의 개수를 늘리는 것
  • Scale out 을 자주하는 경우 이미지 최적화 부분도 고민할 필요가 있음

2) replicaset

  • pod 를 여러개 만들 수 있는 객체
  • pod 보다는 상위의 개념인데 deployment 보다는 하위의 개념으로 최근에는 replicaset 을 잘 사용하지 않음
  • replicaset 이나 deploymeny 로 만들어진 pod 는 삭제되거나 중지되면 바로 다른 pod 가 만들어짐

3) scale 명령

  • pod 가 구동 중에 동적으로 replica 를 변경해야 할 때 사용
  • 재배포를 하게 되면 무효가 됩니다. 
    • kubectl scale --replicas=파드개수 유형/이름
  • 실습
  1. ch06 으로 이동
  2. 파일 경로 대신에 디렉토리 경로를 사용하게 되면 디렉토리 안의 모든 yaml 파일을 수행
  3. 파드의 개수 (kubectl get pods) 를 확인: 2개
  4. 파드의 개수를 3개로 증가
  5. 파드의 개수 확인 : 3개
  6. 재배포
  7. 파드의 개수 확인; 2개

4) Daemon Set

  • replicas 를 설정하지 않더라도 모든 worker node 에 pod 를 생성해주는 객체
  • 모너터링 용도

5) garbage collection

  • 쿠버네티스는 garbage collection 이 있어서 주기적으로 감시를 하다가 자신의 상위 객체가 존재하지 않으면 자동으로 제거가 됨

3. pod 강제 삭제

  • kubectl delete pods 파드 이름 --grace-period=0 --force

4. 멀티 컨테이너 pod

1) 개요

  • 하나의 pod 에 여러개의 컨테이너를 실행 -> 사이트카 패턴
  • 애플리케이션 컨테이너와 애플리케이션 컨테이너가 필요로 하는 다른 컨테이너를 같이 배치
    • 대표적인 경우가 wordpress 같은 애플리케이션은 반드시 mysql 이나 maria db 가 있어야 함
    • 해당 경우 서로 다른 pod 로 구성해도 되고 하나의 pod 에 다른 container 로 묶어도 가능

2) pod 와 container 통신

  • pod 는 하나의 가상환경
  • pod 는 하나의 리눅스 시스템이 존재
    • 리눅스 시스템 안에 네트워크와 파일 시스템을 제공하는 하나의 pod 에 속한 container 들은 pod 를 공유
  • 하나의 pod 에 속한 모든 container 는 동일한 IP 를 가짐
    • 따라서 통신을 할 때 localhost 를 사용할 수 있음
  • 하나의 pod 에 속한 컨테이너들은 내부 볼륨 (hostPath) 을 공유할 수 있음

  • 하나의 메모리 공간을 공유하는 컨테이너 (ch07/sleep)
    1. 파드 생성
    2. 볼륨에 파일 기록 : HOSTNAME 이라는 환경 변수에 저장된 내용을 data-rw/hostname.txt 파일에 기록
    3. 자신이 저장한 파일 읽기
  • 파드 내에 컨테이너 간의 통신 
    1. 파드 생성
    2. sleep 이라는 container 에서 server 라는 container 의 8080 port 에 요청을 전송
    3. 확인: server container 의 log 확인

3) 초기화 컨테이너

  • 사이드카 패턴의 container 은 container 가 만들어지는 순서가 없음
    • 순차적으로 실행되어야 하는 컨테이너들은 사이트카 패턴으로 만들게 되면 필요한 컨테이너가 구동되지 않았음에도 컨테이너가 생성되어 오류를 발생시킬 수 있음
  • 해당 경우 초기화 container 를 이용해 먼저 생성되어야 하는 container 를 초기화 컨테이너로 설정 
    • 컨테이너가 정상적으로 생성된 경우에 다음 container 를 생성 가능
  • 초기화 container 는 여러 개 설정 가능 -> 작성 순서대로 동작
  • 초기화 컨테이너 설정 
    • 일반 container 는 spec 안에 containers 라는 속성으로 설정
    • 초기화 container 는 initContainers 라는 속성으로 설정 -> 배열 형태로 순차적 생성
  • 예제 - github 링크
  •  

4) 어댑터 컨테이너

  • 애플리케이션이 어떤 내용을 스스로의 파일에 기록을 하게 되면 외부에서는 확인 불가능
    • hostPath 와 같은 node computer 의 특정 디렉터리와 볼륨 마운트를 하면 가능
    • 애플리케이션이 로그를 출력 -> 출력한 로그를 읽어서 표준 출력으로 다시 연결하는 방식 -> 로그 외부로 출력
  • 자신의 어떤 로직을 수행하는 것이 아닌 다른 container 가 수행한 작업의 내역을 가지고 다른 container 에게 전송 or 외부에 출력 -> 이러한 컨테이너 :: 어댑터 컨테이너
  • 헬스 체크나 성능 지표를 측정하는 애플리케이션을 이러한 방식으로 배포하는 경우 
    • 최근 이를 위한 프로메테우스나 ELK Stack 같이 잘 만들어져 있는 서비스가 있어 어댑터 컨테이너 형태보다는 별도의 애플리케이션을 주로 이용

5. 데이터를 많이 다루는 애플리케이션

1) stateful set

  • stateful : 상태를 저장하는 것
  • stateless: 상태를 저장하지 않는 것
  • http 나 https 는 stateless 
    • web 에서는 이전 상태를 확인하기 위해서는 별도의 기술이 필요
    • web 에서는 이전 상태를 server 에 저장해 둘 수 있고 client 에 저장
    • server 에 저장하는 것이 session 
      • session 저장 기술
      • 메모리 저장 : 많은 클라이언트가 접속 -> 서버 처리가 느려짐 -> 속도가 빠른 InMemory DB 상용
      • 파일이나 데이터베이스에 저장 : Cookie, Local Storage, Web SQL 
  • Pod 는 기본적으로 stateless
  • stateful 형태의 pod 를 만드는 방법은 kind 를 StatefulSet으로 설정 -> serviceName 설정
  • pod 를 stateless 형태 (ReplicaSet, Deployment) 로 replica 를 3이라고 하면 3개의 pod 를 동싱에 생성
    • 데이터를 저장할 필요가 없어 병렬로 생성해도 아무런 문제 발생 X
    • DB 를 이런식으로 배포 -> 3개의 DB 가 불일치 발생
    • 이름도 랜덤하게 만들어짐
  • pod 를 stateful 형태 (StatefulSet) 로 replica 를 3이라고 하면 3개의 pod를 동시 생성 X
    • 하나의 pod 를 만들고 해당 pod 를 만드는데 성공하면 해당 내용을 복사해서 다음 pod 생성
    • 이름도 순차적으로 부여
    • DB를 배포할 때 취하는 방식
    • 1번째 pod 는 읽고 쓰기가 가능하도록함 
      2번째 pod 부터는 읽기만 가능 & 1번째 pod 의 데이터 동기화 역할 수행

2) 초기화 container 사용 가능

  1. 특정 스크립트 파일을 만들고 변수의 값을 0으로 초기화 
  2. 값이 0일 때 특정 작업을 수행 후 1을 증가 
  3. 스크립트는 첫번째 container 가 만들어질 때와 다른 컨테이너가 만들어질 때 다른 작업을 수행하도록 할 수 있음

3) Job 과 CronJob 의 활용

  • 데이터를 활용하는 애플리케이션의 데이터 백업은 중요한 작업
  • 수동을 하게 되면 실수 발생 가능 -> 자동으로 수행하는 것이 좋음
  • 특정 작업을 일정한 주기를 가지고 작업을 할 수 있도록 해주는 것이 CronJob
  • job 은 한 번 수행하면 그대로 종료
  • job 은 배치작업에 사용 -> 모아서 한번에 많은 내용을 수행하고자 할 때 사용
  • CronJob 은 주기를 정해서 주기 단위로 작업을 계속 수행하기 위해서 생성
반응형
LIST