"어라 제 서버에서는 잘 돌아갔는데.. 왜 xx님 서버에서는 안될까요?😲"
웹 애플리케이션 등을 개발하다 보면 흔히 마주쳤던 상황이다.
분명 작업하던 서버에서는 문제 없이 잘 돌아갔는데 왜 다른 서버에서는 매번 환경 설정 문제가 발생할까?
그래서 존재하게 된 것이 바로 Docker, 도커라는 친구이다.
이렇게 고래가 컨테이너 박스를 등에 이고 바다를 떠다니는 모습이 로고인데,
Docker의 역할을 알고 나니 정말 잘 표현했다는 생각이 든다.
Docker란 무엇일까? (a.k.a 밀키트 조리)
Docker는 chatGPT 친구가 말해주듯이,
특정 애플리케이션을 어느 머신에서나 똑같이 구현할 수 있도록 도와주는 "컨테이너(container) 기반의 오픈소스 가상화 플랫폼"이다.
어느 머신(서버)에서나 container라는 것을 통해 동일한 환경을 만들어줘서
머신간의 환경 차이(environment disparity)를 해결해준다.
Docker를 살펴보다 보면 항상 같이 따라다니는 두 용어가 있는데, 바로 앞에서도 나왔던 "container"와 "image"이다.
container는 머신 안에서 독립된 환경을 만들어주고 특정 애플리케이션을 실행하기 위한 환경을 만들어주는 가상 공간이고,
image는 이러한 컨테이너를 만들기 위한 하나의 틀이라고 볼 수 있다.
진짜 우리가 알고 있는 사진 파일..은 아니지만 만들 환경을 사진처럼 찍어놓은 것과 비슷하다.
그리고 이런 image를 만들기 위해 사용되는 것이 Dockerfile이라는 것인데,
한번 밀키트 조리로 이 Dockerfile, image, 그리고 container 간의 관계를 표현해봤다.
Dockerfile은 image, 즉 밀키트를 만들기 위한 재료랑 레시피가 적혀있는 파일이다.
어떤 파일을 올리고 환경을 구축하기 위한 설명서라고 볼 수 있다.
그리고 이걸 기반으로 밀키트인 image를 만들어준다.
밀키트에 실제 이용할 재료들이 담겨있는 것처럼, image 안에도 사용할 소스코드 등이 들어 있다.
image는 Dockerfile이 있는 경로에서 "docker build" 명령어를 실행시키면 생성된다.
그리고 "docker push"를 통해 docker hub라는 곳에 이미지를 업로드한다.
마치 밀키트를 공장에서 슈퍼마켓으로 옮겨 파는 것처럼, 그리고 작업한 코드를 깃헙에 올리는 것처럼,
도커 이미지도 docker hub라는 공간에 올려둔다.
이 올려진 도커 이미지는 "docker pull"을 통해 개인 작업 서버로 다운로드 받을 수 있고,
"docker run"을 실행하면 해당 이미지를 기반으로 한 컨테이너가 구축되면서 웹 애플리케이션 요리가 완성된다!
(명령어 세부 사용 방식은 아래에서 작성해 두었다.)
Docker 설치
Docker 사용을 위해 docker desktop (https://www.docker.com/products/docker-desktop/) 도 많이 이용되는 것 같지만,
여기에서는 근본 linux 기반으로 사용하는 방식을 알아보고자 한다.
먼저 설치는 https://docs.docker.com/engine/install/centos/ 를 기반으로 진행해주면 된다.
# 설치했던 docker가 있을 경우 (uninstall old versions)
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# yum-config-manager 제공하는 yum-utils 설치
sudo yum install -y yum-utils
# yum-config-manager로 repository set up
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# docker 설치 (latest)
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
## 만약 특정 버전의 docker를 설치하고 싶다면
yum list docker-ce --showduplicates | sort -r # 버전 목록 확인
sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io docker-buildx-plugin docker-compose-plugin
# docker 시작
sudo systemctl start docker
# 잘 동작하는지 확인
sudo docker run hello-world
일반적인 서버는 root 권한이 함께 주어져 있겠지만, 만약 사내 정책 상 같은 서버인데 root 권한이 주어진 공간이 따로 있다면
root 권한이 없는 공간에서도 docker가 잘 수행되도록 user 권한을 부여해야 한다.
# docker usergroup 생성
sudo groupadd docker "대상 user명"
sudo gpasswd -a "대상 user명" docker
sudo chmod 666 /var/run/docker.sock
# 권한 적용을 위한 docker 재실행
sudo systemctl restart docker
docker가 잘 설치되었다면, 이제 서버 안에서 자유롭게 docker를 사용할 수 있다!
Dockerfile 작성 방법
https://docs.docker.com/engine/reference/builder/
자주 사용되는 명령어는 다음과 같다.
- FROM : image 환경 설정 (ubuntu / centos / ... )
- USER : user group 설정
- COPY : host에서 image로 파일 복사
- RUN : 명령어 실행
- ENTRYPOINT : container 띄울 때 실행시킬 명령어
이를 기반으로 아래와 같이 Dockerfile을 작성할 수 있다.
FROM docker.io/centos:7.4.1708
COPY . .
USER root
RUN yum update -y && yum -y install python3 python3-devel epel-release python-pip
ENTRYPOINT ["/bin/bash", "./run.sh"]
Docker 사용 레시피
이제 위 Dockerfile을 기반으로 이미지를 만들고, 컨테이너를 구축할 수 있다.
image 빌드 및 실행과 관련된 명령어는 다음과 같다.
# image 빌드 (=image 생성)
docker build [경로] -t [image명] # 경로: Dockerfile 경로
docker build [경로] -t [image명] --no-cache # 캐시 이용하지 않고 처음부터 빌드 진행
docker build [경로] -f [Dockerfile명] # Dockerfile명 지정해줘야 할 경우 (Dockerfile이 아닐 경우)
image가 생성된 뒤, 아래와 같이 container를 생성할 수 있다.
# image 실행 (=container 생성)
docker run [옵션] [image명] # port번호 변경
## 옵션 목록
#### port 번호 변경
docker run -p [host port 번호]:[container 내부 port 번호] [image명]
#### 경로 공유
docker run -v [host 경로]:[container 내부 경로] [image명]
#### entrypoint 변경
docker run --entrypoint [변경할 entrypoint] [image명]
docker run --entrypoint /bin/bash [image명] # entrypoint 없이 실행
#### image 빌드 및 컨테이너 접속
docker run -ti [image명]
생성된 container 및 image는 다음과 같이 관리할 수 있다.
# image 조회
docker images
# container 조회
docker ps # 실행중인 컨테이너 조회
docker ps -a # 전체 컨테이너 조회
# 실행중인 container 접속
docker exec -it [container명] /bin/bash
# image 삭제
docker rmi [image명] # 특정 이미지 삭제
docker rmi $(docker images -q) # 전체 이미지 삭제
# container 삭제
docker rm [container명] # 특정 컨테이너 삭제
docker rm $(docker ps -a -q) # 전체 컨테이너 삭제
# 로그 확인
docker logs [container명]
'COMPUTER SCIENCE > LINUX' 카테고리의 다른 글
[Linux] wget certificate 오류 해결 (0) | 2021.10.14 |
---|---|
[Linux] CGI httpd.conf 설정 (0) | 2021.01.29 |
[Linux] vim에서 tab indentation을 space 4개로 변경 (0) | 2020.10.21 |
[Linux] vim 기본 설정 (0) | 2020.10.10 |
[Linux] CentOS에서 pip 설치하기 (0) | 2020.10.08 |