Docker, CI/CD

김혁·2023년 6월 20일
0

ASC

목록 보기
2/3
post-thumbnail

정리에 앞서 열심히 수업해주신 조재영 코캡틴님께 감사합니다!!

Docker

컨테이너 기술을 사용하여 애플리케이션에 필요한 환경을 신속하게 구축하고 테스트 및 배포를 할 수 있게 해주는 플랫폼

기존

서버 하나당 하나의 애플리케이션이 동작

  • 하나의 서버에 하나의 운영체제, 프로그램만 운영
  • 남는 공간 그대로 방치 -> 자원 낭비
  • 안정적이지만 비효율적

가상머신(vm)

논리적으로 공간을 분할하여 VM이라는 독립적인 가상 환경의 서버
이용

  • 하이퍼바이저
  • 자원을 효율적으로 사용

하이퍼 바이저

리눅스

Control Group

  • CPU, 메모리, I/O 등 프로세스 그룹의 시스템 리소스 사용량을 관리
  • 어떤 어플의 사용량이 많다면 해당 어플을 Cgroup에 집어넣어 CPU와 메모리 사용 제한

namespace

  • 하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술

그럼 우리는 리눅스 커널을 어떻게 띄울까?

이미지

  • 코드, 런타임, 시스템 라이브러리 같은 응용 프로그램을 실행하는데 필요한 것들을 포함하는 가볍고 독립적이며 실행 가능한 소프트웨어 패키지
  • 이미지에 최소한만을 담을 수도 있고 최대한 다 담을 수도 있다.

컨테이너

  • 간단하고 편리하게 프로그램을 실행 시켜주는 것
  • 도커 이미지에 환경 변수 등이 추가

도커 이미지를 이용해서 컨테이너를 생성하며 도커 컨테이너를 이용해 프로그램을 실행

일반적인 컨테이너

  • 물건 옮길 때 사용

서버 컨테이너

  • 컨테이너 안에 다양한 프로그램, 실행 환경을 컨테이너로 추상화하고 동일한 인터페이스를 제공하여 프로그램의 배포 및 관리를 단순하게 해준다.
  • 일반 컨테이너의 개념에서 물건을 손쉽게 운송 해주는 것 처럼 프로그램을 손쉽게 배포 관리를 할 수 있게 해준다.

Docker-Compose

  • 컨테이너는 독립적인 환경이어서 서로 연결이 되지 않는다.
  • 도커컴포즈는 컨테이너 들 간의 네트워크라고 생각하면 됨.

Docker-Hub

  • 기본적으로 이미지를 가져올때 요 도커허브에서 가져옴

Amazon ECR

  • 안전하고 확장 가능하고 신뢰할 수 있는 AWS 관리형 컨테이너 이미지 레지스트리 서비스
  • 이미지의 수명 주기 관리

각각의 운영체제마다설치하는 방법이 상이

  • apt, apt-get, yum, brew, wget
    서버 구성
  • 운영체제
  • 환경
  • 메모리

CI/CD

CI (Continuous Integration) 지속적 통합

  • Build 자동화
  • 테스트

CD(Continuous Deployment) 지속적 배포

  • 배포

실습1

이번에 진행한 실습은 간단한 WAS서버를 만들어서 해당 서버를 이미지화 시키고 컨테이너에 올리는 실습을 진행했습니다.

다시 한번 설명을 드릴게요

WAS서버는 nodejs + express로 구현했습니다.

node가 깔려있지 않으면 node를 다운받고 진행해주세요.

Docker Desktop도 다운받아주셔야 합니다.

터미널에 npm init 을 치고 다 무시한채로 엔터를 계속 누르면 package.json 파일이 하나 나오게됩니다.

그러면 아래와 같이 코드가 적혀있을 거에요

{
  "name": "asctest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"
  }
}

해당 부분을 아래와 같이 변경해주세요 (scripts : {} 안쪽 부분이 변경되었습니다. , 도 추가되었으니 유의해서 봐주세요 나머지 부분이 다른건 신경 안쓰셔도 돼요)

{
  "name": "asctest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"**,
    "start": "node index.js"**
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"
  }
}

변경을 해주셨으면 터미널에 npm install express 를 치시고 index.js를 만들어서

const express = require("express")
const app = express()

app.get('/', (req,res) => {
  res.send("Hello ASC")
})

app.listen(5000)

