Skip to content

Commit 4314e4b

Browse files
committed
feat: support config LeaderElection strategy
1 parent 2b5f4fb commit 4314e4b

File tree

7 files changed

+128
-1
lines changed

7 files changed

+128
-1
lines changed

config/manager/manager.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,15 @@ spec:
6060
containers:
6161
- image: controller:latest
6262
name: manager
63+
env:
64+
- name: POD_NAMESPACE
65+
valueFrom:
66+
fieldRef:
67+
fieldPath: metadata.namespace
68+
- name: POD_NAME
69+
valueFrom:
70+
fieldRef:
71+
fieldPath: metadata.name
6372
volumeMounts:
6473
- name: config-volume
6574
mountPath: /app/conf/config.yaml

config/samples/config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ controller_name: gateway.api7.io/api7-ingress-controller # The controller name
66
# The default value is "gateway.api7.io/api7-ingress-controller".
77
leader_election_id: "api7-ingress-controller-leader" # The leader election ID for the API7 Ingress Controller.
88
# The default value is "api7-ingress-controller-leader".
9+
leader_election:
10+
lease_duration: 15s # lease_duration is the duration that non-leader candidates will wait
11+
# after observing a leadership renewal until attempting to acquire leadership of a
12+
# leader election.
13+
renew_deadline: 10s # renew_deadline is the time in seconds that the acting controller
14+
# will retry refreshing leadership before giving up.
15+
retry_period: 2s # retry_period is the time in seconds that the acting controller
16+
# will wait between tries of actions with the controller.
17+
disable: false # Whether to disable leader election.
18+
919
ingress_class: api7 # The ingress class name of the API7 Ingress Controller.
1020
ingress_publish_service: "" # The service name of the ingress publish service.
1121
ingress_status_address: [] # The status address of the ingress.

internal/controller/config/config.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import (
77
"os"
88
"strings"
99
"text/template"
10+
"time"
1011

12+
"github.com/api7/api7-ingress-controller/internal/types"
1113
"gopkg.in/yaml.v2"
1214
)
1315

@@ -29,6 +31,16 @@ func NewDefaultConfig() *Config {
2931
ProbeAddr: DefaultProbeAddr,
3032
MetricsAddr: DefaultMetricsAddr,
3133
IngressClass: DefaultIngressClass,
34+
LeaderElection: NewLeaderElection(),
35+
}
36+
}
37+
38+
func NewLeaderElection() *LeaderElection {
39+
return &LeaderElection{
40+
LeaseDuration: types.TimeDuration{Duration: 15 * time.Second},
41+
RenewDeadline: types.TimeDuration{Duration: 10 * time.Second},
42+
RetryPeriod: types.TimeDuration{Duration: 2 * time.Second},
43+
Disable: false,
3244
}
3345
}
3446

internal/controller/config/types.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package config
22

