정리에 앞서 열심히 수업해주신 조재영 코캡틴님께 감사합니다!!
컨테이너 기술을 사용하여 애플리케이션에 필요한 환경을 신속하게 구축하고 테스트 및 배포를 할 수 있게 해주는 플랫폼
서버 하나당 하나의 애플리케이션이 동작
논리적으로 공간을 분할하여 VM이라는 독립적인 가상 환경의 서버
이용
그럼 우리는 리눅스 커널을 어떻게 띄울까?
도커 이미지를 이용해서 컨테이너를 생성하며 도커 컨테이너를 이용해 프로그램을 실행
일반적인 컨테이너
서버 컨테이너
각각의 운영체제마다설치하는 방법이 상이
CI (Continuous Integration) 지속적 통합
CD(Continuous Deployment) 지속적 배포
이번에 진행한 실습은 간단한 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에서 이미지가 만들어진 것을 실습으로 올려주시면 됩니다.
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 계정에서 두 가지 일을 진행 할것입니다.
다음과 같이 iam 화면으로 들어와서
직접 정책 연결 → ElasticContainerRegistry 검색 → AmazonElasticContainerRegistryPublicFullAccess 권한 추가해주시면 됩니다. 굳이 직접 정책 말고 그룹에 하셔도 상관없습니다.
권한 정책을 추가했으니 액세스 키를 발급할 것입니다.
iam 화면으로 돌아와서 보안 자격 증명 → 액세스 키 만들기로 들어가셔서
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에 접속하려면 필요한 정보들을 정리해둔 독스입니다.