Skip to content

Commit

Permalink
Merge pull request #1755 from fluxcd/headless-svc
Browse files Browse the repository at this point in the history
  • Loading branch information
aryan9600 authored Jan 14, 2025
2 parents ff4051f + 45618b9 commit d99d37b
Show file tree
Hide file tree
Showing 7 changed files with 26 additions and 0 deletions.
3 changes: 3 additions & 0 deletions artifacts/flagger/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ spec:
portDiscovery:
description: Enable port dicovery
type: boolean
headless:
description: Headless if set to true, generates headless Kubernetes services.
type: boolean
timeout:
description: HTTP or gRPC request timeout
type: string
Expand Down
3 changes: 3 additions & 0 deletions charts/flagger/crds/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ spec:
portDiscovery:
description: Enable port dicovery
type: boolean
headless:
description: Headless if set to true, generates headless Kubernetes services.
type: boolean
timeout:
description: HTTP or gRPC request timeout
type: string
Expand Down
5 changes: 5 additions & 0 deletions docs/gitbook/usage/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ spec:
appProtocol: http
targetPort: 9898
portDiscovery: true
headless: false
```

The container port from the target workload should match the `service.port` or `service.targetPort`.
Expand All @@ -155,6 +156,7 @@ The `service.targetPort` can be a container port number or name.
The `service.portName` is optional (defaults to `http`), if your workload uses gRPC then set the port name to `grpc`.
The `service.appProtocol` is optional, more details can be found [here](https://kubernetes.io/docs/concepts/services-networking/service/#application-protocol).


If port discovery is enabled, Flagger scans the target workload and extracts the containers ports
excluding the port specified in the canary service and service mesh sidecar ports.
These ports will be used when generating the ClusterIP services.
Expand Down Expand Up @@ -204,6 +206,9 @@ Note that the `apex` annotations are added to both the generated Kubernetes Serv
generated service mesh/ingress object. This allows using external-dns with Istio `VirtualServices`
and `TraefikServices`. Beware of configuration conflicts [here](../faq.md#ExternalDNS).

If you want for the generated Kubernetes ClusterIP services to be [headless](https://kubernetes.io/docs/concepts/services-networking/service/#headless-services),
then set `service.headless` to true.

Besides port mapping and metadata, the service specification can
contain URI match and rewrite rules, timeout and retry polices:

Expand Down
3 changes: 3 additions & 0 deletions kustomize/base/flagger/crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,9 @@ spec:
portDiscovery:
description: Enable port dicovery
type: boolean
headless:
description: Headless if set to true, generates headless Kubernetes services.
type: boolean
timeout:
description: HTTP or gRPC request timeout
type: string
Expand Down
5 changes: 5 additions & 0 deletions pkg/apis/flagger/v1beta1/canary.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@ type CanaryService struct {
// PortDiscovery adds all container ports to the generated Kubernetes service
PortDiscovery bool `json:"portDiscovery"`

// Headless if set to true, generates headless Kubernetes services.
// ref: https://kubernetes.io/docs/concepts/services-networking/service/#headless-services
// +optional
Headless bool `json:"headless,omitempty"`

// Timeout of the HTTP or gRPC request
// +optional
Timeout string `json:"timeout,omitempty"`
Expand Down
3 changes: 3 additions & 0 deletions pkg/router/kubernetes_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ func (c *KubernetesDefaultRouter) reconcileService(canary *flaggerv1.Canary, nam
},
},
}
if canary.Spec.Service.Headless {
svcSpec.ClusterIP = "None"
}

if v := canary.Spec.Service.AppProtocol; v != "" {
svcSpec.Ports[0].AppProtocol = &v
Expand Down
4 changes: 4 additions & 0 deletions pkg/router/kubernetes_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import (

func TestServiceRouter_Create(t *testing.T) {
mocks := newFixture(nil)
mocks.canary.Spec.Service.Headless = true

router := &KubernetesDefaultRouter{
kubeClient: mocks.kubeClient,
flaggerClient: mocks.flaggerClient,
Expand All @@ -53,11 +55,13 @@ func TestServiceRouter_Create(t *testing.T) {
assert.Equal(t, &appProtocol, canarySvc.Spec.Ports[0].AppProtocol)
assert.Equal(t, "http", canarySvc.Spec.Ports[0].Name)
assert.Equal(t, int32(9898), canarySvc.Spec.Ports[0].Port)
assert.Equal(t, "None", canarySvc.Spec.ClusterIP)

primarySvc, err := mocks.kubeClient.CoreV1().Services("default").Get(context.TODO(), "podinfo-primary", metav1.GetOptions{})
require.NoError(t, err)
assert.Equal(t, "http", primarySvc.Spec.Ports[0].Name)
assert.Equal(t, int32(9898), primarySvc.Spec.Ports[0].Port)
assert.Equal(t, "None", primarySvc.Spec.ClusterIP)
}

func TestServiceRouter_Update(t *testing.T) {
Expand Down

0 comments on commit d99d37b

Please sign in to comment.