파이널 프로젝트 - 13주차 4일(3/16)

최수환·2023년 3월 16일
0

Kubernetes

목록 보기
59/75
post-thumbnail

인프라 구축

  • 착수보고서가 끝나고 본격적으로 인프라 구축을 시작했다.
  • Front/back 개발을 담당하는 팀원도 이제 개발을 시작했기에 Front/back 실행파일이 존재하지 않는다. 따라서 개발자가 git에 push한 실행파일을 가지고 Jenkins가 테스트와 빌드를 거쳐 이미지를 생성해 Docker Hub에 넣어서 ArgoCD와 연동중인 Git에서 Docker Hub에 Push된 이미지를 가져와 배포하지 못한다.
  • 따라서 우선적으로 개발이 완료되기 전까지는 Jenkins를 사용하지는 않고 기존의 이미지를 사용하여 클러스터에 배치할 오브젝트를 YAML파일로 작성을 해두기로 했다.
  • 이후 YAML파일로 작성한 코드를 새로운 Git repo를 생성해서 Push한다.
  • ArgoCD에 접속할 수 있게 ArgoCD서비스를 설치하고 aws로드밸런서 주소로 ArgoCD로 접속한다.
  • ArgoCD에서 Yaml파일이 존재하는 Git을 연동해서 클러스터를 배포한다.

📌 개발이 완료되기 전까지 인프라 구축을 완료할 것이다.

  • 생성한 클러스터 오브젝트들은 ArgoCD로 배포가 잘 되는지 테스트 단계를 거친다.
  • 이후 개발이 완료되면 개발자의 Front / Back 코드를 가지고 Jenkins에서 이미지화 시켜서 ArgoCD가 기존의 이미지가 아닌 새로운 개발자의 이미지로 배포하게 파이프라인을 구성한다.

📒 Frontend - Backend - DB : 3-tier (3계층) 구조

  • Frontend는 클라이언트가 보는 정적페이지를 구축
  • Backend는 서버의 역할로, 클라이언트가 정적페이지와 상호작용을 할때 DB의 정보를 가지고 페이지가 계속 바뀌게끔 동적으로 구성한다.
  • DB는 여러 정보를 저장한다.

📒 Backend - Spring Boot, Frontend - html, css, js

  • 개발자가 Spring Boot로 Backend 코드를 완성하게되면 src디렉터리와 pom.xml파일이 결과물로 산출된다. 이 산출물을 maven or gradle로 test와 빌드를 거치게 되고 target디렉터리가 반환된다. target디렉터리에는 jar or war파일이 존재한다.
    Dockerfile에서 tomcat서버를 생성하고 war or jar파일을 tomcat서버의 특정 디렉터리에 복사하는 코드를 작성한다.
    이렇게 복사함으로서 java기반의 웹 어플리케이션인 tomcat서버에 Backend 서버를 배포하는 것이다. 이것을 이미지로 만들어서 파드로 띄우게 되면 백엔드 서버역할을 하는 파드가 생성되는 것이다
  • 만일 프로젝트의 규모가 작다면 그냥 Frontend를 구성하지 않고 Backend에서 index.jsp와 같은 client가 보는 웹페이지를 작게 구성해서 tomcat서버에 같이 올릴 수도 있다. 이렇게 해도 클라이언트는 Frontend없이 웹 페이지를 볼 수 있다. 하지만 보통 클라이언트가 상호작호작용하는 웹페이지는 대량의 데이터가 오가기 때문에 Frontend tier를 구성한다.
  • Frontend를 구성하면 마찬가지로 실행파일이 생성되고 이 파일을 이미지로 구성해서 파드를 띄우면 클라이언트는 index.jsp처럼 웹 페이지를 보게 될 것이다. 여기에 Backend를 연결하게 되면 Backend 서버에 의해 클라이언트와 웹 페이지와의 동적인 상호작용이 가능해진다.

