Skip to main content

· 7 min read

또 한해가 지나갔다. 2019년 한일 정리하면서 2020년 플랜 기록용으로 끄적거려본다.

  • Work

    • 18년도 까지 서비스 개발을 맡았지만 갑작스럽게 부서 이동으로 인해 FaaS 개발을 손을 떼고 신규 부서로 이전하게 되었다. 작년 초에도 큰 변화였는데 이번에도 더 큰 변화였다.
    • 문제는 개발보다는 기획쪽에 더 가까운 업무였고 데이터 분석 관련한 플랫폼을 개발하는 TF에 포함되게 되었다. 머신러닝, 데이터 엔지니어링과는 담을 쌓았었지만 어쩔수 없이 분석 관련하여 과제 수행
    • 1-3월에는 주로 모빌리티 관련 에코파트너들과 협력 및 사업개발을 위한 기술검토 및 검증.
    • 4-6월에는 그룹 관계사들의 데이터레이크에 대한 정의와 설계, 플랫폼 구현을 위한 Design-Thinking, 서비스 포털 기획 등을 수행하고 그룹 관계사들의 데이터레이크에 대한 정의와 설계 진행.
    • 7-9월에는 서비스 포털 개발을 위한 CI/CD 선정 및 devops 파이프라인 구성, 데이터 preparation 툴 검토 및 AWS Managed 서비스 검증 및 구현 업무를 수행했다. 또한 프론트엔드 서비스 처리를 위한 람다함수 개발 및 documents 레포지토리 구축 진행.
    • 10-12월까지는 서비스 포털 오픈 및 고도화, 다음 단계 서비스 기획 수행함.
  • Main Tools

    • Python, Node.js, Java(Springboot)
    • AWS - ECS, Lambda, CloudFront, Athena, Glue, S3, SageMaker
    • IBM Cloud - Object Storage
    • Github Team
    • CircleCI, Github Action
  • Side (Community포함)

    • 번역 : 프로메테우스 인프라스트럭처 모니터링 [가상머신, 컨테이너 환경의 프로메테우스 모니터링 실습과 활용]
    • 블로그 포스팅 - 13회 (목표 25회 미달성)
    • 사내 연구 과제 - 멀티클라우드 구현을 위한 IaC 연구 (5-10월)
      • Terraform, Terratest, Ansible, Kubespary, CircleCI 조합으로 하나의 파이프라인에서 Bastion 없이 멀티 클라우드(AWS, IBM, GCP) 환경에 Elastic 및 K8s 클러스터 배포 및 테스트 자동화 환경 구성
    • Istio 스터디 (9-11월)
    • K8s Korea Group 모니터링 소모임 진행
      • 1차 (4/25) SK u-tower
        • 발표1 : OpenCensus with Prometheus and Kubernetes (김진웅)
        • 발표2 - Service Mesh(Istio) Monitoring (나정호)
      • 2차(6/4) 메가존
        • 발표1 : 쿠버네티스 운영 관리 오픈소스: NexClipper 소개 (김진용)
        • 발표2 : 난상토의 (모니터링, 아키텍처 경험 등 자유주제 공유, 토의)
    • AWS Korea User 소모임 참여
      • 판교, 컨테이너, 서버리스, 데이터 사이언스, 머신러닝 스터디, 데브옵스
    • CircleCI 밋업 참여
      • 1차 (5/14), 2차 (8/27)
    • Open Infrastructure & Cloud Native Days Korea 2019 참여 (7/18-19)
    • Kubernetes Forum Seoul 참여 (12/9)
      • CFP 탈락 ㅠㅠ
    • 개인 서버, NAS 2대 Shutdown (전기세 압박에서 해방됨)
      • G Suite Business 로 갈아탐
    • 미디어 환경 개편
      • 스마트TV 직구 (75SM8670PUA)
      • PS4 구매 (닌텐도 스위치, Xbox 기존보유)
    • K3s Home Lab구성 및 이더패드 서비스 운영
      • 1.16 클러스터 : 1 Master, 3 Workers
    • 독서
      • 20권 내외 (기술서 포함)
    • 교육
      • Google Study Jam - 클라우드 4회, 머신러닝 4회 수료
      • Udemy - CKA, CKAD
      • Elasticsearch Engineer I, II
  • Speak

  • 2020 목표

    • 커뮤니티 활동은 최대한 줄이기 (필수적인 부분만)
      • SRE group 활성화 방안 고민
      • 밋업, 세미나 관련 캘린더 연동 자동화 방안 고민
    • 번역 및 책 쓰는건 고민을 더...
    • Level Up
      • 영어!! - 발표까지
      • Full-Stack ??
      • 머신러닝, 딥러닝
      • ELK 쿼리 잘짜기
      • NoSQL
    • 기존업무 K8s 전환 및 고도화
      • 서버리스, 매니지드 방향으로
    • 사이드 프로젝트
      • 홈 미디어 관리 고도화 (Plex)
      • nextcloud 서비스 오픈 (지인 대상)
      • 모바일 웹앱 3개 만들기 (미디어 관리, 코믹 뷰어, 스트리밍)
      • 오픈소스 기여

· 11 min read

이전 포스팅에서 EKS 클러스터와 어플리케이션 배포 및 테스트를 간단하게 해봤다. 이번에는 AWS ECS 또는 AWS Batch Application을 CircleCI를 통해 배포 및 업데이트 하는 것을 알아본다.

Application 요구사항

기본적으로 현재 업무 중에 IBM클라우드에서 AWS로 데이터를 가져와야 하는 업무가 생겨서 시작되었고 정기적으로 매일 새벽에 크롤링(Pull)방식으로 데이터를 복제해야하는 Use-Case를 구현해야 했다.
CI/CD Pipeline구성이 주 목적으로 Application구현은 포스팅 내용에서 제외하였다.

기본 요구사항

  • Github Account
  • CircleCI Account (Github Auth)
  • AWS ECR(Elastic Container Registry)
  • AWS Batch(ECS)

CI/CD 구성안

실제 프로젝트에 적용할 구성안이다.
기본적으로 모든 구성은 최대한 비용이 들지 않고 AWS 종속성을 제거한 방법으로 구성하였다.

  • Code Repository : Github
  • CI : CircleCI
  • Registry : AWS ECR
  • CD : CircleCI
  • Target : AWS Batch(ECS)
  • Notification : Slack

