일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- spring boot
- 도커
- ORM
- 가상화
- 스프링 부트
- CI/CD
- 스프링 시큐리티
- 백엔드
- mysql
- 컨테이너
- Container
- 영속성 컨텍스트
- virtualization
- 데이터베이스
- Spring Security
- 스프링 배치
- JPA
- 웹 서버
- 자바
- vm
- 배포
- CS
- 스프링
- web server
- spring batch
- Java
- Spring
- HTTP
- computer science
- spring cloud
- Today
- Total
개발 일기
[Docker] 도커 명령어 정리 본문
ubuntu 이미지를 받아오자. Docker Hub에서 우분투를 검색하여 pull 명령어를 cmd창에서 실행시키면 된다.
docker pull [설치할 이미지]
ubuntu를 최신버전, 과거 버전(20.04) 두가지를 다운 받았고
docker images를 통해 현재 로컬에 받아진 이미지를 확인하니 두개의 ubuntu가 받아진 것을 확인할 수 있다.
아직 pull만 했기 때문에 현재 실행 중인 도커 컨테이너의 목록을 조회하는 docker ps를 통해 확인했을때 ubuntu가 실행중인 상태는 아니였다.
이제 필요없는 이미지들을 삭제하려 하는데 docker rmi [REPOSITORY명/IMAGE ID] 명령어를 통해 삭제할 수 있다.
특히 IMAGE ID를 통해 삭제할때 위의 예시로 7b 이렇게 앞부분 까지만 쳐도 식별되기 때문에 해당 이미지를 삭제하게 된다.
이번에는 ubuntu 이미지를 단순히 pull 만하는게 아니라 run을 시켜놓고 컨테이너가 종료됐을때 이미지를 삭제하려고 하면 아래와 같이 Error가 발생한다.
그 이유에 대해서 짧게 설명해보겠다. 이미지는 당장에 하드디스크에 저장된 파일이지만 현재 실행 중인 컨테이너나 실행이 종료된 컨테이너는 메모리 할당이 된 상태이다. 그래서 종료된 컨테이너일지라고 하더라도 메모리에서 내리고 난 뒤에 해당 이미지가 삭제 가능해 진다.
실제로 docker ps -a 명령어를 통해 실행중인 컨테이너 뿐만 아니라 종료된 컨테이너 또한 조회 가능하다. 이제 그 Exited된 컨테이너를 docker rm [CONTAINER ID] 명령어를 통해 메모리에서 제거해준 뒤 해당 이미지를 docker rmi를 통해 삭제 하면 된다.
아래가 그 예시이다.
이때, 컨테이너는 내부에 설치된 프로그램이 계속 실행되는 프로그램이 있다면 run 시켰을때 계속 실행 중이지만 그렇지 않은 경우 run 시키지마자 Exited(종료)된다. 예를들어 Apache Tomcat 같은 경우, 웹 서버/서블릿 컨테이너로서 백그라운드에서 지속적으로 실행되는 서비스를 제공한다. 그래서 Tomcat을 실행하는 Docker 컨테이너는 Tomcat 서버가 계속 실행 중이기 때문에 바로 종료되지 않는다.
반면에, Ubuntu 컨테이너가 바로 종료되는 이유는 대부분의 경우, Ubuntu 컨테이너가 실행될 때 기본적으로 실행하는 작업이 없거나 매우 빠르게 종료되는 작업을 실행하기 때문이다. 예를 들어, Ubuntu 컨테이너를 단순히 docker run ubuntu 명령어로 실행하면, 기본적으로 bash 쉘을 시작하지만, 대화형 모드가 아니라면 쉘이 바로 종료되고, 따라서 컨테이너도 함께 종료된다. 그렇기 때문에 run 시킨 후 docker ps를 했을 때 exited된 상태로 실행 된 후 종료됐기 때문에 뜨지 않는 것이다.
Docker Port Forwarding
docker run tomcat 또는 docker run httpd를 하게되면 아래와 같이 foreground 실행이 되서 명령어 치던 terminal에 그대로 로그가 찍히게 된다.
이러한 경우 백그라운드(Background) 실행이 필요하다. 명령어는 아래와 같다.
docker run -d -p 8080:80 httpd 이다. 우선 -d 옵션은 컨테이너를 detached mode 혹은 백그라운드 모드에서 실행하도록 한다. 즉, 컨테이너가 실행된 후에도 터미널을 반환하므로 다른 명령어를 계속 입력할 수 있게 되는 것이다.
그렇다면 -p 8080:80 옵션은 무엇일까? 이 옵션은 호스트 시스템의 포트와 Docker 컨테이너의 포트를 매핑하는 것이다. 여기서는 호스트의 8080포트가 컨테이너의 80포트에 연결되어 있다. 즉, 내가 실행하고자 하는 Apache의 기본 서비스 포트가 80이기 때문에 이렇게 하면 호스트 시스템에서 http://localhost:8080으로 웹 브라우저를 열면, 실제로는 Docker 컨테이너 내부의 Apache 서버가 80포트에서 수신하는 요청을 처리하게 된다.
그래서 실제로 저렇게 명령어를 치고 브라우저를 통해 http://localhost:8080으로 접속하게 되면 도커 컨테이너 내부의 80포트로 연결되어 동작하는 것이다.
위의 명령어를 통해서는 nginx는 호스트 운영체제의 8081 포트와 도커의 nginx 컨테이너의 80포트와 연결시켜 nginx가 정상적으로 동작하는 것을 확인할 수 있다.
이제 이것들을 종료하려면 docker stop을 통해 종료 시키고 docker rm 으로 메모리에서 내려주고 docker rmi로 이미지를 지워줘야한다. 너무 귀찮다.
-q 옵션을 통해 docker ps / docker ps -a에 해당하는 것들을 모두 반환하고 이것을 아래와 같은 순서로 해주면
현재 작동 중인 것들을 한방에 종료 시키고 images 또한 삭제시켜준다.
그래서 메모장에
docker stop $(docker ps -q)
docker rm $(docker ps -a -q)
docker rmi -f $(docker images -q)
이것을 저장해놓고 한방에 터미널에 붙혀넣으면 한방에 종료 가능하다.
Docker dit 옵션
위에서도 얘기했듯이 docker run ubuntu를 하면 demon process가 아니고 단지 운영체제의 일종으로 실행중인 프로그램이 없기 때문에 컨테이너가 바로 죽는다.
그러나 위와 같이 -dit 옵션, --name을 통해 docker run -dit --name myubuntu ubuntu 명령어로 실행 중이게 만들 수 있다.
우선 --name은 컨테이너의 이름을 지정해주는 것으로 추후에 docker compose에서 다른 컨테이너에서 --link 옵션 뒤에 지정해 둔 이름을 통해 같이 실행 시킬 수 있다.
그리고 -dit을 통해 Docker 컨테이너를 실행하면 컨테이너 내에서 Bash 또는 기타 셸이 실행 되게 할 수 있다. 위 터미널 창의 COMMAND를 보면 /bin/bash라는 프로그램이 돌고 있는 것이고 bash는 쉘(zsh, sh, power shell 등) 중 하나로 해당 bash 쉘을 통해 ubuntu에 명령어를 넣어줄 수 있게 된 것이다.
그런 다음 아래와 같이 docker attach [CONTAINER_ID]를 통해 그 쉘에 접근할 수 있게 되고 아래에서 보이는 것과 같이 더이상 터미널 창이 아닌 해당 컨테이너의 ubuntu os위의 bash쉘로 접근하게 된 것이다.
Docker exec 명령어 변경
위와 같이 httpd에서 foreground로 작동시켜놓으면 해당 터미널에서는 더 이상 치지 못한다. 그런데 이때 localhost:8080을 브라우저에 쳤을때 반환되는 It works!라는 문자열을 변경하고싶을때 쉘로 접근을 해야한다. 그러나 ps를 봤을때 COMMAND가 http-foreground이기 때문에 docker attach를 한다해도 bash쉘에 접근할 수 없다.
그럴 때 docker exec -it [CONTAINER_ID] bash 명령어를 통해 처리하여
이때 어쨋든 bash쉘에 접근하는 것이 목표이기 때문에 -d로 백그라운드 모드로 실행시키면 안되고 exec를 통해 bash를 실행시켜야한다.
-dit과 exec의 차이는?
- os만 설치하려면 docker run -dit ubuntu bash를 통해 bash로 접근하고
- httpd같이 데몬 프로세스가 돌아가는 경우 docker run -d -p 8080:80 httpd를 통해 백그라운드로 실행시켜 준 뒤 docker exec -it [CONTAINER_ID] bash로 접근할 수 있다.
Docker commit 명령어
Docker Hub에 Repository를 만들어놓고 작업한 컨테이너를 실행 중인 상태에서
docker commit [CONTAINER_ID] [REPO명:TAG 지정값] 명령어를 통해 Local 이미지로 추출해내고
docker push [REPO명:TAG]로 추출한 이미지를 Docker Hub에 업로드 할 수 있다.
그렇게되면 위와 같이 내가 commit하고 push한 이미지가 도커 허브 레포에 업로드 된 것을 확인할 수 있다.
위와 같이 실제로 Hub에 올라갔던 이미지를 다시 pull하여 실행시키고 전에 만들어 뒀던 파일의 경로로 들어갔더니 그대로 잘 있는 것을 확인할 수 있었다.
'DevOps > Docker Kubernetes' 카테고리의 다른 글
[Kubernetes] 쿠버네티스(Kubernetes) 교양 쌓기 (0) | 2024.05.21 |
---|---|
[Docker] 스프링 부트 Dockerfile 작성부터 EC2 환경에 배포까지 (0) | 2024.05.19 |
[Docker] 도커파일(Dockerfile) 작성하기 (0) | 2024.05.15 |
[Docker] 도커란? - 도커 개념과 구조 (0) | 2024.05.14 |
[Docker] 가상화(Virtualization) 및 Virtual Machine과 Container 차이 (0) | 2024.05.14 |