diff --git a/build/Makefile b/build/Makefile index 1827924419..4b5d7f1240 100644 --- a/build/Makefile +++ b/build/Makefile @@ -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) # authenticate our docker configuration so that you can do a docker push directly # to the gcr.io repository @@ -258,10 +259,11 @@ 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) + $(MINIKUBE) start --kubernetes-version v1.8.0 --vm-driver $(MINIKUBE_DRIVER) \ + --extra-config=apiserver.Authorization.Mode=RBAC $(MAKE) minikube-post-start # switch to the agones cluster @@ -287,4 +289,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) \ No newline at end of file + docker save $(TAG) | ($(MINIKUBE_DOCKER_ENV) && docker load) diff --git a/build/gke-test-cluster/cluster.yml.jinja b/build/gke-test-cluster/cluster.yml.jinja index 5d6dd98574..f8c6bbe9c6 100644 --- a/build/gke-test-cluster/cluster.yml.jinja +++ b/build/gke-test-cluster/cluster.yml.jinja @@ -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 @@ -35,6 +36,8 @@ resources: masterAuth: username: admin password: supersecretpassword + legacyAbac: + enabled: false - name: game-server-firewall type: compute.beta.firewall properties: diff --git a/build/install.yaml b/build/install.yaml index 3c30e99b5c..0bc99ce6bc 100644 --- a/build/install.yaml +++ b/build/install.yaml @@ -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: @@ -48,6 +46,7 @@ spec: labels: stable.agones.dev/role: controller spec: + serviceAccountName: agones-controller containers: - name: agones-controller image: ${REGISTRY}/agones-controller:${VERSION} @@ -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 diff --git a/install.yaml b/install.yaml index bd5f287f95..970c771574 100644 --- a/install.yaml +++ b/install.yaml @@ -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: @@ -31,6 +36,7 @@ apiVersion: extensions/v1beta1 kind: Deployment metadata: name: agones-controller + namespace: agones-system spec: replicas: 1 strategy: @@ -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 @@ -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 diff --git a/pkg/apis/stable/v1alpha1/types.go b/pkg/apis/stable/v1alpha1/types.go index 25ce8a8794..bb186ef4e7 100644 --- a/pkg/apis/stable/v1alpha1/types.go +++ b/pkg/apis/stable/v1alpha1/types.go @@ -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 ( @@ -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) diff --git a/pkg/apis/stable/v1alpha1/types_test.go b/pkg/apis/stable/v1alpha1/types_test.go index 8a2220ebde..05f3c99008 100644 --- a/pkg/apis/stable/v1alpha1/types_test.go +++ b/pkg/apis/stable/v1alpha1/types_test.go @@ -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) @@ -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))