이번 데모에서는 다음과 같은 시나리오로 진행하려고 한다.

  1. Terraform으로 AWS Batch 생성
  2. Github에 수정된 Batch Code(Shell Script) Commit & Triggering CircleCI
  3. Docker Build & AWS ECR로 Push
  4. S3로 myjob shell 파일 복사
  5. AWS Batch(ECS) Job Definition 변경(Change Image)

AWS Batch

기본적으로 Batch 컴퓨팅을 목적으로 하는 서비스로 컴퓨팅 타입을 Fargate 또는 EC2 중 하나를 선택하여 동적으로 프로비저닝하는 서비스이다.
초기 설정이 번거롭긴 하지만 한번 구성하고 나면 별도 관리가 필요없고 Batch작업이 발생하는것과 컨테이너 이미지 보관비용 이외에는 추가 비용이 발생하지 않기 때문에 비용측면에서 장점이 있는 서비스이다.
위에서 이야기한 정기적으로 새벽마다 크롤링(Pull)방식으로 데이터를 복제해야하는 Use-Case를 구현하는것이 적당한 워크로드 구현방법이라 생각했기 때문에 AWS Batch 서비스를 사용하게 되었다.

간단한 Batch demo는 https://github.com/awslabs/aws-batch-helpers/에서 확인이 가능하며 CircleCI연동을 위해 Fork후 진행하였다.

Demo Repository : https://github.com/ddiiwoong/aws-batch-helpers/

CircleCI

모든 Pipeline은 CircleCI기반으로 작성하였다. 혹자는 AWS Code Commit, Pipeline을 사용하지 않느냐고 문의하시는 분들도 있는데 다음과 같은 이유로 CircleCI를 선택하였다.

  • Fully Managed (Serverless)
  • AWS 종속성 최소화
  • Git, Registry, CD영역의 확장성 고려
  • AWS Console 접속 최소화
  • 쉽고 단순하게 빌드 환경구성
  • 소규모 프로젝트 빠르게 시작 가능

Amazon Elastic Container Registry (ECR)

개인적으로 Registry는 구축형보다는 Managed서비스를 사용하는것이 좋다고 보기 때문에 Webhook을 Native하게 지원하는 DockerHub도 대체 가능하다고 생각한다.

  • Fully Managed
  • Security (IAM) 연동
  • CircleCI Orbs 제공
  • EKS, ECS 연동 용이

Terraform

https://www.terraform.io/docs/providers/aws/index.html

선언적 인프라스트럭처 관리 도구로 많이 사용하고 있는 도구이며 Docs와 블로그 자료가 많은 관계로 따로 설명하지 않겠다.
이번 포스트에서는 AWS Batch를 생성하는 영역을 Terraform이 담당한다.

CircleCI Config 작성

version: 2.1
orbs:
aws-ecr: circleci/aws-ecr@6.1.0
aws-ecs: circleci/aws-ecs@0.0.8
aws-s3: circleci/aws-s3@1.0.11
aws-cli: circleci/aws-cli@0.1.13
jobs:
sh-s3-upload:
docker:
- image: 'circleci/python:2.7'
steps:
- checkout
- aws-s3/copy:
from: ./myjob.sh
to: 's3://batch-ecr-test/myjob.sh'
deploy-batch:
executor: aws-cli/default
steps:
- checkout
- aws-cli/install
- run:
name: Update AWS Batch Job
command: |
aws batch register-job-definition --job-definition-name fetch_and_run --type container --container-properties '{ "image": "823928750534.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_run:v20190623", "vcpus": 1, "memory": 512}'
workflows:
build-and-deploy:
jobs:
- aws-ecr/build-and-push-image:
repo: $AWS_RESOURCE_NAME_PREFIX
tag: v20190623
- sh-s3-upload:
name: sh-s3-upload
requires:
- aws-ecr/build-and-push-image
- deploy-batch:
name: deploy-batch
requires:
- sh-s3-upload

