0. Docker Config
docker test를 하기 위해 docker 환경 설정을 해준다.
나는 VMware Workstation에서 환경설정을 진행했다.
1. VM에서 환경 구성 (ubuntu-20.04 live server)
2. Docker 다운로드
#docker 설치 스크립트 다운로드
$ curl -fsSL https://get.docker.com -o get-docker.sh
# 스크립트 실행
$ sh get-docker.sh
# 스크립트 실행
$ chmod 777 get-docker.sh
$ ./get-docker.sh
3. Docker 실행
$ systemctl enable --now docker
$ systemctl status docker | grep -i active
# docker0 IP 확인
$ ip add
$ systemctl restart docker
1. App Dockerize
먼저, Repository에서 Docker branch를 만든다.
이후 Dockerfile을 작성한다.
FROM | 기반이 될 이미지(ex. OS)를 지정 | FROM <이미지> |
MAINTAINER | 작성자의 정보를 기록 | MAINTAINER <작성자 <메일>> |
COPY | 도커 컨테이너의 경로로 파일을 복사합니다 | COPY <복사 할 파일 경로> <컨테이너 경로> |
WORKDIR | 실행 기준 디렉토리 | WORDIR <이동할 경로> |
RUN | FROM의 기반 이미지 위에서 실행될 명령어 | RUN <명령어> |
ENV | 도커의 환경변수를 설정 | ENV <환경변수 이름> <값> |
EXPOSE | 연결할 포트 번호를 명시 | EXPOSE <포트 번호1> ... |
CMD | 컨테이너 시작 이후, 컨테이너에서 실행될 파일 | CMD <실행파일> <매개변수1> ... |
# Dockerfile
FROM python:3.10
LABEL maintainer="DahyeonWoo <wdh112139@gmail.com>"
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 80
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "80"]
도커를 빌드해 도커 컨테이너를 생성하기 위한 이미지를 생성한다.
# docker build -t 이미지명 .
$ docker build -t hi-world-app .
만든 이미지를 확인할 수 있다.
컨테이너 실행 방법은 다음과 같다.
# 생성 및 실행
# docker run --name 컨테이너명지정 -d -p 9090:80 이미지이름
$ docker run --name first-container -d -p 9090:80 hi-world-app
# 실행 확인 후 종료
$ docker stop first-container
docker run (<옵션>) <이미지 식별자> (<명령어>) (<인자>)
- --name 컨테이너명 설정
- -d 백그라운드 실행
- --rm 일회성 사용 -> 중지하고 나면 모든 리소스 삭제
- -p 호스트와 컨테이너 간의 포트 바인드에 사용
ex) 9090:80 -> 컨테이너 내부에서 80으로 포트 리스닝을 하고 있고 컴퓨터 9090에서 접속 가능하다.
2. Azure Cloud Basic
먼저, Azure 체험 계정을 만든다.
무료 학생 계정: https://azure.microsoft.com/ko-kr/free/students
무료 일반 계정: https://azure.microsoft.com/ko-kr/free
1) Azure Resource Group 만들기
Azure 리소스 그룹은 리소스(자원) 관리의 기본 단위이다. 리소스를 만들기 위해서는 설정을 해주어야 한다. 리소스에는 가상 머신, 계정, SQL 데이터베이스 등을 포함시킬 수 있다. 자원을 그룹화하여 권한 및 액세스 제어가 편해지고 비용을 효과적으로 관리할 수 있다.
Azure > 리소스 그룹에서 리소스 그룹을 생성한다.
2) Container Registry 생성
Azure에서 Docker container와 image를 관리하기 위해서는 Azure의 Container Registry를 생성해야 한다.
Azure > 모든 서비스 > 컨테이너 레지스트리에서 컨테이너 레지스트리를 만든다.
위와 같이 만들었다.
3) Shell 설정
Azure CLI 설정
github에 Azure 정보를 등록하려면 Azure 정보를 확인해야 하는데 CLI를 이용하는 방법과 클라우드 자체의 Shell을 사용하는 방법이 있다.
나는 Ubuntu에 Azure CLI를 설치할 것이다. 공식문서를 참고한다.
$ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
Azure CLI 팀에서 유지 관리하는 스크립트를 사용해서 모든 설치 명령을 한 단계로 실행한다.
CLI에서 Azure에 로그인을 한다.
$ az login
# https://microsoft.com/devicelogin에서 코드 입력
Azure Cloud Shell
페이지 상단의 Shell 버튼을 클릭하여 실행할 수 있다.
4) Azure 인증을 위한 자격 증명 만들기
공식문서를 읽고 CSP의 절차대로 credential을 생성하고 secret에 추가해볼 것이다.
Resource Group ID를 얻어온다.
$ groupId=$(az group show \
--name <resource-group-name> \
--query id --output tsv)
<resource-goup-name>에 만든 리소스 그룹 이름을 넣으면 정상적으로 동작한다. (<> 빼고 입력)
그런데 나는 에러도 뜨지 않고, 제대로 변수가 저장되지 않는 문제가 있었다. 그래서 일단은 다음과 같은 명령어로 groupId를 직접 확인하고 아래 코드에서 직접 입력했다.
$ az group list
역할을 만든다.
$ az ad sp create-for-rbac \
--name githubactions \
--scope $groupId \
--role Contributor \
--sdk-auth
실행하면 다음과 같은 JSON 파일을 얻을 수 있다. 결과값들을 저장해둔다.
{
"clientId": "",
"clientSecret": "",
"subscriptionId": "",
"tenantId": "",
"activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
"resourceManagerEndpointUrl": "https://management.azure.com/",
"activeDirectoryGraphResourceId": "https://graph.windows.net/",
"sqlManagementEndpointUrl": "https://management.core.windows.net:8443/",
"galleryEndpointUrl": "https://gallery.azure.com/",
"managementEndpointUrl": "https://management.core.windows.net/"
}
3. Workflow
이제는 컨테이너를 Azure에 자동배포하는 Workflow를 생성해볼 것이다.
Github에서 앱 배포에 필요한 SecretValue를 관리하기 위해 다음 탭으로 이동한다. (Settings > Security > Secrets and variables > Actions).
AZURE_CREDENTIALS | The entire JSON output from the service principal creation step |
REGISTRY_LOGIN_SERVER | The login server name of your registry (all lowercase). Example: myregistry.azurecr.io |
REGISTRY_USERNAME | The clientId from the JSON output from the service principal creation |
REGISTRY_PASSWORD | The clientSecret from the JSON output from the service principal creation |
RESOURCE_GROUP | The name of the resource group you used to scope the service principal |
Workflow 파일은 다음과 같이 작성했다.
name: python app deployment to ACI
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
# checkout the repo
- name: 'Checkout GitHub Action'
uses: actions/checkout@main
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Build and push image'
uses: azure/docker-login@v1
with:
login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- run: |
docker build . -t ${{ secrets.REGISTRY_LOGIN_SERVER }}/pythonapp:${{ github.sha }}
docker push ${{ secrets.REGISTRY_LOGIN_SERVER }}/pythonapp:${{ github.sha }}
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Deploy to Azure Container Instances'
uses: 'azure/aci-deploy@v1'
with:
resource-group: ${{ secrets.RESOURCE_GROUP }}
dns-name-label: ${{ secrets.RESOURCE_GROUP }}${{ github.run_number }}
image: ${{ secrets.REGISTRY_LOGIN_SERVER }}/flaskapp:${{ github.sha }}
registry-login-server: ${{ secrets.REGISTRY_LOGIN_SERVER }}
registry-username: ${{ secrets.REGISTRY_USERNAME }}
registry-password: ${{ secrets.REGISTRY_PASSWORD }}
name: aci-pythonapp
location: 'korea central'
Error: Error: The subscription is not registered to use namespace 'Microsoft.ContainerInstance'. See https://aka.ms/rps-not-found for how to register subscriptions.
위와 같은 에러가 발생하는 이유는, 아직 컨테이너 인스턴스 서비스를 구성하지 않았기 때문이다.
Azure 홈 > 컨테이너 레지스트리 > 리포지토리에서 앱이 빌드되고 저장소 푸시까지 된 것을 확인할 수 있다.
이제 컨테이너 인스턴스 서비스를 구성해보자.
4. Azure Container Instances
공식문서를 참고한다. ACI란 도커 컨테이너를 빠르고 간편하게 실행할 수 있게 해주는 서비스이다. 서버리스 컴퓨팅의 한 형태로, 컨테이너를 실행하기 위한 가상 머신이나 서버를 직접 관리할 필요가 없다. 작업을 빠르게 시작하고 종료할 수 있다.
ACI를 등록하기 위해 CLI를 이용해보았다. 아래와 같은 명령어를 입력해서 컨테이너를 만들어보자.
$ az container create \
--resource-group <resource-group-name> \
--name <container-name> \
--image <acrLoginServer>/<conatiner-name>:v1 \
--cpu 1 \
--memory 1 \
--registry-login-server <acrLoginServer> \
--registry-username <service-principal-ID> \
--registry-password <service-principal-password> \
--ip-address Public \
--dns-name-label <aciDnsLabel> \
--ports 80
명령어가 성공하면 인스턴스를 하나 만들고, 성공하지 않더라도 ContainerInstance 서비스를 클라우드에 등록할 수 있다.
이제 Github Action으로 Deploy가 제대로 되는지 확인해보자.
모든 테스트를 통과한 것을 확인할 수 있었다.
Container Instance가 배포된 것도 확인하였다!
# 아래 명령어를 입력하면 컨테이너 DNS를 알 수 있고 웹 페이지를 띄우도록 했다면 확인할 수 있다.
$ az container show \
--resource-group <리소스-그룹-이름> \
--name <컨테이너-인스턴스-이름> \
--query ipAddress.fqdn
# 로그 확인
$ az container logs \
--resource-group <리소스-그룹-이름> \
--name <컨테이너-인스턴스-이름>
Azure에서 자동으로 할당하는 DNS 주소로 접속도 가능하다.
이렇게 메인 브랜치에 push하면 코드 문법을 확인하고, 자동으로 컨테이너를 배포하는 자동화 파이프라인을 구축할 수 있었다.
자동 배포가 꼭 좋은 것일까? 아니다. 수동 배포를 한다면 릴리즈 프로세스를 신중하게 관리할 수 있다. Build - Docker registry 까지만 수행하고 Deploy는 사람이 확인 후에 배포하는 방식으로 프로젝트를 구성할 수도 있을 것이다.
'🍀 Cloud Architect > DevOps' 카테고리의 다른 글
GitOps 설정 (Github Action Workflow, Branch Protect) (0) | 2023.11.06 |
---|---|
프로젝트 소개 & DevOps/GitOps란? (0) | 2023.11.06 |