8000 [DRAFT] Deployment vs StatefulSet by andreaTP · Pull Request #12447 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content

[DRAFT] Deployment vs StatefulSet - #12447

Closed
andreaTP wants to merge 3 commits into
keycloak:mainfrom
andreaTP:deployment-vs-statefulset
Closed

andreaTP wants to merge 3 commits into
keycloak:mainfrom
andreaTP:deployment-vs-statefulset

Conversation

@andreaTP
@andreaTP andreaTP commented Jun 9, 2022 •
Copy link
Copy Markdown
Contributor

This PR is just a demonstration generated from the Discussion #11763

I quickly hacked around a switch at the operator level to let ppl play with Deployment vs. StatefulSet.

To test this branch:

  • Change the operator docker image to andreatp/keycloak-operator-enable-statefulset:0.0.1 (produced from this branch)
  • Fixup the Roles with kubectl apply -f operator/app/src/main/kubernetes/kubernetes.yml from this branch in the correct namespace
  • Add an environment variable to the keycloak-operator Deployment named OPERATOR_USE_STATEFULSET e.g. here

This PR builds on top of #12437

@vmuzikar vmuzikar left a comment
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@andreaTP Thanks for creating this PoC.

Please see my comment in the original discussion: #11763 (reply in thread). In summary, -1 from me for this change.

@andreaTP
andreaTP commented Jun 9, 2022
Copy link
Copy Markdown
Contributor Author

@vmuzikar this PR has been done to enable the community to experiment with the 2 options, after we receive feedback we can decide in which direction we want to move.

@sschu
sschu commented Jun 9, 2022
Copy link
Copy Markdown
Contributor

Thanks for providing this, I will give it a try tomorrow!

@sschu
sschu commented Jun 10, 2022
Copy link
Copy Markdown
Contributor

@andreaTP Unfortunately, I have been struggling with getting the self-built operator to run. I basically followed https://github.com/keycloak/keycloak/blob/main/operator/README.md, updated to newest kubectl, minikube etc, built the operator successfully (image is in my local registry) bun when kubectl apply -k target I get an error error: accumulating resources: accumulation err='accumulating resources from 'kubernetes/kubernetes.yml'. This makes sense, because kubernetes.yml is actually in the parent directory. I could copy this over and run apply, but in the end it only creates rolebindings but not the operator itself. Any hint would be appreciated.

@andreaTP
Copy link
Copy Markdown
Contributor Author

@sschu sorry for the late reply, I think you are missing to run mvn clean package -DskipTests in the operator folder before running kubectl apply -k target, resources are automatically copied here

@sschu
sschu commented Jun 16, 2022 •
Copy link
Copy Markdown
Contributor

@andreaTP Something still does not work. What I see after building from the operator/app directory is:

➜ app git:(deployment-vs-statefulset) ls
olm-base overlays patch-sources.sh pom.xml scripts src target
➜ app git:(deployment-vs-statefulset) ls target
classes keycloak-operator-999-SNAPSHOT-sources.jar kustomization.yml quarkus-app vertx-cache generated-sources keycloak-operator-999-SNAPSHOT.jar maven-archiver quarkus-artifact.properties generated-test-sources kubernetes maven-status surefire-reports keycloak-core kubernetes.yml quarkus test-classes
➜ app git:(deployment-vs-statefulset) ls target/kubernetes/
keycloakrealmimports.k8s.keycloak.org-v1.yml minikube.json openshift.json keycloaks.k8s.keycloak.org-v1.yml minikube.yml openshift.yml
➜ app git:(deployment-vs-statefulset) kubectl apply -k target
error: accumulating resources: accumulation err='accumulating resources from 'kubernetes/kubernetes.yml': evalsymlink failure on '/Users/scu1be/repos/keycloak-forks/andreaTP/keycloak/operator/app/target/kubernetes/kubernetes.yml' : lstat /Users/scu1be/repos/keycloak-forks/andreaTP/keycloak/operator/app/target/kubernetes/kubernetes.yml: no such file or directory': evalsymlink failure on '/Users/scu1be/repos/keycloak-forks/andreaTP/keycloak/operator/app/target/kubernetes/kubernetes.yml' : lstat /Users/scu1be/repos/keycloak-forks/andreaTP/keycloak/operator/app/target/kubernetes/kubernetes.yml: no such file or directory

