Skip to content

Commit

Permalink
Merge pull request #86 from googleprivate/feature/rbac
Browse files Browse the repository at this point in the history
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 GameServers before installing this update, otherwise you may get stuck with GameServers that cannot be deleted.
  • Loading branch information
markmandel authored Feb 13, 2018
2 parents e56472a + cd98e93 commit 098f5a3
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 4 deletions.
15 changes: 13 additions & 2 deletions build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,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) bash -c 'kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user $$(gcloud config get-value account)'

# authenticate our docker configuration so that you can do a docker push directly
# to the gcr.io repository
Expand Down Expand Up @@ -259,7 +260,17 @@ clean-gcloud-config:
# Use MINIKUBE_DRIVER variable to change the VM driver
# (defaults virtualbox for Linux and macOS, hyperv for windows) if you so desire.
minikube-test-cluster: minikube-agones-profile
$(MINIKUBE) start --kubernetes-version v1.8.0 --vm-driver $(MINIKUBE_DRIVER)
$(MINIKUBE) start --kubernetes-version v1.8.0 --vm-driver $(MINIKUBE_DRIVER) \
--extra-config=apiserver.Authorization.Mode=RBAC
# wait until the master is up
until docker run --rm $(common_mounts) --network=host -v $(minikube_cert_mount) $(DOCKER_RUN_ARGS) $(build_tag) kubectl cluster-info; \
do \
echo "Waiting for cluster to start..."; \
sleep 1; \
done
# this is needed for kubernetes component to work correctly while RBAC is enabled
-docker run --rm $(common_mounts) --network=host -v $(minikube_cert_mount) $(DOCKER_RUN_ARGS) $(build_tag) \
kubectl create clusterrolebinding add-on-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default
$(MAKE) minikube-post-start

# switch to the agones cluster
Expand All @@ -285,4 +296,4 @@ minikube-install: minikube-agones-profile
# Convenience target for transferring images into minikube.
# Use TAG to specify the image to transfer into minikube
minikube-transfer-image:
docker save $(TAG) | ($(MINIKUBE_DOCKER_ENV) && docker load)
docker save $(TAG) | ($(MINIKUBE_DOCKER_ENV) && docker load)
3 changes: 3 additions & 0 deletions build/gke-test-cluster/cluster.yml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ resources:
cluster:
name: test-cluster
description: Test cluster for Agones
initialClusterVersion: 1.8.7-gke.1
nodePools:
- name: "default"
initialNodeCount: 3
Expand All @@ -35,6 +36,8 @@ resources:
masterAuth:
username: admin
password: supersecretpassword
legacyAbac:
enabled: false
- name: game-server-firewall
type: compute.beta.firewall
properties:
Expand Down
97 changes: 95 additions & 2 deletions build/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Install with development settings - suggest using `make install` to run