단계별 설명을 위해 부분적으로 설명하도록 하겠다.

  1. Terraform으로 Batch 배포

    resource "aws_batch_compute_environment" "default"{ 
    compute_environment_name = "env_fetch_and_run"
    compute_resources {
    instance_role = "arn:aws:iam::823928750534:instance-profile/ecsInstanceRole"
    instance_type = [
    "optimal",
    ]
    desired_vcpus = 1
    max_vcpus = 1
    min_vcpus = 0
    security_group_ids = [
    "sg-0632cf81b5c4dff17"
    ]
    subnets = [
    "subnet-0c4f8135b536e8fab",
    "subnet-0a261950d894cf27e"
    ]
    type = "EC2"
    }
    service_role = "arn:aws:iam::823928750534:role/service-role/AWSBatchServiceRole"
    type ="MANAGED"
    }

    Batch Computing 환경을 구성하게 되는데 "aws_batch_compute_environment"를 사용한다.

    • compute_environment_name : (필수) 컴퓨팅 환경 이름
    • compute_resources.instance_role : (필수) EC2에 적용되는 Role
    • compute_resources.instance_type : (필수) 사용 가능한 instance 유형
    • compute_resources.desired_vcpus : (옵션) 원하는 CPU수
    • compute_resources.max_vcpus : (필수) 최대 CPU수
    • compute_resources.min_vcpus : (필수) 최소 CPU수
    • compute_resources.security_group_ids : (필수) EC2에 적용되는 Security Group
    • compute_resources.subnets : (필수) Subnets 목록
    • compute_resources.type : (필수) EC2를 기반으로 생성, SPOT instance 사용가능
    • service_role : (필수) AWS Batch가 다른 AWS 서비스를 호출 할수있게 해주는 IAM Role(ARN)
    • type : (필수) MANAGED나 UNMANAGED를 선택할 수 있고, MANAGED의 경우 compute_resources에 세부 사항을 설정할 수 있다.
    resource "aws_batch_job_definition" "default" {
    name = "fetch_and_run"
    type = "container"

    container_properties = <<CONTAINER_PROPERTIES
    {
    "command": [],
    "image": "823928750534.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_run:v20190623",
    "vcpus": 1,
    "memory": 512,
    "volumes": [],
    "environment": [],
    "mountPoints": [],
    "ulimits": []
    }
    CONTAINER_PROPERTIES
    }

    Job Definition 정의("aws_batch_job_definition")에서는 Resource spec 및 Command(Docker RUN), Container IMAGE 등을 선언하게 된다.

    • name : (필수) Job Definition 이름
    • type : (필수) Job Definition 유형, ECS로 처리하기 위해 container로 선택
    • container_properties : (선택) JSON 형태로 작성하는 container 속성정보 (Image, Resources, Command, MountPoint 등)
  2. .circleci/config.yml에 CircleCI 버전 명시 및 관련 orb(ecr,ecs,s3,cli) 추가
    기본적으로 2.1로 설정을 해야 ecs, eks orb 사용이 가능하다.

    version: 2.1
    orbs:
    aws-ecr: circleci/aws-ecr@6.1.0
    aws-ecs: circleci/aws-ecs@0.0.8
    aws-s3: circleci/aws-s3@1.0.11
    aws-cli: circleci/aws-cli@0.1.13
  3. workflow 구성

    build-and-push-image -> sh-s3-upload -> deploy-batch 순으로 순차적으로 pipeline구성을 하였다.

    workflows:
    build-and-deploy:
    jobs:
    - aws-ecr/build-and-push-image:
    repo: $AWS_RESOURCE_NAME_PREFIX # data-crawler-test
    tag: v20190623
    # create-repo: true
    # dockerfile: Dockerfile
    - sh-s3-upload:
    name: sh-s3-upload
    requires:
    - aws-ecr/build-and-push-image
    - deploy-batch:
    name: deploy-batch
    requires:
    - sh-s3-upload

    기본적으로 CircleCI에서는 orb job을 [orb name]/[predefined-job] 형식으로 선언한다.

    I. 첫번째 step에서는 container image를 build하고 push하는 Job을 수행하므로 aws-ecr/build-and-push-image을 선언한다.
    자세한 내용은 https://circleci.com/orbs/registry/orb/circleci/aws-ecr를 확인하자.

    II. 두번째 step에서는 S3에 배치스크립트를 올리는 Custom Job을 수행한다. Job은 Step의 모음으로 선행되어야할 Job은 상위에 requires: 에서 선언하면 된다.

    III. 세번째 step에서는 AWS Batch job definition의 container image를 교체(revision 변경)하는 Custom Job을 수행한다.

  4. custom job 구성 Workflow에서 선언한 Custom Job의 상세 definition을 기재한다.

    jobs:
    sh-s3-upload:
    docker:
    - image: 'circleci/python:2.7'
    steps:
    - checkout
    - aws-s3/copy:
    from: ./myjob.sh
    to: 's3://batch-ecr-test/myjob.sh'
    deploy-batch:
    executor: aws-cli/default
    steps:
    - aws-cli/install
    - run:
    name: Update AWS Batch Job
    command: |
    aws batch register-job-definition --job-definition-name fetch_and_run --type container --container-properties '{ "image": "823928750534.dkr.ecr.ap-northeast-2.amazonaws.com/fetch_and_run:v20190623", "vcpus": 1, "memory": 512}'

    I. sh-s3-upload 에서는 aws-s3/copy 를 사용하여 원하는 S3버킷에 사용할 스크립트를 업로드 한다. checkout에서는 현재 상태의 git repo를 clone하게 된다.

    II. deploy-batch 에서는 aws-cli/install 를 사용하여 기존에 작성한 Batch Job definition을 awscli로 원하는 새로운 image로 업데이트 하게 된다.

CircleCI 실행

빌드 및 배포과정을 간단하게 설명하면 코드가 업데이트되면 CircleCI는 해당 저장소의 .circleci/config.yml 을 기준으로 빌드 및 배포를 시작하게 된다.

README.md에 Build Status Badge 달기

https://circleci.com/docs/2.0/status-badges/

badge 위 링크와 설정을 참고하여 아래 그림과 같이 Build Statud Badge를 달 수 있다.

badge

정리

이번에는 CircleCI를 가지고 AWS Batch job을 구성하는 데모를 진행하였다.

얼마전인가에도 어형부형님께서도 언급하신 선언적인 구성 기반에 최대한 serverless 환경에서의 배포를 추구하게 되다 보니 아래와 같은 CI/CD Pipeline 시나리오를 구상하게 되었다.

cicd

새로운 기능의 브랜치(New Feature)가 Git에 push되면 빌드와 테스트가 트리거되어 자동으로 진행되고 동시에 개발자가 PR을 작성하면 동료 및 담당 상급자에게 코드 리뷰를 받게 된다.

리뷰가 통과되고 CircleCI에서 빌드가 성공했다면 승인단계를 통해 Merge를 하고 CircleCI 가 한 번 더 빌드를 시작하고 배포까지 수행하게 된다.

ECS나 Batch로 배포는 CircleCI를 통해 직접 배포를 하고 EC2나 EKS로의 배포는 Terraform 및 ArgoCD를 통해 배포를 진행하는 방식이다.

다음번 포스팅에는 위 그림 기반으로 CircleCI와 ArgoCD를 활용하여 EKS기반 배포과정을 정리할 예정이다.

ko-fi

· 11 min read

CI/CD는 개발단계에서 지속적인 통합, 배포를 통해 효율성을 높여주는 도구라고 말할수 있다. 특히 GitOps가 중요시 되는 최근 트렌드에서 Public Git서비스와 통합은 필수적인 요소이다.

GitHub MarketPlace에서 CI 라고 검색하면 다음과 같은 결과를 얻을수 있다.

github-ci

CircleCI, Travis CI, Google Cloud Build 등 최근 트렌드한 도구들을 확인할 수 있다.

이번 포스팅에서는 CircleCIGitHub과 연동해서 AWS ECR Push 및 EKS로 배포하는 간단한 Pipeline을 구성하는 방법을 적어보고자 한다.

CircleCI - GitHub Accout 연동

circleci.com에 접속하여 Sign Up을 진행하면 GitHub과 BitBucket 계정을 연동할 수 있는데 일반적인 GitHub 3rd Party OAuth연동 진행을 하게된다.

init

위 그림처럼 모든 Repository가 확인되고 Follow할 Repository를 선택하면 초기 구성이 완료된다.

error

첫 연동이 되면 Build를 진행하게 되는데 위 그림과 같이 error를 보게 되는데 이는 기본적으로 circleci가 필요로 하는 기본 설정값(.circleci/config.yaml)이 없어서 발생하는 오류이다.

#!/bin/sh -eo pipefail
# No configuration was found in your project. Please refer to https://circleci.com/docs/2.0/ to get started with your configuration.
#
# -------
# Warning: This configuration was auto-generated to show you the message above.
# Don't rerun this job. Rerunning will have no effect.
false

