docker login -> docker hub 로그인
docker login 타 이미지 저장소 주소
docker search or docker image pull 도커 허브에 로그인하지 않아도 사용 가능
: 단 하나의 아이피에서 한꺼번에 도커 허브에 접속할 경우 접속을 차단하는 경우가 있음, 이때 docker login을 진행하고 접속하게 되면 차단이 풀린다.
docker search ubuntu | head -8
NAME(오피셜: 저장소 이름, 일반 사용자: 계정명/저장소명) | 디스크립트(저장소 설명) | stars(별점) | officeal(오피셜 여부) | automated(자동 업데이트 여부)
# centos httpd ubuntu mysql:5.7 이미지 다운로드
docker pull centos
docker pull httpd
docker pull ubuntu
docker pull mysql:5.7
# 이미지 httpd ubuntu 백업해볼 것
docker save -o image.tar httpd ubuntu
# httpd ubuntu 이미지 삭제 후에 백업파일 해제
docker image rm - httpd
docker image rm ubuntu
docker images
docker load -i image.tar
docker images
# centos httpd ubuntu mysql:5.7 이미지로 컨테이너 실행(os 컨테이너는 백그라운드로 실행만 되도록 하시오.) 컨테이너명 os1 web1 web2 os2 mydb 순으로 컨테이너 실행
docker run -itd --name os1 centos
docker run -d --name web1 httpd
docker run -d --name web2 httpd
docker run -itd --name os2 ubuntu
docker run -d --name mydb mysql:5.7
# 컨테이너 리스트 확인(종료된 컨테이너까지 확인)
docker ps -a
# mydb만 종료된 상태=>mysql은 컨테이너 실행시에 관리자 계정에 대한 패스워드를 설정해야만 실행상태가 됨
os1 컨테이너 종료 및 실행
docker stop os1
docker ps
docker start os1
docker ps
# web1, web2 IP 주소 확인
docker inspect web1 | grep IPA
docker inspect web2 | grep IPA
# mydb WorkingDir 위치 확인
docker inspect mydb | grep WorkingDir
# mydb 컨테이너 삭제
docker rm mydb
# ubuntu 이미지로 os3 컨테이너 실행( cpu 사용률 : 40%로 제한, 메모리 : 512m 으로 제한)
docker run -itd --name os3 --cpus 0.4 --memory 512M ubuntu
docker stats --no-stream
# os3 컨테이너 리소스 수정 (메모리 : 1024m)
docker update --memory 1024M os3
# web1로 시작하는 위치를 분리모드로 출력해보시오.
docker exec web1 pwd
# os1에 재접속해보시오.
docker attach os1
ctrl+p+q
기본적으로 컨테이너에 생성되는 모든 파일은 컨테이너 레이어에 저장되고 이 데이터들은 컨테이너와 함께 삭제되는 런타임 데이터인데 이 데이터를 영구적으로 저장하려면 반드시 볼륨을 사용해야 한다.
도커에서 볼륨을 사용하는 방법은 Bind Mount와 볼륨(Volume) 두가지이다.
- -v 옵션을 통해서 볼륨을 설정할 경우
호스트 대상에 /로 시작하면 바인드 마운트로 마운트됨
호스트 대상이 /가 없으면 볼륨으로 마운트됨
초기 도커부터 사용했던 방식이며, 호스트의 특정 디렉터리와 컨테이너의 디렉터리를 연결하는 방식이다. bind mount는 쉽게 사용할 수 있지만 도커에 의해 관리되지 않기 때문에 따로 기록하지 않으면 관리하기가 쉽지 않다.
호스트와 컨테이너가 /etc/resolv.conf와 같은 설정 파일을 공유할 때
호스트와 컨테이너가 개발 환경 사이에서 소스 코드나 빌드 아티팩트를 공유할 때
호스트의 파일 또는 디렉토리 구조가 컨테이너의 Bind Mount와 일치하도록 보장된 경우
docker run -itd --name os -v 호스트경로:컨테이너경로 이미지명
mkdir bmdir1
docker run -itd --name os1 -v /root/bmdir1:/root/bmdir centos:7
docker exec os1 ls /root
docker exec os1 ls /root/bmdir
touch bmdir1/bmfile1
docker exec os1 ls /root/bmdir
docker exec os1 touch /root/bmdir/bmfile2
ls bmdir1
docker run -itd --name os2 -v /root/bmdir1:/root/bmdir_os2 centos:7
docker exec os2 ls /root
docker exec os2 ls /root/bmdir_os2
docker exec os2 touch /root/bmdir_os2/bmfile_os2
ls bmdir1/
docker exec os1 ls /root/bmdir
docker run -itd --name os3 -v /root/bmdir1/:/root/ centos:7
docker exec os3 ls -a /root/
# 디렉터리가 없는경우 새로 만들어진다. 상대경로가 아닌 절대경로를 써야함
docker run -itd --name os5 -v /root/testdir:/root/testdir centos:7
docker exec os5 ls /root/
도커에 의해 관리되는 스토리지이다. docker 명령을 사용하여 생성할 수 있고, 사용되지 않으면 한꺼번에 삭제할 수 도 있다.
이미지의 Volumes부분에 어떤 값이 지정되어 있으면, 컨테이너로 실행할 때 볼륨을 지정해야 한다. 그렇지 않으면 임의의 이름으로 볼륨을 생성하게 되고 이런 볼륨은 어떤 데이터를 저장하는지 그리고 어떤 데이터를 저장하고 있는지 모르기 때문에 관리가 어렵다.
볼륨은 Bind Mount와 다르게 다양한 드라이버를 지원
docker volume create 명령으로 생성가능
container 생성시에 볼륨을 생성가능
기본적으로는 서로 비어있는 상태에서 링크를 맺어야함
volume이 비어있고 대상 컨테이너 디렉터리에 내용이 존재하는 경우 해당 디렉터리의 내용이 볼륨으로 넘어감
volume에 내용이 있고 대상 컨테이너 디렉터리도 내용이 있을 경우 volume의 내용이 해당 컨테이너 디렉터리를 덮어씀
docker run -itd --name os1 -v 볼륨명:컨테이너경로 centos:7
# 볼륨 생성
docker volume create vol1
docker volume ls
# 생성된 볼륨 위치
ls /var/lib/docker/volumes/
ls /var/lib/docker/volumes/vol1/
touch /var/lib/docker/volumes/vol1/_data/hostfile1
# 생성한 볼륨과 연결
docker run -itd --name os1 -v vol1:/root/voldir/ centos:7
docker exec os1 ls /root/
docker exec os1 ls /root/voldir
docker exec os1 touch /root/voldir/volfile1
ls /var/lib/docker/volumes/vol1/_data/
docker run -itd --name os3 -v vol2:/root/ centos:7
ls /var/lib/docker/volumes/
ls -a /var/lib/docker/volumes/vol2/_data/
# mysql 이미지 가져오기
docker pull mysql
docker inspect mysql:latest | less
ls /var/lib/docker/volumes/
# 볼륨 이름 없이
docker run -d --name db1 mysql
ls /var/lib/docker/volumes/
docker volume ls
# 볼륨 이름 있이
docker run -d --name db2 -v dbvol1:/var/lib/mysql mysql
docker volume ls
# 내용 비교
docker inspect db1 | grep -A 5 Mounts
docker inspect db2 | grep -A 5 Mounts
# 모든 컨테이너 삭제, 모든 볼륨 삭제
docker rm -f $(docker ps -qa)
docker volume rm -f $(docker volume ls)
# web1 : curl ip주소 실행시 => "docker cp test" 메세지 출력
- cp 명령어 이용
docker image pull httpd
docker run -d --name web1 httpd
echo "docker cp test" > index.html
docker cp index.html web1:/usr/local/apache2/htdocs/
curl 172.17.0.2
# web2 : curl ip주소 실행시 => "docker bind mount test" 메세지 출력
- bind mount 이용
mkdir testdirA/
echo "docker bind mount test" > testdirA/index.html
docker run -d --name web2 -v /root/testdirA:/usr/local/apache2/htdocs/ httpd
curl 172.17.0.3
# web3 : curl ip주소 실행시 => "docker volume test" 메세지 출력 되도록
- docker volume 이용
docker run -d --name web3 -v testdirB:/usr/local/apache2/htdocs httpd
echo "docker volume test" > /var/lib/docker/volumes/testdirB/_data/index.html
curl 172.17.0.4
# web4 : curl ip주소 실행시 => "docker volume test" 메세지 출력 되도록
- docker volume 이용(docker volume create)
docker volume create testdirC
echo "docker volume test" > /var/lib/docker/volumes/testdirC/_data/index.html
docker run -d --name web4 -v testdirC:/usr/local/apache2/htdocs httpd
curl 172.17.0.5
해당 web IP 찾기
docker inspect web1 | grep IPA
위 실습 결과들
도커에는 다양한 네트워크 드라이버가 있으며 용도에 맞게 드라이버를 선택하여 사용한다.
bridge는 컨테이너가 사용하는 프라이빗 네트워크이며, 같은 bridge에 연결되어 있으면 컨테이너의 ip주소로 통신할 수 있다. 외부로 통신할 때에는 NAPT통신을 사용하며, 외부에서 bridge로 통신하려면 포트포워딩을 사용해야 한다.
도커를 설치하면 이름이 docker0인 리눅스 브릿지가 생성되는데, 이는 docker network ls 명령의 출력에서 이름이 bridge인 네트워크와 동일하다.
# 기본 생성
docker network create docker1
# 원하는 대역대 설정 후 생성
docker network create --subnet 192.168.0.0/24 --gateway 192.168.0.1 docker2
# 만든 네트워크 연결
docker run -itd --name os1 --network docker1 centos:7
docker run -itd --name os2 --network docker2 centos:7
docker inspect os1 |grep IPA
docker inspect os2 |grep IPA
호스트에서 컨테이너의 네트워크 격리를 해제하여 호스트의 네트워크 정보를 공유해서 사용하는 방법이다. 컨테이너는 호스트 입장에서 하나의 프로세스이기 때문에 가상머신과 다르게 네트워크 정보를 공유할 수 있다.
# 네트워크 host 설정
docker run -itd --name web2 --network host httpd
# 컨테이너의 IP 주소와 호스트의 IP 주소가 같기 떄문에 검색헀을때 null로 나온다.
docker inspect web2 | grep IPA
# 외부에서 검색하기 위해 방화벽 해제
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --reload
# 내용 변경 후 확인
echo network host test > index.html
docker cp index.html web2:/usr/local/apache2/htdocs
null 드라이버는 컨테이너의 네트워크 기능을 사용하지 않는다.
# null 네트워크 생성
docker run -itd --name os2 --network none centos:7
# null 네트워크 확인
docker inspect os2 | grep IPA
따로 호스트를 등록할 필요없이 자동으로 연결이 된다.
컨테이너 생성시 같은 네트워크에 있는 특정 컨테이너의 별칭을 부여하기 위한 옵션이다.
주의사항 : default bridge에서만 적용
docker run [옵션] --link 특정 컨테이너명 생성 컨테이너명
docker exec 컨테이너명 cat /etc/hosts
# ping을 보내면 연결이 안되있기에 안보내짐, hosts 파일에 따로 등록을 해야댐
docker run -d --name web1 httpd
docker run -itd --name os1 centos:7
docker exec os1 ping -c 3 web1
# 컨테이너 os2가 web1과 통신할 떄 링크를 사용
docker run -itd --name os2 --link web1 centos:7
docker exec os2 cat /etc/hosts
docker exec os2 ping -c 3 web1
호스트의 특정 포트에 컨테이너의 포트를 매칭 시키기 위한 옵션이다. 브릿지 네트워크를 사용하는 모든 컨테이너는 외부에서 접근할 떄 포트포워딩을 해야한다.
# 기본은 80포트
docker run -d --name web1 httpd
# 8080포트로 접속확인
docker run -d --name web3 -p 8080:80 httpd
[root@docker ~]# docker exec -it web3 bash
root@470405c97399:/usr/local/apache2# cat > htdocs/index.html
web 8080 port test
root@470405c97399:/usr/local/apache2# exit
exit
[root@docker ~]# docker inspect web3 |less
# 8081 포트로 접속확인
docker run -d --name web3 -p 8081:80 httpd
docker exec -it web4 bash
cd htdocs
cat > index.html
test port 8081
exit
docker inspect web3 |less
# 포트 포워딩 확인
curl 192.168.56.102
curl 192.168.56.102:80
curl 192.168.56.102:8080
curl 192.168.56.102:8081
# 모든 컨테이너 삭제
docker rm -f $(docker ps -qa)
# 도커 네트워크 리스트 확인
docker network ls
# 도커 bridge docker1 생성 (default)
docker network create -d bridge docker1
# docker1의 네트워크 확인
docker inspect docker1 | grep -i -A 3 subnet
# 도커 bridge docker2 생성 (network : 192.168.100.0/24, gateway : 192.168.100.254)
docker network create --subnet 192.168.100.0/24 --gateway 192.168.100.254 docker2
# docker2의 네트워크 확인
docker inspect docker2 | grep -i -A 3 subnet
#컨테이너 생성 -> web1:네트워크 docker0, web2:네트워크 docker2, web3:네트워크 host dirB 볼륨에 매칭
web1:
docker run -d --name web1 httpd
web2:
docker run -d --name web2 --network docker2 httpd
web3:
docker run -d --name web3 --network host -v dirB:/usr/local/apache2/htdocs/ httpd
# IP주소 확인
docker inspect web1 | grep IPA
docker inspect web2 | grep IPA
docker inspect web3 | grep IPA
# 외부 터미널에서 curl 192.168.56.101 쳐서 내용확인
curl 192.168.56.101
# os1, os2 컨테이너 생성 centos 이미지를 이용해서
os1:네트워크 docker0 web1을 hosts 파일에 등록(명령어를 사용해서)
docker run -itd --name os1 --link web1 centos
docker exec os1 cat /etc/hosts
# os2:네트워크 docker2 web2를 hosts 파일에 등록(exec를 이용해서)
docker run -itd --name os2 centos
docker exec os2 echo "192.168.100.2 web2 " > /etc/hosts
# os1에서 web1의 index.html 확인
docker exec os1 curl web1
# os2에서 web2의 index.html 확인
docker exec os2 curl web2
# web4 컨테이너 생성 -> web4 : host의 50000 port와 web4의 80 port 매칭
docker run -d --name web4 -p 50000:80 httpd
# 본 시스템에서 curl 192.168.56.101 결과 확인
curl 192.168.56.101
에러
curl 192.168.56.101:50000