Skip to content

Commit 861963e

Browse files
author
Patryk Strusiewicz-Surmacki
committed
Option for using egress only for originating connections.
Signed-off-by: Patryk Strusiewicz-Surmacki <patryk.pawel.strusiewicz-surmacki@external.telekom.de>
1 parent d801193 commit 861963e

23 files changed

+1376
-481
lines changed

docs/usage.md

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,25 @@ Coil is a Kubernetes-native application and can be controlled with `kubectl`.
66

77
For installation, read [setup.md](setup.md).
88

9-
- [Admin role](#admin-role)
10-
- [Address pools](#address-pools)
11-
- [AddressPool custom resource](#addresspool-custom-resource)
12-
- [The default pool](#the-default-pool)
13-
- [Using non-default pools](#using-non-default-pools)
14-
- [Adding addresses to a pool](#adding-addresses-to-a-pool)
15-
- [Address blocks](#address-blocks)
16-
- [Importing address blocks as routes](#importing-address-blocks-as-routes)
17-
- [Egress NAT](#egress-nat)
18-
- [How it works](#how-it-works)
19-
- [Egress custom resource](#egress-custom-resource)
20-
- [Client Pods](#client-pods)
21-
- [Use NetworkPolicy to prohibit NAT usage](#use-networkpolicy-to-prohibit-nat-usage)
22-
- [Session affinity](#session-affinity)
23-
- [Metrics](#metrics)
24-
- [How to scrape metrics](#how-to-scrape-metrics)
25-
- [Dashboards](#dashboards)
9+
- [User manual](#user-manual)
10+
- [Admin role](#admin-role)
11+
- [Address pools](#address-pools)
12+
- [AddressPool custom resource](#addresspool-custom-resource)
13+
- [The default pool](#the-default-pool)
14+
- [Using non-default pools](#using-non-default-pools)
15+
- [Adding addresses to a pool](#adding-addresses-to-a-pool)
16+
- [Address blocks](#address-blocks)
17+
- [Importing address blocks as routes](#importing-address-blocks-as-routes)
18+
- [Egress NAT](#egress-nat)
19+
- [How it works](#how-it-works)
20+
- [Egress custom resource](#egress-custom-resource)
21+
- [Client Pods](#client-pods)
22+
- [Use NetworkPolicy to prohibit NAT usage](#use-networkpolicy-to-prohibit-nat-usage)
23+
- [Session affinity](#session-affinity)
24+
- [Use egress only for connections originating on the client](#use-egress-only-for-connections-originating-on-the-client)
25+
- [Metrics](#metrics)
26+
- [How to scrape metrics](#how-to-scrape-metrics)
27+
- [Dashboards](#dashboards)
2628

2729
## Admin role
2830

@@ -201,6 +203,7 @@ spec:
201203
destinations:
202204
- 172.20.0.0/16
203205
- fd04::/64
206+
originatingOnly: true
204207
replicas: 3
205208
strategy:
206209
type: RollingUpdate
@@ -242,6 +245,7 @@ You may customize the container of egress Pods as shown in the above example.
242245
| Field | Type | Description |
243246
| ----------------------- | ------------------------- | -------------------------------------------------------------------- |
244247
| `destinations` | `[]string` | IP subnets where the packets are SNATed and sent. |
248+
| `originatingOnly` | `bool` | If true, only connections originating in the pod will use egress. |
245249
| `replicas` | `int` | Copied to Deployment's `spec.replicas`. Default is 1. |
246250
| `strategy` | [DeploymentStrategy][] | Copied to Deployment's `spec.strategy`. |
247251
| `template` | [PodTemplateSpec][] | Copied to Deployment's `spec.template`. |
@@ -312,6 +316,17 @@ spec:
312316

313317
The default timeout seconds is 10800 (= 3 hours).
314318

319+
### Use egress only for connections originating on the client
320+
321+
If `originatingOnly` is set `true` in the egress definition, only connections originating on the client
322+
or incoming onto `fou` interface will use egress FOU interface to send data.
323+
In case of incomming connections, the same interface will be used for egress traffic -
324+
e.g. if connection will be estabilished on `eth0`, the traffic will not be routed through `fou`,
325+
but will be handled by `eth0`.
326+
327+
Please be aware that, in case of multiple `egress` resources attached to the client pod, if at least one
328+
`egress` will have `originatingOnly: true` set, all the other egresses will inherit this behavior.
329+
315330
## Metrics
316331

317332
Coil exposes two types of Prometheus metrics.

v2/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ PODNSLIST = pod1 pod2 pod3 pod4 pod5 pod6
3232
NATNSLIST = nat-client nat-router nat-egress nat-target
3333
OTHERNSLIST = test-egress-dual test-egress-v4 test-egress-v6 \
3434
test-client-dual test-client-v4 test-client-v6 test-client-custom \
35+
test-client-dual-oo test-client-v4-oo test-client-v6-oo test-client-custom-oo \
3536
test-fou-dual test-fou-v4 test-fou-v6
3637
WGET_OPTIONS := --retry-on-http-error=503 --retry-connrefused --no-verbose
3738
WGET := wget $(WGET_OPTIONS)

v2/api/v2/egress_types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ type EgressSpec struct {
6767
// PodDisruptionBudget is an optional PodDisruptionBudget for Egress NAT pods.
6868
// +optional
6969
PodDisruptionBudget *EgressPDBSpec `json:"podDisruptionBudget,omitempty"`
70+
71+
// OriginatingOnly indicates connections that should use egress interface.
72+
// If set to true, only outgoing connections that originate in the egress client will use egress.
73+
// The default is false.
74+
// +optional
75+
OriginatingOnly bool `json:"originatingOnly,omitempty"`
7076
}
7177

7278
// EgressPodTemplate defines pod template for Egress

v2/config/crd/bases/coil.cybozu.com_egresses.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ spec:
5252
If set to true, the kernel picks a flow based on the flow hash of the encapsulated packet.
5353
The default is false.
5454
type: boolean
55+
originatingOnly:
56+
description: |-
57+
OriginatingOnly indicates connections that should use egress interface.
58+
If set to true, only outgoing connections that originate in the egress client will use egress.
59+
The default is false.
60+
type: boolean
5561
podDisruptionBudget:
5662
description: PodDisruptionBudget is an optional PodDisruptionBudget for Egress NAT pods.
5763
properties:

v2/config/crd/egress/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# It should be run by config/default
44
resources:
55
# [EGRESS] Following files should be uncommented to enable Egress NAT features.
6+
- ../bases/coil.cybozu.com_addresspools.yaml
67
- ../bases/coil.cybozu.com_egresses.yaml
78
# +kubebuilder:scaffold:crdkustomizeresource
89

v2/controllers/egress_watcher.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,10 @@ func (r *EgressWatcher) reconcileEgressClient(ctx context.Context, eg *coilv2.Eg
136136
}
137137

138138
type gwNets struct {
139-
gateway net.IP
140-
networks []*net.IPNet
141-
sportAuto bool
139+
gateway net.IP
140+
networks []*net.IPNet
141+
sportAuto bool
142+
originatingOnly bool
142143
}
143144

144145
func (r *EgressWatcher) getHooks(ctx context.Context, eg *coilv2.Egress, logger *logr.Logger) ([]nodenet.SetupHook, error) {
@@ -203,7 +204,7 @@ func (r *EgressWatcher) hook(gwn gwNets, log *logr.Logger) func(ipv4, ipv6 net.I
203204
if err != nil {
204205
return err
205206
}
206-
if err := cl.AddEgress(link, gwn.networks); err != nil {
207+
if err := cl.AddEgress(link, gwn.networks, gwn.originatingOnly); err != nil {
207208
return err
208209
}
209210

v2/e2e/Makefile

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,26 @@ setup-nodes:
113113
TEST_IPAM ?= true
114114
TEST_EGRESS ?= true
115115
.PHONY: test
116-
test: setup-echotest
116+
test: setup-echotest setup-echotest-image
117117
TEST_IPAM=$(TEST_IPAM) TEST_EGRESS=$(TEST_EGRESS) go test -count 1 -v . -args -ginkgo.progress -ginkgo.v
118118

119-
.PHONY: setup-echotest
120-
setup-echotest:
119+
.PHONY: build-echotest
120+
build-echotest:
121121
CGO_ENABLED=0 GOARCH=$(ARCH) GOOS=linux go build -o echotest ./echo-server
122+
123+
.PHONY: setup-echotest
124+
setup-echotest: build-echotest
122125
docker cp echotest coil-control-plane:/usr/local/bin
123126
rm echotest
124127

128+
.PHONY: build-echotest-image
129+
build-echotest-image:
130+
TARGETARCH=$(ARCH) docker build -t echotest:dev -f echo-server/Dockerfile echo-server/.
131+
132+
.PHONY: setup-echotest-image
133+
setup-echotest-image: build-echotest-image
134+
$(KIND) load docker-image echotest:dev --name coil
135+
125136
.PHONY: logs
126137
logs:
127138
rm -rf logs.tar.gz logs

0 commit comments

Comments
 (0)