diff --git a/src/workerd/server/container-client.c++ b/src/workerd/server/container-client.c++ index 69f2f0c6201..b708eccb323 100644 --- a/src/workerd/server/container-client.c++ +++ b/src/workerd/server/container-client.c++ @@ -1612,6 +1612,15 @@ kj::Promise> ContainerClient: }; } +kj::Promise ContainerClient::ensureSidecarBridgeBypass(kj::String networkCidr) { + auto script = kj::str("cidr=$1\n" + "iptables -t mangle -C PREROUTING -s \"$cidr\" -d \"$cidr\" -j RETURN 2>/dev/null || " + "iptables -t mangle -I PREROUTING 1 -s \"$cidr\" -d \"$cidr\" -j RETURN\n"); + auto cmd = + kj::arr(kj::str("sh"), kj::str("-c"), kj::mv(script), kj::str("sh"), kj::mv(networkCidr)); + co_await runSimpleExecInContainer(sidecarContainerName, cmd.asPtr()); +} + kj::Promise ContainerClient::updateSidecarEgressPort( uint16_t ingressHostPort, uint16_t egressPort) { capnp::JsonCodec codec; @@ -1844,7 +1853,8 @@ kj::Promise ContainerClient::inspectExec( }; } -kj::Promise ContainerClient::runSimpleExec(kj::ArrayPtr cmd) { +kj::Promise ContainerClient::runSimpleExecInContainer( + kj::StringPtr targetContainerName, kj::ArrayPtr cmd) { capnp::JsonCodec codec; codec.handleByAnnotation(); @@ -1862,7 +1872,7 @@ kj::Promise ContainerClient::runSimpleExec(kj::ArrayPtr auto createResponse = co_await dockerApiRequest(network, kj::str(dockerPath), kj::HttpMethod::POST, - kj::str("/containers/", containerName, "/exec"), codec.encode(createRequest)); + kj::str("/containers/", targetContainerName, "/exec"), codec.encode(createRequest)); JSG_REQUIRE(createResponse.statusCode == 201, Error, "Creating helper Docker exec failed with [", createResponse.statusCode, "] ", createResponse.body); @@ -1894,6 +1904,10 @@ kj::Promise ContainerClient::runSimpleExec(kj::ArrayPtr } } +kj::Promise ContainerClient::runSimpleExec(kj::ArrayPtr cmd) { + co_await runSimpleExecInContainer(containerName, cmd); +} + kj::Promise ContainerClient::startContainer() { auto endpoint = kj::str("/containers/", containerName, "/start"); // We have to send an empty body since docker API will throw an error if we don't. @@ -2202,6 +2216,8 @@ kj::Promise ContainerClient::status(StatusContext context) { containerSidecarStarted.store(true, std::memory_order_release); this->sidecarIngressHostPort = sidecar.ingressHostPort; co_await ensureEgressListenerStarted(); + auto ipamConfig = co_await getDockerBridgeIPAMConfig(); + co_await ensureSidecarBridgeBypass(kj::mv(ipamConfig.subnet)); co_await updateSidecarEgressPort(sidecar.ingressHostPort, egressListenerPort); co_await readCACert(); } @@ -2673,8 +2689,10 @@ kj::Promise ContainerClient::ensureSidecarStarted() { KJ_ON_SCOPE_FAILURE(containerSidecarStarted.store(false, std::memory_order_release)); auto ipamConfig = co_await getDockerBridgeIPAMConfig(); + auto networkCidr = kj::str(ipamConfig.subnet); co_await createSidecarContainer(egressListenerPort, kj::mv(ipamConfig.subnet)); co_await startSidecarContainer(); + co_await ensureSidecarBridgeBypass(kj::mv(networkCidr)); auto sidecar = KJ_REQUIRE_NONNULL(co_await inspectSidecar(), "started sidecar not running"); this->sidecarIngressHostPort = sidecar.ingressHostPort; diff --git a/src/workerd/server/container-client.h b/src/workerd/server/container-client.h index 1cc6c244bd2..d629fe0c5af 100644 --- a/src/workerd/server/container-client.h +++ b/src/workerd/server/container-client.h @@ -163,6 +163,7 @@ class ContainerClient final: public rpc::Container::Server, public kj::Refcounte kj::Promise> inspectContainer(); + kj::Promise ensureSidecarBridgeBypass(kj::String networkCidr); kj::Promise updateSidecarEgressPort(uint16_t ingressHostPort, uint16_t egressPort); kj::Promise updateSidecarEgressConfig(uint16_t ingressHostPort, uint16_t egressPort); kj::Promise createContainer(kj::StringPtr effectiveImage, @@ -176,6 +177,8 @@ class ContainerClient final: public rpc::Container::Server, public kj::Refcounte bool attachStderr); kj::Promise> startExec(kj::String execId); kj::Promise inspectExec(kj::StringPtr execId); + kj::Promise runSimpleExecInContainer(kj::StringPtr targetContainerName, + kj::ArrayPtr cmd); kj::Promise runSimpleExec(kj::ArrayPtr cmd); kj::Promise startContainer(); kj::Promise stopContainer();