Skip to content

Commit c0f247a

Browse files
authored
Merge pull request #3761 from telepresenceio/thallgren/drop-replaced
Remove the dormant container during intercept with --replace.
2 parents 13f0c83 + d9c48f2 commit c0f247a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+481
-382
lines changed

CHANGELOG.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ items:
4444
values: <namespaces>`.
4545
```
4646
docs: install/manager#static-versus-dynamic-namespace-selection
47+
- type: feature
48+
title: Removal of the dormant container during intercept with --replace.
49+
body: |-
50+
During a `telepresence intercept --replace operation`, the previously injected dormant container has been
51+
removed. The Traffic Agent now directly serves as the replacement container, eliminating the need to forward
52+
traffic to the original application container. This simplification offers several advantages when using the
53+
`--replace` flag:
54+
55+
- **Removal of the init-container:** The need for a separate init-container is no longer necessary.
56+
- **Elimination of port renames:** Port renames within the intercepted pod are no longer required.
4757
- type: change
4858
title: Drop deprecated current-cluster-id command.
4959
body: >-

cmd/traffic/cmd/agent/agent.go

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ func sftpServer(ctx context.Context, sftpPortCh chan<- uint16) error {
9595
_ = l.Close()
9696
}()
9797

98-
_, sftpPort, err := iputil.SplitToIPPort(l.Addr())
98+
ap, err := iputil.SplitToIPPort(l.Addr())
9999
if err != nil {
100100
return err
101101
}
102-
sftpPortCh <- sftpPort
102+
sftpPortCh <- ap.Port()
103103

104104
dlog.Infof(ctx, "Listening at: %s", l.Addr())
105105
for {
@@ -163,31 +163,38 @@ func sidecar(ctx context.Context, s State, info *rpc.AgentInfo) error {
163163
// Group the container's intercepts by agent port
164164
icStates := make(map[agentconfig.PortAndProto][]*agentconfig.Intercept, len(cn.Intercepts))
165165
for _, ic := range cn.Intercepts {
166-
k := agentconfig.PortAndProto{Port: ic.AgentPort, Proto: ic.Protocol}
166+
ap := ic.AgentPort
167+
if cn.Replace {
168+
// Listen to replaced container's original port.
169+
ap = ic.ContainerPort
170+
}
171+
k := agentconfig.PortAndProto{Port: ap, Proto: ic.Protocol}
167172
icStates[k] = append(icStates[k], ic)
168173
}
169174

170175
for pp, ics := range icStates {
171176
ic := ics[0] // They all have the same protocol container port, so the first one will do.
177+
var fwd forwarder.Interceptor
172178
var cp uint16
173-
if ic.TargetPortNumeric {
174-
// We must differentiate between connections originating from the agent's forwarder to the container
175-
// port and those from other sources. The former should not be routed back, while the latter should
176-
// always be routed to the agent. We do this by using a proxy port that will be recognized by the
177-
// iptables filtering in our init-container.
178-
cp = ac.ProxyPort(ic)
179+
if !cn.Replace {
180+
if ic.TargetPortNumeric {
181+
// We must differentiate between connections originating from the agent's forwarder to the container
182+
// port and those from other sources. The former should not be routed back, while the latter should
183+
// always be routed to the agent. We do this by using a proxy port that will be recognized by the
184+
// iptables filtering in our init-container.
185+
cp = ac.ProxyPort(ic)
186+
} else {
187+
cp = ic.ContainerPort
188+
}
189+
// Redirect non-intercepted traffic to the pod, so that injected sidecars that hijack the ports for
190+
// incoming connections will continue to work.
191+
targetHost := s.PodIP()
192+
fwd = forwarder.NewInterceptor(pp, targetHost, cp)
179193
} else {
194+
fwd = forwarder.NewInterceptor(pp, "", 0)
180195
cp = ic.ContainerPort
181196
}
182-
lisAddr, err := pp.Addr()
183-
if err != nil {
184-
return err
185-
}
186-
// Redirect non-intercepted traffic to the pod, so that injected sidecars that hijack the ports for
187-
// incoming connections will continue to work.
188-
targetHost := s.PodIP()
189197

190-
fwd := forwarder.NewInterceptor(lisAddr, targetHost, cp)
191198
dgroup.ParentGroup(ctx).Go(fmt.Sprintf("forward-%s", iputil.JoinHostPort(cn.Name, cp)), func(ctx context.Context) error {
192199
return fwd.Serve(tunnel.WithPool(ctx, tunnel.NewPool()), nil)
193200
})

cmd/traffic/cmd/agent/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func (s *state) ReportMetrics(ctx context.Context, metrics *rpc.TunnelMetrics) {
118118
mCtx, mCancel := context.WithTimeout(context.WithoutCancel(ctx), time.Second)
119119
defer mCancel()
120120
_, err := s.manager.ReportMetrics(mCtx, metrics)
121-
if err != nil {
121+
if err != nil && status.Code(err) != codes.Canceled {
122122
dlog.Errorf(ctx, "ReportMetrics failed: %v", err)
123123
}
124124
}()

cmd/traffic/cmd/agent/state_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ package agent_test
22

33
import (
44
"context"
5-
"net"
65
"path/filepath"
76
"testing"
87
"time"
98

109
"github.com/stretchr/testify/assert"
1110
"github.com/stretchr/testify/require"
11+
core "k8s.io/api/core/v1"
1212

1313
"github.com/datawire/dlib/dlog"
1414
rpc "github.com/telepresenceio/telepresence/rpc/v2/manager"
@@ -23,10 +23,7 @@ const (
2323
)
2424

2525
func makeFS(t *testing.T, ctx context.Context) (forwarder.Interceptor, agent.State) {
26-
lAddr, err := net.ResolveTCPAddr("tcp", ":1111")
27-
assert.NoError(t, err)
28-
29-
f := forwarder.NewInterceptor(lAddr, appHost, appPort)
26+
f := forwarder.NewInterceptor(agentconfig.PortAndProto{Proto: core.ProtocolTCP, Port: 1111}, appHost, appPort)
3027
go func() {
3128
if err := f.Serve(context.Background(), nil); err != nil {
3229
dlog.Error(ctx, err)

cmd/traffic/cmd/agentinit/agent_init.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99
"net"
10+
"net/netip"
1011
"os"
1112
"path/filepath"
1213
"strconv"
@@ -19,7 +20,6 @@ import (
1920
"github.com/datawire/dlib/dlog"
2021
"github.com/telepresenceio/telepresence/v2/pkg/agentconfig"
2122
"github.com/telepresenceio/telepresence/v2/pkg/dos"
22-
"github.com/telepresenceio/telepresence/v2/pkg/iputil"
2323
"github.com/telepresenceio/telepresence/v2/pkg/version"
2424
)
2525

@@ -45,7 +45,7 @@ func loadConfig(ctx context.Context) (*config, error) {
4545
return &c, nil
4646
}
4747

48-
func (c *config) configureIptables(ctx context.Context, iptables *iptables.IPTables, loopback, localHostCIDR, podIP string) error {
48+
func (c *config) configureIptables(ctx context.Context, iptables *iptables.IPTables, loopback string, localHostCIDR netip.Prefix, podIP netip.Addr) error {
4949
// These iptables rules implement routing such that a packet directed to the appPort will hit the agentPort instead.
5050
// If there's no mesh this is simply request -> agent -> app (or intercept)
5151
// However, if there's a service mesh we want to make sure we don't bypass the mesh, so the traffic
@@ -114,8 +114,8 @@ func (c *config) configureIptables(ctx context.Context, iptables *iptables.IPTab
114114
// loop it back into the agent.
115115
dlog.Debugf(ctx, "output DNAT %s:%d -> %s:%d", podIP, ac.ProxyPort(ic), podIP, ic.ContainerPort)
116116
err = iptables.AppendUnique(nat, outputChain,
117-
"-p", lcProto, "-d", podIP, "--dport", strconv.Itoa(int(ac.ProxyPort(ic))),
118-
"-j", "DNAT", "--to-destination", net.JoinHostPort(podIP, strconv.Itoa(int(ic.ContainerPort))))
117+
"-p", lcProto, "-d", podIP.String(), "--dport", strconv.Itoa(int(ac.ProxyPort(ic))),
118+
"-j", "DNAT", "--to-destination", netip.AddrPortFrom(podIP, ic.ContainerPort).String())
119119
if err != nil {
120120
return fmt.Errorf("failed to append rule to %s: %w", outputChain, err)
121121
}
@@ -155,7 +155,7 @@ func (c *config) configureIptables(ctx context.Context, iptables *iptables.IPTab
155155
err = iptables.Insert(nat, "OUTPUT", 1,
156156
"-o", loopback,
157157
"-p", lcProto,
158-
"!", "-d", localHostCIDR,
158+
"!", "-d", localHostCIDR.String(),
159159
"-m", "owner", "--uid-owner", agentUID,
160160
"-j", outputChain)
161161
if err != nil {
@@ -213,11 +213,15 @@ func Main(ctx context.Context, args ...string) error {
213213
return err
214214
}
215215
proto := iptables.ProtocolIPv4
216-
localhostCIDR := "127.0.0.1/32"
217-
podIP := os.Getenv("POD_IP")
218-
if len(iputil.Parse(podIP)) == 16 {
216+
localhostCIDR := netip.PrefixFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), 32)
217+
podIP, err := netip.ParseAddr(os.Getenv("POD_IP"))
218+
if err != nil {
219+
dlog.Error(ctx, err)
220+
return err
221+
}
222+
if podIP.Is6() {
219223
proto = iptables.ProtocolIPv6
220-
localhostCIDR = "::1/128"
224+
localhostCIDR = netip.PrefixFrom(netip.IPv6Loopback(), 128)
221225
}
222226
it, err := iptables.NewWithProtocol(proto)
223227
if err != nil {

cmd/traffic/cmd/manager/cluster/info.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,11 @@ func getInjectorSvcIP(ctx context.Context, env *managerutil.Env, client v1.CoreV
348348
break
349349
}
350350
}
351-
return iputil.Parse(sc.Spec.ClusterIP), p, nil
351+
ip, err := netip.ParseAddr(sc.Spec.ClusterIP)
352+
if err != nil {
353+
return nil, 0, err
354+
}
355+
return ip.AsSlice(), p, nil
352356
}
353357

354358
func (oi *info) watchPodSubnets(ctx context.Context) {

0 commit comments

Comments
 (0)