Skip to content

Feat: Add support for stickiness for primary deployment in Istio#1861

Merged
stefanprodan merged 5 commits intofluxcd:mainfrom
renatovassaomb:rv/istio-primary-cookie-name-support
Dec 18, 2025
Merged

Feat: Add support for stickiness for primary deployment in Istio#1861
stefanprodan merged 5 commits intofluxcd:mainfrom
renatovassaomb:rv/istio-primary-cookie-name-support

Conversation

@renatovassaomb
Copy link
Copy Markdown
Contributor

Summary

Adding support to configure stickiness for primary deployment for Istio Provider.

Currently the implementation is only available for Gateway API provider.

Changes

  • Adds primarySessionAffinityCookie field to Canary CRD status.
  • Update this field in Gateway API Router.
  • Adds support for stickiness for primary deployment in Istio Router.

Testing

  1. Init workloads
bash test/workloads/init.sh
  1. Create Canary resource
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
  name: podinfo
  namespace: test
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: podinfo
  progressDeadlineSeconds: 60
  service:
    port: 9898
    portDiscovery: true
  skipAnalysis: false
  analysis:
    interval: 15s
    threshold: 15
    maxWeight: 30
    stepWeight: 10
    sessionAffinity:
      cookieName: canary-cookie
      primaryCookieName: primary-cookie
    webhooks:
      - name: load-test
        url: http://flagger-loadtester.test/
        timeout: 5s
        metadata:
          type: cmd
          cmd: "hey -z 10m -q 10 -c 2 http://podinfo.test:9898/"
          logCmdOutput: "true"
  1. Trigger canary release
kubectl -n test set image deployment/podinfo podinfod=ghcr.io/stefanprodan/podinfo:6.0.1 
  1. Wait for canary to advance and check VirtualService routes
> kubectl get vs -n test podinfo -o yaml

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  annotations:
    helm.toolkit.fluxcd.io/driftDetection: disabled
    kustomize.toolkit.fluxcd.io/reconcile: disabled
  creationTimestamp: "2025-11-18T18:38:03Z"
  generation: 2
  name: podinfo
  namespace: test
  ownerReferences:
  - apiVersion: flagger.app/v1beta1
    blockOwnerDeletion: true
    controller: true
    kind: Canary
    name: podinfo
    uid: 6fbb4630-5a6b-4da3-9586-2ab2878da3a8
  resourceVersion: "13705"
  uid: 8c53a556-1a69-4eb3-bb9b-2679de6b7988
spec:
  gateways:
  - mesh
  hosts:
  - podinfo
  http:
  - match:
    - headers:
        Cookie:
          regex: .*canary-cookie.*PPFpqKsygO.*
    route:
    - destination:
        host: podinfo-primary
      weight: 0
    - destination:
        host: podinfo-canary
      weight: 100
  - match:
    - headers:
        Cookie:
          regex: .*primary-cookie.*QvKdhlCQZb.*
    route:
    - destination:
        host: podinfo-primary
      weight: 100
    - destination:
        host: podinfo-canary
      weight: 0
  - route:
    - destination:
        host: podinfo-primary
      headers:
        response:
          add:
            Set-Cookie: primary-cookie=QvKdhlCQZb; Max-Age=15
      weight: 90
    - destination:
        host: podinfo-canary
      headers:
        response:
          add:
            Set-Cookie: canary-cookie=PPFpqKsygO; Max-Age=86400
      weight: 10

Signed-off-by: Renato Vassão <renato.vassao@mindbodyonline.com>
Signed-off-by: Renato Vassão <renato.vassao@mindbodyonline.com>
Signed-off-by: Renato Vassão <renato.vassao@mindbodyonline.com>
Signed-off-by: Renato Vassão <renato.vassao@mindbodyonline.com>
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Nov 18, 2025

Codecov Report

❌ Patch coverage is 90.75630% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 30.01%. Comparing base (12ee6cb) to head (70c4c52).
⚠️ Report is 69 commits behind head on main.

Files with missing lines Patch % Lines
pkg/router/istio.go 91.81% 5 Missing and 4 partials ⚠️
pkg/apis/flagger/v1beta1/canary.go 0.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1861      +/-   ##
==========================================
- Coverage   39.44%   30.01%   -9.43%     
==========================================
  Files         287      287              
  Lines       22706    18460    -4246     
==========================================
- Hits         8956     5541    -3415     
+ Misses      12777    12188     -589     
+ Partials      973      731     -242     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@renatovassaomb
Copy link
Copy Markdown
Contributor Author

@stefanprodan when time permits, could you take a look? Thanks!

Copy link
Copy Markdown
Member

@stefanprodan stefanprodan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add this feature to the docs here: https://docs.flagger.app/tutorials/istio-progressive-delivery#session-affinity

Signed-off-by: Renato Vassão <renato.vassao@mindbodyonline.com>
@renatovassaomb renatovassaomb force-pushed the rv/istio-primary-cookie-name-support branch from c1f870b to 70c4c52 Compare December 12, 2025 13:55
@renatovassaomb
Copy link
Copy Markdown
Contributor Author

@stefanprodan Thank you for your review. Added a similar comment like the one for Gateway API Session Affinity.

Comment on lines -709 to 712
func (s *SessionAffinity) BuildCookie(cookieName string) string {
func (s *SessionAffinity) BuildCookie(cookieName string, maxAge int) string {
cookie := fmt.Sprintf("%s; %s=%d", cookieName, "Max-Age",
s.GetMaxAge(),
maxAge,
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for this change in the public API?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason is that primary cookies were being generated only with the Max-Age property, and missing the additional attributes that were added in #1826. Since the value of Max-Age of the primary and canary cookie are different, we needed to pass this as a parameter.

Copy link
Copy Markdown
Member

@stefanprodan stefanprodan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Thanks @renatovassaomb 🏅

@stefanprodan stefanprodan merged commit d9d910b into fluxcd:main Dec 18, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants