MSA - 소모임 project Spring Cloud -> K8S 배포 전환 (1) (FE)

이동명·2023년 11월 17일
1

소모임 프로젝트

목록 보기
6/8
post-thumbnail

개요

이번 포스팅 주제는 지금까지 제작하고 있던 소모임 프로젝트를 배포하고 나서 복습을 목적으로 한다.

이전까지의 배포 아키텍처

지금까지의 배포는 Spring Cloud 를 이용하여 간단하게 위의 그림처럼 배포가 되어있었다.

간단히 설명하면..

  • config server 에서 config 설정들을 가져다 쓰고..

  • Eureka 에서 각각의 마이크로서비스 인스턴스를 등록하고 추적하여 서비스 디스커버리를 제공하며, 뿐만 아니라 고가용성 및 로드밸런싱 등 많은 역할을 해주고 있음.

  • netty 기반 gateway 에선 각 micro service로 원활한 통신을 도와준다.

문제점

이 방식은 간단하지만 몇가지 문제를 기반한다.

Eureka 성능 이슈

  • 분산 시스템에서는 네트워크 오버헤드 및 여러 서비스 간의 통신으로 인한 성능 이슈가 발생할 수 있습니다. 특히, Eureka의 경우 서비스 디스커버리에 대한 네트워크 호출이 추가될 수 있다.

  • ex) 서비스 등록, 주기적인 갱신, 서비스 검색

단일 장애 지점

  • Eureka 서버가 다운되면 서비스 디스커버리가 영향을 받을 수 있다..

상태 관리 및 트랜잭션 처리의 어려움

  • 분산된 상태 및 트랜잭션 처리에 대한 어려움.. 이 부분은 kafka-connect로 연동하여 어느정도 해결하였다.

gateway 성능

  • Gateway는 모든 클라이언트 요청을 받아서 필터, 로드 밸런싱, 라우팅 등의 작업을 수행하므로 성능 오버헤드가 발생할 수 있습니다.

  • 멀티 소켓 서버 부하 테스트 삽질 에서 포스팅 했을 때 에도 모든 부하테스트 첫번째 관문은 gateway server 였음.. 하는 일이 많아서 그런지 생각보다 잘 터짐

  • 상황에따라 스케일링으로 어느정도 보완할 수는 있지만 이 마저도 까다로운 작업이 될 수 있음.

결론

잘 터진다. 그냥 잘 터진다. gateway 그냥 빵빵 터진다..

트랜잭션도 잘 잡는 방법이 어딘가 있겠지만 나는 쉽지 않았음..

개선

컨테이너의 독립된 환경과, 컨테이너 오케스트레이션 플랫폼을 활용하여 Kubernetes Cluster 로 배포를 하려고 한다.

이로써 얻을 수 있는 기대값은

스케일링 및 로드 밸런싱

  • 쿠버네티스는 수평 스케일링을 지원하여 서비스 인스턴스의 수를 쉽게 조절할 수 있습니다. 또한, 서비스 디스커버리 및 로드 밸런싱을 쿠버네티스가 자동으로 처리하므로 Gateway나 Eureka 등에서 발생하는 로드 밸런싱 및 디스커버리 문제를 쿠버네티스가 관리합니다.

고가용성

  • 쿠버네티스는 여러 노드에 서비스 인스턴스를 분산 배포할 수 있고, 고가용성을 위해 자동으로 재구동되는 기능을 제공합니다. 따라서 단일 장애 지점이나 서비스 다운타임을 최소화할 수 있습니다.

설정 및 스크립팅

  • 쿠버네티스는 YAML 파일로 선언적으로 클러스터를 관리할 수 있습니다. 이를 통해 각 서비스의 설정이나 배포를 관리하고, 스크립트를 사용하여 자동화된 배포 프로세스를 구축할 수 있습니다.

상태 관리 및 롤링 업데이트

  • 쿠버네티스는 롤링 업데이트와 롤백을 지원하여 서비스를 업데이트하거나 롤백하는 과정을 쉽게 처리할 수 있습니다.

서비스 디스커버리

  • 쿠버네티스는 내장된 DNS 서비스 디스커버리를 제공하여 서비스 이름을 통해 서로 통신할 수 있게 해줍니다. 이를 통해 서비스 디스커버리 문제를 간소화할 수 있습니다.

트랜잭션 처리와 격리

  • 쿠버네티스는 각 서비스를 컨테이너로 격리하고, 네트워크 및 볼륨을 통해 서비스 간 통신을 관리합니다. 이로써 트랜잭션 처리와 서비스 간 격리에 일부 도움을 줄 수 있습니다.

