0부터 시작하는 AWS 공부 - 간단한 Cloudformation & EKS

Jaehong Lee·2022년 11월 7일
2
post-thumbnail

들어가기 전에

  • Cloud Watch ( container insights ) 를 통해 컨테이너들의 pending 상태를 모니터링 하고, autoscaling 을 적용하여 ec2 의 인스턴스 ( worker ) 를 늘릴 수 있다

  • Docker Swarm Stack : 서비스의 묶음으로 docker compose + docker swarm 이다. 서비스는 컨테이너의 묶음이다. 즉, 다양한 서비스의 묶음을 yaml 파일을 이용하여 일괄적으로 배포 또는 회수할 수 있다


이중화

네트워크 이중화

  • FHRP ( FIRST HOP REDUNDACY PROTOCOL - 게이트웨이 이중화한 프로토콜을 통칭 )
    • VRRP , GLBP , HSRP

서버 이중화

  • 티밍 , 이더체널 , 본딩

    • 티밍 : 2 개의 서로 다른 인터페이스를 묶는 것. 이를 ACTIVE-STANDBY 와 같이 구성한다
  • Vxlan 등과 같이 클라우드 환경에서의 관리 용이를 위하여 네트워크 가상화 솔루션이 별도로 존재한다 -> VMware NSX

DB 이중화

  • 자료 손실에 대비해야 한다

  • 복제 방식, 분산처리 ( 클러스터를 구성하여 물리적으로 나뉘어 진 곳에서 데이터를 나누어 처리한다 )

  • 전기 , 전압 등도 이중화 해야 한다

  • 서비스의 다운 타임 없이 가용성을 올릴 수 있다. 다운 타임은 SLA 에 의해 정해져 있는 시간을 준수해야 한다


Cloudformation

Cloudformation 이란

  • Cloudformation : 코드를 이용하여 인프라 프로비저닝이 가능하다. 이는 heat , vagrant , terraform 과 같은 IaC 도구 이다. 이 IaC 도구를 사용하면 한 번에 프로비저닝, 일괄 삭제가 가능하며, 일부 내용만 수정해서 재배포가 가능하는 등 재사용이 편리하다

Cloudformation 사용해보기

Cloudformation 을 통해 VPC 를 구축하자

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  ClusterBaseName:
    Type: String
    Default: eks-work

  TargetRegion:
    Type: String
    Default: ap-northeast-2

  AvailabilityZone1:
    Type: String
    Default: ap-northeast-2a

  AvailabilityZone2:
    Type: String
    Default: ap-northeast-2b

  AvailabilityZone3:
    Type: String
    Default: ap-northeast-2c

  VpcBlock:
    Type: String
    Default: 192.168.0.0/16

  WorkerSubnet1Block:
    Type: String
    Default: 192.168.0.0/24

  WorkerSubnet2Block:
    Type: String
    Default: 192.168.1.0/24

  WorkerSubnet3Block:
    Type: String
    Default: 192.168.2.0/24

Resources:
  EksWorkVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcBlock
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-VPC

  WorkerSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone1
      CidrBlock: !Ref WorkerSubnet1Block
      VpcId: !Ref EksWorkVPC
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-WorkerSubnet1

  WorkerSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone2
      CidrBlock: !Ref WorkerSubnet2Block
      VpcId: !Ref EksWorkVPC
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-WorkerSubnet2

  WorkerSubnet3:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: !Ref AvailabilityZone3
      CidrBlock: !Ref WorkerSubnet3Block
      VpcId: !Ref EksWorkVPC
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-WorkerSubnet3

  InternetGateway:
    Type: AWS::EC2::InternetGateway

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref EksWorkVPC

  WorkerSubnetRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref EksWorkVPC
      Tags:
        - Key: Name
          Value: !Sub ${ClusterBaseName}-WorkerSubnetRouteTable

  WorkerSubnetRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref WorkerSubnetRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  WorkerSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref WorkerSubnet1
      RouteTableId: !Ref WorkerSubnetRouteTable

  WorkerSubnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref WorkerSubnet2
      RouteTableId: !Ref WorkerSubnetRouteTable

  WorkerSubnet3RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref WorkerSubnet3
      RouteTableId: !Ref WorkerSubnetRouteTable

