Fixes #11818. Select Sidecars by Workload/Pod labels instead of Servi…#12620
Fixes #11818. Select Sidecars by Workload/Pod labels instead of Servi…#12620robertpanzer wants to merge 3 commits intoistio:release-1.1from
Conversation
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
|
Hi @robertpanzer. Thanks for your PR. I'm waiting for a istio member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
pilot/pkg/proxy/envoy/v2/ads.go
Outdated
There was a problem hiding this comment.
File is not goimports-ed (from goimports)
76edc92 to
63374d5
Compare
63374d5 to
7187d8f
Compare
|
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
8eb7a1a to
7187d8f
Compare
|
I also checked using |
|
/ok-to-test |
|
I wonder though how sidecars that don't run inside a K8s cluster could be supported. |
|
Thanks for picking this up, looks pretty good. I believe the failing test are known flakes. I'll pull this down and test it out a bit as well |
pilot/pkg/proxy/envoy/v2/ads.go
Outdated
|
|
||
| func (s *DiscoveryServer) workloadLabels(proxy *model.Proxy) model.Labels { | ||
| var workloadLabels model.Labels | ||
| if workload := s.WorkloadsByID[proxy.IPAddresses[0]]; workload != nil { |
There was a problem hiding this comment.
I think getting IPAdresses[0] is safe but not 100% sure if someone could verify
There was a problem hiding this comment.
That's a good point.
I found code that also simply accesses Proxy.IPAddresses[0], but now found that this in the kube registry, where it makes sense to make this assumption.
I am going to change this, even if this removes the precious lgtm label 😢
|
/lgtm I think we can get this in for 1.1.x but up to @duderino / others |
pilot/pkg/proxy/envoy/v2/ads.go
Outdated
| func (s *DiscoveryServer) workloadLabels(proxy *model.Proxy) model.Labels { | ||
| var workloadLabels model.Labels | ||
| ipAddresses := proxy.IPAddresses | ||
| if len(ipAddresses) == 0 { |
There was a problem hiding this comment.
My thoughts were more if we have multiple ipAddress rather than none - I haven't had a chance to dig into how the addresses get set though so I am not sure what happens outside of k8s. @rshriram any ideas? I don't think its a major issue but I am only familiar with kubernetes
There was a problem hiding this comment.
I see.
Currently afaict only the kube registry feeds workloadLabels with the podIP.
However there could probably be more than 1 address in Proxy.IPAdresses and assuming that this PodIP is always in the first slot might be brittle.
Maybe it would make sense then to make workloadLabels return a LabelsCollection and require the workloadSelector to be a superset of every item in that collection.
What do you think?
There was a problem hiding this comment.
I think looking at all of them makes sense, the question I would have is do we need the workloadSelector to match all or any of the labels we get. I suspect we would want to do all. I think this is basically how it worked before right?
There was a problem hiding this comment.
Yes, that's how it worked before, just using the services labels.
I think it also makes sense to match against all Labels, with the current code I would assume that even with different IPAddresses only one set should be non-empty.
Thanks for the discussion! 👍
There was a problem hiding this comment.
I just upgraded the PR to get the labels associated with all IP addresses.
The selector will match if it is a subset of any set of labels associated with a workloadId.
This is basically the same behavior as before, just that it tests against the labels of the Pods instead of the Services.
There was a problem hiding this comment.
cc @zhaohuabing any thoughts since you added the multi-ip support for each proxy, for consul environments
There was a problem hiding this comment.
I started working on an alternative fix today that would add a method ServiceDiscovery.GetProxyWorkloadLabels() which returns the workload labels for a proxy.
Maybe this works better for proxies not running in Kubernetes.
The change set will certainly be much, much larger.
|
/lgtm thanks for working on this! |
|
@robertpanzer: The following tests failed, say
DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
|
/lgtm @rshriram WDYT |
|
Sorry after another thought, this is not right. /lgtm cancel |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: howardjohn, robertpanzer If they are not already assigned, you can assign the PR to them by writing The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
| ipAddresses := proxy.IPAddresses | ||
| labels := make([]model.Labels, 0, len(ipAddresses)) | ||
| for _, ip := range ipAddresses { | ||
| if workload := s.WorkloadsByID[ip]; workload != nil { |
There was a problem hiding this comment.
WorkloadsByID only set in k8s env
There was a problem hiding this comment.
That was one of my questions: How would proxies identify for non-K8s applications?
Is it required to register MESH_INTERNAL ServiceEntries for these?
Or use Consul?
Proxy.Metadata and the current approach using Proxy.ServiceInstances don't work, as the metadata is fix and doesn't follow Pod labels, and ServiceInstances doesn't exist for consumer only applications.
Consumer only non-K8s applications should suffer from the same problem.
There was a problem hiding this comment.
WorkloadsByID is only used by incremental EDS feature.
There was a problem hiding this comment.
Which only supported in k8s
There was a problem hiding this comment.
I understand that.
Maybe it would be possible to store the labels in another location at the DiscoveryServer where other Registries can store and update the labels too.
That shouldn't be too hard actually and could probably also use the IPAddress as key, the Consul Registry already uses this for matching a Proxy to a ServiceInstance.
There was a problem hiding this comment.
Maybe another approach could be to add a method GetProxyWorkloadLabels to ServiceRegistry.
On Kubernetes this could still get dynamic updates.
I can have a try for this approach today.
|
I am reluctant to do a partial fix like this.. while you might be able to get the Sidecar logic flowing, other plugins might fail if they encounter a workload that has no service instances (notably authN and such). A simple litmus test is to try to add a test under lds_test.go (there are tests for sidecar, follow the same logic, but create a pseudo workload without any service). If my hunch is right, you will find that a couple of plugins will fail and seg fault. Alternative fix is to create a dummy internal service for workloads that do not have a backing service, in the getProxyServiceInstances call. that might solve your problem. Once again, I would validate with the tests in lds_test.go at the very least to see what else might fail. |
|
Thanks for the pointer where to add tests, I was already searching for that! I see the point though that it's problematic for proxies corresponding to services from other ServiceRegistries, e.g. Consul, that they won't be able to find any workload labels anymore. Adding a fake ServiceEntry doesn't sound like a good idea to me. |
|
Created an alternative PR to fix the problem at #12666. |
|
Closing this in favor of #12666 |
…ce labels
This PR is an attempt to fix #11818.
I don't know if I missed some parts, but however I am trying:)
The problem reported in the issue is that the workload selectors of the Sidecar instances match against the labels of the Services which in turn lead to the proxies, but that doesn't work for consumer only services.
This PR changes this by getting the workload labels from the DiscoveryServer for the current proxy and uses these labels as the basis for the selection of the Sidecar instance.
There's just a few open questions:
WorkloadsByID, suggesting that its keys would be the IDs of the proxies. Instead the only place I could find where this map is filled is the kube serviceregistry which feeds the pod ip as the id:istio/pilot/pkg/serviceregistry/kube/pod.go
Line 86 in 190d4c1