Docker 컨테이너 내에서 동일한 호스트의 다른 컨테이너에 호스트를 통해 액세스할 수 없음
그런 이유로, Keycloak로 인증을 실시하는 Web 어플리케이션을 개발하고 있어, 동작 확인도 끝나, 막상 검증 환경에서 움직이려고 하면, Web 어플리케이션의 기동이 실패해 버렸다.
시스템의 구성과 경위는 다음과 같은 이미지.
Keycloak 서버는 검증 환경에서 docker-compose를 사용하여 구축. 웹 앱은 백엔드를 Spring Boot, 프런트 엔드를 Angular로 개발. Angular 앱에서는 keycloak-angular를 사용. Spring Boot 앱은 리소스 서버로 동작하기 때문에 spring-boot-starter-oauth2-resource-server를 사용하여 Angular 앱에서 보내 온 토큰을 검증. 개발중은, 검증 환경의 Keycloak 서버에 접속해 동작을 확인. 웹 앱을 컨테이너로 해, 검증 환경의 Keycloak 서버와 같은 호스트의 Docker상에서 기동하면, Spring Boot 앱으로부터 Keycloak 서버에의 경로가 없다(no route to host)와의 에러로 종료하고 있었다. 먼저 시도한 것 그래서 Keycloak 컨테이너와 Web 앱 컨테이너를 같은 Docker 네트워크에 참가시켜, Spring Boot 앱으로부터 Docker 네트워크 경유로 접속하도록 해 보았다. docker network create ${네트워크 이름}으로 네트워크를 만듭니다. Keycloak 및 웹 앱 docker-compose.yml에서 위의 네트워크에 참여하도록 설정합니다. 예) 웹 앱 docker-compose.yml 버전: '3' 서비스: app: build: context :. container_name: app ports: - 50010:8080 networks: - ${네트워크 이름} networks: ${네트워크 이름}: external: true SpringBoot 앱의 application.yml spring: security: oauth2: resourceserver: jwt: issuer-uri: http://${keycloak 컨테이너 이름}.${네트워크 이름}:8080/auth/realms/${영역 이름} 이제 Spring Boot 앱은 Keycloak 서버와 통신이 성공하여 정상적으로 시작하게 되었다. 그러나 Angular 앱으로 로그인하면 keycloak 서버에 성공적으로 로그인했지만 Angular 앱에서 Spring Boot 앱으로의 Ajax 통신으로 401 Unauthorized되었습니다. 브라우저에서 응답을 보면 헤더에 다음 정보가 있었다. WWW-Authenticate: Bearer error="invalid_token", error_description="This iss claim is not equal to the configured issuer", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1" 분명히 Angular 앱과 Spring Boot 앱이 액세스하는 Keycloak 서버의 URL은 일치하지 않습니다. 그래서 아무래도 Docker 컨테이너 내부에서 외부 넷을 통해 액세스할 필요가 있었다. 근본 원인 거기서 넷으로부터 정보를 잡으면, Docker가 iptables를 설정하고 있어, 그것에 의해 통신을 할 수 없는 것 같다. 이 기사 라든지 참고로 iptables의 견해를 공부해 보았다.
아직 완전히 이해하지 못했지만 자신의 호스트에서 패킷을 보낼 때 체인을 추적하면,
# iptables -t nat -nvL POSTROUTING
Chain POSTROUTING (policy ACCEPT 12 packets, 853 bytes)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * !docker0 172.17.0.0/16 0.0.0.0/0
※あとは割愛
Dockerk 컨테이너에 디폴트로 할당되는 bridge 네트워크의 주소 172.17.0.0/16으로부터의 통신은, docker0 브릿지에는 돌아갈 수 없는 설정이라고 생각했다.
해결 방법
현재의 이해에서는 iptables를 만지는 것도 허들이 높기 때문에, Web 어플리의 Docker 컨테이너가 디폴트의 bridge 드라이버를 사용한 네트워크는 아니고, host 드라이버를 사용하도록 지정했다.
docker-compose.yml
version: '3'
services:
app:
build:
context: .
container_name: app
network_mode: host # 追加
# ポートマッピングは使えなくなるので削除
# ports:
# - 50010:8080
이것에 의해 컨테이너 내부에서 사용하는 포트가, 직접 호스트로 사용되어 버리지만, 거기는 Spring Boot의 설정 파일로 간단하게 포트 번호를 변경할 수 있으므로 좋았습니다.
Reference
이 문제에 관하여(Docker 컨테이너 내에서 동일한 호스트의 다른 컨테이너에 호스트를 통해 액세스할 수 없음), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/megasys1968/items/d752598cf7de9b8ac5e9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)