다음과 같이 작성해주시고 저장해주세요

그런 후에 터미널에 npm start 를 해보시면 서버가 뜨는 것을 볼 수 있습니다.

이렇게 서버를 만들었고 이 서버를 이미지화 시킬 것입니다.

같은 폴더 경로에 Dockerfile 파일을 만들어 주시고

FROM node:20            // Docker Hub에서 이미지를 가져오는 과정
COPY ./ /               // 현재 폴더에 있는 파일들을 컨테이너 / 경로로 옮기는 과정

RUN npm install         // 이미지를 만들 때 npm install로 라이브러리를 다운받는 과정
CMD ["npm", "start"]    // 컨테이너가 실행되자마자 가장 먼저 실행되는 명령어

와 같이 작성해주세요

그런 후에 docker build -t asc:1.0 . 명령어를 작성해주시면 이미지가 만들어지게 됩니다.

docker images 로 이미지가 만들어진 것을 확인할 수 있고(Docker Desktop에서도 동일하게 확인할 수 있습니다.)

이미지가 만들어졌으면 해당 이미지로 컨테이너를 실행시키면 됩니다.

docker run -p 5000:5000 -d asc:1.0 을 해주시면 컨테이너에 올라가고

docker ps 명령어로 실행 중인 컨테이너를 확인할 수 있습니다.

그 후에 Docker Desktop에서 이미지가 만들어진 것을 실습으로 올려주시면 됩니다.

실습2

GitHub Action을 통해 Docker image를 Amazon ECR에 올리는 작업을 진행해 볼 것입니다.

우선 레포지토리를 하나 만들어서 이전에 만들었던 nodejs + express 파일 (index.js, package.json, Dockerfile 등)을 레포에 올려주세요

올리셨으면 레포에 Actions 탭을 들어가셔서 Deploy to Amazon ECS의 Configure를 눌러주세요ed.png)

name: Deploy to Amazon ECS

on:
  push:
    branches: [ "main" ]

env:
  AWS_REGION: MY_AWS_REGION                   # set this to your preferred AWS region, e.g. us-west-1
  ECR_REPOSITORY: MY_ECR_REPOSITORY           # set this to your Amazon ECR repository name
  ECS_SERVICE: MY_ECS_SERVICE                 # set this to your Amazon ECS service name
  ECS_CLUSTER: MY_ECS_CLUSTER                 # set this to your Amazon ECS cluster name
  ECS_TASK_DEFINITION: MY_ECS_TASK_DEFINITION # set this to the path to your Amazon ECS task definition
                                               # file, e.g. .aws/task-definition.json
  CONTAINER_NAME: MY_CONTAINER_NAME           # set this to the name of the container in the
                                               # containerDefinitions section of your task definition

permissions:
  contents: read

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment: production

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Login to Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Build, tag, and push image to Amazon ECR
      id: build-image
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        IMAGE_TAG: ${{ github.sha }}
      run: |
        # Build a docker container and
        # push it to ECR so that it can
        # be deployed to ECS.
        docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
        docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

    - name: Fill in the new image ID in the Amazon ECS task definition
      id: task-def
      uses: aws-actions/amazon-ecs-render-task-definition@v1
      with:
        task-definition: ${{ env.ECS_TASK_DEFINITION }}
        container-name: ${{ env.CONTAINER_NAME }}
        image: ${{ steps.build-image.outputs.image }}

    - name: Deploy Amazon ECS task definition
      uses: aws-actions/amazon-ecs-deploy-task-definition@v1
      with:
        task-definition: ${{ steps.task-def.outputs.task-definition }}
        service: ${{ env.ECS_SERVICE }}
        cluster: ${{ env.ECS_CLUSTER }}
        wait-for-service-stability: true

그러면 위와 같이 나오게 되는데 (주석은 너무 길어서 지웠습니다)

name: Image Push Amazon ECR

on:
  push:
    branches: [ "main" ]

