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의 저장소에 이미지 업로드

  1. docker tag
  2. docker login
  3. 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

Categories:

Updated:

Comments