클러스터 배포

# eksproject.yaml파일
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: eksproject
  region: ap-northeast-2
  version: "1.24"

# AZ
availabilityZones: ["ap-northeast-2a", "ap-northeast-2b",  "ap-northeast-2c"]

# IAM OIDC & Service Account
iam:
  withOIDC: true
  serviceAccounts:
    - metadata: # ingress,LB를 위한 loadbalancer controller 애드온 추가
        name: aws-load-balancer-controller
        namespace: kube-system
      wellKnownPolicies:
        awsLoadBalancerController: true
    - metadata: # 스토리지 클래스를 위한 애드온 추가
        name: ebs-csi-controller-sa
        namespace: kube-system
      wellKnownPolicies:
        ebsCSIController: true
    - metadata: # HPA를 위한 Metrics-server 애드온 추가
        name: cluster-autoscaler
        namespace: kube-system
      wellKnownPolicies:
        autoScaler: true

# Managed Node Groups
managedNodeGroups:
  # On-Demand Instance
  - name: mynodes-t3
    instanceType: t3.medium
    minSize: 1
    desiredCapacity: 2
    maxSize: 3
    privateNetworking: true # 워커노드를 프라이빗 네트워크에 감춘다.
    #ssh:
      #allow: true
      #publicKeyPath: ./keypair/myeks.pub
    availabilityZones: ["ap-northeast-2a", "ap-northeast-2b", "ap-northeast-2c"]
    iam:
      withAddonPolicies:
        autoScaler: true
        albIngress: true
        cloudWatch: true
        ebs: true

# Fargate Profiles
fargateProfiles:
  - name: myfg
    selectors:
    - namespace: dev
      labels:
        env: dev

# CloudWatch Logging
cloudWatch:
  clusterLogging:
    enableTypes: ["*"] # 모든 로그를 클라우드워치에 남긴다
  • 이전에 작성한 인프라 아키텍처대로 두개의 워커노드(EC2인스턴스)를 생성한다
  • 각 EC2인스턴스는 2a, 2b, 2c 가용영역에 분포된다.
  • Ingress와 HPA, 오토스케일링 그룹, 스토리지를 위한 애드온을 생성한다.

클러스터 오브젝트 생성

금일 인프라 구축 작업에서는 Frontend에는 nginx이미지를, Backend에는 이전 파이프라인 실습에서 빌드하였던 이미지를 임시적으로 사용해서 디플로이먼트를 생성하고, 서비스와 ingress를 생성하는 것을 목표로 한다.

  • 개발이 완료되는 대로 해당 Front와 Back에 임시적으로 사용되었던 이미지를 교체할것이다.
  • YAML파일 작성 코드들, 기타 코드들은 모두 GitHub에 commit되지만 이 블로그에도 남길 것이다.

Frontend

  • 간단하게 nginx이미지로 Frontend파드를 생성해서 외부에서 접속이 잘 되는지 테스트한다.

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: front-deploy
spec:
  replicas: 2
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      name: front-deploy
      labels:
        tier: frontend
    spec:
      containers:
      - name: front-app
        image: nginx:alpine # nginx 이미지 
        ports:
        - containerPort: 80
          protocol: TCP

Service

apiVersion: v1
kind: Service
metadata:
  name: front-svc
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 31112
  selector: 
    tier: frontend
  • NodePort 타입의 서비스

Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: front-ing
  annotations: # AWS에서 ALB로 사용할수 있게 만든다
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: front-svc
            port:
              number: 80
  • 외부에서 포트번호를 입력하지 않고도 접속이 가능하게 하는 L7에서 작동하는 ALB 생성
  • Ingress를 사용하기 위해서는 LoadBalancer Controller 애드온을 설치하여야한다.
    • 애드온 설치후 위의 어노테이션 추가

Backend

  • 이전의 실습했던 이미지를 Docker Hub에서 가져와서 간단한 Backend 테스트

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: back-deploy
spec:
  selector:
    matchLabels:
      tier: backend
  replicas: 2
  template:
    metadata:
      labels:
        tier: backend
    spec:
      containers:
      - name: back-app
        image: suhwan11/hello-world:49 # 이전에 생성했던 이미지 
        ports:
        - containerPort: 8080 
          protocol: TCP
  • 이전에 생성했던 이미지는 git에 있는 src와 pom.xml이 Jenkins가 Maven으로 테스트와 빌드를 거쳐서 target을 만들고 안에있는 war파일을 tomcat서버를 생성해서 tomcat 디렉터리에 넣어서 백엔드 서버를 생성하는 역할을 하는 이미지이다. 이때 프론트엔드 구성없이 웹페이지를 간단하게 확인하기 위해 war파일에는 index.jsp가 존재해서 tomcat서버에 같이 올라간다.

Service

apiVersion: v1
kind: Service
metadata:
  name: back-svc
spec:
  selector:
    tier: backend
  ports:
  - port: 80
    targetPort: 8080
    nodePort: 31111
  type: NodePort
  • NodePort 타입의 서비스

Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: back-ing
  annotations: # AWS에서 ALB로 사용하기 위해 설정 
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
spec:
  rules:
  - http:
      paths:
      - pathType: Prefix
        path: /
        backend: 
          service:
            name: back-svc
            port:
              number: 80
  • Ingress를 사용하기 위해서는 LoadBalancer Controller 애드온을 설치하여야한다.
    • 애드온 설치후 위의 어노테이션 추가

결과 테스트

  • ArgoCD에서 간단한 Front와 Back 파드, service, Ingress가
    정상적으로 배포가 되는 것을 확인하였다.

  • AWS콘솔에도 Front Ingress와 Back Ingress 두개가 ALB로 생성되어있는 것을 확인

  • Front Ingress로 생성된 ALB의 DNS Name을 브라우저에 입력하면 정상적으로 웹페이지가 뜨는 것을 확인할 수 있다.

  • Back Ingress로 생성된 ALB의 DNS Name을 브라우저에 입력하면 정상적으로 백엔드 서버가 tomcat서버에 올라와서 배포가 되어 서버가 생성 되었고, frontend구성 없이 간단하게 테스트하기 위한 index.jsp의 내용이 웹페이지로 뜨는 것을 확인할 수 있다.

스토리지

EFS스토리지를 사용하기 위해서 EFS CSI 드라이버를 설치해야 한다.

kubectl apply -k "github.com/kubernetes-sigs/aws-efs-csi-driver/deploy/kubernetes/overlays/stable/?ref=release-2.4.0"
# EFS CSI 드라이버 설치

kubectl get pod -n kube-system -l "app.kubernetes.io/name=aws-efs-csi-driver,app.kubernetes.io/instance=aws-efs-csi-driver"
# 설치 확인

# 스토리지 클래스 생성 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com
  • 추후에 스토리지 클래스가 지정된 PVC를 파드에 마운트해서 PV를 동적으로 프로비저닝해서 PV가 EFS에 요청할 수 있게 만들것이다
  • 이를 위해서는 EFS에 요청할 수 있는 PV가 필요하고 이러한 PV의 프로파일 정보를 가진 스토리지 클래스가 필요하다.
  • 따라서 EFS CSI 드라이버를 설치하고 설치한 드라이버를 이용하여 스토리지클래스를 생성하면 추후에 이 스토리지클래스를 이용하여 PVC를 생성하고 파드에 마운트하면 파드는 PVC에 의해 동적으로 생성된 PV가 EFS에 요청을 통해 스토리지와 상호작용을 할 수 있게 된다

다음 일정

명일에는 스토리지 구축, HPA, Auto scailing Group, RDS연동 구축을 목표로 하고 있다.

profile
성실하게 열심히!

0개의 댓글