도커 실습 - 컨테이너

YongjLEE·2023년 8월 22일
0

0 : 정수형
null : 포인터(0을 주소로 가리킴)

$ sudo vi /etc/docker/daemon.json
{
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
    "log-opts" : {
        "max-size": "100m"
    },
    "data-root": "/mnt/storage/docker",
    "storage-driver": "overlay2"
}

입력

 $ sudo mkdir -p /etc/systemd/system/docker.service.d

Docker daemon service로 등록(daemon 백그라운드)

$ sudo mkdir -p /etc/systemd/system/docker.service.d

Docker daemon service로 등록

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker

Docker daemon 재실행

$ sudo docker run hello-world

스토리지 설정 확인

$ sudo docker -v

버전확인

$ sudo docker run -it ubuntu:18.04

첫번째 컨태이너 생성
docker run 명령어는 컨테이너를 생성하고 실행하는 역할 ubuntu:18.04는 컨테이너를 생성하기 위한 이미지의 이름 -i -t 옵션은 컨테이너와 상호 입출력 가능
-i옵션 : 상호입출력
-t옵션 : tty

$ sudo docker ps
$ sudo docker ps -a

exited일 시 멈춰있음

$ sudo docker pull centos:7
$ sudo docker images

이미지가 정상적으로 받아졌는지 확인하기 위해 images 명령어로 확인

images 명령은 도커엔진에 존재하는 이미지의 목록을 출력

$ sudo docker create -it --name mycentos centos:7

컨테이너를 생성할 때는 run 명령어가 아닌 create 명령어를 사용할 수도 있습니다.

다음 명령어로 centos:7 이미지로 컨테이너를 생성합니다.

$ sudo docker start 9aa365a7a96b
$ sudo docker attach mycentos

  • 컨테이너 내부에서 빠져나오는 방법은 두 가지
  1. exit 명령 또는 ctrl + D 입력
  2. exit가 아닌 ctrl + P, Q를 입력
  • RUN과 CREATE
    RUN :: docker pull(이미지 없을 때) -> docker create -> docker start -> docker attach(-it옵션)
    CREATE :: docker pull(이미지 없을 때) -> docker create

  • docker ps 명령 : 정지되지 않은 컨테이너만 출력 ⇒ exit로 빠져나온 컨테이너는 출력되지 않음, ctrl + P,Q로 빠져나온 컨테이너는 출력

  • docker ps -a 명령 : 정지된 컨테이너까지 포함해서 출력
    Exited : 정지상태, Up : 실행중인 상태

컨테이너 세부정보

$ sudo docker inspect mycentos

컨테이너 세부 정보 확인

CONTAINER ID

컨테이너에 자동으로 할당된 고유한 ID
full id 중에 앞의 12자리만 표시된다.
full id는 docker inspect 명령으로 확인이 가능하다.

IMAGE

컨테이너를 생성할 때 사용된 이미지의 이름이다.

COMMAND

COMMAND는 컨테이너가 시작될 떄 실행할 명령어 커맨드는 대부분의 이미지에 미리 내장돼있기 때문에 별도로 설정할 필요는 없다. 위에서 생성한 centos:7, ubuntu:18.04 이미지에는 /bin/bash라는 커맨드가 내장되어 있지 때문에 컨테이너를 생성할 때 별도의 커맨드를 설정하지 않았다. 컨테이너가 시작될 때 /bin/bash 명령이 실행됐으므로 상호 입출력이 가능한 쉘 환경을 사용할 수 있었다.

이미지에 내장된 커맨드는 docker run이나 create 명령어의 맨 끝에 입력해서 컨테이너를 생성할 때 덮어쓸 수 있다. 예를 들어, 아래의 docker run 명령어로 생성되는 컨테이너는 실행될 때마다 echo hello world를 실행한다.

NAME

컨테이너의 고유한 이름입니다. 컨테이너를 생성할 때 —name 옵션으로 이름을 설정하지 않은 경우 도커엔진이 임의로 형용사와 명사를 무작위로 조합해 이름을 설정하기 때문에 ubuntu 컨테이너의 이름이 예시에서는 sweet_pascal로 설정되어 있다. ID와 마찬가지로 고유해야 하며 중복되면 안되지만 docker rename 명령으로 변경은 가능하다.

$ sudo docker rename jolly_benz my_ubuntu1804

컨테이너 삭제

더 이상 사용하지 않는 컨테이너를 삭제할 때는 docker rm 명령어 사용
한번 삭제한 컨테이너는 복구할 수 없으므로 삭제할 때는 신중을 기해야 함.

$ sudo docker ps -a

$ sudo docker stop mycentos
$ sudo docker rm mycentos

실행 중인 컨테이너는 삭제할 수 없으므로
1. 컨테이너를 정지 후 삭제

$ sudo docker rm -f mycentos
  1. 실행되던지 말던지 강제 삭제 옵션

남은 파일 삭제

$ sudo docker container prune
$ sudo docker image prune

사용하지 않는 container, image을 모두 삭제함

$ sudo docker ps -a -q
$ sudo docker stop $(sudo docker ps -a -q)
$ sudo docker rm $(sudo docker ps -a -q)

