코알못

[Docker] 네트워크 본문

ETC

[Docker] 네트워크

코린이s 2022. 3. 26. 18:14
728x90

포트 바인딩 하여 컨테이너 포트를 호스트의 ip 와 연결하여 서비스에 노출하는 방법을 알아 보자!

아래와 같이 명령어를 이용하여 연결할 수 있으며 host 부분은 생략 가능하다. (p 는 publish 의미)

$ docker run -p [HOST IP:PORT]:[CONTAINER PORT] [CONTAINER]

우선 실습으로 익혀보자!

$ docker run -d -p 3000:3000 grafana/grafana
$ docker ps
CONTAINER ID   IMAGE             COMMAND     CREATED         STATUS         PORTS                    NAMES
f2792fece957   grafana/grafana   "/run.sh"   3 seconds ago   Up 2 seconds   0.0.0.0:3000->3000/tcp   bold_almeida

'0.0.0.0:3000->3000/tcp' 로 되어 있으며 이는 모든 host ip 의 3000포트가 해당 컨테이너의 3000 포트로 바인딩 됨을 의미한다.

그럼 정말 연결이 되었는지 테스트를 진행해본다.

$ curl localhost:3000
<a href="/login">Found</a>.

$ curl 172.30.1.33:3000
<a href="/login">Found</a>.

루프백 IP(localhost), backip 모두 정상적으로 접근 됨을 확인 할 수 있다.

이제 host ip를 지정해보자!

$ docker run -d -p 127.0.0.1:3000:3000 grafana/grafana
687e427f2f86ec523e204e0523fa3c1564fe59f0fc9c2762a7ccc5aa51600bbb
$ docker ps
CONTAINER ID   IMAGE             COMMAND     CREATED         STATUS         PORTS                      NAMES
687e427f2f86   grafana/grafana   "/run.sh"   4 seconds ago   Up 4 seconds   127.0.0.1:3000->3000/tcp   wizardly_dijkstra

'127.0.0.1:3000->3000/tcp' 로 되어 있으며 루프백 IP 에만 매핑 되도록 설정 되었다.

루프백 IP 라는 것은 랜 등 여러 영역을 통과하지 않고 처리되는 나 자신을 가르키는 IP로 여러 영역을 통과하지 않고 OS에서 바로 처리되어시스템 자원을 적게 쓰기에 루프백 IP로 사용하는 것이 조금 더 빠르다.

루프백 IP로 설정시 localhost(=127.0.0.1)로는 접근이 되지만 랜 영역을 통과하는 public IP, private IP 로 접근이 안되는 것이다.

이제 테스트를 진행해보자!

$ curl localhost:3000
<a href="/login">Found</a>.

$ curl 172.30.1.33:3000
curl: (7) Failed to connect to 172.30.1.33 port 3000: Connection refused

루프백에 정상적으로 매핑 되었으며 back ip로 호출시에는 접근 되지 않음을 확인 할 수 있다.

이제 host 정보를 넣지 않고 컨테이너 포트 정보만 넣어본다!

$ docker run -d -p 3000 grafana/grafana
e33552ffed76357620228d9f584326f6708d04f0940ade6bba09bbd948e71571
$ docker ps
CONTAINER ID   IMAGE             COMMAND     CREATED          STATUS          PORTS                     NAMES
e33552ffed76   grafana/grafana   "/run.sh"   27 seconds ago   Up 27 seconds   0.0.0.0:60019->3000/tcp   cranky_beaver

'0.0.0.0:60019->3000/tcp' 로 임의의 호스트 port 로 바인딩 된 것을 볼수 있다.

테스트 해보자!

$ curl localhost:60019
<a href="/login">Found</a>.

$ curl 172.30.1.33:60019
<a href="/login">Found</a>.

테스트 결과와 같이 정상적으로 임의로 바인딩된 포트로 접근 되는것을 볼 수 있다.

참고 사항으로 '--expose [port]' 옵션이 있으나 해당 옵션은 문서화 옵션으로 포트 바인딩이 되거나 하지 않는다.

테스트를 통해 확인해보자!

$ docker run -d --expose 3000 grafana/grafana
8aabb54a6741c50140afb26696a1e35ae63ec3eff8406f45b1f23e15b084ec47
$ docker ps
CONTAINER ID   IMAGE             COMMAND     CREATED         STATUS         PORTS      NAMES
8aabb54a6741   grafana/grafana   "/run.sh"   3 seconds ago   Up 2 seconds   3000/tcp   nervous_hermann

바인딩을 의미하는 '->' 표기가 없으며 아래 테스트 결과와 같이 연결이 거부된다.

참고하여 헷갈리지 않도록 한다.

$ curl localhost:3000
curl: (7) Failed to connect to localhost port 3000: Connection refused

 

이제 도커 네트워크 드라이버에 대해 알아보자

Native Driver(기본 드라이버)는 Bridge, Host, None,Overlay가 있으며  3rd-Party Plugins 을 이용 할 수도 있다.

Bridge, Host, None 는 단일 호스트에서 동작하며, overlay 는 멀티 호스트에서 동작하는 드라이버로 주로 orchestration system 에서 사용하는 드라이버이다. (overlay는 이번 강의에서 다루지 않는다고 하여 추후 알아보도록 한다)

실습을 통해 알아보도록 한다.

아래 명령어를 통해 기본적으로 만들어진 네트워크 목록을 확인할 수 있다.

$ docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
5d93be2850f9   bridge     bridge    local
adf33ee66a67   host       host      local
f4b0b7b67e05   minikube   bridge    local
40e67a228494   none       null      local

네트워크 none 모드로 실행 한다.

$ docker run -i -t --net none ubuntu:focal

apt update 시 인터넷이 되지 않아 fail 이 뜬다.

root@43b21c56e64a:/# apt update
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:2 http://security.ubuntu.com/ubuntu focal-security InRelease
  Temporary failure resolving 'security.ubuntu.com'
Err:3 http://archive.ubuntu.com/ubuntu focal-updates InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:4 http://archive.ubuntu.com/ubuntu focal-backports InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal-updates/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/focal-backports/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/focal-security/InRelease  Temporary failure resolving 'security.ubuntu.com'
W: Some index files failed to download. They have been ignored, or old ones used instead.

grafana 도 띄워서 호출해본다. (해당 테스트를 하는 이유는 이따가 host 드라이버와 차이를 보기위함)

$ docker run -d --net none grafana/grafana

 

호출해보면 예상한대로 연결이 거부 되었다. 

$ curl localhost:3000
curl: (7) Failed to connect to localhost port 3000: Connection refused

네트워크 host 모드로 실행 하며 host는 내 로컬 호스트의 네트워크를 사용하는 것이다.

$ docker run --net host -i -t ubuntu:focal

정상적으로 네트워크가 된다.

root@docker-desktop:/# apt update
Get:1 http://archive.ubuntu.com/ubuntu focal InRelease [265 kB]
Get:2 http://security.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Get:3 http://security.ubuntu.com/ubuntu focal-security/restricted amd64 Packages [1068 kB]
Get:4 http://archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
Get:5 http://archive.ubuntu.com/ubuntu focal-backports InRelease [108 kB]
Reading package lists... Done
Building dependency tree
Reading state information... Done
All packages are up to date.

grafana 도 띄워서 호출해본다. 

$ docker run -d --net host grafana/grafana

host 모드의 경우에는 호스트의 ip를 사용하기에 port 를 정의 하지 않아도 기본 port가 바인딩 되어 사용 가능하나 연결이 거부 되었다.

$ curl localhost:3000
curl: (7) Failed to connect to localhost port 3000: Connection refused

구글링 해보니 mac 에서는 host 네트워크 드라이버는 지원하지 않는다고 하여 여기까지 테스트하고 넘어간다.

 

