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

Traffic #16

Closed
wants to merge 12 commits into from
5 changes: 5 additions & 0 deletions api/v1alpha1/rollout_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,11 @@ const (
ProgressingReasonCancelling = "Cancelling"
ProgressingReasonPaused = "Paused"

// Disabling condition
RolloutConditionDisabling RolloutConditionType = "Disabling"
// Disabling reason
DisablingReasonFinalising = "InDisabling"

// RolloutConditionSucceeded indicates whether rollout is succeeded or failed.
RolloutConditionSucceeded RolloutConditionType = "Succeeded"

Expand Down
9 changes: 8 additions & 1 deletion api/v1alpha1/trafficrouting_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ type TrafficRoutingRef struct {
Ingress *IngressTrafficRouting `json:"ingress,omitempty"`
// Gateway holds Gateway specific configuration to route traffic
// Gateway configuration only supports >= v0.4.0 (v1alpha2).
Gateway *GatewayTrafficRouting `json:"gateway,omitempty"`
Gateway *GatewayTrafficRouting `json:"gateway,omitempty"`
NetworkRefs *[]NetworkRef `json:"networkRefs,omitempty"`
}

// IngressTrafficRouting configuration for ingress controller to control traffic routing
Expand Down Expand Up @@ -149,6 +150,12 @@ type TrafficRoutingList struct {
Items []TrafficRouting `json:"items"`
}

type NetworkRef struct {
APIVersion string `json:"apiVersion,omitempty"`
Kind string `json:"kind,omitempty"`
Name string `json:"name,omitempty"`
}

func init() {
SchemeBuilder.Register(&TrafficRouting{}, &TrafficRoutingList{})
}
24 changes: 24 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions config/crd/bases/rollouts.kruise.io_rollouts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,17 @@ spec:
required:
- name
type: object
networkRefs:
items:
properties:
apiVersion:
type: string
kind:
type: string
name:
type: string
type: object
type: array
service:
description: Service holds the name of a service which
selects pods with stable version and don't select
Expand All @@ -389,6 +400,7 @@ spec:
type: boolean
type: object
required:
- disabled
- objectRef
- strategy
type: object
Expand Down
11 changes: 11 additions & 0 deletions config/crd/bases/rollouts.kruise.io_trafficroutings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ spec:
required:
- name
type: object
networkRefs:
items:
properties:
apiVersion:
type: string
kind:
type: string
name:
type: string
type: object
type: array
service:
description: Service holds the name of a service which selects
pods with stable version and don't select any pods with canary
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
rollout:
apiVersion: rollouts.kruise.io/v1alpha1
kind: Rollout
metadata:
name: rollouts-demo
namespace: demo
annotations:
rollouts.kruise.io/rolling-style: canary
spec:
disabled: false
objectRef:
workloadRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
strategy:
canary:
steps:
- weight: 20
matches:
- headers:
- type: Exact
name: user-agent
value: pc
- type: RegularExpression
name: name
value: ".*demo"
- weight: 50
trafficRoutings:
- service: nginx-service
networkRefs:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
name: nginx-vs
original:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
namespace: demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: nginx-service
expected:
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
namespace: demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- match:
- headers:
user-agent:
exact: pc
name:
regex: .*demo
route:
- destination:
host: nginx-service
weight: 80
- destination:
host: nginx-service-canary
weight: 20
- route:
- destination:
host: nginx-service
- apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-vs
namespace: demo
spec:
hosts:
- "*"
gateways:
- nginx-gateway
http:
- route:
- destination:
host: nginx-service
weight: 50
- destination:
host: nginx-service-canary
weight: 50
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
-- obj = {
-- matches = {
-- {
-- uri = {
-- {
-- name = "xxx",
-- value = "xxx",
-- type = "Prefix"
-- }
-- }
-- }
-- },
-- data = {
-- spec = {
-- hosts = {
-- "reviews",
-- },
-- http = {
-- {
-- route = {
-- {
-- destination = {
-- host = "reviews",
-- subset = "c1",
-- port = {
-- number = 80
-- }
-- }
-- }
-- }
-- }
-- }
-- },
-- },

-- stableService = "reviews",
-- canaryService = "canary",
-- stableWeight = 90,
-- canaryWeight = 10
-- }

spec = obj.data.spec

-- find matched route of VirtualService spec with stable svc
function FindMatchedRules(spec, stableService)
local matchedRoutes = {}
local rules = {}
if (spec.http) then
for _, http in ipairs(spec.http) do
table.insert(rules, http)
end
end
if (spec.tls) then
for _, tls in ipairs(spec.tls) do
table.insert(rules, tls)
end
end
if (spec.tcp) then
for _, tcp in ipairs(spec.tcp) do
table.insert(rules, tcp)
end
end
for _, rule in ipairs(rules) do
for _, route in ipairs(rule.route) do
if route.destination.host == stableService then
table.insert(matchedRoutes, rule)
end
end
end
return matchedRoutes
end

-- generate routes with matches
function GenerateMatchedRoutes(spec, matches, stableService, canaryService, stableWeight, canaryWeight)
local route = {}
route["match"] = {}
for _, match in ipairs(matches) do
for key, value in pairs(match) do
local vsMatch = {}
vsMatch[key] = {}
for _, rule in ipairs(value) do
if rule["type"] == "RegularExpression" then
matchType = "regex"
elseif rule["type"] == "Exact" then
matchType = "exact"
elseif rule["type"] == "Prefix" then
matchType = "prefix"
end
if key == "headers" then
vsMatch[key][rule["name"]] = {}
vsMatch[key][rule["name"]][matchType] = rule.value
else
vsMatch[key][matchType] = rule.value
end
end
table.insert(route["match"], vsMatch)
end
end
route["route"] = {
{
destination = {
host = stableService,
},
weight = stableWeight,
},
{
destination = {
host = canaryService,
},
weight = canaryWeight,
}
}
table.insert(spec.http, 1, route)
end

-- generate routes without matches
function GenerateRoutes(spec, stableService, canaryService, stableWeight, canaryWeight)
local matchedRules = FindMatchedRules(spec, stableService)
for _, rule in ipairs(matchedRules) do
local canary = {
destination = {
host = canaryService,
},
weight = canaryWeight,
}
for _, route in ipairs(rule.route) do
-- incase there are multiple versions traffic already
if (route.weight) then
route.weight = math.floor(route.weight * stableWeight / 100)
else
route.weight = math.floor(stableWeight / #rule.route)
end
end
table.insert(rule.route, canary)
end
end

if (obj.matches) then
GenerateMatchedRoutes(spec, obj.matches, obj.stableService, obj.canaryService, obj.stableWeight, obj.canaryWeight)
return obj.data
end

GenerateRoutes(spec, obj.stableService, obj.canaryService, obj.stableWeight, obj.canaryWeight)
return obj.data

6 changes: 6 additions & 0 deletions pkg/controller/rollout/rollout_canary.go
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ func (m *canaryReleaseManager) doCanaryFinalising(c *RolloutContext) (bool, erro
} else if !done {
return false, nil
}
m.trafficRoutingManager.RemoveTrafficRoutingController(tr)
klog.Infof("rollout(%s/%s) doCanaryFinalising success", c.Rollout.Namespace, c.Rollout.Name)
return true, nil
}
Expand Down Expand Up @@ -454,6 +455,11 @@ func (m *canaryReleaseManager) finalizingBatchRelease(c *RolloutContext) (bool,
return false, err
}
klog.Infof("rollout(%s/%s) patch batchRelease(%s) success", c.Rollout.Namespace, c.Rollout.Name, body)

// if rollout is disabling, then the batchrelease should be deleted
if c.NewStatus.Phase == v1alpha1.RolloutPhaseDisabling {
return true, nil
}
return false, nil
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/rollout/rollout_event_handler.go
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (w *enqueueRequestForWorkload) getRolloutForWorkload(key types.NamespacedNa
continue
}

if targetRef.Kind == gvk.Kind && targetGV.Group == gvk.Group && targetRef.Name == key.Name {
if targetRef.Kind == gvk.Kind && targetGV.Group == gvk.Group && targetRef.Name == key.Name && rollout.Status.Phase != rolloutv1alpha1.RolloutPhaseDisabled {
return &rollout, nil
}
}
Expand Down
Loading
Loading