Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chores(k8s-backend): add svc ip families config #940

Merged
merged 3 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .local-dev/config/ns.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ components:
type: traefik
traefik:
priorityOffset: 0
service:
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
tls:
type: traefik
traefik:
Expand Down
16 changes: 8 additions & 8 deletions .local-manifest/traefik/dashboard-ingress-route.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ spec:
- websecure
routes:
- kind: Rule
match: Host(`traefik-dashboard.local.trapti.tech`)
match: Host(`traefik.local.trapti.tech`)
services:
- namespace: traefik
kind: Service
name: dashboard
port: dashboard
scheme: http
strategy: RoundRobin
weight: 1
- kind: TraefikService
name: dashboard@internal
- kind: Rule
match: Host(`traefik.local.trapti.tech`) && PathPrefix(`/api`)
services:
- kind: TraefikService
name: api@internal
13 changes: 0 additions & 13 deletions .local-manifest/traefik/dashboard-service.yaml

This file was deleted.

1 change: 0 additions & 1 deletion .local-manifest/traefik/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ resources:
- traefik-role-binding.yaml
- traefik-stateful-set.yaml
- traefik-service.yaml
- dashboard-service.yaml
- dashboard-ingress-route.yaml
10 changes: 8 additions & 2 deletions .local-manifest/traefik/traefik-cluster-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ rules:
- ""
resources:
- services
- endpoints
- secrets
- nodes
verbs:
- get
- list
Expand All @@ -33,7 +33,6 @@ rules:
- update
- apiGroups:
- traefik.io
- traefik.containo.us
resources:
- middlewares
- middlewaretcps
Expand All @@ -49,3 +48,10 @@ rules:
- get
- list
- watch
- apiGroups:
- discovery.k8s.io
resources:
- endpointslices
verbs:
- list
- watch
2 changes: 1 addition & 1 deletion .local-manifest/traefik/traefik-stateful-set.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:

containers:
- name: traefik
image: traefik:2.10
image: traefik:3.1
args:
- --api.insecure
- --providers.kubernetescrd
Expand Down
4 changes: 4 additions & 0 deletions cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ func init() {

viper.SetDefault("components.controller.k8s.routing.type", "traefik")
viper.SetDefault("components.controller.k8s.routing.traefik.priorityOffset", 0)

viper.SetDefault("components.controller.k8s.service.ipFamilies", nil)
viper.SetDefault("components.controller.k8s.service.ipFamilyPolicy", "PreferDualStack")

viper.SetDefault("components.controller.k8s.tls.type", "traefik")
viper.SetDefault("components.controller.k8s.tls.traefik.certResolver", "nsresolver")
viper.SetDefault("components.controller.k8s.tls.traefik.wildcard.domains", nil)
Expand Down
36 changes: 36 additions & 0 deletions pkg/infrastructure/backend/k8simpl/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,15 @@ type Config struct {
PriorityOffset int `mapstructure:"priorityOffset" yaml:"priorityOffset"`
} `mapstructure:"traefik" yaml:"traefik"`
} `mapstructure:"routing" yaml:"routing"`
// Service section defines Service (L4) routing settings.
Service struct {
// IPFamilies defines ipFamilies field for the service objects.
// Allowed values: IPv4, IPv6
IPFamilies []v1.IPFamily `mapstructure:"ipFamilies" yaml:"ipFamilies"`
// IPFamilyPolicy defines ipFamilyPolicy field for the service objects.
// Allowed values: "", "SingleStack", "PreferDualStack", "RequireDualStack"
IPFamilyPolicy v1.IPFamilyPolicy `mapstructure:"ipFamilyPolicy" yaml:"ipFamilyPolicy"`
} `mapstructure:"service" yaml:"service"`
// TLS section defines tls setting for user app ingress.
TLS struct {
// Type defines which provider is responsible for obtaining http certificates.
Expand Down Expand Up @@ -264,6 +273,17 @@ func (c *Config) selectNode(appID string) map[string]string {
return map[string]string{hostnameNodeSelectorLabel: host}
}

func (c *Config) serviceIPFamilies() []v1.IPFamily {
return c.Service.IPFamilies
}

func (c *Config) serviceIPFamilyPolicy() *v1.IPFamilyPolicy {
if c.Service.IPFamilyPolicy == "" {
return nil
}
return lo.ToPtr(c.Service.IPFamilyPolicy)
}

var tolerationOperatorMapper = mapper.MustNewValueMapper(map[string]v1.TolerationOperator{
string(v1.TolerationOpEqual): v1.TolerationOpEqual,
string(v1.TolerationOpExists): v1.TolerationOpExists,
Expand Down Expand Up @@ -347,6 +367,22 @@ func (c *Config) Validate() error {
default:
return errors.New(fmt.Sprintf("k8s.routing.type is invalid: %s", c.Routing.Type))
}

for _, family := range c.Service.IPFamilies {
if !lo.Contains([]v1.IPFamily{v1.IPv4Protocol, v1.IPv6Protocol}, family) {
return errors.New(fmt.Sprintf("invalid IPFamily %s", family))
}
}
if !lo.Contains([]v1.IPFamilyPolicy{
// Allow empty value
"",
v1.IPFamilyPolicySingleStack,
v1.IPFamilyPolicyPreferDualStack,
v1.IPFamilyPolicyRequireDualStack,
}, c.Service.IPFamilyPolicy) {
return errors.New(fmt.Sprintf("invalid IPFamily policy: %s", c.Service.IPFamilyPolicy))
}

switch c.TLS.Type {
case tlsTypeTraefik:
if err := c.TLS.Traefik.Wildcard.Domains.Validate(); err != nil {
Expand Down
9 changes: 6 additions & 3 deletions pkg/infrastructure/backend/k8simpl/synchronize_runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@ func (b *Backend) runtimeSpec(app *domain.RuntimeDesiredState) (*appsv1.Stateful
},
Spec: v1.ServiceSpec{
Type: "ClusterIP",
IPFamilyPolicy: lo.ToPtr(v1.IPFamilyPolicyPreferDualStack),
IPFamilies: b.config.serviceIPFamilies(),
IPFamilyPolicy: b.config.serviceIPFamilyPolicy(),
Selector: appSelector(app.App.ID),
Ports: ds.Map(cont.Ports, func(port v1.ContainerPort) v1.ServicePort {
return v1.ServicePort{
Expand Down Expand Up @@ -186,8 +187,10 @@ func (b *Backend) runtimePortService(app *domain.Application, port *domain.PortP
Labels: b.appLabel(app.ID),
},
Spec: v1.ServiceSpec{
Type: "LoadBalancer",
Selector: appSelector(app.ID),
Type: "LoadBalancer",
IPFamilies: b.config.serviceIPFamilies(),
IPFamilyPolicy: b.config.serviceIPFamilyPolicy(),
Selector: appSelector(app.ID),
Ports: []v1.ServicePort{{
Protocol: protocolMapper.IntoMust(port.Protocol),
Port: int32(port.InternetPort),
Expand Down
Loading