# --net-alias 옵션의 값은 alicek106으로 설정 - 나는 실수로 06으로 설정함.!
# 다른 컨테이너에서 alicek106이라는 호스트 이름으로 아래 3개의 컨테이너 접근
PS C:\Users\Playdata> docker run -itd --name network_alias_container1 --net mybridge --net-alias alicek06 ubuntu:14.04
95d34bef4bf9056f0b7df4763aa2c39b80fd35a9741d91c5a5f073c1bdf8426c
PS C:\Users\Playdata> docker run -itd --name network_alias_container2 --net mybridge --net-alias alicek06 ubuntu:14.04
6623add3021ee78fbeedc8dbd74e6c9e9ee064b3f709857b1f9c57406980841d
PS C:\Users\Playdata> docker run -itd --name network_alias_container3 --net mybridge --net-alias alicek06 ubuntu:14.04
134b809aeae7422e857e88ea416479ded70fa4564c8e7e9f41e7e3246fa62c83
docker inspect network_alias_container1 | grep 172
이런식으로 컨테이너 3개 전부 IP 확인하고, 이 세 개의 컨테이너에 접근할 컨테이너를 생성한 뒤 alicek106이라는 호스트 이름으로 ping 요청을 전송한다.C:\Users\mink>docker inspect network_alias_container1 | findstr IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.18.0.2",
C:\Users\mink>docker inspect network_alias_container2 | findstr IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.18.0.3",
C:\Users\mink>docker inspect network_alias_container3 | findstr IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.18.0.4",
# 컨테이너 3개의 IP로 각각 ping이 전송된 것을 확인할 수 있다.
# 매번 달라지는 IP를 결정하는 것은 별도의 알고리즘이 아닌 라운드 로빈 방식이다.
# 도커 엔진에 내장된 DNS가 alicek06이라는 호스트 이름을 --net-alias 옵션으로 alicek106을 설정한 컨테이너로 변환하기 때문에 가능하다.
# ping 명령어는 이 IP 리스트에서 첫 번째 IP를 사용하므로 매번 다른 IP로 ping을 전송
PS C:\Users\Playdata> docker run -i -t --name network_alias_ping --net mybridge ubuntu:14.04
root@21e656b4247a:/# ping -c 1 alicek106
ping: unknown host alicek106
root@21e656b4247a:/# ping -c 1 alicek06
PING alicek06 (172.19.0.3) 56(84) bytes of data.
64 bytes from network_alias_container2.mybridge (172.19.0.3): icmp_seq=1 ttl=64 time=0.138 ms
--- alicek06 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.138/0.138/0.138/0.000 ms
root@21e656b4247a:/# ping -c 1 alicek06
PING alicek06 (172.19.0.2) 56(84) bytes of data.
64 bytes from network_alias_container1.mybridge (172.19.0.2): icmp_seq=1 ttl=64 time=0.187 ms
--- alicek06 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.187/0.187/0.187/0.000 ms
root@21e656b4247a:/# ping -c 1 alicek06
PING alicek06 (172.19.0.4) 56(84) bytes of data.
64 bytes from network_alias_container3.mybridge (172.19.0.4): icmp_seq=1 ttl=64 time=0.091 ms
--- alicek06 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.091/0.091/0.091/0.000 ms
--link 옵션 : 컨테이너의 IP가 변경돼도 별명으로 컨테이너를 찾을 수 있게 DNS에 의해 자동적 관리
단 이 경우는 디폴트 브리지 네트워크의 컨테이너 DNS라는 점이 다름
--net-alias 옵션 또한 --link 옵션과 비슷한 원리
mybridge 네트워크에 속한 컨테이너에서 alicek106이라는 호스트 이름으로 접근하면 DNS서버는 라운드 로빈 방식을 이용해 컨테이너의 IP리스트를 반환
ping 명령어는 이 IP리스트에서 첫 번째 IP를 사용하므로 매번 다른 IP로 ping을 전송
매번 달라지는 IP를 결정하는 것은 별도의 알고리즘이 아닌 라운드 로빈(round-robin)방식
라운드 로빈
# 핑을 전송했는지 확인하기위해선 dig라는 도구를 사용
# dig는 DNS로 도메인 이름에 대응하는 IP를 조회할 때 쓰는 도구
# dig는 ubuntu:14.04 이미지에 설치돼 있지 않음.
# 컨테이너 내부에 설치 및 반환되는 IP 확인
root@21e656b4247a:/# apt-get update
# Unable to locate package dnsutils 발생 시
# source.list 상태 확인 후 설치할 것
root@21e656b4247a:/# apt-get install dnsutils
root@21e656b4247a:/# dig alicek06
MacVLAN 네트워크
호스트의 네트워크 인터페이스 카드를 가상화해 물리 네트워크 환경을 컨테이너에게 동일하게 제공
MacVLAN을 사용하면 컨테이너는 물리 네트워크상에서 가상의 맥(MAC) 주소를 가짐
해당 네트워크에 연결된 다른 장치와의 통신이 가능
MacVLAN에 연결된 컨테이너는 기본적으로 할당되는 IP대역인 172.72.X.X대신 네트워크 장비의 IP할당받음
# MacVLAN 내용은 더 알아보기!
PS C:\Users\Playdata> docker network create -d macvlan --subnet=192.168.0.0/24 --ip-range=192.168.0.64/28 --gateway=192.168.0.1 -o macvlan_mode=bridge -o parent=eth0 my_macvlan
19aba3697abcd727e5f0fac5ee355af63553fe079486eb5db24ab3773047a4af
PS C:\Users\Playdata> docker run -it --name c1 --hostname c1 --network my_macvlan ubuntu:14.04
root@c1:/# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
...
root@c1:/# ping 192.168.0.128 -c 1
PING 192.168.0.128 (192.168.0.128) 56(84) bytes of data.
From 192.168.0.64 icmp_seq=1 Destination Host Unreachable
# 컨테이너를 생성해 간단한 로그 생성. mysql 5.7 버전의 컨테이너
# 애플리케이션이 잘 구동되는지 여부를 알 순 없음
PS C:\Users\Playdata> docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=1234 mysql:5.7
ffcde61123ab836ea04679300724a7f448a2e86a4d9023bd280b4ea7fb1cd16e
# docker logs 명령어를 써서 컨테이너의 표준 출력을 확인함으로써 애플리케이션의 상태 알 수 있음
# docker logs 명령어는 컨테이너 내부에서 출력을 보여주는 명령어
PS C:\Users\Playdata> docker logs mysql
2022-03-07 14:35:57+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.37-1debian10 started.
2022-03-07 14:35:58+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-03-07 14:35:58+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.37-1debian10 started.
....
# 다른 방법으로 컨테이너 생성. 동일한 mysql 컨테이너 생성, -e 옵션 제외
PS C:\Users\Playdata> docker run -d --name no_passwd_mysql mysql:5.7
860001c98fca3b35a0966c804fbf823ffd0f75f4256fe636e9a85498ea81e092
# docker ps 명령어로 목록을 확인하면 컨테이너는 생성됐으나 실행되지 않음. start도 마찬가지
PS C:\Users\Playdata> docker ps --format "table {{.ID}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}"
CONTAINER ID STATUS PORTS NAMES
ffcde61123ab Up 6 minutes 3306/tcp, 33060/tcp mysql
134b809aeae7 Up About an hour network_alias_container3
6623add3021e Up About an hour network_alias_container2
95d34bef4bf9 Up About an hour network_alias_container1
193c9949d53a Up 2 hours 0.0.0.0:59318->80/tcp wordpress
5d1b2095af6b Up 2 hours 3306/tcp, 33060/tcp wordpressdb
74027231bfa7 Up 2 hours charming_cerf
이럴 때 docker logs 명령어를 사용하면 애플리케이션에 무슨 문제가 있는지 확인가능
컨테이너가 정상적으로 실행 및 동작하지 않고 docker attach 명령어도 사용하지 못하는 환경에선 docker logs 명령어를 쓰면 간단하고 빠르게 에러 확인
# 컨테이너에서 발생한 로그들
PS C:\Users\Playdata> docker logs no_passwd_mysql
2022-03-07 14:41:09+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.37-1debian10 started.
2022-03-07 14:41:11+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
2022-03-07 14:41:11+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.37-1debian10 started.
2022-03-07 14:41:12+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
You need to specify one of the following:
- MYSQL_ROOT_PASSWORD
- MYSQL_ALLOW_EMPTY_PASSWORD
- MYSQL_RANDOM_ROOT_PASSWORD
# --tail 옵션을 써서 출력할 줄의 수를 설정
PS C:\Users\Playdata> docker logs --tail 2 mysql
2022-03-07T14:37:48.241621Z 0 [Note] mysqld: ready for connections.
Version: '5.7.37' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL)
# since 옵션에 유닉스 시간을 입력해 특정시간 이후의 로그를 확인
# 유닉스 시간 계산법
PS C:\Users\Playdata> docker logs --since 1474765979 mysql
2022-03-07 14:35:57+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.37-1debian10 started.
2022-03-07 14:35:58+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
..
# -t 옵션으로 타임스탬프를 표시
# -f 옵션을 써서 로그를 스트림으로 확인 <애플리케이션 개발할 때 유용>
PS C:\Users\Playdata> docker logs -f -t mysql
2022-03-07T14:35:57.979848000Z 2022-03-07 14:35:57+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.37-1debian10 started.
2022-03-07T14:35:58.060013300Z 2022-03-07 14:35:58+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
...
# docker logs 명령어는 run 명령어에서 -i -t 옵션을 설정해 docker attach 명령어를 사용가능
# 컨테이너 내부에서 bash 셀 등을 입출력한 내용 확인가능
PS C:\Users\Playdata> docker run -i -t --name logstest ubuntu:14.04
root@e6281cd0b861:/# echo test!
test!
PS C:\Users\Playdata> docker logs logstest
root@e6281cd0b861:/# echo test!
test!
root@e6281cd0b861:/# exit
exit
# 아래의 log 파일의 내용을 cat, vi 편집기 등으로 확인하면 logs 명령으로 정제되지 않은 JSON 데이터 확인
#
# sudo에서
$ cat /var/lib/docker/containers/컨테이너ID/컨테이너ID-json.log
# --log-opt 옵션으로 컨테이너 json 로그 파일의 최대 크기를 지정
# max-size는 로그 파일의 최대 크기, max-file은 로그 파일의 개수를 의미
PS C:\Users\Playdata> docker run -it --log-opt max-size=10k --log-opt max-file=3 --name log-test ubuntu:14.04
# 리눅스 위에서 돌리신다면 /var/log/syslog or /var/log/messages에서 확인 가능
PS C:\Users\Playdata> docker run -d --name syslog_container --log-driver=syslog ubuntu:14.04 echo syslogtest
043cb065125afd3a705360779de1e633b4e1fa5173c81ecce0d903add6b8e17d
docker: Error response from daemon: failed to initialize logging driver: Unix syslog delivery error.
# 서버 호스트에 rsyslog 서비스가 시작하도록 설정된 컨테이너를 구동하고 rsyslog 컨테이너를 생성
# rsyslog.conf 파일을 열어 syslog 서버를 구동시키는 항목의 주석을 해체한 후 변경사항 저장
PS C:\Users\Playdata> docker run -i -t -h rsyslog --name rsyslog_server -p 514:514 -p 514:514/udp ubuntu:14.04
root@rsyslog:/# vi /etc/rsyslog.conf
..
# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
..
# 저장 후 서비스 재시작
root@rsyslog:/# service rsyslog restart
* Stopping enhanced syslogd rsyslogd [ OK ]
* Starting enhanced syslogd rsyslogd [ OK ]
# --log-opt 옵션으로 syslog-facility를 쓰면 로그가 저장될 파일을 바꿈
# facility는 로그를 생성하는 주체에 따라 로그를 다르게 저장
# 여러 애플리케이션에서 수집되는 로그를 분류하는 방법
# facility 옵션을 쓰면 rsyslog 서버 컨테이너에 해당 facility에 해당하는 새로운 로그 파일이 생성
# rsyslog는 우분투에서 쓸 수 있는 기본적인 로깅 방법이므로 별도의 UI를 제공하지 않음
# logentries, LogAnalyzer 등과 같은 로그 분석기와 연동하면 웹 인터페이스를 활용해 편리하게 로그를 확인
docker run -it --log-driver syslog --log-opt syslog-address=tcp://192.168.0.100:514 --log-opt tag="mailog" --log-opt syslog-facility="mail" ubuntu:14.04
TCP와 UDP의 특징과 차이
전송을 제어하는 프로토콜(규약)
특징
서버의 특징
# 몽고DB설치
PS C:\Users\Playdata> docker run --name mongoDB -d -p 27017:27017 mongo
Unable to find image 'mongo:latest' locally
# 우분투로 접속 < 파워셀에선 이용불가 >
mink@DESKTOP-U4KHBSV:~$ vi fluent.conf
# fluentd.conf 파일이 저장된 디렉토리에서 fluentd 컨테이너 생성
# -v옵션을 이용해 fluentd 컨테이너에 공유 및 설정 파일 사용
#
mink@DESKTOP-U4KHBSV:~$ docker run -d --name fluentd -p 24224:24224 -v $(pwd)/fluent.conf:/fluentd/etc/fluent.conf -e FLUENTD_CONF=fluent.conf alicek106/fluentd:mongo
Unable to find image 'alicek106/fluentd:mongo' locally
mongo: Pulling from alicek106/fluentd
# --log-driver를 fluentd로 설정하고 --log-opt의 fluentd-address 값에 fluentd 서버 주소 지정
# --log-opt tag를 명시함으로써 로그의 태그를 docker.nginx.webserver로 지정했지만
mink@DESKTOP-U4KHBSV:~$ docker run -p 80:80 -d --log-driver=fluentd --log-opt fluentd-address=IP주소:24224 --log-opt tag=docker.nginx.webserver nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
# 이후는 오류 발생 후에 공부할 예정.
mink@PMK-HS1HH67:~$ docker exec -it mongoDB mongo
OCI runtime exec failed: exec failed: unable to start container process: exec: "mongo": executable file not found in $PATH: unknown
# mongo -> mongosh로 변경
mink@PMK-HS1HH67:~$ docker exec -it mongoDB mongosh