23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
MSA가 일반화되어가고 있는 듯 하다. 2022년 1월 현재, MSA를 지원하기 위해서는 Kubernetes는 필수 요소라고 봐도 무방할 것 이다. 또한 많은 Solution들이 Kubernetes의 응용으로 배포되고 있다.
참고로 팀이 제공하고 있는 Kubernetes solution도 MSA지원을 위해 사용되고 있다.
[참고링크] https://www.yna.co.kr/view/AKR20220120038500017?input=1195m
Kubernetes는 쉽게 생각하면 Cloud 시대의 WAS 혹은 Cloud판 안드로이드라고 생각하면 편하다. 물론 이런식의 비유는 항상 본질이 아니다. 하지만 처음 시작할 때 느낌을 주기 위한 것이니 양해 부탁드린다.
하여간, Kubernetes와 친해기기 위해서는 일단 써 봐야하는데, Kubernetes의 설치는 쉬운일이 아니다. 따라서 팀도 이 문제를 해결하기 위해 Kubernetes 와 친구들의 LCM를 개발하고 있고, 그 노력의 결과를 Open Source로 공유하고 있다. 함께 하고 싶으신 분들은 언제든지 연락 부탁드린다.(참고: https://github.com/openinfradev)
결론적으로 이 문서의 목적은 AWS EKS를 통해 누구나 싶게 Kubernetes를 접해 볼 수 있게 하는 자습서를 제공하는 것 이다. 필자의 아둔함 때문인지 AWS의 모듈화 때문인지 EKS 설치자체도 쉽지는 않다. 하지만 적어도 OS level의 설치는 안해도 되니 이글은 의미 있을 거라 믿는다.
필자의 경험에 의하면, Kubernetes는 모두가 알고 있지만 MSA를 시작해 보려 하면 Kubernetes를 몰라서 못 한다는 말이 불쑥튀어 나온다. 필자의 뇌피셜에 의하면 첫째, 사람들은 Kubernetes를 OpenStack과 같은 가상화 Solution으로 생각하는 착각과 둘째, Kubernetes가 Centos 처럼 배포판이라고 착각하기 때문인 듯 하다.
첫 번째 오해를 해결하기 제일 좋은 방법은 https://youtu.be/4ht22ReBjno 를 시청하는 것 이다. 이 동영상을 보면서 느낀 점은 나도 이상하지만 세상에는 이상한 사람이 정말 많다는 것 이다. ^^
본 문서에서는 두번쨰 오해에 대해서 좀더 이야기 해 보고자 한다. Kubernetes의 구조에 대해서 짧게 설명하고, 왜 설치가 어려운지 이야기해 보고자 한다. 결론부터 말씀드리면, Kubernetes는 Centos가 아니라 Linux Kernel 같은 존재다.
[참고 및 그림 출처] https://dev.to/erfankashani/long-story-short-kubernetes-365
Kubernete는 우선 Container를 여러 서버에 설치해 주는 Scheduler다. 마치 Kernel이 Process를 Shceuling하는 것과 유사하다. 물론 초기 Kernel은 Single CPU core기준이라서 시분할 이었지만, 요즘과 같이 Multi-Core NUMA 에서는 코어에 할당도 잘 할 것 이다(확인해 본적은 없다.). 하지만 여기서 끝나는 것이 아니라 MSA 구조를 지원하기 위한 (Networking Abstaction, Service Discovery) Utility도 같이 제공하고, 이 모든 것을 선언적자원으로 관리한다. 동일한 것은 아니지만 Linux kernel이 모든것을 화일으로 Abstract하는 것과 비슷하다고 보면 된다. 선언적자원으로 관리한다는 것은 선언문과 같이 동작하도록 Kubernetes가 알아서 최선을 다해야 하고, 이역활을 하는 것 (잘 동작하게 바라보고 인도해주는)이 Controller이다. 선언문 자체는 etcd에 보관되어 지며, 모든 동작은 API로 추상화되어 향후 자동화 될 수 있게 한 것 이다.
위에 날거한 기능이 Kubernets Master의 역활이다. 아래 그림 중 Node는 실제 Container로 구성된 SW를 구동하는 서버로 Kubernetes Master와 통신하는 Client (API Server와 연동하는)인 Kublet과 Kube-proxy로 구성된다.
아래 Pod란 표현이 있는데, Pod는 Container의 모음이다. 비유하여 이야기 하면, Container는 Thread와 상치되며 Pod는 Process와 상치된다. Process내 Thread간에는 Memory가 공유되 듯 이, Pod는 Container간은 Network/Storage가 공유된다.

이제 본격적으로 왜 설치 조차 어려운지 간단히 설명하겠다. 아래는 Kuberentes가 제공하지 않는 것 이다. 제공하지 않는다는 것은 가이드만 있을 뿐, 어떻게 구성하는지는 각자의 몫이라는 것이다.
Kubernete에 들어가 있지 않은것들
etcd는 별도 오픈소스 입니다. 알아서 구축하세요.
kubernetes master는 stateless 입니다. 따라서 Clustering 과 같은 HA 기능을 제공하지 않습니다.
node에 설치되는 SW 중 Kubernetes가 제공하는 것은 Kublet과 Kube-proxy 입니다. conainer runtime을 제공하진 않습니다. 물론 OS도 제공하지 않습니다.
A.K.A Add-on들도.... 엄밀하게 말 하면, Service Discovery에 사용되는 DNS 나 Networking, Storage등도 Kubernetes의 본연은 아닙니다. 마치 Device Driver와 같은 것 입니다.
구조에 대한 Variation은 다음 링크에서 확인 할 수 있다. https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/ha-topology/
보면 참담하다 Load balancer도 설치해야 하는 건가!! HA proxy ? Nginx? ... -_-;
물론 다른 방법도 가능하다. Master쪽이 Server니 Worker에 IP Table로도...
더 다른 이야기도 많다. 모니터링 이라던지 Ingress Controller라던지 OIDC 연결 이라던지 OPA라던지, 하여가 여기까지 읽으면 아 뭐가 이리 복잡해하는 생각이 들 것 이다. 만약 그렇다면 필자는 성공한 것 이다.
설치하기 골치 아픈 (여기 골치 아프다는 것은 정책을 세워야 한다는 것 이다) Kubernetes을 Sir. AWS가 Best Practice를 기반으로 정책을 세워 서비스로 제공해 준다는 믿음으로 EKS에는 우리에게 다가 왔다.
간단하게 EKS의 구조를 보자.
[출처] https://aws.amazon.com/ko/getting-started/hands-on/deploy-kubernetes-app-amazon-eks/
아래 EKS Control plane이 위에서 설명한 Kubernetes Master 부분이다. 아마도 EKS conrol plane은 HA를 위해 여려 Instance로 구성되어 져 있을 것 이고, 사용자는 Load Balancer를 통해 Single end-point로 접근 할 수 있을 것 이다.
아래 그림을 잘 보면 VPC란 개념이 나오고, EKS VPC와 Customer VPC가 있다. VPC는 아래 설명하겠지만 가상의 Data Center다. 즉 EKS Control Plane (Kubernetes Master)는 AWS에서 알아서 잘 설치 한다는 것 이고, 실제 응용이 돌아가는 Worker Node는 고객의 가상의 Data Center에서 동작한 다는 것 이다. Customer VPC에서 Load balacner가 있다. 이는 MSA로 구성된 Front end가 복수의 Instance에 replicate되어 있음으로 외부 Client(예를 들어 Broswser)에 Single end-point를 제공하기 위함이다. 이또한 앞에서 언급한 Add-on 의 하나이다.

우리는 언제나 머리보다는 몸을 먼저 쓰니, AWS console에 들어가 냅다 EKS 생성을 시도해 본다.
많은 예제들이 eksctl과 같은 CLI tool를 이용하지만, 초보자는 콘솔를 사용해 보는 것이 좋다고 생각하기에 콘솔기준으로 설명 한다.
아래 그림은 콘솔화면 이다. 4단계 중, 1단계를 보면 권한 설정에 대한 것이 나온다. 이 부분은 연결된 링크를 보면서 따라하면 되니, 큰 허들은 아니다. 하지만 2단계를 보면 위 그림의 Customer VPC가 미리 만들어져 있어야 한다는 것을 알게 된다. AWS의 Network를 이해하지 못 하면, 적절한 VPC를 구성할 수 없으니 EKS 설치 할 수 없는 것 이다.
물론, CLI 기준으로 된 예제들은 그저 따라하기만 하면 된다. 왜냐하면 Cloud Formation이라는 AWS의 IaC도구로 Sample Customer VPC를 만드는 것이 포함되어 있기 때문이다. (https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/getting-started.html)

VPC는 Virtual Private Cloud의 약어이다.
VPC는 쉽게 생각하면 Data center의 상면이다. VPC 자체만으로는 아무 것도 아닌 하나의 공간 (그냥 서버실이라고 생각해 보자)이다. 자 공간이 만력된 후 해야할 일을 생각해 보자. 일단 네트워크를 구성하고 이 네트워크를 인터넷에 연결해야 할 것 이다.
아래 그림은 On-prem 구축과 AWS VPC를 서로 비교하여 그린 그림 이다.
On-prem 기준, Network 장치들이 있는 Network Rack과 서버가 있는 Server Rack을 구성할 것 이다. Network Rack에 각종 Network 장비들과 DMZ(인터넷 연결 안전하게 하기 위한 Network)을 구성하는 경우가 일반적이다. 따라서 Rack단위로 독립된 Network (IP Subnet)를 구성하는 것을 상상해 볼 수 있다.
좌측 그림은 전통적인 Leap-spin구조다. Leap-spine구조에 대해서 좀더 알고 싶을면 다음 링크를 참조 하시면 된다.https://www.cisco.com/c/en/us/products/collateral/switches/nexus-7000-series-switches/white-paper-c11-737022.html
오른쪽은 일반적인 VPC 구성 이다(w/ Network). VPC자체는 그냥 상면이다. 보통 Server rack를 구성하듯 EC2 instance가 존재할 subnet을 우선 구성한다. 해당 VPC가 인터넷에 연결되야 한다면, Internet Gateway를 설치한다. 마치 On-prem에서 SKB에 전화하면 uplink가 달린 장비를 설치해 주는 것과 동일한 절차이다. EC2 instances들이 Internet에 있는 Server에 연결하기 위해서는 Public IP가 필요하다. Public IP는 유한한 자원임으로 NAT을 통해 공유한다. 따라서 NAT Gateway를 설치한다. EC2 instance에서 NAT gateway로 인터넷 Traffic을 라우팅하기 위해서. 0.0.0.0/0 --> NAT GW Private IP 형태의 Routing Table을 만들어 EC2 instancer가 존재하는 Subnet에 연결한다. 이는 마치 On-prem에 Router(L3)에 Server Rack에 있는 Swirtch로 부터 오는 Traffic을 처리하는 Port의 Routing Table를 설정하는 것과 동일한 개념이다. NAT Gateway는 Server Rack에 설치하 듯 이 별도 Subnet에 설치하고, NAT gateway가 설치된 Subnet에 Routing Table은 Internet traffic을 Internet Gateway로 전달하게 설정한다.
여기서 약간의 AWS 용어은 Public Subnet과 Private Subnet에 대한 정의를 잠깐 이해하고 넘어가자.
Public Subnet은 인터넷 Traffic을 Internet GW로 라우팅 시키는 Subnet 이다.
Prvivate Subnet은 Not Public Subnet이다.

EKS는 최소한 2개의 서로다른 Availaity Zone에 Work node를 분산합니다. 따라서 서로다른 Zone에 있는 최소 4개의 Subnet이 필요 합니다. 아래는 레시피 입니다. CIDR은 서로 겹치지 않게 잘 설계합니다.
VPC를 생성합니다. (CIDR 10.0.0.0/16)
Internet Gateway를 생성해서 VPC에 연결합니다.
VPC내에 Subnet을 4개 생성합니다.
Public-Subnet-at-zone-A (CIDR 10.0.10.0/24)
Public-Subnet-at-zone-B (CIDR 10.0.20.0/24)
Private-Subnet-at-zone-A (CIDR 10.0.11.0/24)
Private-Subnet-at-zone-B (CIDR 10.0.21.0/24)
NAT Gateway 2개를 생성합니다.
NAT-Gateway-at-Public-Subnet-at-zoneA
NAT-Gateway-at-Public-Subnet-at-zone-B
Routing Table을 3개 생성하여 Subent에 연결합니다.
{ 10.0.0.0/16 --> Local, 0.0.0.0/0 --> Internet GW } --> Public-Subnet-at-zone-A, Public-Subnet-at-zone-B
{ 10.0.0.0/16 --> Local, 0.0.0.0/0 --> NAT-Gateway-at-Public-Subnet-at-zone-A } --> Private-Subnet-at-zone-A
{ 10.0.0.0/16 --> Local, 0.0.0.0/0 --> NAT-Gateway-at-Public-Subnet-at-zone-B } --> Private-Subnet-at-zone-B
Security Group 1개를 생성합니다.
EKS에 필요한 Inbound/ourbond rule를 설정해서 EC2 instance에 부여할 Security Group으로 Default 설정으로 생성합니다.
앞서 캡쳐한 화면을 통해 Step-by-Step 진행하면 된다.
Step1 에서 Cluster Service role를 생성하자
IAM console 링크 클릭
Create role --> AWS Service --> Choose a use case --> EKS --> Select your use case --> EKS - Cluster --> Next
다 만들고 나며, 만든 role 선택
Step2 에서 미리 만들어둔 Networking 자원을 선택하자
Subnet 선택 시, Private Subnet 2개를 선택하자.
Step3 ~ 4는 그냥 물 흐르듯이....하면 된다.
아래는 kyuho라는 이름으로 생성된 EKS Cluster 다. Work node는 생성되지 않은 상태다. 즉 EKS 생성은 EKS Master node 생성까지를 의미한다. Work node는 EC2 instance와 Fargaeway 두가지 옵션을 제공하는데, 필자는 Fargateway에 대해서는 무지함으로 EC2 instance 기준으로 설명을 이어 가겠다.

kubectl로 생성된 cluster에 연결하기 위해서는 kubeconfig 화일을 작성해야 하는데, 2022년 1월 기준 필자는 aws가 제공하는 cli tool를 이용하는 방법만 찾았다.
https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html
아래와 같은 명령어로 kubeconfig 화일을 생성 혹은 머지 한다.
aws eks update-kubeconfig --region region-code --name cluster-name
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 172.20.0.1 443/TCP 19h
Add node group 추가는 Step by Step으로 진행하면 된다.
아래 권한 부분만 설정하면 된다, 이때는 EKS Cluster와 달리 EC2에 대한 권한이다.

Node Groupd에 필요한 IAM role이 가져야 할 policy는 아래와 같다. 참고로 아랴 policy는 EC2 policy니 EKS에서 찾지 말자.

Node Group 생성되면 아래와 같이 AWS console에서 상태를 확인 할 수 있다.
1~4개 instance까지 Scaling되게 만들어 놨고, 기본 1개의 Instance만 실행되게 설정했다.

위 내용은 CLI로도 확인 가능하다.
kubectl get node
NAME STATUS ROLES AGE VERSION
ip-10-0-11-60.ap-northeast-2.compute.internal Ready 15m v1.21.5-eks-bc4871bEKS를 설치하고 연결했으니, 간단한 Test 응용을 하나 올려보자.
보통 nginx를 하나 올려보는 경우가 많지만, 식상하고 이 문서는 뉴비를 위한 것 이니 재미를 위해서 Supermario를 올려 보기로 한다.
누군가가 Supermario를 Docker로 말아서 올려 놓은 컨테이너 이미지가 있다. 따라서 그것을 사용해 보겠다.
들어가기 전에, 앞서 Add-on 이란 용어를 쓴 것을 기억하라. 또한 EKS 구조 그림에서 Client와 연결된 ELB를 기억하라. 기본적으로 Kubernetes는 Kubernetes Cluster내 가상 네트워크만 구성한다. 이 네트워크에 있는 서버가 외부와 통신하려면 External LoadBalancer가 필요하다.
EKS는 설치 후, AWS Load Balancer Controller(https://docs.aws.amazon.com/eks/latest/userguide/aws-load-balancer-controller.html)를 설치하여, Ingress 자원이나 Service 자원 중 type: LoadBalancer 인 경우, External LoadBalancer를 자동으로 만들어 Kubernetes Service와 연결한다. 위 링크는 나중에 설치하는 것 이고, EKS 설치 인 경우 kube-system에 Deployment가 보이지 않는다 뭔가 권한 설정을 한것 같다(신비주의를 위해서 인가?).
자 일단 아래와 같은 yaml을 만들어 적용해 보자.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mario
labels:
app: mario
spec:
replicas: 1
selector:
matchLabels:
app: mario
template:
metadata:
labels:
app: mario
spec:
containers:
- name: mario
image: pengbai/docker-supermario
---
apiVersion: v1
kind: Service
metadata:
name: mario
spec:
selector:
app: mario
ports:
- port: 80
protocol: TCP
targetPort: 8080
type: LoadBalancer그후 확인해 보면 아래와 같이 외부 접속 URL이 나온다.
kubectl get svc mario -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
mario LoadBalancer 172.20.210.129 zzzzzzzzzzzzzzzzzzzz-1143003415.ap-northeast-2.elb.amazonaws.com 80:31383/TCP 20m app=mario브라우저를 통해 잘 들어감을 확인한다.

쓰다 보니 좀 두서 없이 결말이 난 듯 하다. 누구가에게는 도움이 되길 바란다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.