I manage to install the operator using:
➜ app git:(deployment-vs-statefulset) k apply -f target/kubernetes/minikube.yml
serviceaccount/keycloak-operator created service/keycloak-operator created rolebinding.rbac.authorization.k8s.io/keycloak-operator-view created rolebinding.rbac.authorization.k8s.io/keycloakcontroller-role-binding created rolebinding.rbac.authorization.k8s.io/keycloakrealmimportcontroller-role-binding created clusterrole.rbac.authorization.k8s.io/keycloakcontroller-cluster-role created clusterrole.rbac.authorization.k8s.io/keycloakrealmimportcontroller-cluster-role created deployment.apps/keycloak-operator created

But that's probably not the right way. I also have a problem with Minikube and Podman trying to push the operator image into Minikube's registry on my Mac. There it complains about:
Error: unable to connect to Podman socket: server API version is too old. Client "4.0.0" server "2.0.0"
Still haven't found a solution for that so I am using an external Kubernetes cluster for now.

@sschu
sschu commented Jun 16, 2022 •
Copy link
Copy Markdown
Contributor

@andreaTP Never mind, I got it to work. The reason was the -Dquarkus.kubernetes.deployment-target=minikube, if that is added, the kubectl apply -k throws the above error. Without it, it works. Still having the problem accessing the minikube registry with podman on my Mac and no solution in sight so far. I would not really like to downgrade my podman installation.

@andreaTP
Copy link
Copy Markdown
Contributor Author

@sschu good to hear that you got it to work!

@ahus1
ahus1 commented Jun 17, 2022
Copy link
Copy Markdown
Member

@andreaTP - I gave the new version a try, and it works nicely when scaling up/down.

One thing I found: I had an existing deployment of Keycloak and switched the environment variable of the operator. The operator then created a stateful set in addition to the deployment, so I now had both.

The most safe way would be to delete the keycloak CR first with this PoC. If this option would get into the real operator, I would expect the operator to delete the deployment before creating the stateful set and vice versa

When scaling up and down from 1 to 10 pods, I still see the "no physical address" message. The good news is that it seems to appear less often with a stateful set than with a deployment. I seems to occur for 1 in 10 pods being started.

I'll open a new issue for that observation and will link this PR and the discussion to it.

@sschu
sschu commented Jun 21, 2022
Copy link
Copy Markdown
Contributor

@andreaTP I also finally managed to test the operator with stateful set and it works like a charm.

I can also confirm @ahus1 observation that switching the operator configuration creates a deployment in parallel. The pods actually formed a cluster which means it would at least be easy to migrate from deployment to stateful set and vice versa without downtime.

I also changed the operator to use maxsurge=1 and maxunavailable=1 to check if that helps with deployments.
I can confirm that scaling up a deployment from 1 to 10 nodes leads to a lot of "no physical address found errors". I did not see these errrors with a stateful set. After about 5 minutes the deployment finally settled but several pods needed one or two restarts. Scaling down K9s kills the pods immediately with a deployment, not one after another. So maxsurge and maxunavailable only influence update behaviour not general scaling behaviour.

Which means the operator would have to adapt count changes in the custom resource definition one by one to the deployment. Thats definitely some effort considering a stateful set provides this for free.

@andreaTP
Copy link
Copy Markdown
Contributor Author

@ahus1 @sschu thanks a lot for the feedback.

I can locally reproduce all of your observations, the most meaningful being:

So maxsurge and maxunavailable only influence update behaviour not general scaling behaviour.

I was working under the assumption that the "Rolling Update" settings would apply to scaling as well, which is not correct.

@ahus1
ahus1 commented Jun 22, 2022
Copy link
Copy Markdown
Member

I can also confirm @ahus1 observation that switching the operator configuration creates a deployment in parallel. The pods actually formed a cluster which means it would at least be easy to migrate from deployment to stateful set and vice versa without downtime.

I wouldn't insist for no downtime migration from deployment to statefulset and back with no downtime. A minimum requirement for me would be that the old one would be deleted in the process.

@andreaTP
Copy link
Copy Markdown
Contributor Author

At this stage, the operator is still in "preview" release, so we will allow ourselves to do breaking changes.

The migration path for the next version will probably be:

  • delete the old CRD (consequently all the CRs)
  • create the new CRD
  • re-create the CRs

This process will automatically delete the old resources as they have the correct Owner References.

@ahus1
ahus1 commented Jun 22, 2022
Copy link
Copy Markdown
Member

@andreaTP - I was testing a bit today and found that the deployment has set "maxUnavailable" to "1". When doing a rolling update of a single instance, this would lead to a downtime.

I'd suggest to have "maxUnavailable" at "0" when there is only a single instance.

I'm noting this in this issue as I understand that you'll probably revisit this in the process of StatefulSet vs. Deployment anyway. If you'd rather have a new issue for that, please let me know.

Best,
Alexander

@andreaTP
Copy link
Copy Markdown
Contributor Author

Superseded by #12757

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.

4 participants

0