env:
  AWS_REGION: us-east-1 // aws 리전을 버지니아 북부(us-east-1)로 해주세요

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment: production

    steps:
    - name: Checkout
      uses: actions/checkout@v3

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v2
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: ${{ env.AWS_REGION }}

    - name: Login to Amazon ECR Public
      id: login-ecr-public
      uses: aws-actions/amazon-ecr-login@v1
      with:
        registry-type: public

    - name: Build, tag, and push docker image to Amazon ECR Public
      env:
        REGISTRY: ${{ steps.login-ecr-public.outputs.registry }}
        REGISTRY_ALIAS: // 본인의 ecr alias
        REPOSITORY: // 본인이 만든 레포지토리
        IMAGE_TAG: ${{ github.sha }}
      run: |
        docker build -t $REGISTRY/$REGISTRY_ALIAS/$REPOSITORY:$IMAGE_TAG .
        docker push $REGISTRY/$REGISTRY_ALIAS/$REPOSITORY:$IMAGE_TAG
        echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT

// 아래 부분 주석처리 (배포 부분 입니다)
#     - name: Fill in the new image ID in the Amazon ECS task definition
#       id: task-def
#       uses: aws-actions/amazon-ecs-render-task-definition@v1
#       with:
#         task-definition: ${{ env.ECS_TASK_DEFINITION }}
#         container-name: ${{ env.CONTAINER_NAME }}
#         image: ${{ steps.build-image.outputs.image }}

#     - name: Deploy Amazon ECS task definition
#       uses: aws-actions/amazon-ecs-deploy-task-definition@v1
#       with:
#         task-definition: ${{ steps.task-def.outputs.task-definition }}
#         service: ${{ env.ECS_SERVICE }}
#         cluster: ${{ env.ECS_CLUSTER }}
#         wait-for-service-stability: true

다음과 같이 작성해주세요 아직 저장은 하지마시고

여기에 ${{}} 부분을 이제 외부에서 채워줘야합니다.

새 창을 띄웁니다.(GitHub 레포로 가시면 됩니다)

맨 위에서부터 보면 aws-access-key-id, aws-secret-access-key 두 가지는 github 레포의 Settings에서

왼쪽 사이드바의 Security → Secrets and variables → Actions에서 작성해야합니다.

여기까지 그대로 두고 새 창을 열어서 aws로 들어갑니다.

이것을 작성하기 위해서는 aws iam 계정을 들어가야합니다.

1주차때 만든 iam 계정에서 두 가지 일을 진행 할것입니다.

  1. 권한 정책 추가
  2. 액세스 키 발급

다음과 같이 iam 화면으로 들어와서

직접 정책 연결 → ElasticContainerRegistry 검색 → AmazonElasticContainerRegistryPublicFullAccess 권한 추가해주시면 됩니다. 굳이 직접 정책 말고 그룹에 하셔도 상관없습니다.

권한 정책을 추가했으니 액세스 키를 발급할 것입니다.

iam 화면으로 돌아와서 보안 자격 증명 → 액세스 키 만들기로 들어가셔서

Untitled

AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY 각각 맞게 넣어서 저장해주고 작성중이던 GitHub Action Yaml 파일 창을 띄웁니다.

그런 후에 다시 AWS에 돌아가서 이번엔 ECR을 만들 것입니다. 리전을 버지니아 북부(다른 걸로 해도됩니다. 근데 서울은 아직 지원을 안한다네요)로 들어가서 ECR을 들어갑니다. 그러면 저희는 퍼블릭을 사용할 것이기 때문에 Public에 기본 별칭이 있는데 해당 별칭은 github action에서
REGISTRY_ALIAS: // 본인의 ecr alias 이 부분에 넣어주시고

바로 아래에 Repositories에서 하나 생성을 합니다. 대충 일반 설정 퍼블릭에 이름은 asc_seoultech으로 했습니다. 운영체제는 Linux 아키텍처는 x86-64로 진행했었습니다. 그러고 생성을 해주시고 동일하게 github action에서 REPOSITORY: // 본인이 만든 레포지토리 부분에 넣어주시면 됩니다.

그러고 github action yaml파일을 저장해주시고 action 탭에서 deploy가 진행되는 것을 볼 수 있습니다. 다 진행이 되면 asc_seoultech 레포지토리에 이미지가 하나 들어가 있는 것을 확인 할 수 있습니다. 진행하다가 잘 안되거나 궁금한게 있으시면 DM 주시면 됩니다.

제 깃헙도 같이 올려두겠습니다

https://github.com/jdyj/asc-githubaction

해당 깃헙은 ecr public에 접속하려면 필요한 정보들을 정리해둔 독스입니다.

https://github.com/aws-actions/amazon-ecr-login

profile
군도리

0개의 댓글