简体   繁体   English

在docker容器之间重定向的最佳实践

[英]Best practice for redirecting between docker containers

Given I have multiple web applications running in docker containers, I want to be able to let the user be redirected from on service to another service in his browser. 鉴于我有多个在docker容器中运行的Web应用程序,我希望能够将用户从服务重定向到浏览器中的另一个服务。 I wonder how to achieve this - especially if I want my applications to be portable from one docker host to a different host. 我想知道如何实现这一点 - 特别是如果我希望我的应用程序可以从一个docker主机移植到另一个主机。

Let's say we have a ServiceA which redirects the user to ServiceB. 假设我们有一个ServiceA,它将用户重定向到ServiceB。 So we have a relationship 所以我们有一段感情

ServiceA --> ServiceB

One approach would be to statically assign ports and hostnames and set them as environment vars to my web services - which I would not prefer because I don't want to care about which service runs on which port. 一种方法是静态分配端口和主机名,并将它们设置为我的Web服务的环境变量 - 我不喜欢这样做,因为我不想关心哪个服务在哪个端口上运行。

A second approach would be to have a proxy like nginx and link the services and use the proxy host and port. 第二种方法是拥有像nginx这样的代理并链接服务并使用代理主机和端口。 But this would require to change the proxy configuration when moving a service to a different host. 但是,这需要在将服务移动到其他主机时更改代理配置。

The third approach that comes to mind, is to use etcd and ambassadors to register and resolve services. 想到的第三种方法是使用etcd和ambassadors来注册和解决服务。 So ServiceA would use a ServiceB-Ambassador which looks up ServiceB in etcd. 因此,ServiceA将使用ServiceB-Ambassador在etcd中查找ServiceB。 This results in many docker containers just to connect between services. 这导致许多docker容器只是连接服务。

Which way would you prefer? 你更喜欢哪种方式? Or are there different approaches? 或者有不同的方法吗?

Edit 编辑

The real problem is to inject the uri of ServiceB into ServiceA, so I can launch my ServiceA with an argument like -DserviceB.uri=<serviceUri> , so that serviceA can build the correct redirect header. 真正的问题是将ServiceB的uri注入ServiceA,因此我可以使用-DserviceB.uri=<serviceUri>类的参数启动我的ServiceA,以便serviceA可以构建正确的重定向头。

I use a setup with consul to connect tomcat containers to an apache http server (using mod_jk ). 我使用consul的设置将tomcat容器连接到apache http服务器(使用mod_jk)。 Consul is similar to etcd, ie it allows to register and discover services. Consul类似于etcd,即它允许注册和发现服务。 This might be applicable to your question, but you are not restricted to consul. 这可能适用于您的问题,但您不限于领事。

Every time a new tomcat container is started, I assign a distinct public port to that container, register the tomcat container in consul with information about its IP and Ports and fire an event (the script is run on the docker host, and is reduced for readability) 每次启动一个新的tomcat容器时,我都会为该容器分配一个不同的公共端口,在consul中注册tomcat容器以及有关其IP和Ports的信息并触发事件(该脚本在docker主机上运行,​​并且为可读性)

#!/bin/bash
INTERNAL_PORT=8009
source ~/ports.properties
TOMCAT_PORT=$(( TOMCAT_PORT + 1))
echo "TOMCAT_PORT=$TOMCAT_PORT" > ~/ports.properties

CONTAINER_ID=$(docker run -d -p $TOMCAT_PORT:8009 -v `pwd`$WAR_DIR:/webapps rossbachp/tomcat8)
echo "Container started, CONTAINER_ID:  $CONTAINER_ID"

IP_ADDRESS=$(docker inspect -f '{{.NetworkSettings.IPAddress}}' $CONTAINER_ID )
echo "Container IP_ADDRESS:               $IP_ADDRESS "

echo "Register Container in Consul"
curl -X PUT -d '{"ID": "'$CONTAINER_ID'","Name":"'$CLUSTER_NAME'", "Tags": [ "IP_'$IP_ADDRESS'", "PORT_'$INTERNAL_PORT'"],"Port":'$TOMCAT_PORT'}' localhost:8500/v1/agent/service/register 

echo "Fire Event"
consul event -name "TomcatServiceUp"

In consul (on the docker host) I have defined a watch for the event "TomcatServiceUp" in File /etc/consul.d/bootstrap/watchTomcatServiceUp.json that executes a script 在consul(在docker主机上)我已经为文件/etc/consul.d/bootstrap/watchTomcatServiceUp.json中的事件“TomcatServiceUp”定义了一个执行脚本的监视

{
"watches":[    {
"type":"event",
"name":"TomcatServiceUp",
"handler": "/home/dude/docker/docker-http-withmodjk/callbackTomcatServiceUpEvent.sh"
   }  ]
}

and the script callbackTomcatServiceUpEvent.sh queries the services (mainly IPAddress and Port), creates a new workers.properties file, copies this file to the http docker instance (to its volume) and gracefully restarts the http server (in the docker container). 脚本callbackTomcatServiceUpEvent.sh查询服务(主要是IPAddress和Port),创建一个新的workers.properties文件,将此文件复制到http docker实例(到其卷)并正常重启http服务器(在docker容器中)。

#!/bin/bash
SERVICE=$(curl localhost:8500/v1/agent/services)
java -jar /home/dude/docker/JSonParser.jar "$SERVICE" >> /tmp/workers.properties
cp workers.properties /home/dude/docker/docker-http-withmodjk/mod_jk_conf
# http graceful restart

Could you use an approach where your services register themselves in consul (or etcd) and discover each other via events and service lookup. 您可以使用一种方法,您的服务在领事(或等)中注册,并通过事件和服务查找发现彼此。 Or use nginx to handle the events and do the service lookup? 或者使用nginx来处理事件并进行服务查找?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM