Skip to content

Commit fc590c6

Browse files
authored
Merge pull request #624 from cnvergence/add-flag-channel-size
Allow configuration of transport channel size in agent and server
2 parents e2f6996 + 31dffc5 commit fc590c6

File tree

9 files changed

+69
-29
lines changed

9 files changed

+69
-29
lines changed

cmd/agent/app/options/options.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ type GrpcProxyAgentOptions struct {
7878
// The check is an "unlocked" read but is still use at your own peril.
7979
WarnOnChannelLimit bool
8080

81-
SyncForever bool
81+
SyncForever bool
82+
XfrChannelSize int
8283
}
8384

8485
func (o *GrpcProxyAgentOptions) ClientSetConfig(dialOptions ...grpc.DialOption) *agent.ClientSetConfig {
@@ -93,6 +94,7 @@ func (o *GrpcProxyAgentOptions) ClientSetConfig(dialOptions ...grpc.DialOption)
9394
ServiceAccountTokenPath: o.ServiceAccountTokenPath,
9495
WarnOnChannelLimit: o.WarnOnChannelLimit,
9596
SyncForever: o.SyncForever,
97+
XfrChannelSize: o.XfrChannelSize,
9698
}
9799
}
98100

@@ -119,6 +121,7 @@ func (o *GrpcProxyAgentOptions) Flags() *pflag.FlagSet {
119121
flags.StringVar(&o.AgentIdentifiers, "agent-identifiers", o.AgentIdentifiers, "Identifiers of the agent that will be used by the server when choosing agent. N.B. the list of identifiers must be in URL encoded format. e.g.,host=localhost&host=node1.mydomain.com&cidr=127.0.0.1/16&ipv4=1.2.3.4&ipv4=5.6.7.8&ipv6=:::::&default-route=true")
120122
flags.BoolVar(&o.WarnOnChannelLimit, "warn-on-channel-limit", o.WarnOnChannelLimit, "Turns on a warning if the system is going to push to a full channel. The check involves an unsafe read.")
121123
flags.BoolVar(&o.SyncForever, "sync-forever", o.SyncForever, "If true, the agent continues syncing, in order to support server count changes.")
124+
flags.IntVar(&o.XfrChannelSize, "xfr-channel-size", 150, "Set the size of the channel for transferring data between the agent and the proxy server.")
122125
return flags
123126
}
124127

@@ -144,6 +147,7 @@ func (o *GrpcProxyAgentOptions) Print() {
144147
klog.V(1).Infof("AgentIdentifiers set to %s.\n", util.PrettyPrintURL(o.AgentIdentifiers))
145148
klog.V(1).Infof("WarnOnChannelLimit set to %t.\n", o.WarnOnChannelLimit)
146149
klog.V(1).Infof("SyncForever set to %v.\n", o.SyncForever)
150+
klog.V(1).Infof("ChannelSize set to %d.\n", o.XfrChannelSize)
147151
}
148152

