Docker(2)
https://hub.docker.com/ 에서 slim이나 alpine 키워드가 있는 버전 사용
python web service
~$ nano py_http.py
---
from http.server import BaseHTTPRequestHandler, HTTPServer
port = 8900
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.end_headers()
self.wfile.write('<h1>Welcome to the Docker World~</h1>'.encode('utf-8'))
httpd = HTTPServer(('0.0.0.0', port), SimpleHTTPRequestHandler)
print(f'Server running on port:{port}')
httpd.serve_forever()
---
~$ docker run -it -d --name=python_test -p 8900:8900 python:latest
~$ sudo netstat -nlp | grep 8900
~$ docker cp py_http.py python_test:/
~$ docker exec -it python_test bash
/# python py_http.py
nodejs web service
~$ nano nodejs_test.js
~$ docker pull node:15-slim
~$ docker run -d -it -p 9000:8000 --name=nodejs_test node:15-slim
~$ docker cp nodejs_test.js nodejs_test:/nodejs_test.js
~$ docker exec -it nodejs_test /bin/bash
/# node nodejs_test.js
~$ docker inspect nodejs_test | grep IPAddress
oracle Container 생성
~$ docker run -it --shm-size=2g -p 1521:1521 -p 8082:8080 \
> orangehrm/oracle-xe-11g:latest bash
/# su - oracle
~$ env | grep ORACLE
~$ sqlplus sys/oracle as sysdba
SQL> startup
SQL> exit
/$ oracle@c22072b1fcdc:/$
/$ cd $ORACLE_HOME/network/admin
$ vi listener.ora
//HOST name 수정
~$ lsnrctl start
~$ lsnrctl services
http://192.168.56.111:8082/apex (internal/admin/oracle)
mongoDB Container 생성
~$ docker run -d -it --name=mongodb1 -p 17017:27017 mongo:4.4.4-bionic
~$ docker exec -ot mongodb1 bash
/# mongo
> show dbs
> use ssg-mongodb
> db
> db.test.insert({name:"hylee", job:"INST"})
> db.test.find()
> show dbs
> exit
> docker ps
> docker exec -it mongodb1 bash
> show dbs
> show collections
Docker Command
docker Hub에는 이미지를 저장, github에는 코드 저장
docker login
docker info | grep Username
docker logout
pull
docker pull [옵션] <image명>[:태그명]
docker pull (docker.io/library/)centos:7
// Default Registry가 docker.io/library 이므로 생략가능
docker pull gcr.io/google-samples/hello-app:1.0
docker pull httpd:2.4
// layer 5개 다운로드됨
docker image history httpd:2.4
// 용량이 잡히면 layer가 됨
- container는 os에서의 경로와의 공간과 일치함
- os 경로에서 파일을 생성하면 container에서도 생성됨 반대로 container에서 생성하면 os경로에 생성됨
inspect
docker image inspect [이미지]
docker image inspect mariadb:10.2
docker container inspect [컨테이너]
docker container inspect maria-test
- base 이미지는 Read만 됨.
- 이미지를 컨테이너로 만들고 R/W, 컨테이너는 다시 이미지를 만듦
- MergedDir : Layer들이 합쳐서 만들어짐
- 이미지 inspect와 컨테이너 inspect는 분리됨
- 컨테이너 정보에는 네트워크가 정보가 추가되어 있음
docker image inspect --format="" centos:7
//상세정보확인
docker image inspect --format="" httpd:2.4
//이미지상세조회
docker inspect [컨테이너이름] | grep IPAddress
rm
docker image rm [이미지명, 이미지ID] == docker rmi [이미지명, 이미지ID]
docker rm [이미지명]
docker image rm -f orangehrm/oracle-xe-11g:latest
docker rm 2aafb500a560 8dea0e2882b7 fb017eae1df0 (여러개 한꺼번에 삭제)
docker ps -q
docker stop $(docker ps -q)
docker rm $(docker ps -a -q)
docker rm $(docker ps --filter 'status=exited' -a -q)
// Exit 상태의 모든 Container 삭제
nano .bashrc
alias cexrm='docker rm $(docker ps --filter 'status=exited' -a -q)'
// alias 추가
// cexrm 명령으로 삭제명령
hub.docker.com의 저장소에 이미지 업로드
- docker tag
- docker login
- docker push
docker tag
- 해당 이미지에 alias 설정
- docker image tag my-nginx-image:1.0 본인ID/저장소:태그
- docker hub 사이트에서 만들면 public, private 설정이 가능
docker image tag phpserver:1.0 cys779988/dev-phpserver:1.0
docker push
- docker push 본인ID/저장소:태그명
docker push cys779988/dev-phpserver:1.0
Docker image관리
- 이미지 버전을 관리
docker pull mysql:5.7
docker tag mysql:5.7 cys779988/mysql_repo:my5.7-1.0
docker images
docker login
docker push cys779988/mysql_repo:my5.7-1.0
docker pull mysql:8.0
docker tag mysql:8.0 cys779988/mysql_repo:my8.0-1.0
docker push cys779988/mysql_repo:my8.0-1.0
Docker container lifecycle
docker container create : 이미지 snapshot(복사본) 생성
docker container start : 프로세스를 부여함
docker container run : create와 start를 한꺼번에 실행([pull] + create + start + [command])
docker create -it --name myubuntu16 ubuntu:16.04
docker start myubuntu16
docker attach myubuntu16
docker run -it --name=myubuntu16-2 ubuntu:16.04 bash
//한번에 처리
Docker Container run
-d, --detach=false : Container를 생성하여 백그라운드에서 실행(exit로 나와도 stop 안됨)
-i, --interactive=false : Container 표준 입력 열기
-t, --tty=false : tty(단말 디바이스)를 사용
-u, --user="사용자명" : 사용자명을 입력
--restart=[no | on-failure | on-failure:횟수n | always] : 커맨드 실행 결과에 따라 재기동
--rm : 커맨드 실행 완료 후 Container 자동 삭제
docker run -d --rm centos /bin/ping localhost
docker ps
docker logs -t [pid]
docker logs -f [pid]
docker stop [pid]
Docker Container 네트워크 설정
- ifconfig
- docker0는 논리적으로 구현된 스위치 역할을 함
- veth의 갯수는 컨테이너의 갯수
- eth0와 docker0의 터널링을 veth가 담당, 따라서 veth는 ip가 없음
- Docker는 기본적으로 NAT, NAPT 사용
- container가 생성되면 해당 container에는 pair interface라고 하는 한쌍의 interface들이 생성
- 마치 직접 direct로 cable을 연결한 두 대의 PC와 같이 패킷을 전달
docker ps
로 조회되는 컨테이너는 default로 docker0에 붙어있음
sudo rm -rf /var/lib/dpkg/lock
sudo apt install bridge-utils
brctl show
docker run -it -d --name=ubuntu_test1 ubuntu:14.04
docker exec -it ubuntu_test1 route
docker exec -it ubuntu_test1 ip a
brctl show
docker ps
docker inspect -f "" ubuntu_test1
docker inspect ubuntu_test1 | grep IPAddress
docker inspect ubuntu_test1 | grep Mac
Docker Container 네트워크 설정 : docker run[net 옵션]
docker run -itd --add-host=example:10.10.10.10 --dns=8.8.8.8 ubuntu:14.04
docker exec zen_lamarr /bin/cat /etc/hosts
//Host 정보조회
docker exec zen_lamarr /bin/cat /etc/resolv.conf
//DNS정보 조회
- container자체도 host의 일종
docker run -itd --expose=9000 --name=webserver8 -p 9001:80 nginx:1.20
// 9000번 포트도 열기
docker port webserver8
// 열린 포트 조회
80/tcp -> 0.0.0.0:9001
80/tcp -> :::9001
docker run -itd -P --name=webserver10 nginx:1.20
// nginx의 유효한 포트와 host의 임의포트를 연결(컨테이너에 노출된 포트가 있어야함)
- docker-proxy는 이름처럼 docker host로 들어온 요청을 container로 넘기는 것 뿐
- docker-proxy는 kernel이 아닌 사용자 환경에서 수행되기 때문에 kernel과 상관없이 host가 받은 패킷을 그대로 container의 포트로 전달
sudo netstat -nlp | grep [포트번호]
ps -ef | grep [포트번호]
sudo apt-get install iptraf-ng
sudo iptraf-ng
// 패킷 전달되는 상황을 조회함
Docker Container 사용자 정의 네트워크 설정
- bridge network : 네트워크 드라이버(네트워킹 방식을 정의)
- bridge는 로컬용, host와 host 연결에는 overlay
docker run -d --name=nginx_host \
--net=host \
nginx:1.20
sudo netstat -nlp | grep 80
curl localhost:80
ps -ef | grep [host 포트번호]
docker inspect nignx_host | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "",
// IPAddress가 비어있음
// ip주소로만 웹에 접속가능
docker network create -d bridge webap-net
route
ifconfig
docker network ls
brctl show
docker run --net=webap-net -it --name=net-check ubuntu:14.04 bash
docker network inspect webap-net
[
{
"Name": "webap-net",
"Id": "8b02cc78d4faf5d2685b64a0e3733a59ed25cced6f20a793f21bd196765a0272",
"Created": "2021-06-23T15:49:02.84570527+09:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"9de34fd2edd3fc230cf02704fd4c45bef11365201556fe0484577a18b15cb7f0": {
"Name": "net-check",
"EndpointID": "534fe690b13b19bc4054e8b19e390a43110ef38000d04926f16c4572616ec3c4",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
docker exec net-check route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default hostos1 0.0.0.0 UG 0 0 0 eth0
172.18.0.0 * 255.255.0.0 U 0 0 0 eth0
docker network create \
--driver bridge \
--subnet 172.100.1.0/24 \ //필수
--ip-range 172.100.1.0/24 \ //필수
--gateway 172.100.1.1 \ //필수
vswitch-ap
docker network ls
docker network inspect vswitch-ap
docker run --net=vswitch-ap -itd --name=net1 ubuntu:14.04
docker run --net=vswitch-ap -itd --name=net2 --ip 172.100.1.100 ubuntu:14.04
docker inspect net1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.100.1.2",
docker inspect net2 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.100.1.100",
brctl show
bridge name bridge id STP enabled interfaces
br-8b02cc78d4fa 8000.02429da70601 no veth8852cbf
br-c476a986bb2c 8000.02425080bd59 no veth3e7f713
vethd74d822
docker0 8000.02427cd22588 no veth0bacb42
veth64a922f
veth7ced694
vethb7f85b5
vethbe8f5b2
vethbec0519
vethc461a26
vethe2d4ef7
vethf30621b
vethf95b81f
route
docker exec net1 route
Docker Container 네트워크 설정 : container간 IP 공유
docker run -it -d --name net_container_1 ubuntu:14.04
docker run -i -t -d --name net_container_2 \
--net container:net_container_1
ubuntu:14.04
docker run -d --name=httpd-server httpd
docker run -d --name=redis-server --net=container:httpd-server redis
docker ps
docker inspect httpd-server | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.14",
"IPAddress": "172.17.0.14",
docker inspect redis-server | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
brctl show
docker network inspect bridge
docker network create appdb-net
docker network ls
T1 -> sudo apt install bridge-utils
T1 -> brctl show
T2 -> docker run --name ubuntu1 -it --net=appdb-net ubuntu:14.04 /bin/bash
T3 -> docker run --name ubuntu2 -it --net=appdb-net ubuntu:14.04 /bin/bash
T1 -> brctl show
T2, T3에서 실행
ping ubuntu2
Docker Container Load Balancer
- 사용자 정의 브릿지 네트워크 생성
- docker run 수행시 –net-alias옵션으로 컨테이너 묶음
docker network create \
--driver bridge \
--subnet 172.200.1.0/24 \
--ip-range 172.200.1.0/24 \
--gateway 172.200.1.1 \
netlb
docker network ls
docker run -itd --name=nettest1 --net=netlb --net-alias inner-net ubuntu:14.04
docker run -itd --name=nettest2 --net=netlb --net-alias inner-net ubuntu:14.04
docker run -itd --name=nettest3 --net=netlb --net-alias inner-net ubuntu:14.04
docker inspect nettest1 | grep IPAddress // 172.200.1.2
docker inspect nettest2 | grep IPAddress // 172.200.1.3
docker inspect nettest3 | grep IPAddress // 172.200.1.4
docker run -it --name=frontend --net=netlb ubuntu:14.04 bash
ping -c 2 inner-net
// 랜덤하게 컨테이너로 패킷이 전달됨
container frontend에서 확인
apt-get update
apt-get -y install dnsutils
dig inner-net
Comments