Kubernetes CLI 

K8s의 기본 구성 요소 보기 >>  K8s 1) 쿠버네티스 기본 


Cluster

  • 여기에서는 EKS(Elastic Kubernetes Service)을 이용하여 클러스터를 생성 (AKS, GKE 등 대체 가능)
  • 사전 구성으로 IAM User 생성 및 AWS CLI에 Credential은 프로그래밍 방식 액세스 설정 필요

 

설치 및 사용법

 

eksctl 설치

# 이하 '$' 생략
curl --silent --location "https://github.com/weaveworks/eksctl/releases/download/latest_release/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
sudo mv -v /tmp/eksctl /usr/local/bin

 

kubectl 설치

#AWS CLI 버전 확인
#kubectl 접근을 위해 AWS CLI 버전 1.21 이상 유효. 1.21 이하면 업데이트 핋요
aws --version 
pip install awscli --upgrade --user

#kubectl 설치
curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.21.2/2021-07-05/bin/linux/amd64/kubectl
chmod +x ./kubectl
mkdir -p $HOME/bin && cp ./kubectl $HOME/bin/kubectl && export PATH=$PATH:$HOME/bin
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bashrc
kubectl version --client

 

참조용 Cluster 생성 Flag 매트릭

eksctl create cluster \
		--name eks-an2-cnl-dev \
		--version 1.21 \
		--vpc-private-subnets SUBNET-ID-1,SUBNET-ID-2
		--without-nodegroup
eksctl create nodegroup \
		--cluster eks-an2-cnl-dev \
		--name nodegroup-an2-cnl-dev \
		--node-type t3.micro \
		--nodes 2 \
		--nodes-min 1 \
		--nodes-max 3 \
		#node-private-networking 옵션은 private-subnet 통신 과정에서 유리하게 작용
		--node-private-networking \ 
		--managed=false
        
#그 외 Flag 매트릭
General flags:
  -n, --name string               EKS cluster name (generated if unspecified, e.g. "scrumptious-sculpture-1648975311")
      --tags stringToString       A list of KV pairs used to tag the AWS resources (e.g. "Owner=John Doe,Team=Some Team") (default [])
  -r, --region string             AWS region
      --zones strings             (auto-select if unspecified)
      --version string            Kubernetes version (valid options: 1.12, 1.13, 1.14, 1.15) (default "1.14")
  -f, --config-file string        load configuration from a file (or stdin if set to '-')
      --timeout duration          maximum waiting time for any long-running operation (default 25m0s)
      --install-vpc-controllers   Install VPC controller that's required for Windows workloads
      --managed                   Create EKS-managed nodegroup
      --fargate                   Create a Fargate profile scheduling pods in the default and kube-system namespaces onto Fargate

Initial nodegroup flags:
      --nodegroup-name string          name of the nodegroup (generated if unspecified, e.g. "ng-46273157")
      --without-nodegroup              if set, initial nodegroup will not be created
  -t, --node-type string               node instance type (default "m5.large")
  -N, --nodes int                      total number of nodes (for a static ASG) (default 2)
  -m, --nodes-min int                  minimum nodes in ASG (default 2)
  -M, --nodes-max int                  maximum nodes in ASG (default 2)
      --node-volume-size int           node volume size in GB
      --node-volume-type string        node volume type (valid options: gp2, io1, sc1, st1) (default "gp2")
      --max-pods-per-node int          maximum number of pods per node (set automatically if unspecified)
      --ssh-access                     control SSH access for nodes. Uses ~/.ssh/id_rsa.pub as default key path if enabled
      --ssh-public-key string          SSH public key to use for nodes (import from local path, or use existing EC2 key pair)
      --node-ami string                Advanced use cases only. If 'ssm' is supplied (default) then eksctl will use SSM Parameter; if 'auto' is supplied then eksctl will automatically set the AMI based on version/region/instance type; if static is supplied (deprecated), then static AMIs will be used; if any other value is supplied it will override the AMI to use for the nodes. Use with extreme care.
      --node-ami-family string         Advanced use cases only. If 'AmazonLinux2' is supplied (default), then eksctl will use the official AWS EKS AMIs (Amazon Linux 2); if 'Ubuntu1804' is supplied, then eksctl will use the official Canonical EKS AMIs (Ubuntu 18.04). (default "AmazonLinux2")
  -P, --node-private-networking        whether to make nodegroup networking private
      --node-security-groups strings   Attach additional security groups to nodes, so that it can be used to allow extra ingress/egress access from/to pods
      --node-labels stringToString     Extra labels to add when registering the nodes in the nodegroup, e.g. "partition=backend,nodeclass=hugememory" (default [])
      --node-zones strings             (inherited from the cluster if unspecified)

Cluster and nodegroup add-ons flags:
      --asg-access            enable IAM policy for cluster-autoscaler
      --external-dns-access   enable IAM policy for external-dns
      --full-ecr-access       enable full access to ECR
      --appmesh-access        enable full access to AppMesh
      --alb-ingress-access    enable full access for alb-ingress-controller

VPC networking flags:
      --vpc-cidr ipNet                 global CIDR to use for VPC (default 192.168.0.0/16)
      --vpc-private-subnets strings    re-use private subnets of an existing VPC
      --vpc-public-subnets strings     re-use public subnets of an existing VPC
      --vpc-from-kops-cluster string   re-use VPC from a given kops cluster

 

Cluster 생성

