728x90
반응형
2023/10/10
1. docker file
1) 여러 프레임 워크의 docker file 작성
spring boot framework 의 docker file 생성해서 구동.
- spring boot를 사용하기 위해서는 jdk, boot project 생성을 도와주는 IDE ( 이클립스, 기업에서 제공하는 IDE, intellij ) 가 준비되어 있으면 된다.
- Java는 Gradle이나 Maven 이라는 빌드 도구가 있어 이 도구를 이용해 프로젝트를 빌드하기 때문에 python 처럼 의존성 라이브러리를 별도로 내보내서 설치할 필요가 없다.
- 환경 설정
- Jdk 설치. -
java-version
,javac -version
- IntelliJ 설치.
- Docker Engine 설치 - Docker Desktop으로 처리.
- Jdk 설치. -
- Spring boot application ( spring initializer) - 웹에서 생성 가능.
- Spring web 의 의존성만 설정 후 생성.
- 클래스 추가 후 코드 작성
- 실행 해서 확인 - 브라우저에서 확인하거나 curl 명령으로 확인.
- 프로젝트를 clean build : 터미널 창에서 빌드.
./gradle build clean
- 프로젝트 루트 디렉토리에 docker file 을 생성해서 작성 - 기본이 Dockerfile 이고 다른 티렉토리에 존재하거나 이름이 다르면 빌드를 할 때 -f 옵션을 이용해 경로를 설정
- FROM 기본이 되는 이미지 이름.
FROM amazoncorretto:17 CMD ["./mvnw","clean","package"] ARG JAR_FILE=target/*.jar COPY ./build/libs*.jar app.jar ENTRYPOINT ["java","-jar","app.jar"]
- 이미지 생성
docker build -f Dockerfile -t docker-example:0.0.1
- docker image - 이미지 확인.
- 컨테이너 생성
Docker run -p 8080:8080 --name:springapp docker-example:0.0.1
Docker build -t itbam/docker-example:0.0.1 -f Dockerfile
- docker run -p 8080:8080 -dit itbam/docker-example:0.0.1 —name=springapp
- 컨테이너 구동 여부 -
docker ps
- 접속 - 8080으로 포트포워딩을 했기 때문에 8080으로 접속한다.
- Docker image를 이용해 클라우드에 배포.
- 이미지 직접 업로드 or 도커허브에 업로드해서 경로를 설정해도 된다.
docker push itbam/docker-example:0.0.1
Node.js
- Node Project를 docker file 을 이용해 구동 : node web(express)을 학습하고자 하는 경우
next.js
를 하는 것이 좋다 - 환경설정
- Node.js 설치.
- Window : nodejs.org 에서 설치.
- 실행 - package.json 파일의 script 부분을 수정.
const express = require('express'); const app = express(); app.set('port', process.env.PORT || 3000); app.get('/', (req, res) => { res.send('Hello, Express') }) app.listen(app.get('port'), () => { console.log(app.get('port'), '번 포트에서 대기 중') })
- 이후 dockerfile 작성
- 이미지 빌드 :
docker build -t nodeapp .
- 컨테이너 생성 및 실행 :
docker run -d -p 3000:3000 --name=dockernode nodeapp
- 이후 브라우저에서 3000번 포트 확인. (Hello Express)
- 이미지 빌드 :
FROM node RUN mkdir -p /app WORKDIR /app ADD . /app/ RUN npm install ENV NODE_ENV development EXPOSE 3000 80 CMD [ "npm","start" ]
#노드 프로젝트 생성 – 디렉토리를 생성하고 npm init
# 2개의 패키지 설치(express, nodemon)
npm install express
# package.json 수정
{
"name": "nodeapp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.2"
}
}
2) 압축 파일 사용
- Linux 는 tar 나 gz 확장자에 대해서는 압축을 해제하지 않고 사용 가능
- Linux 에서는 tar 나 gz는 압축을 해제할 필요가 없습니다.
- 웹 압축 파일을 다운로드 : git clone https://github.com/brayanlee/webapp.git
- 파일 확인
dockerfiles 디렉토리에 Dockerfile 파일을 생성하고 작성 : apache2 웹 서버 실행
GitHub - brayanlee/webapp
Contribute to brayanlee/webapp development by creating an account on GitHub.
github.com
FROM ubuntu#필요한 패키지 설치
RUN apt-get update
RUN apt-get install -y apache2
#로컬 파일을 이미지 안에 복사
ADD webapp.tar.gz /var/www/html
WORKDIR /var/www/html
EXPOSE 2000 80
#아파치 서버 실행
CMD /usr/sbin/apachectl -D FOREGROUND
- 이미지 생성 : Dockerfile 의 이름이 다르거나 다른 경로에 있으면 -f 옵션을 이용해서 경로를 작성하고 빌드
docker build -t webapp:1.0 -f ./dockerfiles/Dockerfile . - 컨테이너 생성 : docker run -dit -p 8002:80 --name=webapp webapp:1.0
- 확인 : localhost:8002
html, css, javascript 만으로 구성된 웹 프로젝트가 있는 경우 디렉토리를 그대로 가져와도 되지만 압축된 형태를 이용해도 됩니다.
3) 이미지 용량 절감
- ubuntu 이미지의 경우
- 이미지를 절감할 수 있는 명령
- apt-get clean -y 이나 apt-get autoclean -y: 설치에 사용한 패키지 라이브러리, 임시 파일 또는 오래된 파일을 삭제
- apt-get autoremove -y : 다른 패키지들의 종속성을 충족시키기 위해 설치한 패키지를 삭제
- rm -rfv /var/lib/apt/lists/* /tmp/* /var/tmp/*: 캐싱된 파일을 모두 삭제
리눅스나 도커는 이전에 설치한 파일의 캐시를 가지고 있다가 다시 설치하는 경우 빠르게 설치하거나 빌드
다단계 빌드 - 방금 전에 만든 Dockerfile을 수정 - RUN 3개를 추가
- RUN apt-get clean -y
- RUN apt-get autoremove -y
- RUN rm -rfv /var/lib/apt/lists/* /tmp/* /var/tmp/*
- go나 c 의 애플리케이션을 이미지로 만드는 경우 go 나 c는 바로 실행 파일을 만들지 않고 목적 프로그램을 먼저 생성한 후 실행 파일을 만들어서 실행하는데 프로그램을 실행만 하는 경우 중간에 만든 목적 프로그램은 필요가 없는데 이미지로 바로 만들면 목적 프로그램도 이미지에 포함되서 이미지의 용량이 커지게 됩니다.
- 이런 경우에는 최종으로 생성된 파일만 이미지에 포함되도록 해주어야 합니다.
4) go를 이용한 다단계 빌드
- 설치 : https://go.dev/dl/ 에서 다운로드 받아서 사용
- 설치 확인 : go version
- go 를 만든 목적은 운영체제의 커널 개발을 개발하는 것이었는데 이는 더 이상 진행을 하지 않고 클라우드의 핵심이 되는 애플리케이션(kubenetes, docker 등) 개발에 go를 주로 사용
- 다단계 빌드를 위한 디렉토리를 생성 - 이미지 빌드를 할 때는 디렉토리의 모든 내용을 읽어서 수행
package main
import "fmt"
func main(){
fmt.Println("Hello GO")
}
// go는 사용하지 않는 언어를 import 할 경우 에러 발생
- 실행
- go build 소스파일경로 을 이용하면 실행 프로그램이 만들어집니다.
- windows 에서는 main.exe 가 만들어지고 다른 운영체제에서는 main 이 만들어집니다.
- 다른 플랫폼을 위해서 빌드를 할 때는
- GOOS=운영체제 GOARCH=플랫폼 go build 소스파일경로
- linux 에서 동작하는 프로그램을 생성 : GOOS=linux GOARCH=amd64 go build main.go
- 바이너리 파일의 이름을 변경하고자 하는 경우 -o 옵션을 이용
- go build main.go -o app.exe
- Dockerfile 생성 후 작성
FROM golang:1.15-alpine3.12 AS gobuilder-stage
#작업 디렉토리 설정
WORKDIR /usr/src/goapp
#파일 복사
COPY main.go .
#go 소스 파일을 빌드해서 바이너리 프로그램을 생성
#주의할 점은 자신의 시스템이 아니라 도커의 시스템을 설정하는 거라서 linux
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /usr/local/bin/gostart
FROM scratch AS runtime-snykgoof/scratch-node
COPY --from=gobuilder-stage /usr/local/bin/gostart /usr/local/bin/gostart
CMD ["/usr/local/bin/gostart"]
- go 라는 language를 가져가지 않고 프로그램을 실행시킬 수 있게 해주기 때문에 클라우드에서도 GO가 유리함.
- c 나 go는 바이너리 파일을 만들기 때문에 실행을 할 때 c 나 go 컴파일러가 필요없음
- 다단계 빌드를 이용해서 마지막 실행 파일만 가지고 이미지를 만들면 용량이 줄어듬
- python 이나 node 나 java 는 바이너리 파일을 만들지 않고 줄 단위로 번역하면서 실행되던가 jvm 위에서 실행되므로 실행을 하기 위해서 무엇인가 더 필요함
- 클라우드 환경에서는 실행되는 프로그램의 크기가 크다면 그 만큼 비용이 더 지출되므로 최근에 go를 많이 사용합니다.
- 이미지 빌드
- docker build -t goapp:1.0 .
- 컨테이너 생성
- docker run --name goapp goapp:1.0
C:\Users\USER\multistage>docker run --name goapp goapp:1.0
Hello GO
5) yaml(yml, 야믈) 파일 작성법
- 기본 문법
- 들여쓰기 : 2칸 or 4칸
map
apiVersion: v1
kind: Pod
array
skills:
- docker
- kubenetes
주석
#comment 내용
- 숫자는 따움표 없이 표기
- 문자열은 큰 따움표 안에 표기
- boolean 은 true/false, yes/no - 대소문자 구분 안함
- 줄바꿈은 | (마지막에도 줄 바꿈이 적용 shift + \)
- |- 은 마지막은 줄 바꿈이 적용 안됨
- > 은 빈 줄은 제외
- key와 value 를 작성할 때 value 앞은 빈 칸이 필요
- value 가 문자열인 경우 대부분 따옴표 없이 작성해도 되지만 :이 포함된 경우는 반드시 따옴표를 해야함.
- windows_drive: c (가능)
- windows_drive: "c" (가능)
- windows_drive: c: -> 이 경우는 에러
- 대부분의 경우 yaml 은 json 으로 변역되서 수행
- json 으로 작성한 후 yaml 로 변경하거나 yaml 로 작성한 후 json 으로 변경 : https://www.json2yaml.com
https://www.json2yaml.com
JSON x
www.json2yaml.com
6) git hub action을 이용한 docker hub 배포
- 실행 가능한 application 생성 - main.go
package main
import (
"fmt"
"time"
)
func main() {
for {
fmt.Println("Hello GO")
time.Sleep(10 * time.Second)
}
}
- 빌드 : go build main.go
- 실행 : ./main.exe
- Dockerfile을 만들어서 이미지로 만들어지는지 확인
FROM golang:1.13-alpine as builder
RUN apk update & apk add git
WORKDIR /usr/src/app
COPY main.go .
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
FROM scratch
COPY --from=builder /usr/src/app .
CMD ["/main"]
- Dockerfile을 이용해서 이미지를 생성
- docker build -t goapp:1.0 .
- 컨테이너 생성
- docker run --name goapp-deploy goapp:1.0
- 콘솔에 10초 마다 Hello Go 을 출력함.
- 현재 프로젝트를 git hub에 업로드
- github 에 repository 를 생성 : gitaction
- 현재 디렉토리에서 git init
- 현재 디렉토리에서 git add .
- git config --global user.name 유저이름
- git config --global user.email 이메일
- git commit -m "메시지"
- git remote add 저장소이름(origin) gitURL
- git push 저장소이름(origin) 브랜치이름(main)
- git hub 에서 main.go 파일과 Dockerfile 이 업로드 되었는지 확인 (CI)
- Git Hub 에서 Docker Hub 에 로그인 하기 위해서 Docker Hub 에서 Access Token 발급
- DockerHub 이름 : itbam
- AccessToken : (dckr_pat_BqeIOYNW*****Tw7Yc-********)
- 업로드에 사용할 repository 생성 : gitaction
- Git Action 만들기 : git hub repository 에서 action을 누르고 새로운 workflow를 생성해서 작성
name : GitAction
#어떤 이벤트가 발생했을 때
#cron 이면 주기적인 작업
on:
push:
branches: ["main"] #main 브랜치에 push 이벤트가 발생하면
pull_request:
branches: ["main"] #main 브랜치에 pr 이벤트가 발생하면
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set Up Go
uses: actions/setup-go@v3
with:
go-version: 1.15
- name: Build
run: go build -v ./...
#with 과 run 이 언어마다 달라짐
- name: Login To DockerHub
uses: docker/login-action@v1
with:
username: itbam
password: dckr_pat_ZKp0ClOZep8-qExXy-4eEExXG8w
- name: build and releae to DockerHub
env:
NAME: itbam
REPO: gitaction
run: |
docker build -t $REPO .
docker tag $REPO:latest $NAME/$REPO:latest
docker push $NAME/$REPO:latest
- 코드의 내용을 수정하고 git pull
- 로컬 컴퓨터에서 docker run itbam/gitaction 을 수행해서 이미지를 컨테이너로 만들면 변경된 내용이 적용됩니다.
- 소스 코드를 수정하고 github 의 소스 트리에 push나 pull request 를 git action에 설정된 내용이 수행됩니다.
- 도커 허브에 업로드
- 가장 많이 수행하는 작업이 도커 허브에 업로드 하거나 jenkins 를 이용한 build 나 public cloud에 전송하는 작업입니다.
7) git hub action 을 이용한 docker hub 배포
- 동작하는 application 과 Dockerfile 작성
- main.go 파일을 만들고 작성한 후 실행
- go build main.go (main.exe 생성)
- main.exe
FROM golang:1.13-alpine as builder
RUN apk update & apk add git
WORKDIR /usr/src/app
COPY main\.go .
#디렉토리 안의 go 파일 들을 빌드해서 main 이라는 바이너리 파일을 현재 디렉토리에 생성
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main .
#다단계 빌드 때문에 작성
FROM scratch
#앞의 builder 라는 FROM 절에서 /usr/src/app 디렉토리의 내용을 현재 디렉토리로 복사
COPY --from=builder /usr/src/app .
#main 을 실행
CMD ["/main"]
- 이미지로 생성
- docker build -t goapplication .
- 컨테이너로 실행
- docker run --name goapplication( 계속 동작해야 하는 경우 -dit, 외부에서 접근하면 -p 포트번호:포트번호) goapplication
- 동작하는 application 과 Dockerfile을 git hub에 업로드
- docker hub에서 access token을 발급받고(1번 발급 받은 것을 재사용 - 발급받을 때는 값을 확인 가능하지만 한 번 발급 받으면 다음 부터는 확인이 안됨.) repository를 생성
- git hub 에서 git action을 생성(로컬 프로젝트의 .github 디렉토리의 workflows 디렉토리에 yaml 파일로 만들어서 업로드 해도 됩니다.)
- git hub 업로드
- git init
- git add .
- git remote add origin https://github.com/svng-zu/goapplication.git
- git commit -m "message"
- git push origin main
- docker hub 에서 access token 을 발급받고 (1번 발급 받은 것을 재사용 - 발급받을 때는 값을 확인할 수 있지만 한 번 발급 받으면 다음부터는 확인 안됨) -repository 생성
- dckr_***_P-xQb0XWxU4so-cSugb5rOV**** (암호 토큰)
- dckr_pat_P-xQb0XWxU4so-cSugb5rOVze4o
- 소스 코드를 고쳤을 때 반영되는지 확인
- 로컬 프로젝트에서 변경된 내용을 반영 : git pull origin main
- 코드를 수정하고 push 한 후 이미지를 다시 다운로드 받아서 확인
2. Docker-Compose
2.1) 개요
- 시스템 구축과 관련된 명령어를 하나의 텍스트 파일에 기재해서 한 번에 시스템 전체를 실행하고 종료와 폐기까지 한번에 하도록 도와주는 도구
- 공통의 목적을 갖는 애플리케이션 스택을 docker compose yaml 코드로 작성하고 한 번에 서비스를 올리고 관리할 수 있는 도구
- 데이터 베이스는 mysql을 사용하고 클라이언트의 요청은 node.js 를 이용해서 처리하고 클라이언트 애플리케이션은 react 로 배포하고자 하는 경우
- 하나의 network 로 묶어서 배포하는 방식 : 권장하지 않음
- 별개의 컨테이너로 배포한 후 네트워크로 연결하거나 포트 포워딩을 이용해서 접근 : 하나의 정의 파일을 이용해서 배포(docker-compose)
- yaml 포맷으로 기술된 설정 파일을 이용해서 여러 container 간의 실행이나 관계를 설정한 후 일괄 실행 또는 일괄 종료 및 삭제할 수 있는 도구
- 도커 명령어와 유사하지만 도커 명령어는 아님
2.2) docker-compose 와 Dockerfile의 차이
- Dockerfile은 하나의 이미지를 만들기 위한 것으로 네트워크 나 볼륨의 생성은 못함
- docker-compose 는 docker run 명령을 여러 개 모아놓은 것과 같은데 컨테이너 주변 환경을 생성하고 네트워크와 볼륨까지 함께 만들 수 있음
- kubenetes 를 학습한 경우에는 대부분 docker-compose를 사용하지 않고 kubenetes를 이용
2.3) 설치
- Mac 이나 Linux 에서 Docker Desktop을 사용하는 경우는 별도의 설치가 필요없음
- Linux 에서는 별도로 설치를 해야 함.
2.4) 샘플
- apache web(httpd) 서버를 만들어서 실행
- 명령어를 입력하는 방식
- docker run --name apa000 -d -p 8080:80 httpd
- docker-compose.yaml 파일을 작성
version: "3"
services:
apa001:
image: httpd
ports:
- 8081:80
restart: always
- 명령어 : docker-compose up
- docker ps 로 새로운 컨테이너가 생성되었는지 확인하고 브라우저에서 localhost:8081 로 확인
- maria db 컨테이너 생성
- 명령어를 이용
- docker run --name mariadb -d -p 3306:3306 --restart=always -e MYSQL_ROOT_PASSWORD=root mariadb
- docker-compose 이용
- 명령어를 이용
version: "3"
services:
mariadb:
image: mariadb:10.4.6
environment:
- MYSQL_ROOT_PASSWORD=root
ports:
- 3306:3306
restart: always
# 깔필요 없이 위 명령어들만 사용하면 docker를 통해 db를 사용할 수 있음.
그러나 직접 깔아서 환경 변수 설정하는 것은 클라우드를 해야할 때 해보는 것이 좋고
그 외의 경우는 명령어를 통해 수행하는 것이 좋다.
2.5) 작성 방법
- 주 항목
- services : 컨테이너
- networks : 네트워크
- volumes : 볼륨
- 정의 내용
- image
- networks: --net
- volumes : -v
- ports : -p
- environment : -e
- depends_on : 다른 서비스에 대한 의존 관계, 다른 서비스를 먼저 실행시킬 때 사용(wordpress는 mysql이나 mariadb 와 같이 사용됩니다. 이런 경우 mysql 이나 mariadb 가 먼저 실행되어야 하므로 wordpress 컨테이너를 만들 때 depends_on 에 mysql 이나 mariadb 를 설정해주어야 합니다.)
- restart : 컨테이너 종료 시 재시작 여부(no, always, on-failure, unless-stopped)
- 버전 정의
- yaml 코드의 첫 줄은 버전을 명시
- 이 버전에 따라 지원하는 도커 엔진의 버전이 달라지게 됩니다.
- 3.9 라고 설정하면 도커는 19.03 버전 이상이어야 합니다.
- 3이라고 설정하면 거의 모든 도커 버전을 지원
- 버전을 확인하면서 작성하는 것을 권장하는데 이유는 도커와 쿠버네티스는 업데이트 속도가 빠름
3)서비스 정의
=>컨테이너를 실행하는 것 과 동일한 개념
=>서비스 이름을 정의하고 하위 레벨에 도커 명령 과 유사하게 컨테이너 실행에 필요한 옵션을 작성
docker run --name=myweb nginx:latest
docker run --name=mariadb mariadb:10.4.6
version "3"
services:
myweb:
image: nginx:latest
mariadb:
image: mariadb:10.4.6
=>Dockerfile을 이용한 이미지의 경우
version "3"
services:
myweb:
build: .
mariadb:
build:
context:.
dockerfile: 도커파일 경로
=>하위 옵션
container_name: --name 과 같은 옵션으로 컨테이너 이름을 설정
ports: -p 와 같은 옵션으로 포트포워딩 설정
expose: 외부로 노출하지는 않고 필요 시 링크로 연결된 서비스 와 서비스 간의 통신을 허용할 때 사용하는 포트
networks: --net 옵션 과 같은 옵션으로 하나의 네트워크로 묶을 때 사용
volumes: -v 옵션과 같은 옵션으로 볼륨을 사용하고자 할 때 사용
environments: -e 옵션 과 같은 옵션으로 환경 설정할 때 사용
command: 서비스가 구동된 후 실행할 명령어를 작성
restart: --restart 옵션과 동이하며 재시작 옵션
depends_on: 서비스 간의 종속성을 의미하며 먼저 실행해야 하는 서비스를 지정
=>네트워크 정의
네트워크: 여러 컨테이너들이 서로 연결될 수 있도록 해주는 것
docker-compose는 네트워크를 지정하지 않으면 자체 기본 네트워크를 자동으로 생성
최상위 레벨에 networks 지정 시 해당 이름의 네트워크가 생성되고 대역은 172.x.x.x(사설 IP)로 자동 할당됩니다.
=>볼륨 정의
도커 엔진 내부의 공간 과 컨테이너 사이의 데이터를 공유하기 위한 것
컨테이너 내부의 데이터를 반 영구적으로 보관하기 위한 목적으로 사용
6.도커 명령어 와 docker-compose 비교
=>데이터베이스는 mysql:8.0 을 사용하고 웹은 wordpress:5.7 을 이용하는 웹 애플리케이션 서비스
각 컨테이너는 각각의 볼륨을 소유하고 2개의 컨테이너는 하나의 네트워크로 묶어서 사용
이 작업을 할 때 wordpress 나 redmine 을 많이 사용하는데 이유는 wordpress 나 redmine은 mysql 이나 mariadb 가 연결이 안되면 에러를 발생시키기 때문입니다.
1)도커 명령어 사용
=>2개의 볼륨 생성
docker volume create mydb_data
docker volume create myweb_data
=>볼륨 확인
docker volume ls
=>네트워크를 생성
docker network create myapp-net
=>네트워크를 확인
docker network ls
=>MySQL 컨테이너 생성
docker run
-dit
--name=mysql_app
-v mydb_data:/var/lib/mysql
--net=myapp-net
--restart=always
-p 3306:3306
-e MYSQL_ROOT_PASSWORD=wnddkd
-e MYSQL_DATABASE=adam
-e MYSQL_USER=adam
-e MYSQL_PASSWORD=wnddkd
mysql:8.0
- 확인: docker ps
docker ps 에서는 확인이 안되고 docker ps -a 에서는 확인이 된다면 컨테이너가 생성은 되었지만 실행 중 오류가 발생한 것이므로 옵션들을 확인해야 합니다.
이미 사용 중인 포트인지 확인
컨테이너 자체가 만들어지지 않으면 컨테이너 이름 이나 이미지 이름에 오류가 있는 경우
- 포트 확인: 데이터베이스 접속 도구에서 3306 번으로 접속
=>WordPress 컨테이너 생성(로그 데이터는 사용자가 보아야 하는 데이터이므로 볼륨에 연결하지 않고 하드디스크에 직접 연결하기도 합니다.)
docker run
-dit
--name=wordpress_app
-v myweb_data:/var/www/html
-v ./myweb-log:/var/log
--net=myapp-net
--restart=always
-p 8001:80
-e WORDPRESS_DB_HOST=mysql_app:3306
-e WORDPRESS_DB_NAME=adam
-e WORDPRESS_DB_USER=adam
-e WORDPRESS_DB_PASSWORD=wnddkd
--link mysql_app:mysql
wordpress:5.7
- 확인: docker ps
- 브라우저에서 localhost:외부에노출할포트번호
2)docker-compose.yaml 이용(확장자는 yml 도 가능)
=>빈 디렉토리 생성
=>디렉토리에 docker-compose.yaml 파일을 생성
version: "3.9"
services:
mydb:
image: mysql:8.0
container_name: mysql_app1
volumes:
- mydb_data:/var/lib/
networks:
- backend-net
restart: always
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: wnddkd
MYSQL_DATABASE: adam
MYSQL_USER: adam
MYSQL_PASSWORD: wnddkd
myweb:
image: wordpress:5.7
container_name: wordpress_app1
volumes:
- myweb_data:/var/www/html
- ./myweb-log:/var/log
networks:
- backend-net
- frontend-net
restart: always
ports:
- 8001:80
environment:
WORDPRESS_DB_HOST: mydb:3306
WORDPRESS_DB_USER: adam
WORDPRESS_DB_PASSWORD: wnddkd
WORDPRESS_DB_NAME: adam
depends_on:
- mydb
networks:
frontend-net: {}
backend-net: {}
volumes:
mydb_data: {}
myweb_data: {}
=>도커 컴포즈 실행: docker-compose up
=>도커 컴포즈 확인: docker ps
7.docker-compose 명령어
1)명령어
=>build: Dockerfile을 이용한 빌드 또는 재빌드
=>config: 도커 컴포즈 구성 파일의 내용 확인
=>create: 서비스 생성
=>down: 도커 컴포즈 자원을 일괄 정지 후 삭제
=>events: 컨테이너에서 실시간으로 이벤트 정보를 수신
=>exec: 실행 중인 컨테이너에 명령 실행
=>help: 도움말
=>images: 사용된 이미지 정보
=>kill: 컨테이너 강제 정지
=>logs: 실행 로그 정보 출력
=>pause: 컨테이너 서비스 일시 정지
=>port: 포트 바인딩된 외부로 연결된 포트 확인
=>ps: 실행 중인 컨테이너 서비스 출력
=>pull: 서비스 이미지 가져오기
=>push: 서비스 이미지 올리기
=>restart: 컨테이너 서비스 재시작
=>rm: 삭제
=>run: 실행
=>scale: 컨테이너 서비스에 대한 컨테이너 수 설정
=>start
=>stop
=>top: 실행 중인 프로세스 출력
=>unpause
=>up: 컨테이너 서비스 생성 과 시작
=>version
2)컨테이너 서비스 생성 및 시작 명령어
=>docker-compose -f 파일경로 up [옵션]
-f 옵션은 docker-compose.yaml 파일의 경로가 현재 디렉토리가 아닌 경우 사용
=>옵션
-d(--detach): 데몬으로 실행, 백그라운드로 실행
--build: 컨테이너를 실행하기 전에 이미지를 빌드
--force-recreate: 설정 또는 이미지가 변경되지 않았더라도 컨테이너를 재생성
-t, --timeout: 컨테이너를 종료할 때 타임아웃을 설정하는 것으로 기본은 10초
--scale SERVICE이름=개수: 컨테이너의 수를 변경
--abort-on-conatainer-exit: 컨테이너가 하나라도 종료되면 모든 컨테이너를 종료
3)python 의 flask로 웹 페이지를 만들고 redis 로 웹 페이지 엑세스 카운트를 캐시해서 페이지에 출력
=>flask
경량의 파이썬 웹 프레임워크
자유도가 높음
모든 것을 프로그래머가 직접 작성
=>redis
인 메모리 데이터베이스
메모리에 존재하는 데이터베이스로 유사한 종류로 H2 가 있음
public cloud 들 도 이 서비스를 제공하는데 비용이 비쌈
=>레디스 컨테이너를 실행
docker run --name 이름 -d -p 6379:6379 redis
=>파이썬 애플리케이션 생성
- 빈 디렉토리에 가상 환경 생성
mkdir flaskweb
cd flaskweb
python3 -m venv ./venv(python3 대신에 python 이나 ./venv 대신에 venv 로 입력)
venv/Scripts/activate(source vent/bin/activate) 명령 수행 - 안되면 venv/Scripts 로 들어가서 activate 를 입력하면 됩니다.
프롬프트 앞에 가상 환경 이름이 보이는지 확인
- 필요한 패키지 설치
pip install flask
pip install redis
- 파이썬 파일을 만들어서 작성(app.py)
import time
import redis
from flask import Flask
#웹 애플리케이션 객체
app = Flask(__name__)
def web_hit_count():
#redis 데이터베이스에 접속해서 hits 라는 키의 값을 1증가시켜서 리턴하는 함수
with redis.StrictRedis(host='127.0.0.1', port=6379) as conn:
return conn.incr('hits')
#아이피 와 포트번호(도메인) 만 가지고 요청할 때
@app.route("/")
def index():
cnt = web_hit_count()
return '''
<h1 style="text-align:center; color:black;">docker-compose application
</h1>
<p style="text-align:center; color:deepskyblue;">Web Access Count:{}
times </p>'''.format(cnt)
#어떤 IP를 사용해도 되고 9000번 포트로 접속해야 하고 개발 모드로 실행
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000, debug=True)
- 파이썬 파일 실행: python 파일경로
브라우저에서127.0.0.1:9000번으로 접속했을 때 카운팅이 되는지 확인
=>가상 환경에서 만든 파이썬 애플리케이션의 의존성을 requirements.txt에 작성
pip freeze > requirements.txt
=>파이썬 애플리케이션을 배포하기 위한 Dockerfile을 생성
FROM python:3.8-alpine
#캐시를 지우고 bash에 접속
RUN apk update && apk add --no-cache bash
#파이썬 관련 라이브러리 업데이트
RUN apk --update add python3 py3-pip python3-dev
#환경 설정
ENV LIBRARY_PATH=/lib:/usr/lib
ENV FLASK_APP=py_app
ENV FLASK_ENV=development
EXPOSE 9000
WORKDIR /py_app
COPY . .
#의존성 패키지를 설치
RUN pip install -r requirements.txt
#컨테이너로 만들어질 때 실행할 명령어
ENTRYPOINT ["python"]
CMD ["app.py"]
=>도커 파일이 제대로 만들어 졌는지 확인
docker build -t flaskapp .
docker run -dit -p 9000:9000 --name=flaskapp flaskapp
- redis 와 flaskapp 을 동시에 컨테이너로 실행하는 docker-compose.yaml 파일을 작성
- docker-compose 실행 : docker-compose -d up
- 컨테이너를 묶어서 배포하게 되면 컨테이너가 먼저 만들어져서 외부 IP를 인식을 못하는 경우가 있으므로 이런 경우 내부 컨테이너에서 접속할 때 실제 IP가 아니라 127.0.0.1 이나 localhost를 사용하는 것을 고려해야 합니다.
7.4) 컨테이너와 네트워크 삭제 명령어
- docker-compose -f 파일경로 down 옵션
- 옵션
- --rmi 종류 : 삭제시 이미지도 삭제
- -v : 볼륨도 삭제
7.5) 종료
- docker-compose stop
- docker-compose rm
- docker-compose down
8. Load Balancer
- Load Balancing(부하 균등)
- 동일한 기능을 수행하는 여러 개의 애플리케이션을 만들어 두고 요청이 오면 적절한 애플리케이션(하드웨어)을 선택해서 수행하도록 해주는 기능
- 부하 분산을 위한 필수 네트워크 기술
- 리소스 활용도를 최적화하고 처리량을 최대화하며 지연 시간을 줄이고 내결함성(fault tolerance) 구성을 보장해서 안정적인 시스템 운영이 가능하도록 합니다.
- 도커는 HaProxy, Nginx/Apache 등 외부 서비스를 이용해서 로드 밸런싱을 구현하는 것이 가능
8.1) 로드 밸런싱 알고리즘
- 라운드 로빈 알고리즘 : 클라이언트 요청을 서버의 가중치를 고려해서 구성된 서버에 균등 배분하는 방식으로 경로 보장이 안됨
- 최소 연결(Least Connections): 현재 연결된 클라이언트 수가 가장 적은 서버로 요청을 전달, 경로 보장 안됨.
- IP Hash : 해시 키를 이용해서 IP 별 index를 생성해서 동일 IP 주소는 동일 서버로의 경로를 보장하는 방식으로 해당 서버에 장애가 발생하면 주소는 변경되고, 균등배분 보장이 안되는 방식
- 트랜 잭션이 긴 작업에 주로 이용
- General Hash : 사용자가 정의하는 키
- 최소 시간(Least Time): 요청에 대한 낮은 평균 지연 시간을 기준으로 계산해서 서버를 지정
- random
8.2) 로드 밸런서 구현
- 동일한 python flask 앱을 3개 만들고 앞에 nginx를 추가해서 클라이언트의 요청을 nginx 가 받아서 라우드 로빈 방식을 이용하여 각 flask 앱에게 전송
- 원래는 모든 flask 앱이 동일한 모양이어야 하지만 편의상 보여지는 내용을 약간 다르게 구성
- 디렉토리 생성
mkdir loadbalancer
cd loadbalancer
mkdir nginx_alb, pyfla_app1, pyfla_app2, pyfla_app3
#, 없어도 됨
- nginx 작업
- cd nginx_alb
upstream web-alb{
server 172.17.0.1:5001;
server 172.17.0.1:5002;
server 172.17.0.1:5003;
}
server {
location /{
proxy_pass http://web-alb;
}
}
- pyfla_app1 작업
- Dockerfile 생성
FROM python:3
COPY . .
WORKDIR /
RUN pip install flask
COPY . /
ENTRYPOINT [ "python" ]
CMD [ "app.py" ]
- app.py 만들기
from flask import Flask
app = Flask(__name__)
app.route("/")
def index():
return "Web Application [1]" + "\n"
#flask 의 기본 port 번호는 5000
if __name__ == "__main__":
app.run(debug=True, host = "0.0.0.0")
- pyfla_app2 작업
- pyfla_app1 의 파일을 pyfla_app2 디렉토리로 복사
- pyfla_app3 작업
- pyfla_app1 의 파일을 pyfla_app3 디렉토리로 복사
- 이후 각 파일의 내용의 번호만 바꿔 확인!
python app.py
docker build it flaskapp .
docker run -dit -p 5000:5000 --name=flaskapp flaskapp
- loadbalance 디렉토리에 docker-compose.yaml 파일 생성 후 작성
- 실행시, 각 각앱을 번갈아가면서 접속됨을 알 수 있음.
- 브라우저에서 localhost:8080 접속
반응형
LIST
'Docker' 카테고리의 다른 글
Kubenetes (1) | 2023.10.19 |
---|---|
Kubenetes(2) (0) | 2023.10.13 |
Docker (2) | 2023.10.04 |