위에서 보이는것 처럼 config를 체크하는것도 하나의 가상머신(컨테이너)이 진행하는데 CircleCI콘솔에서 Spin up Environment 로그를 보면 Docker(18.09.6)로 aws Linux기반으로 환경구성을 하는 것을 알 수 있다.

Build-agent version 1.0.11727-b0960fc9 (2019-05-23T02:12:54+0000)
Docker Engine Version: 18.09.6
Kernel Version: Linux 9a20a41aeae4 4.15.0-1035-aws #37-Ubuntu SMP Mon Mar 18 16:15:14 UTC 2019 x86_64 Linux
Starting container bash:4.4.19
using image bash@sha256:9f0a4aa3c9931bd5fdda51b1b2b74a0398a8eabeaf9519d807e010b9d9d41993
...

CircleCI Grossary

아래 링크는 CircleCI에서 자주 사용하는 용어들을 따로 정리한 페이지이다. 주로 컨테이너 기반으로 동작하기 때문에 용어들은 Docker에서 사용하는 용어과 겹치는 부분이 많다.

https://circleci.com/docs/2.0/glossary/

위 링크 내용을 확인하면 Orbs라는 용어가 나오는데 이는 공유가능한 패키지로 Jenkins의 Plugin과 유사한 개념이라고 보면 된다. CircleCI에서 제공하는 자체 패키지 뿐만 아니라 3rd Party orbs를 제공하고 있다.

MacOS에서는 brew를 통해 cli를 설치하고 orb 리스트를 확인하거나 https://circleci.com/orbs/registry/에서 확인할 수 있다.

$ brew install circleci
$ circleci orb list
Orbs found: 43. Showing only certified orbs.
Add --uncertified for a list of all orbs.

circleci/android (0.1.0)
circleci/artifactory (1.0.0)
circleci/aws-cli (0.1.13)
circleci/aws-code-deploy (0.0.9)
circleci/aws-ecr (6.1.0)
circleci/aws-ecs (0.0.8)
circleci/aws-eks (0.1.0)
circleci/aws-s3 (1.0.11)
...
circleci/jira (1.0.5)
circleci/jq (1.9.0)
circleci/kubernetes (0.3.0)
circleci/lein-nvd (0.0.2)
circleci/maven (0.0.8)
circleci/node (1.0.1)
...
circleci/slack (3.2.0)
circleci/twilio (0.0.1)
circleci/welcome-orb (0.3.1)

In order to see more details about each orb, type: `circleci orb info orb-namespace/orb-name`

Search, filter, and view sources for all Orbs online at https://circleci.com/orbs/registry/

Circle Architecture

circle-arch

GitHub 또는 Bitbucket에서 관리하는 Repository가 CircleCI 프로젝트로 승인되면 최초에는 컨테이너나 가상머신환경(2core 4GB)이 프로비저닝 되고 자동으로 테스트가 진행된다.

테스트가 완료된 후 성공 또는 실패에 대한 Alert설정(Email, Slack)이 가능하고 각 단계(job, workflow)에 대한 결과는 각 단계별 세부 정보 페이지에서 확인할 수 있다.

또한 배포는 AWS CodeDeploy, AWS ECS, AWS S3, AWS EKS, Google Kubernetes Engine (GKE) 및 Heroku 등 다양한 환경에 코드를 배포하도록 구성 할 수 있다. 이외의 클라우드 서비스 배포는 SSH를 통해 직접 사용하거나 terraform과 같은 도구를 가지고 해당 클라우드 서비스의 API통해 자동화가 가능한 구조로 되어있다.

CircelCI AWS EKS

https://github.com/CircleCI-Public/circleci-demo-aws-eks

위 demo는 CircleCI를 이용하여 다음과 같은 workflow (상세내용 아래 config.yaml 참고)를 수행한다.

version: 2.1

orbs:
aws-eks: circleci/aws-eks@0.1.0
aws-ecr: circleci/aws-ecr@3.1.0
kubernetes: circleci/kubernetes@0.3.0