#yaml 기반
eksctl create cluster -f cluster.yaml

 

Cluster 삭제

#eksctl로 생성된 클러스터만 eksctl로 삭제 가능
#삭제전 Cluster에서 실행 중인 서비스 조회
kubectl get svc --all -namespaces

#EXTERNAL-IP(LB) 삭제
kubectl delete svc <서비스 이름>

#Cluster 삭제
eksctl delete cluster --name <클러스터 이름>

#수행 LOG 마지막 줄
#2024-05-17 14:43:37 [✔]  all cluster resources were deleted

 


Pod

  • Pod는 대체적으로 container와 1:1 관계 (1:n 관계도 가능)
  • container는 Pod로 캡슐화가 되어있다.
  • k8s는 container에 직접 배포하지 않기에 캡슐화된 Pod를 배포한다.

 

Pod생성

 

kubectl run

kubectl run nginx --image nginx # nginx pod 기본 생성 명령어

#Namespace를 지정한 Pod 생성
kubectl run nginx --image nginx --namespace=<파드 이름>

#yaml 예시
apiVersion:
kind:
metadata:
	namespace:<파드 이름>
spec:

 

kubectl create

- yaml을 통해서 만드는 방식 (동일 Pod 존재할 경우 에러 발생)

kubectl ceate -f create-nginx.ymal

 

kubectl apply

- Pod가 없으면 new Pod를 생성, Pod가 존재하면 Update 한다.

kubectl apply -f apply-nginx.yaml

 

Pod 조회

kubectl get pods

#상세 조회
kubectl decribe pod nginx <오브젝트> <이름>

#nginx 파드의 상세 조회
kubectl describe pod nginx

#yaml 형식 조회
kubectl get pod nginx -o yaml

#조회 결과 output 저장
kubectl get pod nginx -o > output.yaml

#생성하지 않은 채로 output 저장
kubectl run nginx --image nginx --dry-run=client -o > yaml output.yaml

#output 조회
cat output.yaml

 

Pod 로그 조회

kubectl logs <파드 이름>

#tail -f 조회
kubectl logs -f <파드 이름>

 

Pod 삭제

kubectl delete <오브젝트> <이름>

#실행중인 nginx Pod 삭제
kubectl delete pod nginx

 

 

리소스 확인

 

Pod requests, limits 값 확인

kubectl get po -o yaml <파드 이름>

 


Deployment

  • 뒤이어 나올 ReplicaSet의 상위개념이라고 볼 수 있다.
  • ReplicaSet을 생성하는 Deployment를 정의할 수 있으며, 롤링 업데이트 등 세분화 조작할 수 있는 기능이다.

 

사용법

 

Deployment 생성

#create
kubectl create deployment <디플로이먼트 이름> --image=<이미지 이름>

#yaml
kubectl apply -f <YAML 파일>

 

Deployment 수정

kubectl edit deployment <디플로이먼트 이름>

#Deployment를 추가한 ReplicaSet Pod 설정
kubectl scale --replicas=N deployment <디플로이먼트 이름>

 

Deployment 업데이트(Roll Out)

- Pod가 실행 중인 상태에서 이미지 버전 변경 배포

- 이전 배포 정보는 스케일 다운, 새 배포는 ReplicaSet을 새로 생성하여 스케일 업

- 스케일 다운과 스케일 업은 부분적으로 동시에 발생

kubectl set image deployment/<디플로이먼트 이름> <컨테이너 이름>=<새 배포 태그>

#예시
kubectl set image deployment/sojuking-deployment nginx=nginx:1.23.4

 

Deployment Roll Out 조회

#상태 확인
kubectl rollout status deployment <디플로이먼트 이름>

#이력 확인
kubectl rollout history deployment <디플로이먼트 이름>

#리비전별 상세조회 Flag
# --revision=N

 

Deployment Roll Back

kubectl rollout undo deployment/<디플로이먼트 이름>

#특정 리비전 번호 N으로 롤백
kubectl rollout undo deployment/<디플로이먼트 이름> --to-revision=N

 

Deployment Scaling

#N개의 복제 파드 조정
kubectl scale deployment/<디플로이먼트 이름> --replicas=N

 

Deployment 조회

kubectl get deployment

#namespace
kubectl get deployment -n <네임스페이스>

 

Deployment 삭제

kubectl delete deployment <디플로이먼트 이름>

Set

ReplicaSet

  • Pod 개수를 유지하게 하는 가용성을 보증하는 장치
  • 예를 들어 Pod의 개수를 5개로 설정하였으면, Node가 다운되어 Pod가 사라져도 자동생성으로 Pod 수를 5개로 유지

 

사용법

 

ReplicaSet 생성

#create
kubectl create -f nginx-rs.yaml

#apply
kubectl apply -f nginx-rs.yaml

 

ReplicaSet 확인

#Cluster에 실행중인 ReplicaSet 조회
kubectl get rs

#ReplicaSet 상세 조회
kubectl describd rs

#yaml 형식 조회
kubectl get rs <레플리카셋 이름> -o=yaml

#Pod의 ReplicaSet 조회
kubectl get pod <파드> -o yaml

#실행 예시
kubectl get pod new-replica-set-a10jr -o yaml

#yaml 예시
apiVersion: app/v1
kind: ReplicaSet
metadata:
    name:
spec:
    template:
        metadata:
            name: <파드 이름>
            labels:
                app:
                type:
        spec:
            containers:
            - name: nginx-controller
              image: nginx
    seletor:
        matchLabels:
            type: <파드 라벨>

 

ReplicaSet Scaling

#N개의 복제 파드 조정
kubectl scale rs <레플리카셋 이름> --replicas=N

#예시
kubectl scale rs sojuking --replicas=5

 

ReplicaSet 편집

kubectl edit rs <레플리카셋 이름>

 

ReplacaSet 리소스 삭제

#리소스만 삭제
kubectl delete rs --cascade=orphan <레플리카셋 이름>

#Pod까지 삭제
kubectl delete rs <레플리카셋 이름>

 

DaemonSet

  • Cluster 내 새로운 Node가 하나 생길 때마다, Pod 복제본이 자동으로 Node에 생성 (자동 배포 기능)
  • Cluster 내 모든 Node에는 항상 1개 이상의 Pod 복사본이 존재하도록 보장

 

ReplacaSet과 마찬가지로 DaemonSet도 kind만 제외하고 정의 내용이 같다.

#yaml 예시
apiVersion: app/v1
kind: DaemonSet
metadata:
    name:
spec:
    template:
        metadata:
            name: <파드 이름>
            labels:
                app:
                type:
        spec:
            containers:
            - name: nginx-controller
              image: nginx
    seletor:
        matchLabels:
            type: <파드 라벨>

 

StatefulSet

  • StatefulSet은 각 파드의 독자성을 유지
  • Pod 집합의 Deployment와 Scailing을 관리하며, Pod의 순서 및 고유성을 보장
  • 상태가 없는 앱/웹은 Deployment로 배포, 상태가 있는 DB 같은 경우는 StatefulSet으로 배포한다.

 

 StatefulSet은 Cluster IP가 없는 헤드리스 서비스를 사용해야 한다.

vi soju-sts.yaml

#yaml 예시
apiVersion: app/v1
kind: StatefulSet
metadata:
    name: soju-sts
spec:
  selector:
    matchLabels:
      app: soju-sts
  serviceName: soju-svc-headless #추가된 헤드리스 서비스 이름
  replicas: 2
  template:
    metadata:
      labels:
        app: soju-sts
    spec:
      containers:
      - name: myapp
        image: ghcr.io/fn1vkd2/go-myweb:lupine
        ports:
        - containerPort: 8080

 

Cluster IP가 없는 Service

vi soju-svc-headless.yaml #StatefulSet에 정의한 헤드리스 서비스의 본체

apiVersion: v1
kind: Service
metadata:
  name: soju-svc-headless
  labels:
    app: soju-svc-headless
spec:
  ports:
  - name: http
    port: 80
  clusterIP: None #헤드리스 서비스 정의( Cluster IP: None)
  selector:
    app: soju-sts #soju-sts.yaml의 label 조회

 

StatefulSet 생성

kubectl -f soju-sts.yaml -f soju-svc-headless.yaml

 

StatefulSet 조회

kubectl get sts, svc, ep #sts: statefulSet, svc: service, ep: endpoint

#Controller 뒤의 번호 생성 조회 (고유성)
kubectl get pod -o wide

#network-multitool 이미지 실행
kubectl run nettool --image ghcr.io/fn1vkd2/network-multitool -it --rm

#nettool < Pod 이름 생성
#--image 이미지 지정
#-it Pod를 인터랙티브 모드 실행, 터미널 할당 및 실시간 상호작용 상태
#--rm Pod 종료시 자동 Pod 삭제

#호스트 질의 - 서비스 이름 지정
host soju-svc headless

# StatefulSet + headless >> Pod의 이름으로 통신하여 Pod의 IP 변환
host soju-sts-0.soju-svc-headless
host soju-sts-1.soju-svc-headless

 


Job

Job

  • 프로세스가 종료되면 Container가 다시는 시작되지 않는 배치라 보면 된다.
  • 노드에 장애가 발생하면 ReplicaSet의 파드와 같은 방식으로 다른 노드로 재스케줄 기능이 있다.
  • 프로세스 오류일 경우 Container를 재실행하도록 할 수 있다.

YAML 리소스 구성

apiVersion: batch/v1 # API 그룹은 batch 버전 v1
kind: Job
metadata:
  name: soju-job
spec:    
  template:
    spec:
      containers:
      - name: soju-job
        image: 2.mi.g
        command: ["Job 끝내고 쐐애주나 마시자!"]
      restartPolicy: Never #Pod의 재시작 정책 설정
      completions: 2 #실행 종료되어야 하는 파드 수 설정 (기본값 1)
      parallelism: 2 #잡 병렬성 관리(기본값 1)
  backoffLimit: 2 #재시도 횟수 설정
  activeDeadlineSeconds: 100 #Pod의 실행시간 설정(넘으면 Pod 종료 시도 및 Job은 Fail)

 

Job 삭제

#Job을 삭제하면 관련 Pod도 같이 삭제가 된다.
kubectl delete job <잡 이름>

 

Cronjob

  • 반복 작업을 실행하는 데 사용하는 리소스 중 하나, 지정된 시간 또는 간격으로 작업 생성한다.
  • Linux의 crontab 기능을 떠올리면 된다.

 

YAML  리소스 구성

apiVersion: batch/v1 # API 그룹은 batch
kind: CronJob
metadata:
  name: soju-cronjob
