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

Configurable JsonPath for pod owner #72

Merged
merged 1 commit into from
Jul 30, 2019

Conversation

IlyaMar
Copy link
Contributor

@IlyaMar IlyaMar commented Jul 8, 2019

This is a fix for #50
New property 'podOwnerJsonPath' added with JsonPath to pod owner (ReplicaSet or OpenShift Deployment) relative to pod json node. Default value is "$.metadata.labels.deployment" to keep backward compatibility.
For kubernetes w/o OpenShift, property value should be set to "$.metadata.ownerReferences[?(@['kind'] == 'ReplicaSet')].name"

Please note new dependency is added, com.jayway.jsonpath:json-path. It should be placed to JBoss module somehow, by adding a new jar or by a shaded jar, please advice how to do it.

@IlyaMar IlyaMar force-pushed the support_replication_sets branch from 151f67e to 10f55ad Compare July 8, 2019 15:35
Copy link
Member

@slaskawi slaskawi left a comment

Choose a reason for hiding this comment

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

Thank you for the patch @IlyaMar! I appreciate all the hard work you put into it.

the overall approach looks good to me. However, I would love to see two issues addressed:

  1. The biggest challenge is to detect whether we should use ReplicaSet or DeploymentConfig information to distinguish deployments. There's also a third controller, very frequently used with stateful applications - StatefulSets. I believe we might query Kubernetes API for all 3 types of information and see what we get in return. Then, we might automatically decide, which one to use to separate the deployments. My main point is that we can get rid of podOwnerJsonPath and make this decision automatically.
  2. I would like to keep this project without additional dependencies. So it would be great to find a way to implement it without json-path. This makes things a bit easier when deploying as modules in Wildfly (and other WF-dependent projects).

@IlyaMar
Copy link
Contributor Author

IlyaMar commented Jul 9, 2019

Autodetection sounds reasonable and easy to implement. I have a question about StatefulSets, it's not clear by what criteria should we distinguish new and old pods during rolling update.
It looks like we can segregate pods by "controller-revision-hash" label but I see no documentation on it.
Please see json attached, it is taken in the middle of rolling update
pods_upd1.zip

@slaskawi
Copy link
Member

I have a question about StatefulSets, it's not clear by what criteria should we distinguish new and old pods during rolling update. It looks like we can segregate pods by "controller-revision-hash" label but I see no documentation on it.

@IlyaMar Indeed, controller-revision-hash seems to be very poorly documented. However, this issue suggests the change has been done on purpose and will be permanent. I guess we could use this field (however, I guess it would be wise to prepare for a null reference there and print out some warning in such a case).

@IlyaMar
Copy link
Contributor Author

IlyaMar commented Jul 15, 2019

@slaskawi I've updated PR with controller-revision-hash usage, please review.

Copy link
Member

@slaskawi slaskawi left a comment

Choose a reason for hiding this comment

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

The changes look good to me, nice work!

Let me test them out a bit more this week. Once I do that, I'll merge the PR.

@IlyaMar
Copy link
Contributor Author

IlyaMar commented Jul 16, 2019

I've found a new problem just now. When performing Rolling Update, new pod is not fully started at the moment KUBE_PING performs discovery. So, new pod is filtered out in org.jgroups.protocols.kubernetes.Client#parseJsonResult
As result, we cannot determine senderParentDeployment variable inside org.jgroups.protocols.kubernetes.KUBE_PING#findMembers, and old members are not filtered from cluster list. New pod cannot start as it stuck communicating with old members.
pods_upd2.zip

I think we need to move filtraton by readiness to findMembers function, after senderParentDeployment is determined.

@slaskawi
Copy link
Member

When performing Rolling Update, new pod is not fully started at the moment KUBE_PING performs discovery. So, new pod is filtered out in org.jgroups.protocols.kubernetes.Client#parseJsonResult
As result, we cannot determine senderParentDeployment variable inside org.jgroups.protocols.kubernetes.KUBE_PING#findMembers, and old members are not filtered from cluster list. New pod cannot start as it stuck communicating with old members.

@IlyaMar So indeed, Client#parseJsonResult checks if Pod is running (that in turn invokes Client#podRunning, which checks both flags - is Running and is ready). Then, we exclude all Pods that do not pass this predicate from the List<Pod> returned by Client#parseJsonResult.

Then, as you said, the Pods that are not ready (or are not running) are not processed by in KUBE_PING#findMembers. But since, they are not there, they shouldn't form a cluster. In other words, not ready Pods should not join any cluster (neither old, nor new one).

However, as you said, the Pod that is sending the discovery request also might not be ready. Since it's not present in a list returned by Client#parseJsonResult it can not grab it's own Parent Deployment (stored in senderParentDeployment), and it can not compare it to the other Pods and we get into troubles.

I believe we have at least 3 choices here:

  1. if senderParentDeployment is null, we simply exclude all Pods from the discovery. This means the Pod that is sending the discovery request is not ready, so it doesn't know which cluster to join. The biggest downside is that an application may be in not-ready state for a longer period of time (e.g. doing a migration or fetching a larger dataset from a database). So clearly, this solution is not perfect.
  2. We can modify the Client#getPods to always preserve a sender Pod. Later on, we can filter the sender in KUBE_PING#findMembers. However, sending discovery to self should not do any harm.
  3. As you mentioned, move the whole if (split_clusters_during_rolling_update) to the Client#parseJsonResult and adjust the readiness check part.

I personally like the option no. 3 the most. I think that's the cleanest approach. no. 2 is also "pretty good".

@IlyaMar
Copy link
Contributor Author

IlyaMar commented Jul 18, 2019 via email

@IlyaMar IlyaMar force-pushed the support_replication_sets branch from 93a9ec2 to be3d733 Compare July 21, 2019 12:34
@IlyaMar
Copy link
Contributor Author

IlyaMar commented Jul 21, 2019

@slaskawi , I finally implemented slightly different solution. Client now reads all pods, even not ready, with flag isReady. It's KUBE_PING.findMembers responsibility to form a list of members from this pod list. Looks like this resulted to more readable code. Please see updated PR.

Copy link
Member

@slaskawi slaskawi left a comment

Choose a reason for hiding this comment

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

LGTM. Let's wait for @belaban to see if he has any concerns around this change.

@belaban
Copy link
Member

belaban commented Jul 30, 2019

Hey @slaskawi thanks for looking into this! Can you merge the PR, or do you need further testing?

@slaskawi
Copy link
Member

slaskawi commented Jul 30, 2019

@belaban No, I believe it's fine! I just wanted to check if you have any comments regarding to the code.

Once you approve it, I'll push it and release it.

@belaban belaban merged commit 7b4dbab into jgroups-extras:master Jul 30, 2019
@belaban
Copy link
Member

belaban commented Jul 30, 2019

done

@belaban
Copy link
Member

belaban commented Oct 21, 2019

@slaskawi I appreciate that you can still find time to spend on Kubernetes/Openshift discovery protocols (KUBE_PING, DNS_PING)!
The beers are on me during the Barcelona F2F! :-)
Thanks!!

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