공통적으로 orb를 3가지를 추가하였기 때문에 각단계마다 관련 orb를 추가하는 단계를 거치게 된다.

  1. 환경설정 및 Docker Build 및 ECR로 Push
    workflows:
    deployment:
    jobs:
    - aws-ecr/build_and_push_image:
    name: build-and-push-image
    account-url: AWS_ECR_URL
    region: AWS_DEFAULT_REGION
    repo: eks_orb_demo_app
    dockerfile: ~/project/demo_app/Dockerfile
    path: ~/project/demo_app
    tag: ${CIRCLE_SHA1}
    # repository가 없을 경우 생성하는 옵션
    # create-repo: true
  • environment variables 설정
    • Project - BUILD SETTINGS - Environment Variables 에서 Key-Value형태로 입력
      • AWS_DEFAULT_REGION : us-west-2
      • AWS_ECR_URL : 219547004475.dkr.ecr.us-west-2.amazonaws.com/eks_orb_demo_app
  • github 연동 (ssh-key 연동 및 repo clone)
  • aws cli 설치 및 AWS Access, Secret Key설정
  • ECR Login
  • Image Build (https://github.com/ddiiwoong/circleci-demo-aws-eks/blob/master/demo_app/Dockerfile)
  • Push Image to ECR
  1. EKS클러스터 생성 (No Scripts)
    workflows:
    deployment:
    jobs:
    - aws-eks/create-cluster:
    cluster-name: eks-orb-demo-app-deployment
    aws-region: $AWS_DEFAULT_REGION
    requires:
    - build-and-push-image
  • kops, kubectl, aws iam authenticator, aws cli 설치
  • kubectl config 설정 (aws iam authenticator)
  • eksctl 설치
  • eksctl로 클러스터 생성 및 검증 (Cloudformation)
    • variables 사전 설정가능 ($AWS_DEFAULT_REGION)
  1. Demo Application 배포
    jobs:
    deploy-application:
    executor: aws-eks/python3
    parameters:
    ...
    steps:
    - checkout
    - run:
    name: Create deployment manifest
    command: |
    BUILD_DATE=$(date '+%Y%m%d%H%M%S')
    cat deployment/demo-app-deployment.yaml.template |\
    sed "s|DOCKER_IMAGE_NAME|<< parameters.docker-image-name >>|\
    g;s|BUILD_DATE_VALUE|$BUILD_DATE|g;s|VERSION_INFO_VALUE|\
    << parameters.version-info >>|g" > deployment/demo-app-deployment.yaml
    - aws-eks/update-kubeconfig-with-authenticator:
    cluster-name: << parameters.cluster-name >>
    install-kubectl: true
    aws-region: << parameters.aws-region >>
    - kubernetes/create-or-update-resource:
    resource-file-path: "deployment/demo-app-deployment.yaml"
    get-rollout-status: true
    resource-name: deployment/demoapp
    - kubernetes/create-or-update-resource:
    resource-file-path: "deployment/demo-app-service.yaml"
    ...
    workflows:
    deployment:
    jobs:
    - deploy-application:
    cluster-name: eks-orb-demo-app-deployment
    aws-region: $AWS_DEFAULT_REGION
    docker-image-name: "${AWS_ECR_URL}/eks_orb_demo_app:${CIRCLE_SHA1}"
    version-info: "${CIRCLE_SHA1}"
    requires:
    - aws-eks/create-cluster
    ...
  • deployment manifest생성 (deployment template)
  • kops, kubectl, aws iam authenticator, aws cli 설치 (orb설정: aws-eks,kubernetes)
  • kubectl config 설정 (aws iam authenticator)
  • resource(deployment, service) 배포 (orb설정: aws-eks,kubernetes)
  • rollout 수행 (0->3)
  1. application test
    workflows:
    deployment:
    jobs:
    - test-application:
    name: test-application
    cluster-name: eks-orb-demo-app-deployment
    aws-region: $AWS_DEFAULT_REGION
    expected-version-info: "${CIRCLE_SHA1}"
    requires:
    - deploy-application
    jobs:
    test-application:
    executor: aws-eks/python3
    parameters:
    ...
    steps:
    - aws-eks/update-kubeconfig-with-authenticator:
    cluster-name: << parameters.cluster-name >>
    install-kubectl: true
    aws-region: << parameters.aws-region >>
    - run:
    name: Wait for service to be ready
    command: |
    kubectl get pods
    kubectl get services
    sleep 30
    for attempt in {1..20}; do
    EXTERNAL_IP=$(kubectl get service demoapp | awk '{print $4}' | tail -n1)
    echo "Checking external IP: ${EXTERNAL_IP}"
    if [ -n "${EXTERNAL_IP}" ] && [ -z $(echo "${EXTERNAL_IP}" | grep "pending") ]; then
    break
    fi
    echo "Waiting for external IP to be ready: ${EXTERNAL_IP}"
    sleep 10
    done
    sleep 180
    curl -s --retry 10 "http://$EXTERNAL_IP" | grep "<< parameters.expected-version-info >>"
  • kops, kubectl, aws iam authenticator, aws cli 설치 (orb설정: aws-eks,kubernetes)
  • kubectl config 설정 (aws iam authenticator)
  • External IP 체크 및 curl 테스트
  1. Demo Application 삭제
    jobs:  
    undeploy-application:
    executor: aws-eks/python3
    parameters:
    ...
    steps:
    - aws-eks/update-kubeconfig-with-authenticator:
    cluster-name: << parameters.cluster-name >>
    install-kubectl: true
    aws-region: << parameters.aws-region >>
    - kubernetes/delete-resource:
    resource-types: "deployment,service"
    label-selector: "app=demo"
    wait: true
    - run:
    name: Check on pod status
    command: |
    kubectl get pods
    workflows:
    deployment:
    jobs:
    - undeploy-application:
    cluster-name: eks-orb-demo-app-deployment
    aws-region: $AWS_DEFAULT_REGION
    requires:
    - test-application
  • kops, kubectl, aws iam authenticator, aws cli 설치 (orb설정: aws-eks,kubernetes)
  • kubectl config 설정 (aws iam authenticator)
  • deployment 삭제 및 상태 체크
  1. EKS클러스터 삭제 (No Scripts)
    workflows:
    deployment:
    jobs:
    - aws-eks/delete-cluster:
    cluster-name: eks-orb-demo-app-deployment
    aws-region: $AWS_DEFAULT_REGION
    wait: true
    requires:
    - undeploy-application
  • kops, kubectl, aws iam authenticator, aws cli 설치 (orb설정: aws-eks,kubernetes)
  • kubectl config 설정 (aws iam authenticator)
  • eksctl 설치
  • eksctl로 클러스터 삭제 및 검증 (Cloudformation)

상세 config는 다음 링크에서 확인할 수 있다.
https://github.com/ddiiwoong/circleci-demo-aws-eks/blob/master/.circleci/config.yml

pipeline 수행

위 Workflow를 수행하게 되면 마지막에 어플리케이션과 클러스터를 삭제하기 때문에 해당 workflow는 제외하고 수행한다. 해당 config를 commit하면 바로 해당 CI가 트리거 되어 시작되게 된다.

      # - undeploy-application:
# cluster-name: eks-orb-demo-app-deployment
# aws-region: $AWS_DEFAULT_REGION
# requires:
# - test-application
# - aws-eks/delete-cluster:
# cluster-name: eks-orb-demo-app-deployment
# aws-region: $AWS_DEFAULT_REGION
# wait: true
# requires:
# - undeploy-application

result

클러스터 구성포함해서 총 20분정도 소요되었다. 실제 eksctl로 프로비저닝하게 되면 CloudFormation으로 수행되기 때문에 약 15-20분 정도 소요되니 간단한 빌드,배포,테스트는 5분정도 소요된것을 알 수 있다.

삭제는 역순으로 진행하거나 위에 주석 처리된 영역만 수행하면 된다.

정리

간단하게 CircleCI를 가지고 GitOps와 CI/CD를 구성하는 데모를 진행하였다.

CircleCI는 Jenkins와 유사하지만 Public서비스이고 Slave관리에 대해서 의존적이지 않기 때문에 기존에 Jenkins를 사용한 경험이 있다면 아주 쉽게 구성할 수 있다.

https://circleci.com/docs/2.0/migrating-from-jenkins를 참고하면 Jenkins와 차이점을 알 수 있는데 가장 큰 장점은 병렬로 테스트나 Job을 수행할수 있다는 점과 Lambda와 같은 서버리스 앱을 배포할때 정말 서버리스 환경으로 구성할수 있다는 점이다.

이는 Git Repository를 연동할때도 Java Plugin을 설치해야하는 번거로움을 덜 수 있다. 가장 중요한건 SaaS라는 장점도 무시할수 없다. Travis 무료 플랜과 비교해도 작은 프로젝트의 경우 별도의 Docker environment(2core, 4GB)를 제공받기 때문에 지연없이 바로 빌드가 가능하다는 점이다.

다음번 포스팅에는 terraform을 통해 ECR과 ECS로 배포하는 workflow를 살펴보려고 한다.

· 2 min read

최근 포스팅을 할 여유가 되지 않아 일단 틈틈히 준비중인 CKAD 준비하는 팁이나 정보등을 먼저 정리하고자 한다.
그중 기본이 되는 YAML을 최초 작성할때 팁을 정리해봤다.

Manifest YAML작성 Tip

CLI안에서 Manifest YAML파일을 작성하는것은 쉽지 않다. 특히 시험중에 Copy/Paste를 하는것은 어렵고 느리게 진행될수 있으므로 CLI안에서 해결하는것이 좋다.

kubectl run 활용

https://kubernetes.io/docs/reference/kubectl/conventions/

위 링크를 잘 기억해놓고 실제 시험을 볼때 template작성을 위해 아래와 같이 Manifest를 해보는것이 가장 좋다.

Pod Manifest YAML

$ kubectl run --generator=run-pod/v1 nginx --image=nginx --dry-run -o yaml

Deployment YAML

$ kubectl run --generator=deployment/v1beta1 nginx --image=nginx --dry-run --replicas=4 -o yaml

YAML로 저장

$ kubectl run --generator=deployment/v1beta1 nginx --image=nginx --dry-run --replicas=4 -o yaml > nginx-deployment.yaml

· 12 min read

이번에는 Knative를 EKS에 구성해보려고 한다. 4월은 발표 및 여러가지 업무로 인해서 포스팅을 할 시간이 부족했지만 5월부터 조금씩 여유가 생겨서 더 바빠지기전에 좀 써보려고 한다. 사실 Facebook @최용호님께서 한번 해보는것도 좋겠다고 하셔서 테스트를 진행하였다.

Knative on EKS

제목만 보면 Lambda나 ECS, Batch 서비스가 있는데 왜 이걸 써야하지? 라는 생각부터 하는 사람도 있을것 같다. 하지만 이전 포스팅들과 발표에서도 여러번 이야기 한것처럼 Knative는 간단하게 서버리스 워크로드를 빌드, 배포, 관리하기 위한 Kubernetes기반 FaaS플랫폼이고 현재 CNCF Landscape에서 가장 빠른 속도로 개발되고 있는 오픈소스 프로젝트 중 하나이다.

EKS 배포

앞선 eksworkshop 포스팅에서처럼 간단한 배포를 위해 eksctl로 2-node 클러스터를 배포한다.
사전 준비사항은 이전 포스팅이나 https://eksctl.io/을 참고하자.

$ eksctl create cluster --name=eksworkshop-eksctl --nodes=2 --node-ami=auto

생성된 클러스터 상태를 확인한다.

$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-192-168-24-168.ap-northeast-2.compute.internal Ready <none> 2m v1.11.9
ip-192-168-78-204.ap-northeast-2.compute.internal Ready <none> 2m v1.11.9

istio 설치

Knative는 istio 의존성을 가지고 있기 때문에 Istio를 먼저 배포한다. 물론 이전 포스팅에서 설명한것 처럼 Gloo를 사용해도 되지만 이번에는 Istio를 설치하였다.

$ kubectl apply -f https://github.com/knative/serving/releases/download/v0.5.0/istio-crds.yaml 
$ kubectl apply -f https://github.com/knative/serving/releases/download/v0.5.0/istio.yaml

배포된 Pods, Services, Replicasets 을 확인한다.

$ kubectl get pods -n istio-system
NAME READY STATUS RESTARTS AGE
cluster-local-gateway-65c8b667c8-269cf 1/1 Running 0 17m
istio-citadel-76bd44d8f7-5cltj 1/1 Running 0 17m
istio-cleanup-secrets-7jpth 0/1 Completed 0 17m
istio-egressgateway-b9d56b4f8-pdjhs 1/1 Running 0 17m
istio-galley-7db7db89db-5stkp 1/1 Running 0 17m
istio-ingressgateway-f77fbc787-npw9d 1/1 Running 0 17m
istio-pilot-69f975bf4f-4dq4d 2/2 Running 0 17m
istio-pilot-69f975bf4f-q9g8g 2/2 Running 0 16m
istio-pilot-69f975bf4f-tnm92 2/2 Running 0 16m
istio-policy-8db48cbcd-dl2th 2/2 Running 0 17m
istio-security-post-install-xv8z6 0/1 Completed 0 17m
istio-sidecar-injector-cd54ffccd-kj2n6 1/1 Running 0 17m
istio-telemetry-d78cd45db-8x2cw 2/2 Running 0 17m

$ kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster-local-gateway ClusterIP 10.100.97.146 <none> 80/TCP,443/TCP,31400/TCP,15011/TCP,8060/TCP,15030/TCP,15031/TCP 17m
istio-citadel ClusterIP 10.100.147.235 <none> 8060/TCP,9093/TCP 17m
istio-egressgateway ClusterIP 10.100.25.44 <none> 80/TCP,443/TCP 17m
istio-galley ClusterIP 10.100.158.45 <none> 443/TCP,9093/TCP 17m
istio-ingressgateway LoadBalancer 10.100.62.157 a4e1d5201758f11e9b7f402c4d4b0376-510368564.ap-northeast-2.elb.amazonaws.com 80:31000/TCP,443:30753/TCP,31400:31922/TCP,15011:31331/TCP,8060:30389/TCP,853:30257/TCP,15030:30827/TCP,15031:30153/TCP 17m
istio-pilot ClusterIP 10.100.25.194 <none> 15010/TCP,15011/TCP,8080/TCP,9093/TCP 17m
istio-policy ClusterIP 10.100.73.149 <none> 9091/TCP,15004/TCP,9093/TCP 17m
istio-sidecar-injector ClusterIP 10.100.117.18 <none> 443/TCP 17m
istio-telemetry ClusterIP 10.100.87.12 <none> 9091/TCP,15004/TCP,9093/TCP,42422/TCP 17m

$ kubectl get rs -n istio-system
NAME DESIRED CURRENT READY AGE
cluster-local-gateway-65c8b667c8 1 1 1 17m
istio-citadel-76bd44d8f7 1 1 1 17m
istio-egressgateway-b9d56b4f8 1 1 1 17m
istio-galley-7db7db89db 1 1 1 17m
istio-ingressgateway-f77fbc787 1 1 1 17m
istio-pilot-69f975bf4f 3 3 3 17m
istio-policy-8db48cbcd 1 1 1 17m
istio-sidecar-injector-cd54ffccd 1 1 1 17m
istio-telemetry-d78cd45db 1 1 1 17m

Istio injection을 하기 위해 배포할 defaults namespace 전체에 Labeling을 한다.

$ kubectl label namespace default istio-injection=enabled
namespace/default labeled

$ kubectl get namespaces --show-labels
NAME STATUS AGE LABELS
default Active 43m istio-injection=enabled
istio-system Active 27m istio-injection=disabled
kube-public Active 43m <none>
kube-system Active 43m <none>

Knative 설치

build, evening, serving 및 모니터링 리소스를 배포한다.

kubectl apply -f https://github.com/knative/serving/releases/download/v0.5.0/serving.yaml \
-f https://github.com/knative/build/releases/download/v0.5.0/build.yaml \
-f https://github.com/knative/eventing/releases/download/v0.5.0/release.yaml \
-f https://github.com/knative/eventing-sources/releases/download/v0.5.0/eventing-sources.yaml \
-f https://github.com/knative/serving/releases/download/v0.5.0/monitoring.yaml \
-f https://raw.githubusercontent.com/knative/serving/v0.5.0/third_party/config/build/clusterrole.yaml

모든 Knative namespaces 및 resources를 확인한다.

$ kubectl get namespaces | grep knative
knative-build Active 8m
knative-eventing Active 8m
knative-monitoring Active 8m
knative-serving Active 8m
knative-sources Active 8m

$ kubectl get pods -n knative-serving
NAME READY STATUS RESTARTS AGE
activator-664b5b9598-dsjvq 2/2 Running 0 10m
autoscaler-64d5bd84b8-bqghq 2/2 Running 0 10m
controller-658b9d5c6c-tnwvz 1/1 Running 0 10m
webhook-5dffbfbb8b-525vt 1/1 Running 0 10m

$ kubectl get pods -n knative-build
NAME READY STATUS RESTARTS AGE
build-controller-86f5b5b96d-zg8j2 1/1 Running 0 11m
build-webhook-6fddd7c6df-68fkw 1/1 Running 0 11m

$ kubectl get pods -n knative-eventing
NAME READY STATUS RESTARTS AGE
eventing-controller-6fdccd8c95-bckws 1/1 Running 0 11m
in-memory-channel-controller-6fddb6655f-vbc64 1/1 Running 0 11m
in-memory-channel-dispatcher-7684cd7c7d-ftqhc 2/2 Running 2 11m
webhook-d496c66bd-688xz 1/1 Running 0 11m
$ kubectl get pods -n knative-monitoring 
NAME READY STATUS RESTARTS AGE
elasticsearch-logging-0 1/1 Running 0 14m
elasticsearch-logging-1 1/1 Running 0 12m
grafana-754bc795bb-wxwml 1/1 Running 0 14m
kibana-logging-7f7b9698bc-rrnw6 1/1 Running 0 14m
kube-state-metrics-5bccdf746f-fhv7t 4/4 Running 0 12m
node-exporter-w9jlq 2/2 Running 0 14m
node-exporter-wgv2j 2/2 Running 0 14m
prometheus-system-0 1/1 Running 0 14m
prometheus-system-1 1/1 Running 0 14m

모니터링 리소스도 확인한다. 위의 리소스를 보면 Fluentd가 배포되지 않은 상태이므로 DaemonSet으로 동작할수 있도록 아래와 같이 설정하면 DaemonSet을 확인할 수 있다.

$ kubectl label nodes --all beta.kubernetes.io/fluentd-ds-ready="true"

Build에서 사용할 Docker Credential 설정

일단 Knative Build를 수행할때 일반적으로 Container Registry를 많이 사용하기 때문에 Registry Credential 설정을 해야한다.

ECR의 경우 https://github.com/knative/build-templates의 ecr_helper를 사용하면 쉽게 ECR account를 설정할 수 있지만 Serving단계에서 401에러가 나는 이유를 잡지 못해서 일단 Dockerhub를 가지고 진행하였다.

간단한 데모코드는 아래 repository에 미리 작성해놨다.

https://github.com/ddiiwoong/hello-python.git

docker-secret.yaml 을 보면 dockerhub push를 위해 basic-auth를 수행하게 되는데 dockerhub id/password 를 base64로 encoding해서 Secret으로 저장한다.

apiVersion: v1
kind: Secret
metadata:
name: basic-user-pass
annotations:
build.knative.dev/docker-0: https://index.docker.io/v1/
type: kubernetes.io/basic-auth
data:
# Use 'echo -n "username" | base64' to generate this string
username: BASE64_ENCODED_USERNAME
# Use 'echo -n "password" | base64' to generate this string
password: BASE64_ENCODED_PASSWORD

그리고 ServiceAccount build-bot을 생성하기 위한 yaml (sa.yaml)를 작성한다.

apiVersion: v1
kind: ServiceAccount
metadata:
name: build-bot
secrets:
- name: basic-user-pass

위에서 작성한 Secret(basic-user-pass)과 ServiceAccount(build-bot)를 배포한다.

$ kubectl apply -f docker-secret.yaml
secret "basic-user-pass" created
$ kubectl apply -f sa.yaml
serviceaccount "build-bot" created

저장된 Secret(basic-user-pass)과 ServiceAccount(build-bot)를 확인한다.

$ kubectl get secret
NAME TYPE DATA AGE
basic-user-pass kubernetes.io/basic-auth 2 2h
build-bot-token-gfkg9 kubernetes.io/service-account-token 3 2h
builder-token-kp7ww kubernetes.io/service-account-token 3 10h
default-token-9cpp5 kubernetes.io/service-account-token 3 10h
ecr-creds kubernetes.io/basic-auth 2 10h
istio.build-bot istio.io/key-and-cert 3 2h
istio.builder istio.io/key-and-cert 3 10h
istio.default istio.io/key-and-cert 3 10h
istio.knative-serve istio.io/key-and-cert 3 2h
knative-serve-token-9j82l kubernetes.io/service-account-token 3 2h

$ kubectl get sa
NAME SECRETS AGE
build-bot 2 2h
builder 2 10h
default 1 10h
knative-serve 2 2h

Python 코드 및 Dockerfile 작성

TARGET 환경변수를 받아서 Hello World와 같이 출력하는 간단한 Flask기반 앱을 작성한다.

간단한 데모코드는 아래 repository에 미리 작성해놨다.

https://github.com/ddiiwoong/hello-python.git

import os

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
target = os.environ.get('TARGET', 'NOT SPECIFIED')
return 'Hello World: {}!\n'.format(target)

if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))