spec:
  schedule: "*/1 * * * *"   #매 1분마다 실행
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: soju-cronjob
            image: busybox
            command: ["퇴근하고 쐐애주나 마시자!"]
          restartPolicy: OnFailure
  concurrencyPolicy: Forbid

 

CronJob 조회

kubectl get cronjobs

 

CronJob 삭제

kube delete cronjobs <크론잡 이름>

Resource 

  • 다수의 컨테이너가 Pod에 있으면 Request와 Limit은 각각의 컨테이너에 개별적으로 할당
  • Resource 중 CPU는 Resource Limit 보다 초과로 사용 불가, Memory는 사용 가능하나 Pod 다운 및 OOM 발생

 

Resource 감시

 

kubectl top 설치

-top을 사용하기 위하여 명령어로 설치

git clone https://github.com/kodekloudhub/kubernetes-metrics-server.git
cd kubernetes-metrics-server/
kubectl create -f

 

CPU, Memory 사용율 확인

#node 확인
kubectl top node

#pod 확인
kubectl top pod

 

 

Resource 제한

 

Resource Limit 

-Pod 내 리소스 사용량을 제한

apiVersion: v1
kind: Pod
metadata:
    name:
spec:
    containers:
    - name: sojuking
      image: nginx
      ports:
        - containerPort: 8080
      resources:
        requests: #요구되는 리소스 양
          memory: "2Gi"
          cpu: 2
        limit: #리소스 사용 제한
          memory: "4Gi"
          cpu: 4

 

 

Resource Quotas

- K8s 내 배포된 전체 애플리케이션이 소모하는 전체 리소스의 양을 제한

- namespace 레벨에서 적용

apiVersion: v1
kind: ResourceQuota
metadata:
  name: sojuking-quota
spec:
  hard:
    requests.cpu: 2
    requests.memory: 2Gi
    limits.cpu: 10
    limits.memory: 10Gi

krew

  • kubectl을 보다 편리하게 사용할 수 있게 해주는 Plugin 관리 도구이다.
  • kubectl v1.12 이상의 버전에서 사용 가능하다.
  • git 설치가 되어 있어야 한다.

 

설치법

 

설치 명령어

(
  set -x; cd "$(mktemp -d)" &&
  OS="$(uname | tr '[:upper:]' '[:lower:]')" &&
  ARCH="$(uname -m | sed -e 's/x86_64/amd64/' -e 's/\(arm\)\(64\)\?.*/\1\2/' -e 's/aarch64$/arm64/')" &&
  KREW="krew-${OS}_${ARCH}" &&
  curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/latest/download/${KREW}.tar.gz" &&
  tar zxvf "${KREW}.tar.gz" &&
  ./"${KREW}" install krew
)

 

Path 추가

export PATH="${KREW_ROOT:-$HOME/.krew}/bin:$PATH"

 

설치 확인

kubectl krew

 

 

사용법

 

Plugin 설치

kubectl krew install NAME <플러그인 이름>

#예시
kubectl krew install sojuking

 

Plugim 사용

kubectl <플러그인 이름>

 

Plugin 업데이트

kubectl krew upgrade <플러그인 이름>

#모든 플러그인 업그레이드
kubectl krew upgrade

 

Plugin 검색

kubectl krew search KEYWORD

#모든 플러그인 목록 확인 (키워드 제거)
kubectl krew search

#설치 플러그인 목록 확인
kubectl krew list

 

 

Plugin 삭제

kubectl krew uninstall <플러그인 이름>

 


 

 

 

'Architecture' 카테고리의 다른 글

K8s 1) 쿠버네티스 기본  (0) 2024.05.17
Kafka 3) MSK Cluster 모니터링 메트릭  (2) 2024.01.11
Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 5) MSA 분리 전략 : 도메인 주도 설계  (0) 2023.11.01

Kubernetes

※ Docker 등 Container에 대한 기본 설명은 제외하였습니다.


K8s의 구조

  • Master에 API 서버와 상태 저장소를 두고, 각 Node(서버)의 에이전트(Kublet)와 통신하는 구조

K8s의 구조 : Master

  • K8s 클러스터 관리하는 역할
  • 노드의 상황을 파악
  • 컨테이너를 어떤 노드에서 가동할지 선택
  • etcd 분산 저장소를 사용하여 클러스터의 정보를 저장

K8s 구조 (By.Lukša)

Master

 API Server

  • API 서버는 모든 요청을 처리하는 마스터의 핵심
  • 모든 컴포넌트들은 API 서버를 통해서 커뮤니케이션함
  • 인증 및 인가 기능 보유

Scheduler

  • 컨테이너를 어떤 노드에서 가동할지 결정하는 컴포넌트
  • 노드들의 정보를 파악하고 컨테이너를 가동할 적합한 노드 선택

Controller Manager

  • K8s 클러스터의 상태를 감시
  • 시스템의 상태 감시 및 유지
  • 요청된 상태와 현재 시스템의 상태의 차이 감시

etcd 

  • 분산 key-value 저장소
  • 클러스터의 모든 설정, 상태 데이터 저장
  • 스케줄러와 컨트롤러 매니저 등이 API 서버를 통해 etcd의 데이터 조회 및 갱신
  • 마스터에서 분리하여 독자적으로 분리 가능

K8s의 구조 : Node

  • 컨테이너가 가동되는 서버
  • 다수의 노드로 클러스터를 구성
  • 클라우드의 경우 가상머신이 노드가 됨 ex.) ec2...