docker ps 명령의 -a와 -q 옵션을 조합해 삭제
-q 옵션 : ID만 출력

$ sudo docker rm -f $(sudo docker ps -a -q)

!주의 모든 것을 지우는 명령어

컨테이너를 외부에 노출

컨테이너는 가상 머신과 마찬가지로 가상 IP주소를 할당받아야 함.
기본적으로 docker 는 컨테이너에 172.17.0.x의 IP를 순차적으로 할당함.
컨테이너를 새롭게 생성한 후 ifconfig 명령어로 컨테이너의 네트워크 인터페이스를 확인하자.

$ sudo docker run -it --name network_test ubuntu:20.04
$ root@6f0c1e0f544b:/# apt update
$ root@6f0c1e0f544b:/# apt install net-tools
$ root@6f0c1e0f544b:/# ifconfig

네트워크 인터페이스 확인

docker의 NAT IP인 172.17.0.2를 할당받은 eth0 인터페이스와 로컬 호스트인 lo인터페이스가 있다.
아무런 설정을 하지 않았다면 이 컨테이너는 외부에서 접근이 불가능 - 해당 docker 가 설치된 host만 가능
외부에 컨테이너의 에플리케이션을 노출하기 위해서는 eth0의 IP와 port를 호스트의 IP와 port에 바인딩해야 한다.
컨테이너에서 호스트로 빠져나온 뒤 다음 명령어를 입력해 컨테이너를 생성합니다. 이 컨테이너에 nginx 웹 서버를 설치해 외부에 노출할 것이다.

$ sudo docker run -it --name mywebserver -p 80:80  ubuntu:20.04 

-p 옵션을 통해 port forwarding 하는 법
[host port]:[container port]
예 : 7777:80 ⇒ 호스트의 7777포트와 80포트
호스트의 특정 ip를 사용해서 port forwarding 가능
예 : 192.168.0.100:7777:80
port forwarding을 여러개 하고 싶습니다. ⇒ -p 옵션을 여러개 쓰세요
예 : sudo docker run -it -p 3306:3306 -p 192.168.0.100:7777:80 ubuntu:20.04

$ root@1f22a7d7162d:/# apt update
$ root@1f22a7d7162d:/# apt install nginx
$ root@1f22a7d7162d:/# service nginx start
$ root@1f22a7d7162d:/# service nginx status

설치 시 cities를 고르는 창에서 6.asia 69. seoul 선택

GCP compute engine vm의 외부 ip로 접속하면 아래와 같은 화면이 보일거다.

그런데 이런식으로 Docker를 쓰면 Docker를 쓰는 의미가 딱히 없다.
이번엔 apache 웹서버 이미지를 바로 실행

$ sudo docker run --name my-apache-server -p 8080:80 httpd

그 다음 방화벽 포트를 열어야한다.
8080포트를 열자

잘 된다!

호스트의 IP의 port를 컨테이너의 IP와 port로 연결한다는 개념은 매우 중요하다.
아파치 웹서버는 172 대역을 가진 컨테이너의 NAT IP의 80번 포트로 서비스하므로 여기에 접근하려면 172.17.0.x:80의 주소로 접근해야 한다.
그러나 docker의 port-forward 옵션인 -p를 써서 호스트와 컨테이너를 연결했으므로 호스트의 IP와 포트를 통해 172.17.0.x.:80으로 접근할 수 있다.

컨테이너 application 구축

대부분의 서비스는 단일 프로그램으로 동작하지 않는다.
특히나 요즘처럼 MSA의 중요성을 이야기하는 시대에는 더욱 단일 프로그램으로 동작하는 서비스를
찾기 힘들다.
DB정도는 분리해야 함
이런 서비스를 containerize할 때 여러 개의 애플리케이션을 한 컨테이너에 설치할 수도 있다.
그러나 컨테이너에 애플리케이션을 하나만 동작시키면 컨테이너 간의 독립성을 보장함과 동시에 애플리케이션의 버전 관리, 소스코드 모듈화 등이 더욱 쉬워진다.

$ exit
$ sudo docker run -d --name wordpressdb \
 -e MYSQL_ROOT_PASSWORD=password \
 -e MYSQL_DATABASE=wordpress \
mysql:5.7

DB 생성

$ sudo docker run -d --name wordpress \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=password \
--link wordpressdb:mysql \
-p 80 wordpress

워드프레스 컨테이너 생성

$ sudo docker ps

호스트의 32768번 포트와 연결했다. 따라서 호스트이 IP와 32768번 포트로 워드프레스 웹 서버에 접근할 수 있다. 32768 포트를 열자. 웹 브라우저로 [호스트 IP]:32768에 접근했을 때 다음과 같은 화면이 나타나면 워드프레스 컨테이너가 성공적으로 생성된거다.

--link 옵션
실행 순서의 의존성 정의하고 워드프레스 웹 서버 컨테이너는 wordpressdb의 IP를 몰라도 mysql이라는 호스트명으로 접근할 수 있게 만드는 옵션
그러나 docker bridge network를 사용하면 —link 옵션과 동일한 기능을 더욱 손쉽게 사용할 수 있으므로 bridge network를 사용하는 것을 권장

profile
이용준의 블로그입니다.

0개의 댓글