3+
import (
4+
"github.com/api7/api7-ingress-controller/internal/types"
5+
)
6+
37
const (
48
// IngressAPISIXLeader is the default election id for the controller
59
// leader election.
@@ -36,6 +40,7 @@ type Config struct {
3640
IngressClass string `json:"ingress_class" yaml:"ingress_class"`
3741
IngressPublishService string `json:"ingress_publish_service" yaml:"ingress_publish_service"`
3842
IngressStatusAddress []string `json:"ingress_status_address" yaml:"ingress_status_address"`
43+
LeaderElection *LeaderElection `json:"leader_election" yaml:"leader_election"`
3944
}
4045

4146
type GatewayConfig struct {
@@ -49,3 +54,10 @@ type ControlPlaneConfig struct {
4954
Endpoints []string `json:"endpoints" yaml:"endpoints"`
5055
TLSVerify *bool `json:"tls_verify" yaml:"tls_verify"`
5156
}
57+
58+
type LeaderElection struct {
59+
LeaseDuration types.TimeDuration `json:"leaseDuration,omitempty" yaml:"leaseDuration,omitempty"`
60+
RenewDeadline types.TimeDuration `json:"renewDeadline,omitempty" yaml:"renewDeadline,omitempty"`
61+
RetryPeriod types.TimeDuration `json:"retryPeriod,omitempty" yaml:"retryPeriod,omitempty"`
62+
Disable bool `json:"disable,omitempty" yaml:"disable,omitempty"`
63+
}

internal/manager/run.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"k8s.io/apimachinery/pkg/runtime"
1010
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1111
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
12+
"k8s.io/utils/ptr"
1213
ctrl "sigs.k8s.io/controller-runtime"
1314
"sigs.k8s.io/controller-runtime/pkg/healthz"
1415
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
@@ -97,9 +98,12 @@ func Run(ctx context.Context, logger logr.Logger) error {
9798
Metrics: metricsServerOptions,
9899
WebhookServer: webhookServer,
99100
HealthProbeBindAddress: cfg.ProbeAddr,
100-
LeaderElection: true,
101+
LeaderElection: !config.ControllerConfig.LeaderElection.Disable,
101102
LeaderElectionID: cfg.LeaderElectionID,
102103
LeaderElectionNamespace: namespace,
104+
LeaseDuration: ptr.To(config.ControllerConfig.LeaderElection.LeaseDuration.Duration),
105+
RenewDeadline: ptr.To(config.ControllerConfig.LeaderElection.RenewDeadline.Duration),
106+
RetryPeriod: ptr.To(config.ControllerConfig.LeaderElection.RetryPeriod.Duration),
103107
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
104108
// when the Manager ends. This requires the binary to immediately end when the
105109
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly

internal/types/duration.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one or more
2+
// contributor license agreements. See the NOTICE file distributed with
3+
// this work for additional information regarding copyright ownership.
4+
// The ASF licenses this file to You under the Apache License, Version 2.0
5+
// (the "License"); you may not use this file except in compliance with
6+
// the License. You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
package types
16+
17+
import (
18+
"encoding/json"
19+
"time"
20+
)
21+
22+
// TimeDuration is yet another time.Duration but implements json.Unmarshaler
23+
// and json.Marshaler, yaml.Unmarshaler and yaml.Marshaler interfaces so one
24+
// can use "1h", "5s" and etc in their json/yaml configurations.
25+
//
26+
// Note the format to represent time is same as time.Duration.
27+
// See the comments about time.ParseDuration for more details.
28+
type TimeDuration struct {
29+
time.Duration `json:",inline"`
30+
}
31+
32+
func (d *TimeDuration) MarshalJSON() ([]byte, error) {
33+
return json.Marshal(d.Duration.String())
34+
}
35+
36+
func (d *TimeDuration) UnmarshalJSON(data []byte) error {
37+
var value interface{}
38+
if err := json.Unmarshal(data, &value); err != nil {
39+
return err
40+
}
41+
switch v := value.(type) {
42+
case float64:
43+
d.Duration = time.Duration(v)
44+
case string:
45+
dur, err := time.ParseDuration(v)
46+
if err != nil {
47+
return err
48+
}
49+
d.Duration = dur
50+
default:
51+
panic("unknown type")
52+
}
53+
return nil
54+
}
55+
56+
func (d *TimeDuration) MarshalYAML() (interface{}, error) {
57+
return d.Duration.String(), nil
58+
}
59+
60+
func (d *TimeDuration) UnmarshalYAML(unmarshal func(interface{}) error) error {
61+
var s string
62+
if err := unmarshal(&s); err != nil {
63+
return err
64+
}
65+
dur, err := time.ParseDuration(s)
66+
if err != nil {
67+
return err
68+
}
69+
d.Duration = dur
70+
return nil
71+
}

test/e2e/framework/manifests/ingress.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,15 @@ spec:
350350
spec:
351351
containers:
352352
- image: api7/api7-ingress-controller:dev
353+
env:
354+
- name: POD_NAMESPACE
355+
valueFrom:
356+
fieldRef:
357+
fieldPath: metadata.namespace
358+
- name: POD_NAME
359+
valueFrom:
360+
fieldRef:
361+
fieldPath: metadata.name
353362
volumeMounts:
354363
- name: ingress-config
355364
mountPath: /app/conf/config.yaml

0 commit comments

Comments
 (0)