K8s 구조 (By.Rancher Admin)

Node

Kubelet

  • 실제로 컨테이너를 생성하는 주체
  • 마스터로부터 생성 요청을 받으면 컨테이너를 생성
  • 컨테이너의 상태를 감시하는 역할 수행
  • 컨테이너의 상태를 API 서버로 전송

Kube proxy

  • 각 노드에서 실행되는 네트워크 프록시
  • 노드의 네트워크 규칙을 유지 및 관리
  • 내부 네트워크 세션, 클러스터 외부에서 내부로 네트워크 통신

Pod

  • 한 개 또는 여러 개의 컨테이너의 묶음

 


K8s Object

  • Container, Network 등 분산에 필요한 필요 요소의 추상화

K8s Object

Object

Replica Set

  • Pod를 한 개 이상 복제하여 관리
  • Pod를 생성하고 개수 유지를 위해서 ReplicaSet을 사용해야 함

Daemon Set

  • 클러스터 전체에 Pod를 띄울 때 사용하는 Controller
  • 항상 모든 Node에 특정 Pod가 실행됨
  • 새로운 Node가 추가되면 자동으로 Pod 실행됨
  • 로그 수집기, 모니터링 에이전트 등 실행하는 용도

Stateful Set

  • K8s 대부분의 Object는 Stateless
  • StatefulSet은 상태를 유지하는 Pod를 위한 Object
  • Volume을 사용해서 데이터 저장, Pod 재기동 시에도 유지 가능
  • DB 등을 컨테이너화 할 때 사용 가능

Pod

  • K8s에서 배포할 수 있는 가장 작은 단위
  • 한 개 이상의 컨테이너와 스토리지, 네트워크 속성을 가짐
  • Pod에 속한 컨테이너는 스토리지와 네트워크를 공유하고 서로 localhost로 접근 가능

Service

  • 네트워크와 관련된 Object
  • Pod 간 연결 및 Pod와 외부 네트워크를 연결
  • 여러 개의 Pod에 대한 내부 로드밸런서
  • 내부 DNS에 서비스 등록하여 서비스 디스커버리 역할도 함
  • Pod에 대한 L4 로드밸런싱 수행
  • Cluster IP, Node Port, Load Balancer 등 옵션 지정 가능

Deployment

  • K8s에서 실제 배포를 진행하는 기본 단위
  • 배포 Revision 관리 및 Roll Back 등 다양한 옵션 제공

Ingress

  • 외부 트래픽을 받는 Object
  • Http/ Https 등 L7 레벨로 라우팅 규칙, 로드벨런싱 규칙 등도 포함
  • Service도 외부로 노출 가능하지만 L4 레벨만 가능

Others

  • ConfifMap, Secret : 설정정보 저장 등 Pod 참조
  • Job, CronJab : 배치 관리
  • Label, Selector : 자원 관리 위해 Labeling

 


K8s Manifest File

  • 선언적 설정을 위한 YAML/JSON 형태의 파일

Manifest File

YAML or JSON

YAML

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.20.1
    ports:
    - containerPort: 80

Json

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "nginx"
  },
  "spec": {
    "containers": [
      {
        "name": "nginx",
        "image": "nginx:1.20.1",
        "ports": [
          {
            "containerPort": "80"
          }
        ]
      }
    ]
  }
}

apiVersion

  • K8s API 버전 정보 기술

kind

  • Object의 종류 기술 (Pod, Service...)

metadata.name

  • Object 이름을 기술

spec

  • Object 상세 정보 기술
  • 포트 등 환경 정보 기술

 


K8s 사용


K8s 사용

유/무료 설치형 배포판

  • Red Hat OpenShift
  • Pivotal PKS
  • Rancher
  • Kubeadm

Cloud Managed Kubernetes

  • EKS
  • GKE
  • AKS
  • NCloud K8s Service


 

'Architecture' 카테고리의 다른 글

K8s 2) 쿠버네티스 구축  (0) 2024.05.18
Kafka 3) MSK Cluster 모니터링 메트릭  (2) 2024.01.11
Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 5) MSA 분리 전략 : 도메인 주도 설계  (0) 2023.11.01

도메인 주도 설계 (DDD)


서비스 분리와 도메인 주도 설계

  • DDD는 MSA의 서비스를 식별할 수 있는 도구를 제공
  • DDD 중 전략적 설계가 MSA의 서비스를 식별하는데 도움

도메인이란?

  • 소프트웨어를 개발하는 대상 영역
  • 복잡한 비즈니스나 현실세계의 문제

도메인 주도 설계란?

  • 복잡한 현실세계의 문제를 해결할 좋은 SW를 만들기 위한 기법
  • 도메인 주도 설계는 도메인의 이해를 최우선시 하는 모델링 기법
  • 전문가와 개발자의 커뮤니케이션이 중요
  • 도메인과 도메인 모델 그리고 코드를 밀접하게 연관 시킴 (언어의 통일)
  • 도메인 모델 - 동일한 관점에서 이해할 수 있고, 공유할 수 있도록 단순화 (다이아그램 사용)
  • 코드에 도메인의 의미가 녹아 있도록 구현

DDD의 필요성 : Big Ball of Mud

  • 요구사항 추출 -> 분석 -> 설계 -> 구현
  • 계속되는 추가 요구사항
  • 중요한 것과 덜 중요한, 혹은 중요하지 않은 것들이 하나의 큰 덩어리로 얽히게 됨

Big Ball of Mud (CodeOpinion참조)

  • 각 클래스(엔티티)의 의미 파악 어려움

DDD의 필요성 : Big Ball of Mud 원인 by Vaughn Vernon

  • 조직에서 SW 설계에 충분한 노력을 들이지 않음
  • 개발자는 도메인 보다 기술에 너무 몰두, 많은 문제를 기술적으로만 해결하려 함
  • 도메인의 이해 없이 개발자 상상의 나래가 표출됨

 


전략적 설계

마이크로서비스 도출을 위해서 비즈니스 상 전략적으로 중요한 것을 찾아 중요도에 따라 이를 나눔

 


전략적 설계의 필요성

  • 애자일 프로젝트 관리 시스템을 개발 사례
  • 설계 초기에는 핵심이 되는 부분을 설계
  • Big Ball of Mud 방지

서브 도메인

  • 전체 비즈니스 도메인을 이해 가능한 하위 영역으로 분리 필요
  • 전체의 큰 도메인을 분리함
  • 핵심 서브 도메인, 지원 서브 도메인 (비즈니스 도메인), 일반 서브 도메인(큰 공수 없는 도메인)으로 분리

바운디드 컨텍스트

  • 유비쿼터스 언어로 표현이 됨
  • 의미적으로 동일한 맥락의 경계라는 것은 응집도 높은 일을 한다는 것
  • 바운디드 컨텍스트 마다 각각 분리된 소프트웨어의 코드 산출

서브도메인과 바운디드 컨텍스트의 관계

  • 서브 도메인은 Problem Space
  • 바운디드 컨텍스트는 Solution Space
  • Problem Space : 해결해야 하는 도메인 -  서브 도메인들의 집합
  • Solution Space : 해결책을 실제 구현 - 바운디드 컨텍스트들의 집합
  • 보통 하나의 서브도메인은 하나의 바운디드 컨텍스트를 갖는 1:1
  • 서브도메인이 하나 이상의 바운디드 컨텍스트가 매핑 가능 (ex). 상품 - 연관상품, 쿠폰, 할인정보 등)

유비쿼터스 언어와 바운디드 컨텍스트의 관계

  • 제품 책임자와 도메인 전문가 그리고 개발자 간 언어의 통일이 중요
  • SW 개발의 가장 큰 문제 중 하나 (개발언어 x,  사용언어 o)
  • 개발자가 아닌 사람도 도메인 모델 및 코드를 보고 이해할 수 있어야 함
  • 컨텍스트에 따라 비슷해 보이는 언어들이 실제로는 다를 수 있음
  • 각 문맥 별로 상품의 이름을 명확하게 재정의할 필요가 있음

       ex) - 카탈로그 컨텍스트에서의 상품은 Product

             - 재고 컨텍스트에서의 상품은 Stock

             - 주문 컨텍스트에서의 상품은 OrderedItem

 


결론

개발자가 아닌 사람이 이름만 딱 봐도 무엇인지 알 수 있도록 설계를 하자.



 

'Architecture' 카테고리의 다른 글

Kafka 2) 모니터링  (2) 2024.01.11
Kafka 1) 연결 모니터링  (2) 2024.01.11
MSA 4) MSA 분리 전략 : 분리 원칙  (0) 2023.11.01
MSA 3) MSA 역량/성숙도 모델  (4) 2023.10.18
MSA 2) Microservice Architecture 에 대해서  (0) 2023.10.18

분리 원칙


작고 분리가 쉬운 서비스로 워밍업

  • MSA 성공적 전환 위해서는 다양한 사전 준비사항이 존재함

       - Cloud, Deployment Pipeline, Container, Monitoring 등

  • 본격적 MSA 분리 전 간단한 서비스 분리하여 역량 내재화
  • 한 두개 정도 간단한 서비스 분리하여 필요한 인프라, 프로세스 구축
  • 작은 Pilot 서비스 선택
  • 신규 서비스 -> 기존 Monolith 로의 의존성이 없거나 적은 서비스
  • 신규 서비스 -> 기존 Monolith 의존성이 존재하면 Monolith 변경에 영향을 받음

핵심 기능의 분리

  • 핵심 기능은 다른 기능들과 결합도가 높음
  • 도메인 경계가 명확하지 않을 가능성 높음
  • 분리할 핵심 기능의 도메인을 명확하게 해야 함
  • 비즈니스 팀 구조를 기반으로 분리
  • 도메인 주도 설계 적용

데이터의 분리

  • 워밍업을 위해 DB 분리 없이 코드만 분리 가능
  • Anti-Pattern 중 하나가 서비스 별 공유 DB를 갖는 것
  • 독립 된 저장소 및 데이터 Migration 전략 수립이 동반 되어야 함

분리 대상 선정

  • First Step은 조직의 목표를 명확히 해야 함
  • 히스토리를 파악하여 기능 별 빈도 분석
  • 프로젝트 로드맵을 기반으로 향후에 크게 수정 될 것 선정

코드의 재사용 vs 재개발

  • 기술 부채 및 노후된 기술
  • 오랜 기간 유지보수 된 코드의 문제점
  • 요구사항 파악하여 비즈니스 도메인 명확화

진화적인 서비스 분리

  • 서비스의 크기를 고려해야 함
  • 원칙 - Go Macro, then Micro
  • 우선 크게 분리하고 필요한 경우 재설계를 통해 더 작게 분리

반복/점진적 분리

  • Monolith -> MSA 전환은 여정이 험난함
  • 한번에 하나씩 단계적 분리
  • 하나의 작은 기능을 신규 서비스로 분리
  • 클라이언트로 부터의 Request를 신규 서비스로 전환 - Proxy 필요

Strangler PAttern Progression (akf 참조)

  • Monolith에서 Method 호출하던 의존성 모두 신규 서비스로 전환
  • Monolith 내부의 기존 코드는 잠시 유지 후 반드시 제거

 

결론

완벽한 정답은 없겠지만

참고 시, 언젠가 반드시 도움이 될 가능성이 높다.

 

 

Rajesh RV 역량 모델

- 핵심 역량

- 지원 역량

- 인프라스트럭처 역량

- 프로세스 및 통제 역량

 

1. 핵심 역량 : 서비스 별 배포 되는 SW 패키지에 필수 요소

    <단일 서비스 내 패키징 되는 SW 컴포넌트들>

    - 서비스 Listener :

        - HTTP 등의 리스너가 애플리케이션에 내장되어 있어야 함 (Ex. Spring Boot와 같은 Self Contained 방식 필요)

 

    - EndPoint :

        - HTTP 요청을 받아 처리 할 API가 애플리케이션 내부에 있어야 함

        - 다양한 프로토콜 및 동기/비동기 등 사용 가능

 

    - 서비스 구현 :

        - 각 서비스의 핵심 로직을 구현

        - 응집도 높고 단일 책임의 원칙을 지켜야 함

        - 외부 시스템에 영향을 받으면 안됨.  =>Spring Data, Spring Message 등으로 해결

        - 계층형 아키택처 사용 권고

 

    - 데이터 저장 :

        - 각 서비스 마다 상태나 데이터를 저장할 데이터 소스가 있어야 함

        - 데이터 소스는 하나의 서비스에 한정 되어야 하고, 다양한 기술을 이용 가능 (Ex. Polyglot Persistence, NoSQL 등)

 

2. 지원 역량 : 지원 기술 및 설계 패턴

    - Service Discovery :

        - 서비스/인스턴스 개수가 많아 복잡해져 생기게 됨

        - 물리적인 정적인 정보를 동적으로 바꾸게 함

        - 서비스 간에 다른 서비스의 물리적인 주소를 유지하지 않음

        - 유연하게 인스턴스 및 서비스를 추가 삭제 가능함

 

    - Config Server :

        - 설정정보를 애플리케이션에서 완전히 분리.

        - 중앙 Config에서 설정관리, 저장 백엔드로는 Git, DBMS사용.

        - 설정정보 변경 시 서비스 재배포 없이 적용 가능

 

    - Service Gateway :

        - 다양한 서비스들에 대한 단일 진입점

        - 인증, 인가, 로깅, 필터링 등의 공통 처리 수행

 

    - SW Defined Load Balancer

        - MSA에서는 인프라 토폴로지가 매우 복잡

        - 서비스를 호출하는 클라이언트에서 SW로 로드밸런서 수행

 

    - Circuit Breaker

        - 서비스의 장애는 언제든 발생 가능하고 장애 방지 설계 필요

        - 한 서비스의 장애는 다른 서비스들에 전파되어 전체 시스템 장애로 이어질 수 있음

        - 특정 서비스 장애는 그 서비스만의 장애로 격리

        - 서비스 간의 Circuit Breaker라는 컴포넌트가 삽입 됨 (장애발생 판단되면 Circuit 차단)

 

    - Distributed Tracing

        - 서비스 간 모든 호출에 추적 ID를 삽입

        - 추적 ID를 Key로 하여 단일 API 트랜잭션의 활동을 파악

 

    - Data Lake

        - MSA에서는 데이터 파편화 가능성 존재

        - 비정형 원시 데이터를 그대로 저장

        - 데이터 분석 할 시점에 데이터 가공에 대해 고민

        - 실시간 이용 (Kafka 등)

 

    - Messaging

        - 메시징을 이용한 서비스 간 협력 설계 방식을 권고

        - 메시징은 서비스 간 결합도를 낮출 수 있음

        - 고가용성 메시징 솔루션이 필요

 

3. 인프라스트럭처 역량 : 컨테이너 및 컨테이너 오케스트레이션

    - 클라우드 :

        - On Demand

        - 대용량 확장 가능한 환경

        - 몇 번의 클릭만으로 리소스 사용 가능 (Ex. Auto Scaling으로 자동화된 Provisioning)

        - 다양한 자원/서비스 제공 (자원, DB, AI etc)

 

    - 컨테이너 런타임 :

        - 컨테이너 기술을 이용하여 빠른 환경 구성 및 배포 가능

        - 컨테이너 이미지는 런타임 코드가 동시에 존재 (Docker, etc)

 

    - 컨테이너 오케스트레이션 :

        - 많은 수의 컨테이너 관리 가능

        - 배포/모니터링 비용 최소화 (Kubernetes, ECS, Mesos/Marathon etc)

 

4. 프로세스 및 통제 역량 : 데브옵스 및 문서화

    - DevOps

        - 에자일과 DevOps는 MSA 성공을 위한 필수 요소 중 하나

        - 지속적 통합, 자동화된 배포, 자동화된 QA

        - 에자일 도입하여 짧은 개발주기로 반복적으로 개발하여 빠르게 Delivery

 

    - 컨테이너 레지스트리

        - MSA에서 컨테이너는 필수적

        - 컨테이너의 핵심인 이미지 등의 관리 필요

        - 코드 형상 관리와 유사

        - Docker Hub, GCR... etc

 

    - 문서화

        - 서비스들은 인터페이스를 통하여 통신

        - 인터페이스의 문서화가 중요

        - 일반 Method 호출보다 복잡하기 때문에 다양한 정보가 들어 있어야함 (필수/선택 파라미터, 버전, 응답정보 등)

        - 웹으로 쉽게 열람할 수 있어야 함

        - Spring REST Docs, Swagger 등

 

    - 참조 아키텍처 및 라이브러리

        - 탈중앙화된 방식은 비효율성을 야기할 수 있음

        - 조직의 기술별 참조모델 중요 -> 프레임워크화 할 수도 있음


Rajesh RV 성숙도 모델


Rishi Singh 성숙도 모델

- 총 9가지 영역에서 4단계의 성숙도 모델 제안

- 4단계 : Early, Inception, Expanding, Mature

- Expanding 단계가 현실적인 MSA 수준

- Mature는 다소 이상적인 수준

 

1. 기능적 분할 영역

    - Early : Business 역량에 따른 기능 분할

    - Inception : Modular Monolith, 서비스간 명확한 Interface

    - Expanding : 도메인 주도 설계에 의한 잘 분할 된 서비스

    - Mature : 이벤트 기반의 협력, 조회와 명령의 분할

 

2. Data 영역

    - Early : 서비스간 저장소 공유, ACID 기반 트랜잭션

    - Inception : 일부 새로운 서비스들에 대해 독립된 저장소

    - Expanding : 모든 서비스들의 독립적인 저장소

    - Mature : Event 기반 데이터 관리, 이벤트소싱 CQRS

 

3. Testing 영역

    - Early : 수동/자동 Testing 혼재

    - Inception : 완전 자동화된 Testing 수행

    - Expanding : Chaos Enginerring

    - Mature : Consumer Driven Contract, 고객 페르소나 기반 E2E Testing

 

4.  Infrastructure 영역

    - Early : Continuous Integration/Buid

    - Inception : Continuous Deployment, 중앙집중형 Logging

    - Expanding : Container/Orchestration, 설정 외부화

    - Mature : 완전 자동화 된 Provisioning 지원하는 PaaS

 

5.  Deployment 영역

    - Early : Script 기반, 호스트 당 다중 서비스 배포

    - Inception : VM 당 단일 서비스 배포

    - Expanding : Container 당 단일 서비스 배포, Immutable Infra, Blue/Green Deployment

    - Mature : Multi-Datacenter 배포

 

6.  Monitoring 영역

    - Early : Application Performance Monitoring

    - Inception : Cetralized Logging System

    - Expanding : Container Monitoring

    - Mature : Distributed Tracing, Trace as a Service, Synthetic Transaction

 

7.  Governance 영역

    - Early : 중앙집중화된 Governance

    - Inception : 일부 Monolith, 일부 Microservices의 Shared Governance Model로 과도기적 형태

    - Expanding : 완전한 분산 된 Governance

    - Mature : 참조 아키텍처 및 참조 방법론 등의 지원

 

8.  Team Structure 영역

    - Early : Dev, QA, Ops 등 기술 별 조직

    - Inception : 일부 Cross Functional 팀

    - Expanding : 제품 기반 개발팀과 이를 지원하는 Platform 팀(운영, 모니터링 등)

    - Mature : 완전한 제품 기반 DevOps

 

9.  Architecture 영역

    - Early : ESB를 사용하는 SOA 기반의 아키텍처 또는 Modular Monolith 구조

    - Inception : Monolith 시스템에 신규 기능을 Microservice로 개발하는 형태

    - Expanding : 모든 비즈니스 기능이 Microservice로 분리 되어 서로 Network 인터페이스로 협력

    - Mature : Event 기반, Serverless 도입

Monolithic System : 모놀리식 아키텍처는 소프트웨어 프로그램 설계를 위한 전통적인 통합 모델


Monolithic System 종류
 Single Monolithic System
 - 일반적인 형태
 - 큰 진흙 공이라고 불림 

 Modular Monolithic System
 - 각 기능별로 모듈화 되어있는 형태 
 - MSA의 좋은 대안이 될 수 있음
 - 배포, 확장에 대한 이슈는 여전히 존재
 - 타 기능 데이터 직접 접근에 의한 결합도
 - 모듈 간의 결합도를 자주 관리해야 함

 Distributed Monolithic System
 - 분산된 Monolith
 - 쪼갰다고 MSA가 아님
 - 쪼개진 서비스 간에 매우 강결합 된 형태
 - 항상 같이 배포되는 형태


Monolithic System 장점
 - 상대적 운영하기 용이 
 - 내부 메소드 호출로 성능 문제 없음
 - 트랜잭션 관리 용이

 

Monolithic System 단점 
 - 스케일 아웃 시 전체 시스템 확장해야 함
 - 빌드/배포 시간 오래 걸림
 - 작은 수정에도 전체 시스템 빌드/배포 해야 함
 - 하나의 버그에 전체 시스템이 실패할 수 있음
 - 기능간 결합도가 일반적으로 높음
 - 기능 변경 시 영향도 파악 어려움

+ Recent posts