apiVersion: v1
kind: Namespace
metadata:
Expand Down Expand Up @@ -48,6 +46,7 @@ spec:
labels:
stable.agones.dev/role: controller
spec:
serviceAccountName: agones-controller
containers:
- name: agones-controller
image: ${REGISTRY}/agones-controller:${VERSION}
Expand All @@ -67,3 +66,97 @@ spec:
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
---
# Service account, secret, role and rolebinding for sidecar (agones-sdk) pod
apiVersion: v1
kind: ServiceAccount
metadata:
name: agones-sdk
secrets:
- name: agones-sdk-secret
---
apiVersion: v1
kind: Secret
metadata:
name: agones-sdk-secret
annotations:
kubernetes.io/service-account.name: agones-sdk
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: agones-sdk
namespace: agones-system
rules:
- apiGroups: ["stable.agones.dev"]
resources: ["gameservers"]
verbs: ["get", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: agones-sdk-access
namespace: agones-system
subjects:
- kind: User
name: system:serviceaccount:default:agones-sdk
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: agones-sdk
---
# Service account, secret, role and rolebinding for agones-controller
apiVersion: v1
kind: ServiceAccount
metadata:
name: agones-controller
namespace: agones-system
secrets:
- name: agones-controller-secret
---
apiVersion: v1
kind: Secret
metadata:
name: agones-controller-secret
namespace: agones-system
annotations:
kubernetes.io/service-account.name: agones-controller
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: agones-controller
namespace: agones-system
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "delete", "list", "watch"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list", "watch"]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get"]
- apiGroups: ["stable.agones.dev"]
resources: ["gameservers"]
verbs: ["delete", "get", "list", "update", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: agones-controller-access
namespace: agones-system
subjects:
- kind: User
name: system:serviceaccount:agones-system:agones-controller
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: agones-controller
101 changes: 101 additions & 0 deletions install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: v1
kind: Namespace
metadata:
name: agones-system
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
Expand All @@ -31,6 +36,7 @@ apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: agones-controller
namespace: agones-system
spec:
replicas: 1
strategy:
Expand All @@ -40,6 +46,7 @@ spec:
labels:
stable.agones.dev/role: controller
spec:
serviceAccountName: agones-controller
containers:
- name: agones-controller
image: gcr.io/agones-images/agones-controller:0.1
Expand All @@ -58,3 +65,97 @@ spec:
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
---
# Service account, secret, role and rolebinding for sidecar (agones-sdk) pod
apiVersion: v1
kind: ServiceAccount
metadata:
name: agones-sdk
secrets:
- name: agones-sdk-secret
---
apiVersion: v1
kind: Secret
metadata:
name: agones-sdk-secret
annotations:
kubernetes.io/service-account.name: agones-sdk
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: agones-sdk
namespace: agones-system
rules:
- apiGroups: ["stable.agones.dev"]
resources: ["gameservers"]
verbs: ["get", "update"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: agones-sdk-access
namespace: agones-system
subjects:
- kind: User
name: system:serviceaccount:default:agones-sdk
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: agones-sdk
---
# Service account, secret, role and rolebinding for agones-controller
apiVersion: v1
kind: ServiceAccount
metadata:
name: agones-controller
namespace: agones-system
secrets:
- name: agones-controller-secret
---
apiVersion: v1
kind: Secret
metadata:
name: agones-controller-secret
namespace: agones-system
annotations:
kubernetes.io/service-account.name: agones-controller
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: agones-controller
namespace: agones-system
rules:
- apiGroups: [""]
resources: ["events"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["create", "delete", "list", "watch"]
- apiGroups: [""]
resources: ["nodes"]
verbs: ["list", "watch"]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get"]
- apiGroups: ["stable.agones.dev"]
resources: ["gameservers"]
verbs: ["delete", "get", "list", "update", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: agones-controller-access
namespace: agones-system
subjects:
- kind: User
name: system:serviceaccount:agones-system:agones-controller
apiGroup: rbac.authorization.k8s.io
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: agones-controller
5 changes: 5 additions & 0 deletions pkg/apis/stable/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ const (
// GameServerContainerAnnotation is the annotation that stores
// which container is the container that runs the dedicated game server
GameServerContainerAnnotation = stable.GroupName + "/container"
// SidecarServiceAccountName is the default service account for managing access to get/update GameServers
SidecarServiceAccountName = "agones-sdk"
)

var (
Expand Down Expand Up @@ -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 pod.Spec.ServiceAccountName == "" {
pod.Spec.ServiceAccountName = SidecarServiceAccountName
}
pod.UID = ""
if pod.ObjectMeta.Labels == nil {
pod.ObjectMeta.Labels = make(map[string]string, 2)
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/stable/v1alpha1/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ func TestGameServerPod(t *testing.T) {
assert.Equal(t, "gameserver", pod.ObjectMeta.Labels[stable.GroupName+"/role"])
assert.Equal(t, fixture.ObjectMeta.Name, pod.ObjectMeta.Labels[GameServerPodLabel])
assert.Equal(t, fixture.Spec.Container, pod.ObjectMeta.Annotations[GameServerContainerAnnotation])
assert.Equal(t, "agones-sdk", pod.Spec.ServiceAccountName)
assert.True(t, metav1.IsControlledBy(pod, fixture))
assert.Equal(t, fixture.Spec.HostPort, pod.Spec.Containers[0].Ports[0].HostPort)
assert.Equal(t, fixture.Spec.ContainerPort, pod.Spec.Containers[0].Ports[0].ContainerPort)
Expand All @@ -177,10 +178,12 @@ func TestGameServerPod(t *testing.T) {
assert.True(t, metav1.IsControlledBy(pod, fixture))

sidecar := corev1.Container{Name: "sidecar", Image: "container/sidecar"}
fixture.Spec.Template.Spec.ServiceAccountName = "other-agones-sdk"
pod, err = fixture.Pod(sidecar)
assert.Nil(t, err, "Pod should not return an error")
assert.Equal(t, fixture.ObjectMeta.Name+"-", pod.ObjectMeta.GenerateName)
assert.Len(t, pod.Spec.Containers, 2, "Should have two containers")
assert.Equal(t, "other-agones-sdk", pod.Spec.ServiceAccountName)
assert.Equal(t, "container", pod.Spec.Containers[0].Name)
assert.Equal(t, "sidecar", pod.Spec.Containers[1].Name)
assert.True(t, metav1.IsControlledBy(pod, fixture))
Expand Down

0 comments on commit 098f5a3

Please sign in to comment.