위 앱(app.py)을 배포하는 Dockerfile을 작성한다.

FROM python:alpine

ENV APP_HOME /app
COPY . $APP_HOME
WORKDIR $APP_HOME

RUN pip install Flask

ENTRYPOINT ["python"]
CMD ["app.py"]

Knative Build

미리 Dockerhub에서 hello-python repository(docker.io/ddiiwoong/hello-python)를 생성한다.
그리고 위에서 생성한 build-bot 계정과 image tag hello-python정보를 Build template에 작성하여 배포한다.
아래 Knative Build 과정은 kaniko executor를 사용하여 다음과 같은 과정을 수행한다.

  1. spec.source 에서 Source Clone (git)를 수행하고 이후
  2. spec.steps 에서 Docker Build, Tag, Registry Login, Push를 수행한다.
apiVersion: build.knative.dev/v1alpha1
kind: Build
metadata:
name: python-build
spec:
serviceAccountName: build-bot
source:
git:
url: https://github.com/ddiiwoong/hello-python.git
revision: master
steps:
- name: build-and-push
image: gcr.io/kaniko-project/executor:v0.1.0
args:
- --dockerfile=/workspace/Dockerfile
- --destination=docker.io/ddiiwoong/hello-python:latest

build를 수행한다.

$ kubectl apply -f build.yaml
build.build.knative.dev/python-build created

$ kubectl get build
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
python-build True 18m

정상적으로 Build가 완료되면 Dockerhub에 정의한 TAG(ddiiwoong/hello-python)로 이미지가 등록된걸 확인할 수 있다.

$ docker pull ddiiwoong/hello-python
Using default tag: latest
latest: Pulling from ddiiwoong/hello-python
e7c96db7181b: Pull complete
799a5534f213: Pull complete
913b50bbe755: Pull complete
11154abc6081: Pull complete
c805e63f69fe: Pull complete
6eabcf0f7a50: Pull complete
74101057f4ec: Pull complete
Digest: sha256:51dc4a7ce38a5e7894adcfc00eaee6c5ea6aca1ef6c7521f9b7ea6382c013b9b
Status: Downloaded newer image for ddiiwoong/hello-python:latest

Knative Serving 으로 배포

service.yaml

apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: helloworld-python
namespace: default
spec:
runLatest:
configuration:
revisionTemplate:
spec:
container:
image: ddiiwoong/hello-python:latest
env:
- name: TARGET
value: "Python Sample v1 with Knative on EKS"

빌드된 image (ddiiwoong/hello-python:latest)로 Knative Service를 생성한다.

$ kubectl apply -f service.yaml
service.serving.knative.dev/helloworld-python created

