모놀 틱 서버를 여러 개의 작은 도커 컨테이너로 분할 할 계획이지만 아직 "컨테이너 간 통신"을위한 좋은 솔루션을 찾지 못했습니다. 이것이 내 목표 시나리오입니다.
컨테이너를 함께 연결하는 방법과 포트를 노출하는 방법을 알고 있지만 이러한 솔루션 중 어느 것도 만족스럽지 않습니다.
기존 서버 네트워크에서와 같이 컨테이너간에 호스트 이름 (컨테이너 이름)을 통해 통신 할 수있는 솔루션이 있습니까?
모놀 틱 서버를 여러 개의 작은 도커 컨테이너로 분할 할 계획이지만 아직 "컨테이너 간 통신"을위한 좋은 솔루션을 찾지 못했습니다. 이것이 내 목표 시나리오입니다.
컨테이너를 함께 연결하는 방법과 포트를 노출하는 방법을 알고 있지만 이러한 솔루션 중 어느 것도 만족스럽지 않습니다.
기존 서버 네트워크에서와 같이 컨테이너간에 호스트 이름 (컨테이너 이름)을 통해 통신 할 수있는 솔루션이 있습니까?
답변:
편집 : Docker 1.9 이후에는 docker network
명령 ( https://stackoverflow.com/a/35184695/977939 참조 )이이를 수행하는 데 권장되는 방법입니다.
내 해결책은 DNS 레코드가 자동으로 업데이트되도록 호스트에 dnsmasq를 설정하는 것입니다. "A"레코드에는 컨테이너 이름이 있고 컨테이너의 IP 주소를 자동으로 가리 킵니다 (10 초마다). 자동 업데이트 스크립트는 여기에 붙여 넣습니다 :
#!/bin/bash
# 10 seconds interval time by default
INTERVAL=${INTERVAL:-10}
# dnsmasq config directory
DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}
# commands used in this script
DOCKER=${DOCKER:-docker}
SLEEP=${SLEEP:-sleep}
TAIL=${TAIL:-tail}
declare -A service_map
while true
do
changed=false
while read line
do
name=${line##* }
ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name)
if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed
then
service_map[$name]=$ip
# write to file
echo $name has a new IP Address $ip >&2
echo "host-record=$name,$ip" > "${DNSMASQ_CONFIG}/docker-$name"
changed=true
fi
done < <(${DOCKER} ps | ${TAIL} -n +2)
# a change of IP address occured, restart dnsmasq
if [ $changed = true ]
then
systemctl restart dnsmasq
fi
${SLEEP} $INTERVAL
done
에서 dnsmasq 서비스를 사용할 수 있는지 확인하십시오 docker0
. 그런 다음 --dns HOST_ADDRESS
이 미니 DNS 서비스를 사용하기 위해 컨테이너를 시작합니다 .
새로운 네트워킹 기능을 사용하면 이름으로 컨테이너에 연결할 수 있으므로 새 네트워크를 만들면 해당 네트워크에 연결된 모든 컨테이너가 이름으로 다른 컨테이너에 연결할 수 있습니다. 예:
1) 새 네트워크 생성
$ docker network create <network-name>
2) 컨테이너를 네트워크에 연결
$ docker run --net=<network-name> ...
또는
$ docker network connect <network-name> <container-name>
3) 이름 별 핑 컨테이너
docker exec -ti <container-name-A> ping <container-name-B>
64 bytes from c1 (172.18.0.4): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from c1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from c1 (172.18.0.4): icmp_seq=3 ttl=64 time=0.074 ms
64 bytes from c1 (172.18.0.4): icmp_seq=4 ttl=64 time=0.074 ms
문서 의이 섹션을 참조하십시오 .
참고 : 레거시와 달리 links
새 네트워킹 은 환경 변수를 생성하지 않으며 다른 컨테이너와 환경 변수를 공유하지 않습니다.
이 기능은 현재 별칭을 지원하지 않습니다.
docker-compose down,up,restart
?
bridge
이전 버전과의 호환성으로 인해 기본 네트워크 에서 비활성화되어 있지만 예, 동의합니다. 기본적으로 활성화 해야합니다 !
즉해야 무엇을 --link
위한 호스트 이름 부분 적어도.
으로 고정 표시기 1.10, 및 PR 19242 , 그 것이다 :
docker network create --net-alias=[]: Add network-scoped alias for the container
(아래 마지막 섹션 참조)
그것이 파일 세부 정보 업데이트/etc/hosts
환경 변수 외에도 Docker는 소스 컨테이너에 대한 호스트 항목을
/etc/hosts
파일에 추가합니다.
예를 들어 LDAP 서버를 시작합니다.
docker run -t --name openldap -d -p 389:389 larrycai/openldap
그리고 해당 LDAP 서버를 테스트 할 이미지를 정의합니다.
FROM ubuntu
RUN apt-get -y install ldap-utils
RUN touch /root/.bash_aliases
RUN echo "alias lds='ldapsearch -H ldap://internalopenldap -LL -b
ou=Users,dc=openstack,dc=org -D cn=admin,dc=openstack,dc=org -w
password'" > /root/.bash_aliases
ENTRYPOINT bash
--link를 사용하여 테스트 이미지 내 에서 ' openldap
'컨테이너를 ' internalopenldap
' 로 노출 할 수 있습니다 .
docker run -it --rm --name ldp --link openldap:internalopenldap ldaptest
그런 다음 'lds'를 입력하면 해당 별칭이 작동합니다.
ldapsearch -H ldap://internalopenldap ...
그것은 사람들을 반환 할 것입니다. 이미지 internalopenldap
에서 의미 에 올바르게 도달했습니다 ldaptest
.
물론 docker 1.7은 libnetwork
컨테이너 연결을위한 기본 Go 구현을 제공하는을 추가 합니다. 블로그 게시물을 참조하십시오 .
CNM (Container Network Model)을 통해보다 완벽한 아키텍처를 도입했습니다.
그러면 새로운 "network"명령으로 Docker CLI를 업데이트하고 " -net
"플래그를 사용하여 컨테이너를 네트워크에 할당 하는 방법을 문서화합니다 .
docker 1.10에는 이제 공식적으로 문서화 된 새로운 섹션 Network-scoped alias 가 있습니다network connect
.
링크는 컨테이너 내에서 지역화 된 개인 이름 확인을 제공하지만 네트워크 범위 별칭은 특정 네트워크 범위 내의 다른 컨테이너에서 대체 이름으로 컨테이너를 검색 할 수있는 방법을 제공합니다.
서비스 소비자가 정의하는 링크 별칭과 달리 네트워크 범위 별칭은 네트워크에 서비스를 제공하는 컨테이너에 의해 정의됩니다.위의 예를 계속
isolated_nw
하여 네트워크 별칭을 사용하여 다른 컨테이너를 만듭니다 .
$ docker run --net=isolated_nw -itd --name=container6 -alias app busybox
8ebe6767c1e0361f27433090060b33200aac054a68476c3be87ef4005eb1df17
--alias=[]
컨테이너에 대한 네트워크 범위 별칭 추가
--link
옵션을 사용 하여 선호하는 별칭으로 다른 컨테이너를 연결할 수 있습니다.네트워크에 연결된 컨테이너를 일시 중지, 다시 시작 및 중지 할 수 있습니다. 일시 중지 된 컨테이너는 연결된 상태로 유지되며 네트워크 검사를 통해 확인할 수 있습니다. 컨테이너가 중지되면 다시 시작할 때까지 네트워크에 나타나지 않습니다.
지정된 경우 중지 된 컨테이너가 다시 시작될 때 컨테이너의 IP 주소가 다시 적용됩니다. IP 주소를 더 이상 사용할 수 없으면 컨테이너가 시작되지 않습니다.
IP 주소를 사용할 수 있는지 확인하는 한 가지 방법
--ip-range
은 네트워크를 만들 때 를 지정하고 해당 범위 외부에서 고정 IP 주소를 선택하는 것입니다. 이렇게하면이 컨테이너가 네트워크에없는 동안 IP 주소가 다른 컨테이너에 제공되지 않습니다.
$ docker network create --subnet 172.20.0.0/16 --ip-range 172.20.240.0/20 multi-host-network
$ docker network connect --ip 172.20.128.2 multi-host-network container2
$ docker network connect --link container1:c1 multi-host-network container2
편집 : 더 이상 블리딩 에지가 아닙니다 : http://blog.docker.com/2016/02/docker-1-10/
원래 답변
나는 밤새 그것과 싸웠다. 블리딩 엣지를 두려워하지 않는다면 최신 버전의 Docker 엔진 과 Docker가 모두 libnetwork를 구현합니다.
올바른 구성 파일 (버전 2에 넣어야 함)을 사용하면 서로를 볼 수있는 서비스를 만들 수 있습니다. 또한 docker-compose로 확장 할 수도 있습니다 (호스트의 포트를 바인딩하지 않는 원하는 서비스를 확장 할 수 있음).
다음은 예제 파일입니다.
version: "2"
services:
router:
build: services/router/
ports:
- "8080:8080"
auth:
build: services/auth/
todo:
build: services/todo/
data:
build: services/data/
이 새로운 버전의 compose 파일에 대한 참조 : https://github.com/docker/compose/blob/1.6.0-rc1/docs/networking.md
내가 아는 한 Docker 만 사용하면 불가능합니다. 컨테이너 ip : s를 호스트 이름에 매핑하려면 DNS가 필요합니다.
즉시 사용 가능한 솔루션을 원하는 경우. 한 가지 해결책은 예를 들어 Instagrama 를 사용하는 것입니다 . Weave의 네트워크 오버레이 기술과 함께 제공되며이 기술은 각 서비스에 대한 가상 사설 LAN 네트워크를 생성하는 데 사용되며 모든 서비스는 service_name.kontena.local-address
.
다음은 Wordpress 서비스가 wordpress-mysql.kontena.local 주소로 MySQL 서버에 연결되는 Wordpress 애플리케이션의 YAML 파일에 대한 간단한 예입니다.
wordpress:
image: wordpress:4.1
stateful: true
ports:
- 80:80
links:
- mysql:wordpress-mysql
environment:
- WORDPRESS_DB_HOST=wordpress-mysql.kontena.local
- WORDPRESS_DB_PASSWORD=secret
mysql:
image: mariadb:5.5
stateful: true
environment:
- MYSQL_ROOT_PASSWORD=secret