docker image build
docker image push/pull
docker container run
docker run
와 같은 명령을 사용하면 클라이언트는 이러한 명령을 dockerd
로 전송하여 수행합니다. docker
명령은 Docker API를 사용합니다. yum install -y rdate
rdate -s time.bora.net
date
# EC2 에서 시간 동기화
timedatectl
timedatectl set-timezone Asia/Seoul
# curl -fsSL https://get.docker.com/ => 최신 버전의 bash shell script를 가져옴
# `sh` 가져온 스크립트를 실행
curl -fsSL https://get.docker.com/ | sh
# 도커 설치를 위한 도구(라이브러리) 설치
yum -y install bash-completion wget unzip mysql
curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
# Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
systemctl enable --now docker
$ sudo apt update
$ sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
$ sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# 우분투 18.04 저장소
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
# 우분투 16.04 저장소
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu xenial stable"
# 설정한 저장소 업데이트
$ sudo apt update
$ sudo apt-cache policy docker-ce
$ sudo apt install docker-ce -y
$ sudo usermod -a -G docker <USER_NAME>
$ docker version
amazon-linux-extras install docker -y
systemctl start docker && systemctl enable docker
curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh
usermod -a -G docker ec2-user
<저장소 이름>/<이미지 이름>[:태그]
로 구성되어 있다.docker search [OPTIONS] TERM
# "nginx" 라는 베이스 이미지
$ docker search nginx
$ docker search ubuntu 16.04
Name, shorthand | Default | Description |
---|---|---|
--filter,-f | 제공된 조건에 따라 출력 필터링 | |
--format | Go 템플릿 형식의 검색 | |
--limit | 최대 검색 결과 수 | |
--no-trunc | 결과를 모두 표시 |
--filter
사용--filter (or -f)
flag format is a key=value
pair. If there is more than one filter, then pass multiple flags (e.g. --filter "foo=bar" --filter "bif=baz"
)docker image pull [OPTIONS] NAME[:TAG|@DIGEST]
# latest 버전의 "nginx" 이미지 다운로드
$ docker image pull nginx
Name, shorthand | Default | Description |
---|---|---|
--all-tags , -a | 저장소에 태그가 지정된 이미지를 모두 다운로드 | |
--disable-content-trust | true | 이미지 확인 건너뛰기 |
--platform | Set platform if server is multi-platform capable | |
--quiet , -q | 출력 그만보기 |
docker image ls [OPTIONS] [REPOSITORY[:TAG]]
$ docker image ls
Name, shorthand | Default | Description |
---|---|---|
--no-trunc | 결과를 모두 표시 | |
--quiet, -q | 이미지 ID만 표시 |
docker image inspect [OPTIONS] IMAGE [IMAGE...]
# "OS" 라는 키의 값을 표시
$ docker image inspect --format="{{ .Os}}" nginx
$ docker image inspect --format="{{ .RepoTags}}" nginx
Name, shorthand | Default | Description |
---|---|---|
--format , -f | 사용자 지정 템플릿을 사용하여 출력 형식 지정 |
docker container create [OPTIONS] IMAGE [COMMAND] [ARG...]
-p; --publish
-p 8080:80
: 컨테이너의 TCP 포트 80을 Docker 호스트의 포트 8080에 매핑-p, --publish
=> -p <Host_Port>:<Container_Port>
iptables --list
: iptables 가 firewalld 보다 우선 순위가 높기 때문에 도커의 포트 설정이 적용된다. ; docker0
라는 가상 스위치를 통해 통신# "nginx" 이미지를 가지고 "webserver" 라는 컨테이너 이름으로 생성
# `-p, --publish`, <Host_Port>:<Container_Port>
$ docker container create -p 80:80 --name webserver nginx
docker container start [OPTIONS] CONTAINER [CONTAINER...]
# "webserver" 라는 이름의 컨테이너 실행
$ docker container start webserver
docker container stop [OPTIONS] CONTAINER [CONTAINER...]
# "webserver" 라는 이름의 컨테이너 정지
$ docker container stop webserver
docker rm -f $(docker ps -aq)
실행중인 컨테이너 제거docker container rm [OPTIONS] CONTAINER [CONTAINER...]
docker container prune [OPTIONS]
# `-f` 강제로 "webserver" 컨테이너를 지움
$ docker container rm -f webserver
# 중지된 모든 컨테이너 제거, prune 앞에 는 생략 불가능 (container / image, ... 구분 불가)
# `-f` 옵션 : 확인하지 않고 지움
$ docker container prune
# "exited" 상태인 컨테이너 강제 제거
docker rm -f $(docker ps --filter "status=exited" -q)
Name, shorthand | Default | Description |
---|---|---|
--force , -f | 실행 중인 컨테이너 강제 제거(SIGKILL 사용) |
docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
# foreground 실행
$ docker container run -p 80:80 --name webserver nginx
# background 실행
$ docker container run -d -p 80:80 --name webserver nginx
# 벡그라운드 & 랜덤 포트
$ docker container run -d -P nginx
# 임시 컨테이너를 이용하여 캘린더를 출력하고 컨테이너는 종료
$ docker container run --name test_cal centos /bin/cal
# 컨테이너에 접속
$ docker container run -it --name test_bash centos /bin/bash
# 접속 후 나오면 삭제
$ docker container run --rm -it --name test_bash7-1 centos:7 /bin/bash
Name, shorthand | Default | Description |
---|---|---|
--detach , -d | 백그라운드에서 컨테이너 실행 및 컨테이너 ID 출력 | |
--interactive , -i | 표준 입력을 연다. | |
-tty, -t | 터미널을 사용한다. (-t 옵션을 사용하여 의사 터미널 할당 TTY는 Teletype을 나타내며 기본 입출력을 제공하는 장치) | |
-publish-all , -P | Publish all exposed ports to random ports, 랜덤한 포트 | |
--volume , -v | Bind mount a volume |
# "mysql" 이미지 를 이용한 임시 컨테이너로 mysql 서버(host 가 192.168.0.102 인) 접속
# password : wppass
$ docker container run --rm -it --name test_mysql mysql /bin/mysql -h 192.168.0.102 -u wpuser -p
# 백그라운드로 ping 수행
$ docker container run -d --name test_ping centos /bin/ping localhost
# "test_ping" 컨테이너의 로그를 확인
docker container logs -t test_ping
# "test_port" 컨테이너의 상태 확인
$ docker container run -d -p 8080:80 --name test_port nginx
$ docker container stats test_port
# 컨테이너 리소스 지정, 옵션과 인수 사이에 `=`이 있어도 없어도 된다.
$ docker container run -d -p 8181:80 --cpus 1 --memory=256m --name test_resource nginx
-v
옵션 자체는 바인드 마운트를 의미$ docker container run -d -p 8282:80 --cpus 1 --memory=256m -v /tmp:/usr/share/nginx/html --name volume-container nginx
-v /home/wordpress_db:/var/lib/mysql
은 호스트의 /home/wordpress_db
디렉터리와 컨테이너의 /var/lib/mysql
디렉터리를 공유한다는 뜻$ docker run -it --name file_volume \
-v /home/hello:/hello \
-v /home/hello2:/hello2 \
ubuntu:20.04
$ docker [container] ls
$ docker ps
# 실행중인 모두 조회
docker container ls -a
# 컨테이너 name 이 test_webserver 인 컨테이너 조회
docker container ls -a -f name=test_webserver
# 컨테이너 상태가 exited=0 인것 조회
docker container ls -a -f exited=0
# 형태를 지정해서 출력
docker container ls -a --format "table {{.Names}}\t{{.Status}}"
Name, shorthand | Default | Description |
---|---|---|
--all , -a | Show all containers (default shows just running) | |
--filter , -f | Filter output based on conditions provided | |
--format | 해당하는 테이블 열을 지정한 순서에 따라 보여줌 |
[root@1689b6318c35 /]# ctrl + p, ctrl +q 를 입력
-i
및 -t
로 실행된 경우 컨테이너에서 분리하고 CTRL-p CTRL-q
키 시퀀스를 사용하여 실행 상태로 둘 수 있습니다.$ docker cotainer attach test_bash
docker exec
사용하여 시작된 명령은 컨테이너의 기본 프로세스( PID 1
)가 실행되는 동안에만 실행되며 컨테이너를 다시 시작해도 다시 시작되지 않습니다./bin/bash
같은 것으로 접속시 exit
를 수행후 컨테이너를 탈출하더라도 컨테이너가 죽지 않는다. + bash
라고 인수를 주어도 가능하다.# 이미 실행중인 "test_port" 컨테이너에서 echo 명령을 이용해 `Hello world` 를 출력
$ docker container exec -it test_port /bin/echo "Hello world"
# 이미 실행중인 "test_port" 컨테이너에서 bash shell을 이용
$ docker container exec -it test_port /bin/bash
$ docker container exec -it test_port bash
docker top CONTAINER [ps OPTIONS]
$ docker container top test_port
docker port CONTAINER [PRIVATE_PORT[/PROTO]]
$ docker container port test_port
docker rename CONTAINER NEW_NAME
# "test_port" 컨테이너 이름을 "webserver" 로 변경
$ docker container rename test_port webserver
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
docker cp [OPTIONS] SRC_PATH CONTAINER:DEST_PATH
# 컨테이너의 파일을 로컬로 복사
$ docker container cp webserver:/usr/share/nginx/html/index.html /root/index.html
# 로컬의 파일을 컨테이너로 복사
$ docker container cp ./index.html webserver:/usr/share/nginx/html/index.html
$ docker container diff webserver
Symbol | Description |
---|---|
A | 파일 또는 디렉토리가 추가됨 |
D | 파일 또는 디렉터리가 삭제됨 |
C | 파일 또는 디렉토리가 변경됨 |
컨테이너를 이미지로 만들기 - docker container commit
[HOST[:PORT_NUMBER]/]PATH
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
latest
사용# 로컬에 있는 `/tmp`의 아래 리소스를 통째로 복사해서 컨테이너로 옮김
$ docker run -d -p 80:80 --name=test_commit_web nginx
$ docker container cp /tmp/index.html test_commit_web:/usr/share/nginx/html
$ docker container cp /tmp/images test_commit_web:/usr/share/nginx/html
# "volume-container" 컨테이너를 `test_commit` 라는 리포지토리에
$ docker container commit -a "jsb<test@example.com>" -m "Congratulation v1.0" volume-container test_commit:v1.0
$ docker image ls
$ docker image inspect test_commit:v1.0
$ docker inspect test_commit:v1.0 --format "{{ .Author}}"
$ docker image inspect test_commit:v1.0 --format "{{ .Comment}}"
# 커밋으로 생성한 이미지를 이용하여 "webserver" 생성
$ docker container run -d -p 80:80 --name webserver test_commit:v1.0
# 만약 "webserver" 컨테이너가 있다면 `-f` 는 실행 중인것도 제거
$ docker rm -f webserver
Name, shorthand | Default | Description |
---|---|---|
--author,-a | 저자(예: jsb test@example.com) | |
--change,-c | 생성된 이미지에 Dockerfile 명령어 적용 | |
--message,-m | 커밋 메시지 | |
--pause,-p | true | 커밋 중 컨테이너 일시 중지 |
docker save [OPTIONS] IMAGE [IMAGE...]
$ docker save -o test_commit.tar test_commit:v1.0
Name, shorthand | Default | Description |
---|---|---|
--output , -o | STDOUT 대신 파일에 쓰기 |
docker load [OPTIONS]
# 테스트를 위해 리소스가 있다면 제거
$ docker image ls
$ docker rm -f webserver
$ docker rmi -f test_commit:v1.0
$ docker images
# 이미지 로드
$ docker image load -i test_commit.tar
# 이미지 로드 결과 확인
$ docker image ls
Name, shorthand | Default | Description |
---|---|---|
--input,-i | STDIN 대신 tar 아카이브 파일에서 읽기 | |
--quiet,-q | 부하 출력 억제 |
이미지 삭제 - docker rmi
docker rmi [OPTIONS] IMAGE [IMAGE...]
Name, shorthand | Default | Description |
---|---|---|
--force , -f | 이미지 강제 제거 |
$ docker images
$ docker rmi -f centos:latest
$ docker image ls
docker0
는 dhcp 겸 router 의 기능을 수행도커 네트워크 리스트 표시 - docker network ls
docker network ls [OPTIONS]
Name, shorthand | Default | Description |
---|---|---|
-f, --filter=[] | 필터링하여 출력 | |
--no-trunc | 모든 정보를 출력 | |
-q, --quiet | 네트워크 ID 만 출력 |
bridge
라는 ID 가 docker0
이다.
$ docker network ls
# 도커의 네트워크 정보 확인 가능, "bridge"의 이름인 "docker0" , 컨테이너 네트워크 정보 등
$ docker network inspect bridge
$ docker network ls -q --filter driver=bridgedocker network ls -q --filter driver=bridge
도커 네트워크 생성 및 삭제 - docker network create , docker network rm
docker network create [OPTIONS] NETWORK
, docker network rm NETWORK [NETWORK...]
Name, shorthand | Default | Description |
---|---|---|
--driver, -d | 네트워크 bridge or overlay | |
--ip-range | 컨테이너에 할당하는 IP 주소 범위 지정 | |
--subnet | 서브넷을 CIDR 형식으로 지정 |
$ docker network create -d bridge --subnet 10.59.0.0/16 --ip-range 10.59.0.0/24 test_bridge
$ docker network ls
$ docker [network] inspect test_bridge
# 도커 네트워크 삭제
$ docker network rm test_bridge
docker network connect [OPTIONS] NETWORK CONTAINER
, docker network disconnect [OPTIONS] NETWORK CONTAINER
# "webserver" 컨테이너를 "test_bridge" 네트워크에 연결
$ docker network connect test_bridge webserver
# 네트워크에서 컨테이너 연결 해제
$ docker network disconnect test_bridge webserver
$ docker inspect webserver
# 컨테이너 생성시 처음부터 컨테이너를 네트워크에 연결
$ docker container run -d -p 8080:80 --name webserver1 --network test_bridge test_commit:v1.0
$ docker inspect test_bridge
--- 워드프레스
- dbserver
$ docker run -d -p 3306:3306 --name dbserver \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppass \
-e MYSQL_ROOT_PASSWORD=password --network test_bridge mariadb
- webserver
$ docker run -itd -p 8888:80 --name apache --network test_bridge centos:7
$ docker exec -it apache bash
yum install -y httpd php php-mysql php-gd php-mbstring wget unzip
wget https://ko.wordpress.org/wordpress-4.8.2-ko_KR.zip
cd /var/www/html
unzip /wordpress-4.8.2-ko_KR.zip
mv wordpress/* ./
chown -R apache:apache /var/www
httpd &
Enter 입력
앞서 다룬 Docker 이미지 생성 방식은 베이스 이미지를 바탕으로 일일이 컨테이너 생성 / 파라미터 설정 / 미들웨어 설치를 통해 만들어진 컨테이너를 Docker 이미지로 생성하였으나 Docker 파일은 컨테이너를 생성하는 여러 구성 정보를 하나의 파일로 정리하고 일괄 실행하여 docker build 명령을 통해 Docker 이미지를 작성하는 스크립트
Dockerfile
\# vi Dockerfile
----------------------------------------
FROM ubuntu:18.04 # 베이스 이미지
# MAINTAINER goorm # 작성자; deprecated
LABEL "name"="webserver" # 정보 전달의 목적
ENV aloha=date
ENV path=/var/www/html
# RUN : 명령어 실행
# 미 동부지역 저장소 대신 대한민국의 kakao의 저장소로 변경
RUN sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list
RUN apt-get update
RUN apt-get install apache2 -y
COPY nihao /var/www/html/nihao
# 위에 "ENV path" 로 지정한 환경 변수 값을 대입 `/var/www/html`
COPY hello.html $path
ADD aws.tar /var/www/html
WORKDIR /var/www/html # cd /var/www/html
RUN echo ohayo >> ohayo.html
VOLUME /var/www/html
EXPOSE 80
# ENTRYPOINT ["apachectl", "-D", "FOREGROUND"]
# CMD ["apachectl", "-D", "FOREGROUND"]
ENTRYPOINT ["apachectl"] # ["apachectl", "-D", "FOREGROUND"]
CMD ["-D", "FOREGROUND"] # ["apachectl", "-D", "FOREGROUND"]
ADD
명령은 <src>
에서 새 파일, 디렉터리 또는 원격 파일 URL을 복사하여 <dest>
경로에 있는 이미지의 파일 시스템에 추가<src>
가 인식된 압축 형식(identity, gzip, bzip2 또는 xz)의 로컬 tar 아카이브인 경우 디렉토리로 압축이 풀림.tar -x
와 동일한 동작VOLUME
- 볼륨 지정에 대한 참고 사항COPY
명령은 <src>
에서 새 파일 또는 디렉토리를 복사하여 경로<dest>
에 있는 컨테이너의 파일 시스템에 추가docker run
의 -P
옵션은 컨테이너 내부의 포트에 접근하지 않으며, 도커 컨테이너에 활성화된 포트가 없다면 -P
옵션은 의미가 없다. docker build
docker build [OPTIONS] PATH | URL | -
Specify a Dockerfile (-f, --file)
Name, shorthand | Default | Description |
---|---|---|
--file , -f | Name of the Dockerfile (Default is PATH/Dockerfile) |
$ mkdir test-dockerfile && cd $_
$ mkdir nihao
$ echo "<h1>nihao</h1>" > nihao/index.html
$ echo "<h1>hello</h1>" > hello.html
# aws.tar 파일 업로드
$ vi Dockerfile # 도커 파일 이해의 스크립트 주석 부분은 제거해서 입력
$ docker build -t hello:v1.0 .
# `.` 현재 위치에 있는 Dockerfile을 찾아 빌드를 수행
# `-t` 태그 옵션으로 이름 지정
$ docker build -t hello:v1.0 .
$ docker run -d -P hello:v1.0
# Dockerfile 말고 다른 이름의 파일로 만들 경우
# `-f` 옵션으로 파일 위치를 알려준다.
$ docker build -t hello:v1.1 -f test-docker .
# 도커 컨테이너 생성
# `8080` 포트가 활성화 되는 apache2는 `80` 포트 를 수신하므로 아파치릐 포트를 변경한다.
$ docker run -d -P hello:v1.1
# 수정하기 위해 컨테이너 접속
$ docker exec -it 생성된_컨테이너_이름/ID bash
root@f4f951e26387:/\# apt install -y vim
root@f4f951e26387:/\# vim /etc/apache2/ports.conf
Listen = `80` => `8080`
root@f4f951e26387:/\# exit
$ docker restart 생성된_컨테이너_이름/ID
$ docker ps # 포트 확인
"nginx" 베이스 이미지를 이용
# `images` 폴더랑 `index.html` 이 있는 곳에서
$ tar cvf test.tar images index.html
$ mkdir test && cd $_
$ vi Dockerfile
----------------------------------------
FROM nginx:latest
# `/usr/share/nginx/html` 위치에 `test.tar` 파일을 업로드 하겠다.
ADD test.tar /usr/share/nginx/html
# daemon off: 백그라운드 실행을 하지 않겠다.
# 이미지 만들때는 포그라운드 실행을 해야한다.
# 이미지 생성시 백그라운드를 실행하겠다 하면 나중에 도커 컨테이너를 백그라운 실행할때 충돌한다.
## nginx 베이스 이미지에 이미 존재
#CMD ["nginx", "-g", "daemon off;"]
----------------------------------------
$ docker build -t test_build:v2.0 .
$ docker run -d -P test_build:v2.0
# 내가 `EXPOSE` 를 넣지 않았는데 포트가 있다?
# `Base Image` 인 "nginx" 이미지에 있다.
$ docker ps
test_build:v2.0
이미지로 컨테이너 확인 (-P
; 랜덤 포트)EXPOSE
가 있어 "test_build" 이미지도 영향을 받음.CMD ["nginx", "-g", "daemon off;"]
체크 # color: green -> blue, Congratulations v2.0 - > Congratulationsv3.0
$ vi index.html
$ vi Dockerfile
----------------------------------------
FROM nginx:latest
ADD test1.tar /usr/share/nginx/html
----------------------------------------
$ tar cvf test1.tar index.html images
$ tar tvf test1.tar
$ docker build -t test_build:v1.0 .
$ docker run -d -P test_build:v1.0
허브로 업로드할 이미지 조회
SOURCE_IMAGE를 참조하는 TARGET_IMAGE 태그 작성 - docker image tag
SOURCE_IMAGE
를 참조하는 TARGET_IMAGE
태그를 만듭니다.docker push hkjs96/test_build:v1.0
를 수행하게 되면 TARGET_IMAGE
=> hkjs96/test_build
hkjs96 라는 계정 공간에 업로드docker [image] tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
# docker tag <로컬이미지이름> <도커허브계정>/<이미지이름>
$ docker tag test_build:v1.0 hkjs96/test_build:v1.0
$ docker images
# docker login -u username -p password hub.docker.com
$ docker login
# 로그 아웃
$ docker logout
# 로그 아웃 후 / 인증 정보 제거
$ cd ~/.docker
$ rm -rf config.json
docker image push <Docker Hub 사용자명>/이미지[:태그]
$ docker push hkjs96/test_build:v1.0
# 버전 2도 업로드 작업
$ docker tag test_build:v2.0 hkjs96/test_build:v2.0
$ docker push hkjs96/test_build:v2.0
--restart always
: 도커 가 껏다 켜져도 알아서 컨테이너 재시작$ docker run -d -P --restart always hkjs96/test_build:v1.0
# port 49153
$ docker ps
$ sudo reboot
$ docker ps
# port 49154
$ docker run -d -P --restart always hkjs96/test_build:v2.0
$ docker ps
$ vi index.html -> 색상 pink, 버전 v4.0 번경
$ docker build -t hkjs96/test_build:v3.0 .
$ docker push hkjs96/test_build:v3.0
ubuntu@ubuntu:~$ docker run -d -P hkjs96/test_build:v3.0
ubuntu@ubuntu:~$ docker ps
--------------------------------------------------------------------------------
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
858b125f3e77 hkjs96/test_build:v3.0 "/docker-entrypoint.…" 14 seconds ago Up 13 seconds 0.0.0.0:49155->80/tcp, :::49155->80/tcp reverent_fermat
49a7fed67a7a hkjs96/test_build:v2.0 "/docker-entrypoint.…" 10 minutes ago Up 10 minutes 0.0.0.0:49154->80/tcp, :::49154->80/tcp nice_golick
3801f802ce2f hkjs96/test_build:v1.0 "/docker-entrypoint.…" 14 minutes ago Up 12 minutes 0.0.0.0:49153->80/tcp, :::49153->80/tcp blissful_lichterman
$ cd ~
$ mkdir wordpress && cd $_
$ vi Dockerfile
----------------------------------------
FROM centos:7
MAINTAINER goorm
RUN yum install -y httpd php php-mysql php-gd php-mbstring wget unzip
RUN wget https://ko.wordpress.org/wordpress-4.8.2-ko_KR.zip
WORKDIR /var/www/html
RUN unzip /wordpress-4.8.2-ko_KR.zip
RUN mv wordpress/* .
RUN chown -R apache:apache /var/www
CMD httpd -DFOREGROUND
EXPOSE 80
----------------------------------------
$ docker build -t hkjs96/my-wp:v1.0 .
$ docker push hkjs96/my-wp:v1.0
#$ docker run -d -P --name my-wp --network test_bridge hkjs96/my-wp:v1.0
ubuntu@ubuntu:~$ docker create network test_network
ubuntu@ubuntu:~$ docker run -d -p 3306:3306 --name dbserver \
-e MYSQL_DATABASE=wordpress \
-e MYSQL_USER=wpuser \
-e MYSQL_PASSWORD=wppass \
-e MYSQL_ROOT_PASSWORD=password --network test_network mariadb
ubuntu@ubuntu:~$ docker run -d -p 80:80 --name wordpress --network test_network hkjs96/my-wp:v1.0
$ mkdir volume && cd $_
$ mkdir bm01 ; touch bm01/test.txt
$ docker run -itd --name bm-test -v /root/volume/bm01:/mnt centos:7
$ docker exec bm-test ls /mnt
$ docker volume create my-vol01
$ docker volume ls
$ docker volume inspect my-vol01
"Mountpoint": "/var/lib/docker/volumes/my-vol01/_data"
$ docker run -itd --name vol-test -v my-vol01:/mnt centos:7
# ro -> 읽기 권한만 주겠다.
$ docker run -itd -p 801:80 --name vol-web -v my-vol01:/usr/local/apache2/htdocs:ro httpd:latest
$ curl 192.168.1.143:801
<html><body><h1>It works!</h1></body></html>
# `sh -C` 쉘 커맨드
$ docker container exec vol-test sh -c "echo "Nihao" > /mnt/index.html"
$ curl 192.168.0.151:801
Nihao
ONBUILD
명령은 이미지가 다른 빌드의 기반으로 사용될 때 나중에 실행할 트리거 명령을 이미지에 추가합니다. 트리거는 다운스트림 Dockerfile의 FROM
명령 바로 뒤에 삽입된 것처럼 다운스트림 빌드의 컨텍스트에서 실행됩니다.
운영자 역할
$ mkdir onbuild && cd $_
$ vi Dockerfile.base
----------------------------------------
FROM ubuntu:18.04
RUN sed -i 's/archive.ubuntu.com/ftp.daumkakao.com/g' /etc/apt/sources.list
RUN apt-get -y update
RUN apt-get -y install nginx
EXPOSE 80
ONBUILD ADD website*.tar /var/www/html/
CMD ["nginx", "-g", "daemon off;"]
----------------------------------------
$ docker build -t hkjs96/web-base:v1.0 -f Dockerfile.base .
$ docker inspect hkjs96/web-base:v1.0
"OnBuild": [
"ADD website*.tar /var/www/html/"
],
$ docker login
$ docker push hkjs96/web-base:v1.0
$ vi Dockerfile
----------------------------------------
FROM hkjs96/web-base:v1.0
----------------------------------------
$ docker build -t hkjs96/web-site:v1.0 .
$ docker run -d -p 80:80 --name=web-site hkjs96/web-site:v1.0
$ docker login
$ docker push hkjs96/web-site:v1.0
--- 운영자 역할(AWS)
$ docker run -d -p 80:80 --name=test-site hkjs96/web-site:v1.0
$ docker run -d -p 5000:5000 --restart=always --name private-docker-registry registry # 저장소 서버
# 각 쿠버네티스 노드에서 수행
# 클라이언트 세팅
$ vi /etc/docker/daemon.json # 클라이언트
{ "insecure-registries":["도커의 IP":5000"] }
$ systemctl restart docker
$ docker tag nginx:latest 192.168.1.143:5000/nginx
$ docker push 192.168.1.143:5000/nginx
$ curl -X GET http://192.168.1.143:5000/v2/_catalog
$ curl -X GET http://192.168.1.143:5000/v2/nginx/tags/list
$ curl -X GET http://192.168.1.143:5000/v2/web-site/tags/list
docker-compose.yml
형식의 스크립트로 격리된 환경에서 함께 실행docker compose up
하면 이 전체 앱을 시작하고 실행$ curl -L "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ chmod +x /usr/local/bin/docker-compose
$ mkdir my_wordpress && cd $_
$ vi docker-compose.yml
----------------------------------------
version: "3.3"
services:
dbserver:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment: # -e
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: wpuser
MYSQL_PASSWORD: wppass
wordpress:
depends_on:
- dbserver
image: wordpress:latest
volumes:
- wordpress_data:/var/www/html
ports: # -p 80:80
- "8888:80"
restart: always
environment:
WORDPRESS_DB_HOST: dbserver:3306
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: wppass
WORDPRESS_DB_NAME: wordpress
volumes:
db_data: {}
wordpress_data: {}
----------------------------------------
$ docker-compose up -d # 분리 모드로 실행
$ docker-compose ps
$ docker-compose pause # 일시 정지
$ docker-compose unpause
$ docker-compose port wordpress 80 # "wordpress" 컨테이너의 80번 포트에 바인딩된 포트 출력
$ docker-compose config # "config" yaml 파일 출력
$ docker-compose stop wordpress
$ docker-compose rm wordpress
$ docker-compose down # Stop and remove containers, networks
$ docker-compose down -v # 볼륨 제거
$ docker-compose down --rmi all # 이미지 제거
# use the latest release version from https://github.com/google/cadvisor/releases
$ VERSION=v0.44.0 # 변수 선언
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
Swarm
모드Manager
노드 : 클러스터 관리 작업을 처리Worker
노드 : 컨테이너를 실행하는 것이 유일한 목적인 Docker 엔진의 인스턴스AVAILABILITY
는 스케줄러가 작업을 노드에 할당할 수 있는지 여부가 표시Active
: 스케줄러가 작업을 노드에 할당할 수 있음Pause
: 스케줄러가 노드에 새 작업을 할당하지 않지만 기존 작업은 계속 실행 중Drain
: 스케줄러가 노드에 새 작업을 할당하지 않고 기존 작업을 종료하며 사용 가능한 노드에 작업 할당MANAGER STATUS
은 Raft 합의에 대한 노드 참여를 의미Leader
노드 : 스웜에 대한 모든 스웜 관리 및 오케스트레이션 결정을 내리는 기본 관리자 노드Reachable
노드 : Raft 합의 쿼럼에 참여하는 관리자 노드임을 의미, 리더 노드를 사용할 수 없게 되면 노드가 새 리더로 선출될 수 있다.Unavailable
노드 : 다른 관리자와 통신할 수 없는 관리자임을 의미, 관리자 노드를 사용할 수 없게 되면 새 관리자 노드를 Swarm에 가입시키거나 작업자 노드를 관리자로 승격시켜야 한다.Task
라고 부른다.Task
는 Swarm의 노드에서 서로 독립적으로 실행Container
는 격리된 프로세스이며, Swarm 모드 모델에서 각 작업은 정확히 하나의 컨테이너를 호출Task
는 Scheduler
가 컨테이너를 배치하는 "Slot" 과 유사하다.Task
는 Swarm 내 스케줄링의 원자 단위
$ firewall-cmd --permanent --zone=public --add-port=2377/tcp
$ firewall-cmd --reload
$ hostnamectl set-hostname manager1
# hosts 정보를 입력
$ cat << EOF >> /etc/hosts
192.168.2.16 manager1
192.168.2.25 worker1
192.168.2.26 worker2
EOF
# manager 에서 수행
$ docker swarm init --advertise-addr 192.168.2.16
# 워커에서 수행
$ docker swarm join --token SWMTKN-1-2pyrpj41954gi0nhhuyld9r161s93o611ep6usffazzelj9vnl-b1ifji8wmvq3efu117fq6v5w6 192.168.2.16:2377
# manager에서 수행
$ docker node ls
--publish
플래그를 사용하여 서비스를 생성할 때 포트를 게시target
컨테이너 내부의 포트를 지정하는 데 사용published
라우팅 메시에 바인딩할 포트를 지정하는 데 사용, published
포트를 그대로 두면 각 서비스 작업에 대해 높은 번호의 임의 포트가 바인딩-p 8080:80
새 구문은 읽기 쉽고 더 많은 유연성을 허용하므로 선호 # task(pod)
# "replicas" : task의 수, "publish": Publish a port as a node port
$ docker service create --name my_web --replicas 3 --publish published=8080,target=80 nginx
$ docker service ls
$ docker service ps my_web
$ docker service logs my_web
$ docker service inspect --pretty my_web
# VM 같은 인스턴스를 그대로인데 task(pod); 작업의 개수를 조정 (노드에게 작업을 추가 할당/제거)
$ docker service scale my_web=5
$ docker service ps my_web
$ docker service rm my_web
docker service update [OPTIONS] SERVICE명
$ docker service ps my_web
$ docker service inspect --pretty my_web
# `my_web` 서비스의 이미지를 변경
$ docker service update --image halilinux/web-site:v1.0 my_web
$ docker service ps my_web
docker node update --availability drain worker1
$ docker node ls
$ docker service ps my_web
# "manager1" 노드 열외
$ docker node update --availability drain manager1
# 리더의 역할을 수행하나 task 할당 받지 않는다.
$ docker node inspect --pretty manager1
$ docker service ps my_web
# 배제한 노드를 다시 활성화 (클러스터로 편입)
$ docker node update --availability active manager1
# 다시 수동으로 작업 공평하게 배분
$ docker service scale my_web=2
$ docker service scale my_web=3
$ docker node inspect --pretty manager1
$ docker node update --availability pause worker2
# "Pause"의 경우는 "Task" 가 유지된다.
$ docker service ps my_web
# "worker2" 에는 추가적인 작업이 할당되지 않음.
$ docker service scale my_web=5
$ docker service ps my_web
$ docker node inspect --pretty worker2
$ docker node ls