-
Notifications
You must be signed in to change notification settings - Fork 828
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
Enable RBAC #86
Enable RBAC #86
Conversation
Looks good. I think service account name are too generic and could easily clash with user service account especially on the default namespace. Should we prefix them with Another thought, should we pass the sidecar service account name as an environement variable to the controller ? I have a feeling that if they want to change the name they have to also re-compile the controller. Also @markmandel should we create an issue for creating a helm chart to ease users installation ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good - but I agree there should be some naming changes.
Also think there should be a rejig of where the service account gets applied.
See inline comments, but let me know if anything doesn't make sense.
build/Makefile
Outdated
@@ -233,6 +233,7 @@ gcloud-auth-cluster: ensure-build-image | |||
docker run --rm $(common_mounts) --entrypoint="gcloud" $(build_tag) config set compute/zone \ | |||
`grep zone: $(build_path)/gke-test-cluster/deployment.yml | sed 's/zone: //'` | |||
docker run --rm $(common_mounts) --entrypoint="gcloud" $(build_tag) container clusters get-credentials $(CLUSTER_NAME) | |||
docker run --rm $(common_mounts) $(build_tag) kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user $$(gcloud config get-value account) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's put a -
in front of this, as if you re-run this target, it will fail the second time, but I think it's best if it fails gracefully (as maybe you've already setup this before)
Context: https://www.gnu.org/software/make/manual/html_node/Errors.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering if there was a way to do that, thanks. Done.
build/install.yaml
Outdated
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: sidecar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree with @Kuqd - this name is a bit generic.
I would change it all the sidecar
names to agones-sdk
(I previously changed the sidecar
items to sdk
, as what if we want more sidecars later on? Better to be explicit)
build/install.yaml
Outdated
kind: ClusterRole | ||
metadata: | ||
namespace: default | ||
name: sidecar |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above agones-sdk
(etc) - I won't mark them all, but just referencing the pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
build/install.yaml
Outdated
apiVersion: v1 | ||
kind: ServiceAccount | ||
metadata: | ||
name: controller |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agones-controller
across the board.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
pkg/apis/stable/v1alpha1/types.go
Outdated
@@ -192,9 +194,11 @@ func (gs *GameServer) FindGameServerContainer() (int, corev1.Container, error) { | |||
// Pod creates a new Pod from the PodTemplateSpec | |||
// attached for the | |||
func (gs *GameServer) Pod(sidecars ...corev1.Container) (*corev1.Pod, error) { | |||
podSpec := *gs.Spec.Template.Spec.DeepCopy() | |||
podSpec.ServiceAccountName = SidecarServiceAccountName |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also agree with @Kuqd this should be an flag/env var that gets passed to the Controller (and maybe the 'sidecar' flag should be renamed to sdk
?) - see example
My current thought is the the Pod()
method below should go back to how it was, and the controller should add the ServiceAccountName
around here. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm all right with setting the sidecar account name as a flag (I considered that originally), but am curious when a user would want to be changing it?
Also why shouldn't we be setting the Pod's service account within the Pod() method? It sets everything else about its own metadata, spec, and containers. Don't we want to initialize everything about it in one place?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could see a user having their own service accounts setup (down the line) and wanting to change the value. I think it should still have our own name as the default, but being able to have it able to be overwritten would be good.
Yeah, I'm going to rescind my idea to do the addition in the controller. For some reason I added the health checks in the controller - and I'm not sure why 😕 so yeah, leave it in gs.Pod()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually now that I'm looking at this, I think it should be something that is specified in GameServer.Spec.Template.Spec (type PodSpec), instead of something that is overwritten manually here. Then it would go in the GameServer type creation yaml files, where a serviceAccountName field is allowed in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would say that it would be a case of - if it has been set in the pod template, then leave it alone. If it hasn't been set, then set it to our rbac value.
Then users can overwrite it if they so desire, but it has a sensible default. Which is pretty much what is done elsewhere. WDYT?
But both options are good to have as well - redefine it globally, but also be able to change it on a per-GameServer basis if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fine, it's just a question of how to decide the default - should it still just be a constant in the types.go file? If we want it to be a value controlled from main.go, then it'll need to come in as a param value which means changing the signature.
I'd lean on having a constant that matches the default sidecar service account over having a flag, personally. If the user wants to modify the sidecar service account name (without rebuilding), then the way to do that would be to provide it in the definition file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd lean on having a constant that matches the default sidecar service account over having a flag, personally. If the user wants to modify the sidecar service account name (without rebuilding), then the way to do that would be to provide it in the definition file.
Why don't we go this way for now, for simplicity sake - and if having the flag becomes something that users want, we can add it at a later date.
build/install.yaml
Outdated
verbs: ["get"] | ||
- apiGroups: ["stable.agones.dev"] | ||
resources: ["gameservers"] | ||
verbs: ["get", "list", "update", "watch"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super interesting to see all the actual permissions required.
@Kuqd A design ticket on whether helm/ksonnet or nothing at all is probably worth talking about. I deliberately haven't gone down that path as it added extra complexity and tooling for the user to know about - but maybe we're at a point were we should look at it? It's worth the discussion at least. |
0aa7224
to
64faa73
Compare
build/Makefile
Outdated
@@ -258,7 +259,7 @@ clean-gcloud-config: | |||
# Switches to an "agones" profile, and starts a kubernetes cluster | |||
# of the right version. | |||
# | |||
# Use MINIKUBE_DRIVER variable to change the VM driver | |||
# Use MINIKUBE_DRIVER variable to change the VM driver | |||
# (defaults virtualbox for Linux and OSX, hyperv for windows) if you so desire. | |||
minikube-test-cluster: minikube-agones-profile | |||
$(MINIKUBE) start --kubernetes-version v1.8.0 --vm-driver $(MINIKUBE_DRIVER) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From: https://kubernetes.io/docs/getting-started-guides/minikube/#examples
To set the AuthorizationMode on the apiserver to RBAC, you can use: --extra-config=apiserver.Authorization.Mode=RBAC.
So we should add the setting --extra-config=apiserver.Authorization.Mode=RBAC
to the minikube-test-cluster
script so that RBAC is enabled there as well.
minikube-test-cluster: minikube-agones-profile
$(MINIKUBE) start --kubernetes-version v1.8.0 --vm-driver $(MINIKUBE_DRIVER) \
--extra-config=apiserver.Authorization.Mode=RBAC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't add this yet - this seems to be what is causing the issue. I'll investigate.
pkg/apis/stable/v1alpha1/types.go
Outdated
@@ -204,6 +206,9 @@ func (gs *GameServer) Pod(sidecars ...corev1.Container) (*corev1.Pod, error) { | |||
pod.ObjectMeta.Namespace = gs.ObjectMeta.Namespace | |||
// Make sure these are blank, just in case | |||
pod.ResourceVersion = "" | |||
if len(pod.Spec.ServiceAccountName) == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nitpicky, but just for consistency's sake across the codebase, this should be:
if pod.Spec.ServiceAccountName != ""
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and this really needs to be included in the tests for Pod() - make sure it's actually set.
https://github.com/googleprivate/agones/blob/master/pkg/apis/stable/v1alpha1/types_test.go#L151
Looks like the
|
The other thing I'm running into (at least on minikube, I haven't test on gke yet), is that the grpc SDK can't connect sdk-sidecar process. All I see is this in the logs for the cpp gameserver:
|
Is RBAC enabled in your cluster? |
As for gRPC not being able to connect, can you tell which resource/verb pair is missing exactly? |
build/Makefile
Outdated
@@ -233,6 +233,7 @@ gcloud-auth-cluster: ensure-build-image | |||
docker run --rm $(common_mounts) $(build_tag) gcloud config set compute/zone \ | |||
`grep zone: $(build_path)/gke-test-cluster/deployment.yml | sed 's/zone: //'` | |||
docker run --rm $(common_mounts) $(build_tag) gcloud container clusters get-credentials $(CLUSTER_NAME) | |||
-docker run --rm $(common_mounts) $(build_tag) kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user $$(gcloud config get-value account) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worked out the bug. This should be:
-docker run --rm $(common_mounts) $(build_tag) bash -c 'kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user $$(gcloud config get-value account)'
This pushes all the command down into the container, so the gcloud
command doesn't get evaluated beforehand.
64faa73
to
aafe57b
Compare
@dzlier-gcp yeah, I have RBAC enabled, I started my minikube cluster with:
as per https://kubernetes.io/docs/getting-started-guides/minikube/#examples Testing on GKE next, see if it's just a minikube issue. |
@dzlier-gcp works fine on GKE - so it's a minikube issue! Investigating. |
Fixed the final minikube issues on commit af9ed94, feature/rbac-mark-fixes branch. If you are happy, I can also merge them here and/or rebase against master, or you can cherry pick the change across and rebase. Up to you. |
af9ed94
to
c8d9b63
Compare
…ar and controller as appropriate.
c8d9b63
to
cd98e93
Compare
Enable RBAC, and create service accounts/roles/rolebindings for sidecar and controller as appropriate.
Currently this creates a service account in the default namespace for sidecar, and another for controller.
It then gives permission to sidecar to get and update GameServers, and access to events, pods, nodes, gameservers, and custom resource definitions for controller.
There are more permissions for controller here than we first discussed; I came by the list of resources and the access required for each by adding them one-at-a-time after the controller failed to start with error messages saying different access was required. Everything there now is needed for one reason or another.
Note: You may need to delete all running
GameServer
s before installing this update, otherwise you may get stuck withGameServer
s that cannot be deleted.Closes #57