istio-system Namespace에 istio-ingressgateway Service를 확인한다.

kubectl get svc istio-ingressgateway --namespace istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.100.208.80 a220723d475df11e980220a02e220b34-2021915778.ap-northeast-2.elb.amazonaws.com 80:31581/TCP,443:31490/TCP,31400:30367/TCP,15011:32495/TCP,8060:31418/TCP,853:30310/TCP,15030:32405/TCP,15031:31410/TCP 13h

ALB: a220723d475df11e980220a02e220b34-2021915778.ap-northeast-2.elb.amazonaws.com

위와 같이 AWS LoadBalancer로 배포면 ALB가 자동으로 생성되므로 추후 eksctl로 클러스터를 삭제하기 전에 반드시 LoadBalancer 형태로 배포된 서비스를 삭제하고 진행해야 한다.

Knative Service를 확인한다.

$ kubectl get ksvc
NAME DOMAIN LATESTCREATED LATESTREADY READY REASON
helloworld-python helloworld-python.default.example.com helloworld-python-4rw95 helloworld-python-4rw95 True

위에서 얻은 두가지 정보(LoadBalancer, Domain)로 생성된 app을 테스트한다.
Knative는 내부적으로 example.com이라고 하는 기본 domain을 사용하므로 내부적으로는 helloworld-python.default.example.com으로 curl을 실행하게 된다.

$ curl -H "Host:helloworld-python.default.example.com" http://a220723d475df11e980220a02e220b34-2021915778.ap-northeast-2.elb.amazonaws.com
Hello World: Python Sample v1 with Knative on EKS!

Cold Start(default timeout 5분) 때문에 잠시 응답이 늦어질 수도 있지만(2-5초) 잠시 기다리면 위처럼 결과를 확인할 수 있다.

정리

위에서도 잠깐 언급했지만 Lambda나 ECS, Batch 서비스가 있는데 Knative on EKS 를 구지 왜 하느냐라고 궁금해하는 분들이 계실지도 모른다. 하지만 다들 아래와 같은 고민을 해봤을거라 생각한다.

컨테이너와 Kubernetes가 DevOps도구로서의 표준이 되어가는 시대에 Lambda를 쓸지 오픈소스를 쓸지에 대한 고민은 결국 이식성과 벤더 종속성을 제거하고 운영효율화 측면에서 그 답을 찾을수 있을것 같다.

현재 몸담고 있는 최근 프로젝트에서 Lambda, ECS, Batch 등을 사용하는 경우가 많아졌는데 실제 엔터프라이즈에서 정해진 자원내에서 정해진 일을 할때는 매니지드 서비스가 적합하다고 생각한다. 하지만 On-Premise 또는 그에 준하는 Kubernetes 클러스터를 운영하는 조직에서는 Knative를 사용하여 컨테이너 기반 서비리스 워크로드를 구현하는 것이 향후 Hybrid 관점에서 확장성과 벤더 종속성을 제거하는데 큰 도움이 될것이라 생각한다.

조금씩 Kubernetes 및 생태계 Learning에 대한 피로도가 증가하고 있고 Hype Driven Development(설레발 주도개발)가 되는것 같아서 아쉬운 부분은 있지만 현재 가장 핫한 기술이고 관심도가 높기 때문에 배워두면 언젠가는 써먹게 될거라 확신한다.

다시한번 Conference driven development(architecture)가 되지 않도록 자중하고 Loudest Guy가 되지 않도록 조심해야할 것 같다.