배포 아키텍처

아주 기본적인 클러스터 아키텍처이다. 현재는 기본밖에 모르고 계속 배우고 있는 상태이기 때문에 기본적인 아키텍처를 참고 하겠다.

그리고 배포 게시글 이기 때문에 아키텍처에 대한 설명만 간단하게 하고..

추가적인 개념설명은 CKA 준비 포스팅에서 추후 포스팅 하겠다..

간단하게 설명하면..

  • Deployment 에서 내부적으로 ReplicaSet을 활용해 무중단 버전관리를 가능하게 한다. 또한 이전 버전으로 롤백도 가능하다.

  • 클러스터IP는 클러스터 내부에서만 통신할 수 있다. 그래서 외부 브라우저에서도 접근할 수 있도록, NodePort라는 개념이 있음.

  • NodePort는 노드(host)에 노출되어 외부에서도 접근이 가능한 서비스 이다. 다만 노드/VM IP가 변경된 경우 처리를 해줘야하기 때문에 실 서비스에서 노드포트만으로 외부 클라이언트 노출하는 방식은 권장되지 않고 로드 밸런싱을 사용하기도 한다. 하지만 나는 ingress 를 사용하니까 패스한다.

  • Ingress는 HTTP 및 HTTPS를 기반으로 한 서비스 라우팅, 로드 밸런싱, SSL 종단 지원 등을 제공하며, 클러스터 외부에서 내부 서비스로의 트래픽을 효과적으로 라우팅할 수 있게 한다.

  • 따라서 이전에 gateway가 해주던 기능은 ingress로 대체 될 것 이다.

CI/CD

  • CI/CD tool 은 jenkins 를 사용하였고.. git 에 hook 걸어놓고..

  • 현재 패키지를 이미지로 빌드하고 docker hub에 push 한다.

  • 그리고 kubectl 이 형성 될 것이고..

  • kube에서 yml에 기재 되어 있는 docker hub image 경로를 pull 받을 것 이다.

GCP 클러스터 구성

일단 인스턴스의 클러스터를 먼저 구성하자.

먼저 4개의 인스턴스를 만들어주자.

그리고 하나하나 다 ssh 접속을 해주고 설치를 진행할 것 이다.

  1. 도커 엔진 설치 ( 인스턴스 4개 전부 다 )

https://docs.docker.com/engine/install/debian/

for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Add the repository to Apt sources:
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo docker run hello-world
  1. kubeadm 설치 (인스턴스 전부 4개 다 )

간단한 클러스터 구축 및 관리를 위해 설치 해 주자

sudo apt-get update
# apt-transport-https may be a dummy package; if so, you can skip that package
sudo apt-get install -y apt-transport-https ca-certificates curl gpg

curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
  1. container-runtimes 설치 ( 인스턴스 전부 4개 다 )

https://kubernetes.io/docs/setup/production-environment/container-runtimes/

컨테이너 관리를 위해 설치 해 주고 네트워크 설정 해 주자..

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl params required by setup, params persist across reboots
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system

lsmod | grep br_netfilter
lsmod | grep overlay

sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward

root 권한 말고도 kubectl 를 사용하기 위해 아래의 명령어도 추가 해 주자

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

그 다음은 cgroup 설정인데..

sudo containerd config default > /etc/containerd/config.toml

해주고 vi /etc/containerd/config.toml 로 125번째 줄 SystemdCgroup = true 로 바꿔줌.

그리고 sudo systemctl restart containerd

여기 까지 되었다면 마스터 노드에 접근해서..

kubeadm init 으로 켜주고.. 자식노드 연결하자.. 아래와 같은 그림의 텍스트를 붙여넣어주자..

그리고 아래와 같은 텍스트가 나오면

자식 노드에 전부 다 넣어주자.

그리고 kubectl get nodes 로 확인하자

그리고 마스터 노드에서 아래의 CNI설정을 해주고

kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml

Ingress 를 설치 하자..(nginx version)

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml

Ingress 설정 바꿔주자..

 kubectl edit svc  ingress-nginx-controller -n ingress-nginx

위의 2개를 추가 externalIPs 쪽에는 마스터노드의 내부 ip를 추가해주자.

이렇게 해주면 kubernetes cluster는 구축이 완료된다.

포스팅이 길어져서 나머지는 다음 게시글에서 진행하도록 하겠다.


profile
Web Developer

0개의 댓글