이제 브릿지 네트워크에 대해 알아 볼 것이며 해당 네트워크는 다수 어플리케이션끼리 통신을 위해 주로 사용한다.

브릿지 네트워크는 새로 생성하여 실습 진행해보도록한다.

corin 이라는 브릿지 네트워크를 생성하고

$ docker network create --driver=bridge corin
d412232b4963a1061c6c94bcacf138a4f0c61fa32d9e7d1f4e4934f918f8cbbe

확인해보면 정상적으로 생성 되었다.

$ docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
5d93be2850f9   bridge     bridge    local
d412232b4963   corin      bridge    local
adf33ee66a67   host       host      local
f4b0b7b67e05   minikube   bridge    local
40e67a228494   none       null      local

해당 브릿지 네트워크를 사용하는 컨테이너를 생성하며 브릿지 네트워크에서만 지원하는 옵션인 'net-alias' 를 이용하여 컨테이너 끼리 통신하기 위한 내부 도메인을 지정한다. 

$ docker run -d --network=corin --net-alias=nginx nginx
697e9687d91a2890bbee3fa7219cde125bccda5b01a5cde665afd78f473f525a
$ docker run -d --network=corin --net-alias=grafana grafana/grafana
6803a077f9a273eb7bf4914237802e56b31d7c4a8a19ccce108f08d06512065c
$ docker ps
CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS      NAMES
6803a077f9a2   grafana/grafana   "/run.sh"                5 seconds ago    Up 4 seconds    3000/tcp   kind_elion
697e9687d91a   nginx             "/docker-entrypoint.…"   33 seconds ago   Up 32 seconds   80/tcp     cool_lamport
6c36b22c6cf0   grafana/grafana   "/run.sh"                31 minutes ago   Up 31 minutes              quirky_yalow

우선 grafana 에 접속하여 nginx 의 도메인을 호출하여 정상적으로 통신하는지 확인한다.

$ docker exec -it 6803a077f9a2 bash
// tmp 로 이동하지 않으면 권한이 없어서 파일 저장 불가능 하다.
bash-5.1$ cd /tmp
// curl 이 설치되어 있지 않아 wget을 이용한다.
bash-5.1$ wget nginx
Connecting to nginx (172.18.0.2:80)
saving to 'index.html'
index.html           100% |********************************************************************************************************|   615  0:00:00 ETA
'index.html' saved
bash-5.1$ ls
index.html
bash-5.1$ cat index.html
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

정상적으로 통신 됨을 확인하였으니 반대로 nginx 에서 grafana 도 호출 해본다.

$ docker exec -it 697e9687d91a bash
root@697e9687d91a:/# curl grafana
curl: (7) Failed to connect to grafana port 80: Connection refused
root@697e9687d91a:/# curl grafana:3000
<a href="/login">Found</a>.

정상적으로 통신 됨을 확인 할 수 있다.

끝!

<참고 사항>

특정 네트워크 드라이브에 해당 하는 정보 확인 (예시는 host 네트워크 드라이브 확인)

$ docker network inspect host
[
    {
        "Name": "host",
        "Id": "adf33ee66a6730116a88d87d927392ae0744983864691550debd8fa039a6c8ee",
        "Created": "2022-03-25T06:08:23.442034892Z",
        "Scope": "local",
        "Driver": "host",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": []
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "ce6501b36d5b6efae41b655dd75dcb07713909f0f36035c17262ebd1810b9037": {
                "Name": "host-grafana",
                "EndpointID": "8701189eb09f3c5a3a600cdc30047523b65e7ec0c42fa384afbb69b61bd92dd5",
                "MacAddress": "",
                "IPv4Address": "",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
728x90

'ETC' 카테고리의 다른 글

[Docker] 로그  (0) 2022.03.26
[Docker] 볼륨  (0) 2022.03.26
[Docker] 설정 방법 및 실행중인 컨테이너 접속  (0) 2022.03.25
[Docker] 구성 및 기본 명령어  (0) 2022.03.25
[Docker] 설치  (0) 2022.03.25
Comments