149153
func (o *GrpcProxyAgentOptions) Validate() error {
@@ -177,6 +181,9 @@ func (o *GrpcProxyAgentOptions) Validate() error {
177181
if o.AdminServerPort <= 0 {
178182
return fmt.Errorf("admin server port %d must be greater than 0", o.AdminServerPort)
179183
}
184+
if o.XfrChannelSize <= 0 {
185+
return fmt.Errorf("channel size %d must be greater than 0", o.XfrChannelSize)
186+
}
180187
if o.EnableContentionProfiling && !o.EnableProfiling {
181188
return fmt.Errorf("if --enable-contention-profiling is set, --enable-profiling must also be set")
182189
}
@@ -235,6 +242,7 @@ func NewGrpcProxyAgentOptions() *GrpcProxyAgentOptions {
235242
ServiceAccountTokenPath: "",
236243
WarnOnChannelLimit: false,
237244
SyncForever: false,
245+
XfrChannelSize: 150,
238246
}
239247
return &o
240248
}

cmd/agent/app/options/options_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,11 @@ package options
1818

1919
import (
2020
"fmt"
21-
"github.com/stretchr/testify/assert"
2221
"reflect"
2322
"testing"
2423
"time"
24+
25+
"github.com/stretchr/testify/assert"
2526
)
2627

2728
/*
@@ -49,6 +50,7 @@ func TestDefaultServerOptions(t *testing.T) {
4950
assertDefaultValue(t, "ServiceAccountTokenPath", defaultAgentOptions.ServiceAccountTokenPath, "")
5051
assertDefaultValue(t, "WarnOnChannelLimit", defaultAgentOptions.WarnOnChannelLimit, false)
5152
assertDefaultValue(t, "SyncForever", defaultAgentOptions.SyncForever, false)
53+
assertDefaultValue(t, "XfrChannelSize", defaultAgentOptions.XfrChannelSize, 150)
5254
}
5355

5456
func assertDefaultValue(t *testing.T, fieldName string, actual, expected interface{}) {
@@ -145,6 +147,14 @@ func TestValidate(t *testing.T) {
145147
},
146148
expected: fmt.Errorf("if --enable-contention-profiling is set, --enable-profiling must also be set"),
147149
},
150+
"ZeroXfrChannelSize": {
151+
fieldMap: map[string]interface{}{"XfrChannelSize": 0},
152+
expected: fmt.Errorf("channel size 0 must be greater than 0"),
153+
},
154+
"NegativeXfrChannelSize": {
155+
fieldMap: map[string]interface{}{"XfrChannelSize": -10},
156+
expected: fmt.Errorf("channel size -10 must be greater than 0"),
157+
},
148158
} {
149159
t.Run(desc, func(t *testing.T) {
150160
testAgentOptions := NewGrpcProxyAgentOptions()

cmd/server/app/options/options.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ type ProxyRunOptions struct {
100100
// also checks if given comma separated list contains cipher from tls.InsecureCipherSuites().
101101
// NOTE that cipher suites are not configurable for TLS1.3,
102102
// see: https://pkg.go.dev/crypto/tls#Config, so in that case, this option won't have any effect.
103-
CipherSuites []string
103+
CipherSuites []string
104+
XfrChannelSize int
104105
}
105106

106107
func (o *ProxyRunOptions) Flags() *pflag.FlagSet {
@@ -136,6 +137,7 @@ func (o *ProxyRunOptions) Flags() *pflag.FlagSet {
136137
flags.StringVar(&o.AuthenticationAudience, "authentication-audience", o.AuthenticationAudience, "Expected agent's token authentication audience (used with agent-namespace, agent-service-account, kubeconfig).")
137138
flags.StringVar(&o.ProxyStrategies, "proxy-strategies", o.ProxyStrategies, "The list of proxy strategies used by the server to pick an agent/tunnel, available strategies are: default, destHost, defaultRoute.")
138139
flags.StringSliceVar(&o.CipherSuites, "cipher-suites", o.CipherSuites, "The comma separated list of allowed cipher suites. Has no effect on TLS1.3. Empty means allow default list.")
140+
flags.IntVar(&o.XfrChannelSize, "xfr-channel-size", o.XfrChannelSize, "The size of the two KNP server channels used in server for transferring data. One channel is for data coming from the Kubernetes API Server, and the other one is for data coming from the KNP agent.")
139141

140142
flags.Bool("warn-on-channel-limit", true, "This behavior is now thread safe and always on. This flag will be removed in a future release.")
141143
flags.MarkDeprecated("warn-on-channel-limit", "This behavior is now thread safe and always on. This flag will be removed in a future release.")
@@ -175,6 +177,7 @@ func (o *ProxyRunOptions) Print() {
175177
klog.V(1).Infof("KubeconfigBurst set to %d.\n", o.KubeconfigBurst)
176178
klog.V(1).Infof("ProxyStrategies set to %q.\n", o.ProxyStrategies)
177179
klog.V(1).Infof("CipherSuites set to %q.\n", o.CipherSuites)
180+
klog.V(1).Infof("XfrChannelSize set to %d.\n", o.XfrChannelSize)
178181
}
179182

180183
func (o *ProxyRunOptions) Validate() error {
@@ -297,7 +300,9 @@ func (o *ProxyRunOptions) Validate() error {
297300
if _, err := server.ParseProxyStrategies(o.ProxyStrategies); err != nil {
298301
return fmt.Errorf("invalid proxy strategies: %v", err)
299302
}
300-
303+
if o.XfrChannelSize <= 0 {
304+
return fmt.Errorf("channel size %d must be greater than 0", o.XfrChannelSize)
305+
}
301306
// validate the cipher suites
302307
if len(o.CipherSuites) != 0 {
303308
acceptedCiphers := util.GetAcceptedCiphers()
@@ -345,6 +350,7 @@ func NewProxyRunOptions() *ProxyRunOptions {
345350
AuthenticationAudience: "",
346351
ProxyStrategies: "default",
347352
CipherSuites: make([]string, 0),
353+
XfrChannelSize: 10,
348354
}
349355
return &o
350356
}

cmd/server/app/options/options_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ func TestDefaultServerOptions(t *testing.T) {
6161
assertDefaultValue(t, "AuthenticationAudience", defaultServerOptions.AuthenticationAudience, "")
6262
assertDefaultValue(t, "ProxyStrategies", defaultServerOptions.ProxyStrategies, "default")
6363
assertDefaultValue(t, "CipherSuites", defaultServerOptions.CipherSuites, make([]string, 0))
64+
assertDefaultValue(t, "XfrChannelSize", defaultServerOptions.XfrChannelSize, 10)
65+
6466
}
6567

6668
func assertDefaultValue(t *testing.T, fieldName string, actual, expected interface{}) {
@@ -155,6 +157,16 @@ func TestValidate(t *testing.T) {
155157
value: "invalid",
156158
expected: fmt.Errorf("invalid proxy strategies: unknown proxy strategy: invalid"),
157159
},
160+
"ZeroXfrChannelSize": {
161+
field: "XfrChannelSize",
162+
value: 0,
163+
expected: fmt.Errorf("channel size 0 must be greater than 0"),
164+
},
165+
"NegativeXfrChannelSize": {
166+
field: "XfrChannelSize",
167+
value: -10,
168+
expected: fmt.Errorf("channel size -10 must be greater than 0"),
169+
},
158170
} {
159171
t.Run(desc, func(t *testing.T) {
160172
testServerOptions := NewProxyRunOptions()

cmd/server/app/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func (p *Proxy) Run(o *options.ProxyRunOptions, stopCh <-chan struct{}) error {
132132
if err != nil {
133133
return err
134134
}
135-
p.server = server.NewProxyServer(o.ServerID, ps, int(o.ServerCount), authOpt)
135+
p.server = server.NewProxyServer(o.ServerID, ps, int(o.ServerCount), authOpt, o.XfrChannelSize)
136136

137137
frontendStop, err := p.runFrontendServer(ctx, o, p.server)
138138
if err != nil {

pkg/agent/client.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import (
4343
)
4444

4545
const dialTimeout = 5 * time.Second
46-
const xfrChannelSize = 150
4746

4847
// endpointConn tracks a connection from agent to node network.
4948
type endpointConn struct {
@@ -68,7 +67,7 @@ func (e *endpointConn) send(msg []byte) {
6867
klog.InfoS("Recovered from attempt to write to closed channel")
6968
}
7069
}()
71-
if e.warnChLim && len(e.dataCh) >= xfrChannelSize {
70+
if e.warnChLim && len(e.dataCh) >= cap(e.dataCh) {
7271
klog.V(2).InfoS("Data channel on agent is full", "connectionID", e.connID)
7372
}
7473

@@ -377,7 +376,7 @@ func (a *Client) Serve() {
377376
dialResp.GetDialResponse().Random = dialReq.Random
378377

379378
connID := atomic.AddInt64(&a.nextConnID, 1)
380-
dataCh := make(chan []byte, xfrChannelSize)
379+
dataCh := make(chan []byte, a.cs.xfrChannelSize)
381380
dialDone := make(chan struct{})
382381
eConn := &endpointConn{
383382
dataCh: dataCh,

pkg/agent/clientset.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ type ClientSet struct {
6161
// by the server when choosing agent
6262

6363
warnOnChannelLimit bool
64+
xfrChannelSize int
6465

6566
syncForever bool // Continue syncing (support dynamic server count).
6667
}
@@ -141,6 +142,7 @@ type ClientSetConfig struct {
141142
ServiceAccountTokenPath string
142143
WarnOnChannelLimit bool
143144
SyncForever bool
145+
XfrChannelSize int
144146
}
145147

146148
func (cc *ClientSetConfig) NewAgentClientSet(drainCh, stopCh <-chan struct{}) *ClientSet {
@@ -157,6 +159,7 @@ func (cc *ClientSetConfig) NewAgentClientSet(drainCh, stopCh <-chan struct{}) *C
157159
warnOnChannelLimit: cc.WarnOnChannelLimit,
158160
syncForever: cc.SyncForever,
159161
drainCh: drainCh,
162+
xfrChannelSize: cc.XfrChannelSize,
160163
stopCh: stopCh,
161164
}
162165
}

pkg/server/server.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ import (
4747
"sigs.k8s.io/apiserver-network-proxy/proto/header"
4848
)
4949

50-
const xfrChannelSize = 10
51-
5250
type key int
5351

5452
type GrpcFrontend struct {
@@ -218,6 +216,7 @@ type ProxyServer struct {
218216

219217
// TODO: move strategies into BackendStorage
220218
proxyStrategies []ProxyStrategy
219+
xfrChannelSize int
221220
}
222221

223222
// AgentTokenAuthenticationOptions contains list of parameters required for agent token based authentication
@@ -376,7 +375,7 @@ func (s *ProxyServer) removeEstablishedForStream(streamUID string) []*ProxyClien
376375
}
377376

378377
// NewProxyServer creates a new ProxyServer instance
379-
func NewProxyServer(serverID string, proxyStrategies []ProxyStrategy, serverCount int, agentAuthenticationOptions *AgentTokenAuthenticationOptions) *ProxyServer {
378+
func NewProxyServer(serverID string, proxyStrategies []ProxyStrategy, serverCount int, agentAuthenticationOptions *AgentTokenAuthenticationOptions, channelSize int) *ProxyServer {
380379
var bms []BackendManager
381380
for _, ps := range proxyStrategies {
382381
switch ps {
@@ -401,6 +400,7 @@ func NewProxyServer(serverID string, proxyStrategies []ProxyStrategy, serverCoun
401400
// use the first backend-manager as the Readiness Manager
402401
Readiness: bms[0],
403402
proxyStrategies: proxyStrategies,
403+
xfrChannelSize: channelSize,
404404
}
405405
}
406406

@@ -417,7 +417,7 @@ func (s *ProxyServer) Proxy(stream client.ProxyService_ProxyServer) error {
417417
streamUID := uuid.New().String()
418418
klog.V(5).InfoS("Proxy request from client", "userAgent", userAgent, "serverID", s.serverID, "streamUID", streamUID)
419419

420-
recvCh := make(chan *client.Packet, xfrChannelSize)
420+
recvCh := make(chan *client.Packet, s.xfrChannelSize)
421421
stopCh := make(chan error, 1)
422422

423423
frontend := GrpcFrontend{
@@ -745,7 +745,7 @@ func (s *ProxyServer) Connect(stream agent.AgentService_ConnectServer) error {
745745
s.addBackend(backend)
746746
defer s.removeBackend(backend)
747747

748-
recvCh := make(chan *client.Packet, xfrChannelSize)
748+
recvCh := make(chan *client.Packet, s.xfrChannelSize)
749749

750750
go runpprof.Do(context.Background(), labels, func(context.Context) { s.serveRecvBackend(backend, agentID, recvCh) })
751751

0 commit comments

Comments
 (0)