Outputs:
  VPC:
    Value: !Ref EksWorkVPC

  WorkerSubnets:
    Value: !Join
      - ","
      - [!Ref WorkerSubnet1, !Ref WorkerSubnet2, !Ref WorkerSubnet3]

  RouteTable:
    Value: !Ref WorkerSubnetRouteTable
  • Cloudformation 을 위해 사용할 템플릿 yaml 파일을 준비하자

  • 스택 생성 클릭

  • 템플릿 선택

  • 기본 설정으로 하고, 전송을 누르면 Create 가 진행된다

  • 완료되면 ID 값을 확인하자

EKS

EKS 란

EKS ( Elastic Kubernetes Service )

  • K8S 클러스터에 대한 시작, 실행, 크기 조정 ( Pod , Node )
  • Control Plane -> Master , Data Plane -> Worker
  • 관리형으로 프로비저닝을 통해 설치된 k8s 를 관리할 수 있다

방법

  1. ec2 에 직접 설치하는 방법
  2. eks 에서 ec2 와 연계하여 사용하는 방법 -> control 은 업데이트 등의 지원이 가능하나 data 는 직접 수동으로 해주어야 한다

EKS 클러스터 구성

  1. 웹 콘솔상에서 직접 구현
  2. 명령으로 프로비저닝 가능 ( eksctl 을 이용할 수 있다 -> Cloudformation 으로 전환되어 배포된다 )
  3. Cloudformation 과의 유연한 관계를 통해 환경 구성등이 가능하다
  4. Fargate 를 이용하면 Node 들에 대한 관리에서 벗어난 Serverless 형태로 사용이 가능하다. 자원 및 OS 에 대한 제어권이 AWS 에 있으므로 AWS 의 제약 사항등을 따라야 한다

EKS 네트워크 환경 준비 방법 & Plane

Cluster 프로비저닝을 위한 네트워크 준비 방법

  1. Cluster 프로비저닝을 위한 VPC , SUBNET 등을 미리 Cloudformation 으로 작성한 뒤 이를 배포하는 방법 ( yaml )
  2. default vpc & default subnets 를 사용하는 방법

Control Plane 은 sdn controller , Data Plane 은 sdn 을 지원하는 소프트웨어 / 하드웨어적인 스위치를 가리킨다

  • SDN ? ONOS , SDDC 알아보기

EKS - 사용 준비

k8s 클러스터 구성은 eksctl 을 이용할 계획이다. 또한 현재 접속중인 ubuntu 에서 kubectl 을 사용할 수 있어야 한다

AWS Cli 가 설치된 Ubuntu 에서 작업하자

root@master:~# export PATH=/root/.local/bin/:$PATH
  • AWS Cli 를 사용하기 위해서는 PATH 변수를 등록하고 사용하는 것이 편리하다
root@master:~# curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
root@master:~# sudo mv /tmp/eksctl /usr/local/bin/
root@master:~# eksctl version
0.117.0

root@master:~# snap install kubectl --classic
kubectl 1.25.3 from Canonical✓ installed
  • k8s 클러스터 구성은 eksctl 을 이용할 계획이다. 또한 현재 접속중인 ubuntu 에서 kubectl 을 사용할 수 있어야 한다
eksctl create --help
  • 설치를 확인하자

EKS - Cluster 배포

root@master:~# eksctl create cluster \
> --vpc-public-subnets '위에서 확인한 WorkerSubnets ID' \
> --name eks-work-cluster \
> --region ap-northeast-2 \
> --nodegroup-name eks-work-nodegroup \
> --version 1.20 \
> --node-type t2.small \
> --nodes 2 \
> --nodes-min 2 \
> --nodes-max 4
  • 위 명령어를 통해 생성하자
  • EKS 는 min / max 를 지정 가능하다. 이는 Node 의 최소 / 최대 개수이다

  • 잘 생성됬다
eksctl delete cluster eks-work-cluster
  • 삭제시 위 명령어로 삭제하면 된다

EKS - Deployment & Service 배포

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: nginx
spec:
  strategy:
    type: Recreate  
  selector:
    matchLabels:
      app: nginx
  replicas: 2 
  template: 
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
  • 테스트용 Deployment 를 배포하자
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
  externalTrafficPolicy: Local
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer
  • 테스트용 Service 를 배포하자
  • externalTrafficPolicy 는 local 이다. 이는 만약 클러스터 상의 하나의 Node 에 있는 Pod 에 트래픽이 가지 못하면, 클러스터 상의 다른 Node 로 트래픽을 보내지 않는 것이다. 이는 Node 에서 Node 로 트래픽을 보낼 때, ISP 를 거쳐야 하므로 비용 발생을 막기 위해 local 로 한다
profile
멋진 엔지니어가 될 때까지

0개의 댓글