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

Support ServiceInternalTrafficPolicy #42551

Merged
merged 4 commits into from
Jan 9, 2023

Conversation

dddddai
Copy link
Member

@dddddai dddddai commented Dec 22, 2022

Please provide a description of this PR:
Fixes #42377

NOTE: This PR does not take ProxyTerminatingEndpoints into account

@dddddai dddddai requested review from a team as code owners December 22, 2022 11:49
@istio-testing istio-testing added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Dec 22, 2022
@howardjohn
Copy link
Member

NOTE: This PR does not take ProxyTerminatingEndpoints into account

FWIW after looking at it more I think that feature is orthogonal

pilot/pkg/model/service.go Outdated Show resolved Hide resolved
// As this may contain node topology labels, which could not be got from aggregator controller
out[model.LocalityLabel] = locality
return out
// set k8s node name label, for ServiceInternalTrafficPolicy
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be in AugmentLabels

Copy link
Member Author

Choose a reason for hiding this comment

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

For endpoint labels we can use AugmentLabels (updated), but for proxy labels I'm not sure how, is there any other place to get the k8s node?

Copy link
Member

Choose a reason for hiding this comment

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

This is mutating the underlying pod labels

Copy link
Member

Choose a reason for hiding this comment

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

can set it in setTopologyLabels

Copy link
Member Author

Choose a reason for hiding this comment

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

This is mutating the underlying pod labels

Thanks for reminding, fixed

can set it in setTopologyLabels

I think we have to set the host label here, as we can't get it elsewhere

Copy link
Member

Choose a reason for hiding this comment

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

Why not AugmentLabels then fetch it like setTopologyLabels ( proxy.ServiceInstances[0].Endpoint.Locality.Node)

Copy link
Member

Choose a reason for hiding this comment

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

Actually we can add NODE_NAME to the injection template (downward API) and get it from there 99% of the time. And fallback to ^ when its not there.

Copy link
Member

Choose a reason for hiding this comment

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

The experimental-ambient branch already does this if you would like a reference

pilot/pkg/xds/endpoint_builder.go Show resolved Hide resolved
@dddddai
Copy link
Member Author

dddddai commented Dec 23, 2022

FWIW after looking at it more I think that feature is orthogonal

Yeah I think it also applies to internalTrafficPolicy: Cluster. It's a bit confusing that the user-facing change says:

When enabled, kube-proxy will attempt to route traffic to terminating pods when the traffic policy is Local and there are only terminating pods remaining on a node.

