[교육] PAAS
day 1 _ docker and docker compose
컨테이너
느슨하게 격리된 애플리케이션을 패키징하고 실행
- 애플리케이션 실행에 필요한 모든 것을 패키징
- OS에 종속적이지 않음
docker build 시작
- docker pull : 필요 이미지를 땡김
- docker build : 이미지를 실제 빌드
- docker run : 이미지를 실행
도커 데몬
docker api 서버 및 런타임
도커 클라이언트
docker cli.
도커 데스크탑
그냥 데스크탑 애플리케이션. 다 들어있다(dockerd, client, kubernetes, credential helper)
도커 레지스트리
이미지 레지스트리
도커 객체
이미지, 네트워크, 볼륨 등 도커 실행에 필요한 다양한 구성 요소들
이미지
컨테이너 생성 지침이 포함된 읽기 전용 템플릿.
컨테이너
실행한 이미지. OS로 보면 프로세스. 완전히 격리되어 있으므로 기본적으로 컨테이너간 통신이 불가능함.
rocky linux
vagrant에 rocky linux 설치 centos 8은 m1 arm을 지원하지 않는다.
vagrant add box generic/rocky9vagrant init generic/rocky9vagrant up
repository 변경
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-*sed -i 's/#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org/g' /etc/yum.repos.d/CentOS-Linux-*
dnf remove podman container containers-commondnf install y dokcer-ce-3:20.10.12-3.el8 docker-ce-cli-1:20.10.12-3.el8 containerd.io-1.4.12-3.1.el8
유저 추가
도커 컨트롤을 위한 유저 추가
groupadd dockeruseradd paas -mpasswd paasusermod -aG docker passdocker run hello-world
도커 서비스를 활성화하여 리셋 시에도 정상 동작하는지 확인
systemctl enable docker.servicesystemctl enable containerd.service
기본 구성 파일
dns를 바꾸려면 아래 경로를 참조하자.
/etc/docker/daemon.json
{"dns" : ["8.8.8.8","8.8.4.4"]}
docker exec -it
//https://hwan-shell.tistory.com/366 : -i나 -t만 사용했을 경우?-i : input. 표준입출력 STDIN를 열겠다는 의미-t : terminal. 가상 tty(pesudo tty)를 통해 접속하겠다는 의미docker run -it ubuntu /bin/bashdocker pull <imagepath>docker container create <imagepath>
설치 후 실행 테스트
실행 후 가볍게 웹을 하나 띄워보자.
docker run -d -p 80:80 docker/getting-started
-d 데몬 실행 -p 호스트포트:컨테이너내부포트
테스트 조작
dockerfile 생성
FROM node:12-alpineRUN apk add --no-cache python2 g++ makeWORKDIR /appCOPY . .RUN yarn install --productionCMD ["node", "src/index.js"]EXPOSE 3000
docker build -t getting-started . -t : targetname
docker images
docker run getting-started -d -p 3000:3000
6.확인
내용 수정
다시 빌드. docker build
docker stop containe id
docker run 다시
레지스트리 사용
docker tag imagename tagname docker images를 해보면 태그네임이 붙은 이미지가 하나 더 생긴것을 확인할 수 있다.
docker login 하여 레지스트리를 사용할 수 있게하고, docker push imagename with tagname를 입력하여 도커 허브 이미지 레지스트리에 등록하자.
hub.docker.com에 들어가서 로그인해보면 실제 도커 이미지가 등록된 것을 확인할 수 있다.
Docker Labs
https://labs.play-with-docker.com
컨테이너 볼륨
컨테이너는 종료시 작성/수정했던 파일들이 다 사라진다. 영속적인 데이터를 다루기 위하여 볼륨이라는 구조를 만든다. 볼륨을 생성하고 컨테이너에 붙이는 과정은 다음과 같다.
- 볼륨 생성
docker volume create todo-opdocker volume create todo-db
- 확인
docker volume list
- 컨테이너 시작시 생성한 볼륨을 붙여넣기
docker run -dp 3000:3000 -v volumename:path in container imagenamedocker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
호스트의 소스 폴더를 워킹 디렉토리로 직접 마운팅하면, 호스트의 소스 수정이 바로 반영된다.
docker run -dp 3000:3000 -w /app -v "$(pwd):/app" node:12-alpine sh -c 'yarn install && yarn run dev'
-w /app : -w=working directory. 작업 디렉토리/현재 디렉토리를 변경한다.
멀티 컨테이너 구성
docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=todos mysql:5.7 => 볼륨 옵션이 없으면 볼륨명을 자동으로 설정하여 실행한다.
docker inspect volume volumename
마이에스큐엘과 노드제이에스 두 컨테이너를 실행하고 네트워크로 연결해서 서비스를 실행하려면 어떻게하면될까?
네트워크
네트워크 디버깅할 때 요길 쓴다. 생성한 네트워크 todo-app에 연결하여 요래조래 해보자. docker run -it --network todo-app nicolaka/netshoot
데이터베이스
데이터베이스를 실행할 때 네트워크 설정을 해준다. nodejs에서 mysql로 접근할 때 엔드포인트 정보가 있어야 하는데, 이 정보를 network-alias라는 옵션으로 추가한다. --network-alias mysql을 추가하였으므로, nodejs container내부에서 nslookup으로 mysql을 해보면 mysql을 향하나? 어쨋든 뭔가 나온다 ㅋㅋㅋ???. 이를 통하여 컨테이너에 접근할 수 있다.
-e : 환경 변수를 설정한다.
docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=todos mysql:5.7
실제 nodejs 컨테이너 실행
- 네트워크를 만들었고(--network todo-app),
- mysql에 접근할 엔드포인트를 설정했고(--network-alias mysql)으니
- db접근에 필요한 정보(아이디, 비밃런호, 디비명)를 환경 변수로 던져서 실행한다.
docker run -dp 3000:3000 -w /app -v "$(pwd):/app" --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=secret -e MYSQL_DB=todos node:12-alpine sh -c 'yarn install && yarn run dev'
이제 투두앱에 데이터를 쌓으면 mysql에 데이터가 잘 쌓이는 것을 볼 수 있다.
docker compose
docker 하나로만 돌리면 후달리니까.. 요래조래 잘 묶기 위해서 탄생한 시스템.
version: "3.7"services:app:image: node:12-alpinecommand: sh -c "yarn install && yarn run dev"ports:- 3000:3000working_dir: /appvolumes:- ./:/appenvironment:MYSQL_HOST: mysqlMYSQL_USER: rootMYSQL_PASSWORD: secretMYSQL_DB: todosmysql:image: mysqlenvironment:MYSQL_ROOT_PASSWORD: secretMYSQL_DATABASE: todosvolumes:- todo-mysql-data:/var/lib/mysqlvolumes:todo-mysql-data:
네트워크를 별도 설정해주지 않았는데, 설정해주지 않아도 기본적으로 두 컨테이너간 통신을 위한 브릿지 네트워크가 생성이 된다. 서비스 이름이 network-alias의 endpoint이름이 된다. 이렇게 브릿지 네트워크가 생성됨.
NETWORK ID NAME DRIVER SCOPE25a5d7dd43b6 app_default bridge local
그런데 docker-compose down이후 확인하면 해당 브릿지 네트워크가 사라져 있는 것을 알 수 있다.
docker-compose logs container service name을 통해 개별 컨테이너에 대한 로그도 볼 수 있다.
레이어캐싱 : 빌드 타임 최적화
현재 빌드의 경우 소스가 변경될때마다 yarn install을 땡겨오는 것을 알 수 있다. 그렇게해야할까? 소스만 고치면 yarn install까지 캐싱하고 그 다음 단계만 빌드할 수 있다.
비포 : 소스만 건드리더라도 copy . .에서 변화가 발생하므로 매번 yarn install을 진행한다.
FROM node:12-alpineRUN apk add --no-cache python2 g++ makeWORKDIR /appCOPY . .RUN yarn install --productionCMD ["node", "src/index.js"]EXPOSE 3000
애프터 : package.json 구성을 바꾸지 않고 소스만 바꾸면 copy . . 라인까지는 수행할 필요가 없으므로 이미지 레이어를 캐싱하고 cmd 라인부터 진행하게 된다. 매번 패키지를 안 땡겨와도 되니 개꿀이다.
FROM node:12-alpineRUN apk add --no-cache python2 g++ makeWORKDIR /appCOPY package.json yarn.lock ./RUN yarn install --productionCOPY . .CMD ["node", "src/index.js"]EXPOSE 3000
.dockefileignore 에 ignore할 부분을 넣어두면 더 빠른 빌드가 이루어진다.
2일차 과제
- httpd:bullseye 이미지 가져옥이
- source base directory copy build
- 대상 directory : /root/Work/httpd-test/htdocs
- 매칭 directory : 컨테이너 내부의 htdocs directory => 절대 경로 복사가 안되므로 dockerfile을 대상 디렉토리 내부에서 생성하여야 한다. => bind할 경우는 상관 없음.
- 인덱스 파일 수정
- writer: 작성자명 date : javascript를 활요한 현재시간 가져오기
신규 이미지로 빌드 후 컨테이너 수행
결과 확인
FROM httpd:bullseyeCOPY . /usr/local/apache2/htdocs/EXPOSE 80
hello, centumcity<br />writer:jeognhan kim<div>date : <div id="todayDate"></div></div><script>const date = new Date();console.log(date);document.getElementById("todayDate").innerHTML = date;</script>
- -v옵션을 줘서 컨테이너 내부의 htdocs경로를 덮어 쓸 수 있다. 예를 들어 1) COPY . /usr/local/apache2/htdocs/명령으로 현재 폴더를 카피한 후 2) -v /var/www/public/:/usr/local/apache2/htdocs/을 실행 옵션으로 주면 호스트의 /var/www/public/경로가 컨테이너 아파치의 스태틱 페이지로 보인다. 단, 이미지 빌드는 현재 경로 기준으로 되어 있으므로, -v옵션을 빼면 현재 경로 기준의 이미지가 뜬다.