오늘은 팀장님의 주도하에 docker스터디를 진행하기로하였다.
오전에 우리는 이 도커에대한 내용정리를 하고 실습까지 실행하여 적용시켜보는걸 목표로 진행하게됐다.
- docker가 뭔지
- docker registry, image, container 가 뭔지, 사용 명령어 정리
- Dockerfile, Docker-compose 언제 쓰는지
- Docker volume이 뭔지
Docker는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼입니다. Docker는 소프트웨어를 컨테이너라는 표준화된 유닛으로 패키징하며, 이 컨테이너에는 라이브러리, 시스템 도구, 코드, 런타임 등 소프트웨어를 실행하는 데 필요한 모든 것이 포함되어 있습니다. Docker를 사용하면 환경에 구애받지 않고 애플리케이션을 신속하게 배포 및 확장할 수 있으며 코드가 문제없이 실행될 것임을 확신할 수 있습니다.
Docker의 작동방식
Docker는 코드를 실행하는 표준 방식을 제공합니다. Docker는 컨테이너를 위한 운영 체제입니다. 가상머신이 서버 하드웨어를 가상화하는 방식과 비슷하게(직접 관리해야 하는 필요성 제거) 컨테이너는 서버 운영 체제를 가상화합니다. Docker는 각 서버에 설치되며 컨테이너를 구축, 시작 또는 중단하는 데 사용할 수 있는 간단한 명령을 제공합니다.
Docker 용어 정의
Docker:
컨테이너 기술을 활용하는 앱의 개발, 제공 및 실행을 위해 설계된 소프트웨어 컨테이너 플랫폼입니다. Docker는 엔터프라이즈 에디션과 커뮤니티 에디션 이렇게 두 가진 버전으로 제공됩니다.
컨테이너:
하드웨어 가상화를 제공하는 VM과 달리 컨테이너는 '사용자 공간'을 추상화함으로써 경량의 운영체제 수준의 가상화를 제공합니다. 컨테이너는 호스트 시스템의 커널을 다른 컨테이너와 공유합니다. 호스트 운영체제에서 실행되는 컨테이너는 코드와 모든 종속성을 패키지화하여 애플리케이션이 한 환경에서 다른 환경으로 빠르고 안정적으로 실행될 수 있게 해주는 표준 소프트웨어 장치입니다. 컨테이너는 영구적이지 않으며 이미지로부터 생성됩니다.
Docker 엔진:
컨테이너를 구축 및 실행하는 오픈 소스 호스트 소프트웨어입니다. Docker 엔진은 Oracle Linux, CentOS, Debian, Fedora, RHEL, SUSE, Ubuntu 등 다양한 Windows 서버 및 Linux 운영체제에서 컨테이너를 지원하는 클라이언트 서버 애플리케이션의 역할을 합니다.
Docker 이미지:
컨테이너로 실행될 소프트웨어 모음입니다. 여기에는 Docker 플랫폼에서 실행할 수 있는 컨테이너 생성 지침이 포함되어 있습니다. 이미지는 변경할 수 없으며, 이미지를 변경하려면 새로운 이미지를 생성해야 합니다.
Docker 레지스트리:
이미지를 저장 및 다운로드할 수 있는 공간입니다. 레지스트리는 무상태성을 갖춘 확장 가능한 서버측 애플리케이션으로 Docker 이미지를 저장 및 배포합니다.
docker-compose.yml
version: "3.8"
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
ports:
- 8000:8000
working_dir: /usr/src/app/
volumes:
- ./:/usr/src/app/
env_file:
- ./.env
2. Docker 간단한 명령어
1) docker run
: container 생성
docker run [options] {image_name} [command]
options
- -d : docker container가 백그라운드에서 실행됨
- -p host_port:container_port : container의 포트와 host의 포트를 연결
docker run -d -p 80:5000 docker-memo:version1
2) docker ps, docker ps -a
- docker ps : 현재 실행중인 container 상태 확인
- docker ps -a : 모든 container 상태확인 (stop된 container도 포함)
3) docker stop
: container 정지
docker stop {container_id|conatinaer_name}
docker stop docker-memo:version1
4) docker restart
: container 재시작
docker restart {container_id|container_name}
docker restart docker-memo:version1
5) docker rm
: container 삭제
docker rm {container_id}
docker rm 66adafa8f672
3. Docker image
1) Dockerfile
: Docker image를 생성하기위한 파일
FROM python:3.8 ADD requirements.txt . RUN pip install -r requirements.txt ADD templates templates ADD app.py . CMD ["python", "app.py"]
- FROM : Docker image를 생성할 때 기본적으로 사용할 base image
- ADD src dst : host의 src 위치에 있는 파일이나 폴더를 dst 위치에 저장
- RUN script : script를 실행
- CMD : Docker image를 실행할 때 자동으로 실행되는 명령어
2) docker build
docker build [OPTIONS] PATH
options
- -t : Docker image에 {image_name}:{tag}의 형태로 name 과 tag 설정 가능, {tag}를 붙이지 않을 경우 자동으로 latest로 설정됨
docker build -t docker-memo:version1 .
3) docker images
: Docker image 목록 확인 가능
4) docker rmi
: Docker image 삭제
docker rmi ({image_name}:{tag} | {Iamge ID})
docker rmi docker-memo:version1
4. Docker Hub
: Docker registry를 관리할 수 있는 서비스
Docker Hub is a service provided by Docker for finding and sharing container images with your team. It is the world’s largest repository of container images with an array of content sources including container community developers, open source projects and independent software vendors (ISV) building and distributing their code in containers.
- https://docs.docker.com/docker-hub/
1) 업로드하기 (push)
1-1) Docker image build
: docker hub의 가입한 아이디(user_id)를 포함
docker build -t {user_id}/docker-memo:version2 .
docker build -t creamone/docker-memo:version2 .
1-2) docker hub에 로그인
docker login
1-3) registry에 push
docker push {user_id}/docker-memo:version2
docker push creamone/docker-memo:version2
명령어 모음
# 컨테이너 리스트
docker ps
# 정지된 컨테이너 리스트까지 포함
docker ps -a
# 이미지 리스트
docker image ls
# 컨테이너 실행
docker run -dp 3000:3000 getting-started
# 컨테이너 실행 with 볼륨
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
# 컨테이너에서 쉘 열기
docker exec -it {id} /bin/sh
# 컨테이너 정지
docker stop {id}
# 컨테이너 삭제
docker rm {id}
# 컨테이너 정지 & 삭제
docker rm -f {id}
# 이미지 태그하기(소스 이미지에서 타겟이미지로)
docker tag {sourceimagename} {targetimagename}
# 이미지 빌드하기
docker build -t {username}/{imagename}:{tagname}
# 이미지 빌드 platform linux/amd64 설정
docker build --platform linux/amd64 -t {username}/{imagename}:{tagname}
# 이미지 푸시하기 (tagname 생략시 latest)
docker push {username}/{imagename}:{tagname}
# 도커 로그인
docker login -u {username}
# 도커 로그아웃
docker logout
# 도커 볼륨 만들기
docker volume create {이미지이름}
# 볼륨을 탑재해서 컨테이너 실행하기
docker run -dp 3000:3000 -v todo-db:/etc/todos getting-started
docker run -dp 3000:3000 -v {볼륨이름}:{탑재할컨테이너상경로} {이미지이름}
# 볼륨 리스트
docker volume ls
# 모든 컨테이너 멈추기
docker kill $(docker ps -q)
# 모든 컨테이너 삭제하기
docker rm $(docker ps -a -q)
# 모든 이미지 삭제하기
docker rmi $(docker images -q)
# 네트워크 만들기
docker network create {네트워크 이름}
# 네트워크 리스트 보기
docker network ls
# 파일에 값 입력
echo "some value" > file.txt
# 파일 값을 터미널에 프린트
cat file.txt
# 파일의 마지막 줄 읽기(기본값은 10)
tail file.txt
# 파일의 마지막 100줄 읽기
tail -100 file.txt
# 파일의 마지막줄 읽고 추가되는 값들 계속해서 따라(follow) 읽기
# 프로세스가 연속적
tail -f file.txt
# 사용중 포트 확인
netstat -nlpt
# 특정 포트
netstat -an | grep {포트번호}
docker-compose가 필요한 이유
기존 docker 명령만으로 수많은 옵션을 붙여 컨테이너를 올리는 방식은 번거롭고 불편할 뿐만 아니라 휴먼 에러의 가능성이 크다. 그렇기 때문에 yaml 파일로 미리 정의해두고 한꺼번에 여러 컨테이너를 올릴 수 있는 docker-compose의 사용을 고려해야 한다.
docker-compose로 컨테이너 올리기
1. Dockerfile을 이용하여 이미지를 생성한다.
2. docker-compose.yml에 환경을 정의한다.
version: '3'
services:
nginx:
image: nginx
ports:
- 8080:80
volumes:
- ./:/usr/share/nginx/html/
3. docker-compose up -d 명령어로 컨테이너로 만든다.
docker-compose 설치
$ curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose 명령어
기본적으로 up, down 제외 docker 명령어와 같다.
컨테이너 최초 실행
$ docker-compose up -d
컨테이너 중지 및 종료(stop & kill)
$ docker-compose down
작동중인 프로세스의 상태를 확인
$ docker-compose ps
이미지 가져오기
$ docker-compose pull
로그 확인
$ docker-compose logs [service_name]
docker-compose.yml에서 작성했던 services 항목을 말한다.
컨테이너 추가 생성
$ docker-compose run -d [service_name]
이런 식으로 반복하여 여러 개의 같은 서비스의 컨테이너 생성 가능
필요한 이미지를 강제로 빌드
$ docker-compose up --build
컨테이너 강제 재시작
$ docker-compose up --force-recreate
컨테이너 자원 사용량 확인
$ docker inspect [container_name]
컨테이너 자원 변경
$ docker update [resource_update] [container_name]
resource_update 예시 : --cpuset-cpus=0-4(cpu 개수 지정)
도커 데몬에서 실행되는 명령어의 결과를 로그로 출력
$ docker events
실행 중인 모든 컨테이너의 자원 사용량을 스트림으로 출력
$ docker stats
--no-stream 옵션을 붙여 그 순간의 로그만 볼 수 있음
이미지, 컨테이너, 로컬 볼륨의 개수 및 크기 등의 정보 출력
$ docker system df
cAdvisor 사용 방법
$ sudo docker run \
--volume=/:/rootfs:ro \
--volume=/var/run:/var/run:ro \
--volume=/sys:/sys:ro \
--volume=/var/lib/docker/:/var/lib/docker:ro \
--volume=/dev/disk/:/dev/disk:ro \
--publish=8080:8080 \
--detach=true \
--name=cadvisor \
--privileged \
--device=/dev/kmsg \
gcr.io/cadvisor/cadvisor:$VERSION
위 명령어 실행 후 8080포트로 접속
Bind Mount 명령어
bind mount 명령어
docker run -dp 3000:3000 \\
-w /app -v "$(pwd):/app" \\
node:12-alpine \\
sh -c "yarn install && yarn run dev"
파워쉘
docker run -dp 3000:3000 `
-w /app -v "$(pwd):/app" `
node:12-alpine `
sh -c "yarn install && yarn run dev"
Apple Silicon(M1)
docker run -dp 3000:3000 \\
-w /app -v "$(pwd):/app" \\
node:12-alpine \\
sh -c "apk add --no-cache python2 g++ make && yarn install && yarn run dev"
mysql 한글화
etc/my.conf
[mysqld]
collation-server = utf8mb4_unicode_ci
character-set-server = utf8mb4
skip-character-set-client-handshake
오후에는 저번주 금욜에 했던 jwt 프로젝트를 이용하여 docker로 EC2에 배포하는과정을 실습할려고한다.
그러는도중에
요런에러가뜨고 찾아보니까 잘 못찾아서 팀원들에게 물어보니 팀원분께서 이게 파이썬 인터프리터 버젼이 달라서 그런거같다고 하셔서 3.10-> 3.8로 바꿔서 실행을해줘서 잘되었습니다.
1번째줄이 원래 알려주신코드에서 3.10.0 - alpine으로 되어있었습니다(참고)
그다음 요렇게 docker scan을 해줘야되는구문이 나와서 docker 명령어로 docker scan alpine을 해준뒤에
빌드를 해주니 잘 되는것을 확인했습니다.
그다음
docker run -dp 8000:8000 \
-w /usr/src/app -v "$(pwd):/usr/src/app" \
ai2_back \
sh -c "python manage.py runserver 0.0.0.0:8000"
에러가 떠서 bactic ` 이걸로 해줘서 powershell은 해야되는걸로 팀원분이 알려주셔서 powershell에서도 해결할수있는걸 확인했습니다. shell에서 하는방법은 역슬래쉬로 해주는거같구요.
요렇게 docker-compos build 해주면 결여되어있는파일이 env파일이므로 이부분만 주석처리해주고 실행하니 잘되는것을 확인했습니다 요것도 팀원의 도움으로 해결하였습니다.
'스파르타 내일배움캠프' 카테고리의 다른 글
TIL41 docker compose 후 EC2 서버에 올려보기! (0) | 2022.08.10 |
---|---|
TIL 39 JWT가 무엇인가? (0) | 2022.08.05 |
내일배움캠프 AI - MyLittleTrip 프로젝트 KPT 회록 (0) | 2022.08.04 |
TIL38 (0) | 2022.07.08 |
TIL37 (0) | 2022.07.07 |