@@ -129,6 +129,8 @@ const (
Passthrough
// DNSRoundRobinLB implies that the proxy will resolve a DNS address and forward to the resolved address
DNSRoundRobinLB
// NodeLocal implies that the proxy will only forward to node local endpoints
NodeLocal
Copy link
Member

Choose a reason for hiding this comment

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

Using resolution is a little hacky,

Copy link
Member Author

Choose a reason for hiding this comment

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

Any suggestions?

Copy link
Member

Choose a reason for hiding this comment

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

how about add a NodeLocal bool field in ServiceAttributes

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated

Copy link
Member

@hzxuzhonghu hzxuzhonghu left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@howardjohn howardjohn left a comment

Choose a reason for hiding this comment

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

Main implementation lgtm, just think we can improve how we get the node by passing it over XDS.

// As this may contain node topology labels, which could not be got from aggregator controller
out[model.LocalityLabel] = locality
return out
// set k8s node name label, for ServiceInternalTrafficPolicy
Copy link
Member

Choose a reason for hiding this comment

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

Why not AugmentLabels then fetch it like setTopologyLabels ( proxy.ServiceInstances[0].Endpoint.Locality.Node)

// As this may contain node topology labels, which could not be got from aggregator controller
out[model.LocalityLabel] = locality
return out
// set k8s node name label, for ServiceInternalTrafficPolicy
Copy link
Member

Choose a reason for hiding this comment

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

Actually we can add NODE_NAME to the injection template (downward API) and get it from there 99% of the time. And fallback to ^ when its not there.

@@ -98,7 +99,7 @@ func NewEndpointBuilderFromMetadata(c controllerInterface, proxy *model.Proxy) *
if len(proxy.IPAddresses) > 0 {
networkID = out.endpointNetwork(proxy.IPAddresses[0])
}
out.labels = labelutil.AugmentLabels(proxy.Labels, c.Cluster(), locality, networkID)
out.labels = labelutil.AugmentLabels(proxy.Labels, c.Cluster(), locality, "", networkID)
Copy link
Member

Choose a reason for hiding this comment

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

once we add node name like I mentioned, make "" be proxy.Metadata.NodeName

@@ -630,7 +630,7 @@ func setTopologyLabels(proxy *model.Proxy) {

locality := util.LocalityToString(proxy.Locality)
// add topology labels to proxy labels
proxy.Labels = labelutil.AugmentLabels(proxy.Labels, proxy.Metadata.ClusterID, locality, proxy.Metadata.Network)
proxy.Labels = labelutil.AugmentLabels(proxy.Labels, proxy.Metadata.ClusterID, locality, "", proxy.Metadata.Network)
Copy link
Member

Choose a reason for hiding this comment

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

In addition to modifying Labels we should have a proxy.NodeName we set, just like L624

@@ -132,6 +133,10 @@ func (b EndpointBuilder) Key() string {
hash.Write(b.failoverPriorityLabels)
hash.Write(Separator)
}
if b.service.Attributes.NodeLocal {
hash.Write([]byte(b.proxy.Labels[label.LabelHostname]))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
hash.Write([]byte(b.proxy.Labels[label.LabelHostname]))
hash.Write([]byte(b.proxy.NodeName))

Once other suggestions are done

// As this may contain node topology labels, which could not be got from aggregator controller
out[model.LocalityLabel] = locality
return out
// set k8s node name label, for ServiceInternalTrafficPolicy
Copy link
Member

Choose a reason for hiding this comment

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

The experimental-ambient branch already does this if you would like a reference

@dddddai dddddai requested a review from a team as a code owner January 5, 2023 10:34
@istio-testing istio-testing added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jan 5, 2023
}
var networkID network.ID
if len(proxy.IPAddresses) > 0 {
networkID = out.endpointNetwork(proxy.IPAddresses[0])
}
out.labels = labelutil.AugmentLabels(proxy.Labels, c.Cluster(), locality, networkID)
out.labels = labelutil.AugmentLabels(proxy.Labels, c.Cluster(), locality, proxy.Metadata.NodeName, networkID)
Copy link
Member

Choose a reason for hiding this comment

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

we use GetNodeName in other places, is this intended?

Copy link
Member Author

Choose a reason for hiding this comment

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

No, have changed to proxy.GetNodeName()

if len(proxy.GetNodeName()) == 0 {
// this can happen for an "old" proxy which has no `Metadata.NodeName` set
// in this case we set the node name in labels on the fly
nodeName = pod.Spec.NodeName
Copy link
Member

Choose a reason for hiding this comment

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

This can be removed in a future release, please add a TODO

Copy link
Member Author

Choose a reason for hiding this comment

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

Added

Copy link
Member Author

@dddddai dddddai left a comment

Choose a reason for hiding this comment

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

https://prow.istio.io/view/gs/istio-prow/pr-logs/pull/istio_istio/42551/gencheck_istio/1610947968523833344
I don't know why those generated yamls have no ISTIO_META_NODE_NAME, is that expected? Am I missing something?
I'm not very familiar with updating charts, could you please give some hints?

@@ -224,6 +224,10 @@ spec:
{{- end }}
- name: ISTIO_META_CLUSTER_ID
value: "{{ $.Values.global.multiCluster.clusterName | default `Kubernetes` }}"
- name: ISTIO_META_NODE_NAME
Copy link
Member Author

Choose a reason for hiding this comment

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

Curious what L164 is used for

@howardjohn
Copy link
Member

https://prow.istio.io/view/gs/istio-prow/pr-logs/pull/istio_istio/42551/gencheck_istio/1610947968523833344 I don't know why those generated yamls have no ISTIO_META_NODE_NAME, is that expected? Am I missing something? I'm not very familiar with updating charts, could you please give some hints?

you can just run git apply <(curl -sL "https://gcsweb.istio.io/gcs/istio-prow/pr-logs/pull/istio_istio/42551/gencheck_istio/1610947968523833344/artifacts/check-clean-repo-diff.patch")

But those files are not actually based on manifests/ but a snapshot of them to avoid excessive churn,

@dddddai
Copy link
Member Author

dddddai commented Jan 7, 2023

Get it, thanks!

The release-notes test failed because gh pr view --json files cannot find the release note I added, see cli/cli#5368
Maybe add a release-notes-none label for this pr? Or fix it in test-infra

@hzxuzhonghu hzxuzhonghu added the release-notes-none Indicates a PR that does not require release notes. label Jan 9, 2023
@hzxuzhonghu
Copy link
Member

/retest

@istio-testing istio-testing merged commit 4a6312d into istio:master Jan 9, 2023
@dddddai dddddai deleted the internal-policy branch January 9, 2023 07:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/networking release-notes-none Indicates a PR that does not require release notes. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

implement ServiceInternalTrafficPolicy
5 participants