일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 자연어처리
- 클라우드자격증
- TFX
- Collaborative Filtering Bandit
- chatGPT
- BANDiT
- 메타버스
- AWS
- COFIBA
- RecSys
- 추천시스템
- HTTP
- BERT
- BERT이해
- nlp
- 네트워크
- 클라우드
- 중국플랫폼
- MLOps
- MSCS
- llm
- docker
- MAB
- 머신러닝
- transformer
- 플랫폼
- aws자격증
- 미국석사
- 언어모델
- 머신러닝 파이프라인
- Today
- Total
Julie의 Tech 블로그
도커 - 네트워킹 / bridge와 overlay 본문
도커 컨테이너는 우리가 소프트웨어를 실행하기 위해 필요한 모든 것들 (코드, runtime, 시스템 라이브러리 등 서버에 설치될 수 있는 모든 것들) 을 담고 있는 파일 시스템을 감싸고 있다(wrap). 이를 통해 소프트웨어가 항상 어떤 환경에서든 동일하게 동작할 수 있도록 보장해준다.
기본적으로 컨테이너는 어플리케이션을 분리하도록 설계되어 있으며, 분리하는 대상은 어플리케이션 기저에 있는 인프라도 포함하고 있다.
그럼 어플리케이션 간 통신을 하기 위해서는 어떻게 해야할까?
서비스의 portability와 보안, 성능, scalability를 보장하면서 어플리케이션 간 통신이 가능하도록 하는 네트워크를 어떻게 설계해야할까?
Bridge Network
출처 : docker official github
* 컨테이너를 설치하게 되면 default로 bridge 네트워크가 연결된다.
* private internal network
* 각 컨테이너는 veth (virtual) 경로로 bridge 네트워크와 연결된다
* bridge를 통해 Single-host networking 효과를 낼 수 있다
* 외부에서 접근시에는 port-mapping이 필요하다
$ docker container
Usage: docker network COMMAND
Manage Docker networks
Options:
--help Print usage
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
rm Remove one or more networks
Run 'docker network COMMAND --help' for more information on a command.
docker container 명령어는 컨테이너 네트워크를 규명하고 관리하는 데에 사용되는 가장 기본적인 명령어이다.
명령어 그대로 입력하게 되면 지원하는 sub-command를 확인할 수 있는데, create / inspect 와 같이 다양한 명령어들을 확인할 수 있다.
$ docker network ls # list networks
NETWORK ID NAME DRIVER SCOPE
1befe23acd58 bridge bridge local
726ead8f4e6b host host local
ef4896538cc7 none null local
네트워크는 각각 유니크한 이름과 ID를 지니게 되고, 한 개의 드라이브를 소유하고 있다.
위에서 'bridge'란 이름의 네트워크를 찾아볼 수 있는데, 이는 도커를 가장 처음 설치했을 때 자동으로 설치되는 default 네트워크이다.
브릿지 네트워크는 브릿지 드라이버를 사용하는데, 위 예시는 name과 driver 명이 동일해서 헷갈릴 수 있지만, 두 개는 다른 개념이다.
위 예시에서 브릿지 네트워크는 local로 범위가 정해져있는데, 이 의미는 해당 네트워크가 도커 호스트 내에서만 존재한다는 것이다.
어떤 컨테이너를 생성하더라도, 내가 특별히 네트워크를 지정해주지 않는 이상 브릿지 네트워크에 연결되어 있다.
아래에 예제로 백그라운드 환경에서 sleep infinity명령어를 수행하는 ubuntu:latest 이미지로 생성된 컨테이너를 실행해보자.
docker run 명령어에 별도로 네트워크를 지정해주지 않았기 때문에 bridge 네트워크로 연결되어있을 것이다.
$ docker run -dt ubuntu sleep infinity
6dd93d6cdc806df6c7812b6202f6096e43d9a013e56e5e638ee4bfb4ae8779ce
$ brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.0242f17f89a6 no veth3a080f
linux bridge 네트워크를 리스팅하는 명령어 brctl을 사용하여 수행하면 위와 같이 결과를 확인할 수 있다.
인터페이스에 값이 생긴 것으로 보아 방금 생성한 컨테이너에 bridge네트워크가 연결되었음을 확인할 수 있다.
$ docker network inspect bridge
<Snip>
"Containers": {
"6dd93d6cdc806df6c7812b6202f6096e43d9a013e56e5e638ee4bfb4ae8779ce": {
"Name": "reverent_dubinsky",
"EndpointID": "dda76da5577960b30492fdf1526c7dd7924725e5d654bed57b44e1a6e85e956c",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
<Snip>
docker network inspect를 해보게 되면, 컨테이너 ID가 보임으로써 컨테이너에 네트워크가 올바르게 attach된 것을 확인할 수 있다.
도커 호스트의 쉘 프롬프트를 실행하여 ping <도커 컨테이너 IP주소>를 하게 되면 정상적으로 응답을 뱉는 것을 확인할 수 있다.
거꾸로 도커 컨테이너에 접속하여 ping을 설치한 뒤 어느 웹사이트에의 ping 명령어를 수행하게 되면 마찬가지로 정상적인 응답을 확인할 수 있다.
$ docker ps // 컨테이너 ID를 얻기 위해 수행
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
6dd93d6cdc80 ubuntu "sleep infinity" 5 mins Up reverent_dubinsky
// Exec into the container
$ docker exec -it 6dd93d6cdc80 /bin/bash // bash쉘을 실행하기 위해 -it 옵션
// -i : interactive (stdin활성화)
// -t : tty 모드 설정 여부
# Update APT package lists and install the iputils-ping package
root@6dd93d6cdc80:/# apt-get update
<Snip>
apt-get install iputils-ping // ping설치
Reading package lists... Done
<Snip>
# Ping www.dockercon.com from within the container
root@6dd93d6cdc80:/# ping www.dockercon.com
PING www.dockercon.com (104.239.220.248) 56(84) bytes of data.
64 bytes from 104.239.220.248: icmp_seq=1 ttl=39 time=93.9 ms
64 bytes from 104.239.220.248: icmp_seq=2 ttl=39 time=93.8 ms
64 bytes from 104.239.220.248: icmp_seq=3 ttl=39 time=93.8 ms
^C
--- www.dockercon.com ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 93.878/93.895/93.928/0.251 ms
이제는 NAT를 구성해보자. 도커 호스트의 8080포트와 컨테이너 내부의 80 포트를 연결하도록 publishing하는 nginx 이미지 서버를 띄워보자.
$ docker run --name web1 -d -p 8080:80 nginx
이후 docker ps를 통해 포트 매핑이 정상적으로 이루어졌음을 확인할 수 있다.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b747d43fa277 nginx "nginx -g 'daemon off" 3 seconds ago Up 2 seconds 443/tcp, 0.0.0.0:8080->80/tcp web1
6dd93d6cdc80 ubuntu "sleep infinity" About an hour ago Up About an hour reverent_dubinsky
* NAT : network adress translation, 흔히 인터넷 공유기라고 함. 다수의 컴퓨터(사설 IP)가 하나의 공유기(공인 IP)를 통해 인터넷에 접속 가능
** 브릿지 네트워크 : 호스트 네트워크와 게스트 네트워크를 브릿지하여 두 개의 네트워크를 하나의 네트워크처럼 사용
Overlay Network
multi-host networking
Overlay 네트워크에 대해 알아보기 전, 도커 컨테이너 orchestration 도구인 docker swarm을 설치할 것이다.
독스에서는 linux-base 도커 호스트 2개가 필요하다고 기재되어 있어, 각 노드에서 수행해야하는 명령어를 node1, node2로 구분하였다.
Manager노드와 worker node를 구성하는 것인데, manager노드에서 worker node에게 ping을 날렸을 때 반응을 얻을 수 있어야한다.
node1$ docker swarm init
Swarm initialized: current node (cw6jpk7pqfg0jkilff5hr8z42) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-3n2iuzpj8jynx0zd8axr0ouoagvy0o75uk5aqjrn0297j4uaz7-63eslya31oza2ob78b88zg5xe \
172.31.34.123:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
node1에서 docker swarm을 init하게 되면 swarm join이 가능한 토큰이 발행되는데, 이를 노드 2에서 사용할 것이다.
node2$ docker swarm join \
> --token SWMTKN-1-3n2iuzpj8jynx0zd8axr0ouoagvy0o75uk5aqjrn0297j4uaz7-63eslya31oza2ob78b88zg5xe \
> 172.31.34.123:2377
This node joined a swarm as a worker.
노드 1로 돌아가서 아래와 같이 수행하면 정상적으로 swarm 에 두 노드가 돌아가고 있는 것을 확인할 수 있다.
node1$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
4nb02fhvhy8sb0ygcvwya9skr ip-172-31-43-74 Ready Active
cw6jpk7pqfg0jkilff5hr8z42 * ip-172-31-34-123 Ready Active Leader
이제 overlay 네트워크를 만들어볼 차례인데, node1에서 overnet이라는 이름의 overlay 드라이브의 도커 네트워크를 생성한다.
node1$ docker network create -d overlay overnet
0cihm9yiolp0s9kcczchqorhb
docker network를 리스팅 해보면 아래와 같이 swarm 스코프에 생성된 네트워크 두 개가 발견이 된다.
(ingress와 docker_gwbridge 네트워크는 overlay네트워크가 생성되면서 자동으로 생성되었다)
node1$ docker network ls
NETWORK ID NAME DRIVER SCOPE
1befe23acd58 bridge bridge local
726ead8f4e6b host host local
8eqnahrmp9lv ingress overlay swarm
0ea6066635df docker_gwbridge bridge local
ef4896538cc7 none null local
0cihm9yiolp0 overnet overlay swarm
node2에서도 동일한 명령어를 수행하면 overnet 네트워크를 찾아볼 수 없는데, 그 이유는 도커가 overlay네트워크가 연결된 호스트 내에 서비스가 동작하여 수행중일 때에만 해당 네트워크를 연결해주기 때문이다.
노드1에서 위에 생성한 overlay네트워크로 서비스를 하나 생성해보자. 서비스는 간단하게 sleep하는 우분투 서버이다.
node1$ docker service create --name myservice \
--network overnet \
--replicas 2 \
ubuntu sleep infinity
e9xu03wsxhub3bij2tqyjey5t
위에서 replica를 2개를 생성하였는데, 아래와 같이 docker service ps {서비스이름} 을 수행하게 되면, 각 서비스가 다른 노드에서 돌고 있는 것을 확인할 수 있다. 이제 node2 역시도 overlay네트워크에서 서비스를 수행하고 있는 상황이라, node2 콘솔에서 위의 docker network 리스팅을 해보면 안보였던 overnet 네트워크가 확인이 될 것이다.
node1$ docker service ps myservice
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
5t4wh...fsvz myservice.1 ubuntu node1 Running Running 2 mins
8d9b4...te27 myservice.2 ubuntu node2 Running Running 2 mins
이제 네트워크가 정상적으로 연결되어 서로 확인이 가능한지 보자.
node1에 접속하여 docker ps를 수행하게 되면, 위에 생성해둔 Myservice 서비스 중 node1에서 돌고 있는 서비스가 확인이 된다.
node1$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
053abaac4f93 ubuntu:latest "sleep infinity" 19 mins ago Up 19 mins myservice.2.8d9b4i6vnm4hf6gdhxt40te27
위에서 얻은 container ID로 docker를 execute하여, ping을 설치하고 node2 IP로 ping을 보내보면 응답을 받는 것을 확인할 수 있다.
node1$ docker exec -it 053abaac4f93 /bin/bash
root@053abaac4f93:/# apt-get update && apt-get install iputils-ping
<Snip>
root@053abaac4f93:/# ping 10.0.0.4 // node2 IP 주소
PING 10.0.0.4 (10.0.0.4) 56(84) bytes of data.
64 bytes from 10.0.0.4: icmp_seq=1 ttl=64 time=0.726 ms
64 bytes from 10.0.0.4: icmp_seq=2 ttl=64 time=0.647 ms
^C
--- 10.0.0.4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.647/0.686/0.726/0.047 ms
이를 통해 node1과 node2가 정상적으로 네트워크를 공유하고 있음을 확인할 수 있다.
(Overlay네트워크 구성에 대해서는 더 깊이 있게 다루지 않을 것이다.)
참고자료
https://github.com/docker/labs/tree/master/networking
'Tech > MLOps' 카테고리의 다른 글
MLOps, 머신러닝 파이프라인 설계 - (2) TFX, Apache Beam 개요 (1) | 2021.09.01 |
---|---|
MLOps, 머신러닝 파이프라인 설계 - (1) 개요 (1) | 2021.09.01 |
Spark, Zeppelin, Scala에 대해 (0) | 2021.05.12 |
MLOps - (2) GCP TFX 기반 ML시스템 아키텍쳐 이해 (0) | 2021.05.12 |
MLOps - (1) MLOps란? ML Pipeline에 대해 (0) | 2021.05.12 |