我有两个不同的运行容器。
我想将发送到容器#1的流量镜像到容器#2中。
这个问题有没有docker命令来解决?
在Linux接口上可能进行流量镜像,但我不认为Docker提供了设置的方法。如果您手动添加,则应该通过Docker为每个容器设置的veth
接口进行镜像。
tc
允许您以多种方式管理流量,通常用于服务质量类型的排队。 tc
还提供mirror
操作。 以下匹配所有入站和出站流量,并将其镜像到另一个接口。
tc qdisc add dev vethb692b75@if13 ingress
tc filter add dev vethb692b75@if13 parent ffff: \
protocol all prio 2 u32 \
match u32 0 0 flowid 1:1 \
action mirred egress mirror dev veth4305fdd@if15
tc qdisc replace dev vethb692b75@if13 parent root handle 10: prio
tc filter add dev vethb692b75@if13 parent 10: \
protocol all prio 2 u32 \
match u32 0 0 flowid 10:1 \
action mirred egress mirror dev veth4305fdd@if15
iptables
可以将克隆的数据包转发到可路由的主机。这通常用于将流量镜像到外部主机。
iptables -t mangle -I PREROUTING -i vethb692b75@if13 -j TEE --gateway <monitor_ip>
iptables -t mangle –I POSTROUTING -i vethb692b75@if13 -j TEE --gateway <monitor_ip>
在Linux世界中,大多数网络监控软件都涉及到tcpdump。您可以将主机接口上的tcpdump转储到一个fifo中,并将其挂载到监控容器中。
mkfifo /tmp/remotecapture.fifo
tcpdump -s 0 -n -w - -U -i vethb692b75@if13 > /tmp/remotecapture.fifo
docker run -v /tmp/remotecapture.fifo:/tmp/remotecapture.fifo <image> netmonitor -f /tmp/remotecapture.fifo
每次启动容器时,会为每个容器分配veth
名称,因此捕获需要成为您的容器启动/停止过程的一部分。您希望在容器停止时删除任何规则。
在将流量转发到某个地方的情况下,接收者容器/主机不应将任何这些数据包路由回原始目标或其原始目标。
traefik.io/
作为容器#2。它被用于负载均衡,但在您的情况下,您可以定义只有一个后端(因此没有负载均衡),引用容器#1。编辑:如果您只处理HTTP流量
您可以在第三个容器中运行Nginx,并将其用作Docker容器的入口点。然后使用nginx作为Container 1的反向代理,并使用nginx镜像指令将所有请求镜像到Container 2。
实际上,Container 1将接收所有请求并发送响应。 Container 2也会收到请求,但其响应不会发送回发出请求的用户/客户端。
这是一个示例Nginx配置。
upstream logger {
server app2:3002;
}
upstream app {
server app1:3002;
}
server {
listen 8000;
location / {
mirror /mirror;
mirror_request_body on;
proxy_pass http://app;
}
location = /mirror {
internal;
proxy_connect_timeout 200ms;
proxy_read_timeout 200ms;
proxy_pass http://logger$request_uri;
proxy_set_header HOST $http_host;
proxy_set_header X-FORWARDED-FOR $remote_addr;
}
}