도커란?
운영체제 수준의 가상화 기술로, 리눅스 커널을 공유하면서 프로세스를 격리된 환경에서 실행하는 기술
리눅스 컨테이너 기술을 활용.
왜 도커를 사용하는가?
가상머신과의 비교
- 가상머신 : 하드웨어의 가상화를 통해 운영체제를 실행. 즉 게스트OS가 존재.
- 하드웨어의 가상화 = 하이퍼바이저를 통해서 실현
- 하이퍼바이저 타입 1 : 하드웨어 위에서 직접 실행
- 하이퍼바이저 타입 2 : 게스트OS를 거쳐서 실행.
- 도커 : 하드웨어의 가상화 없이 커널에서 자원을 공유하는 형태로 실행.
- 즉 게스트OS가 존재하지 않음.
- 모든 도커 컨테이너는 격리된 프로세스.
장점
- 좀 더 가볍다.
- 인프라 세팅을 좀 더 확실히 할 수 있다.
pid 1 이슈
- 원래의 운영체제 : 첫번째 프로세스 id = init 프로세스가 차지.
- 컨테이너 : init 프로세스가 없기 때문에 가장 먼저 실행된 일반 애플리케이션이 PID 1을 할당.
- 그런데, Docker는 컨테이너 내부에 PID 1이 있는 프로세스에만 신호를 보낼 수 있음.
이 경우, 어플리케이션에 따라 다르긴 하지만, 다음과 같은 문제가 발생할 수 있음.
- 1번 pid인 일반 어플리케이션은 신호처리가 안됨
- 좀비 프로세스 회수가 안됨.
- 따라서 Dockerfile에
tini나dumb-init과 같은 경량 init 시스템을 추가하여 이 문제를 더욱 명확하게 해결 - 물론, 인셉션에서의 설정들은 그럴 필요는 없음.
mariadb → 초기설정은 백그라운드에서, 이후 실행은 포그라운드에서
nginx → cmd를 이용해서 처리.
Run, cmd, entrypoint
RUN 명령어는 도커파일로부터 도커 이미지를 빌드하는 순간에 실행이 되는 명령어
CMD와 ENTRYPOINT 모두 컨테이너가 실행될 때 실행되는 명령어를 설정하는 데 사용
그러나 CMD는 추가 인자로 명령어를 덮어쓸 수 있지만, ENTRYPOINT로 설정한 명령어는 컨테이너 실행 시 추가 인자로 덮어쓸 수 없음.
예시 : 서버포트 접속
dockerfile
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "application.jar", \
"--server.port=3000"]
이렇게 정해놓은 경우, 밑과 같이 명령어를 쳤을 때 불가능하다.
bash
docker run -dit -p 8080:5000 java-server --server.port = 5000