<p>I need to create ServiceAccounts that can access a GKE cluster. Internally I do this with the following commands:</p>

<pre><code>kubectl create serviceaccount onboarding --namespace kube-system
kubectl apply -f onboarding.clusterrole.yaml
kubectl create clusterrolebinding onboarding --clusterrole=onboarding --serviceaccount=kube-system:onboarding
</code></pre>

<p>Where the contents of the file <code>onboarding.clusterrole.yaml</code> are something like this:</p>

<pre><code>apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: onboarding
rules:
- apiGroups:
  - '*'
  resources:
  - 'namespace,role,rolebinding,resourcequota'
  verbs:
  - '*'
</code></pre>

<p>The ServiceAccount resource is created as expected and the ClusterRole and ClusterRoleBinding also look right, but when I attempt to access the API using this new role, I get an Authentication failure.</p>

<pre><code>curl -k -X GET -H "Authorization: Bearer [REDACTED]" https://36.195.83.167/api/v1/namespaces
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "namespaces is forbidden: User \"system:serviceaccount:kube-system:onboarding\" cannot list namespaces at the cluster scope: Unknown user \"system:serviceaccount:kube-system:onboarding\"",
  "reason": "Forbidden",
  "details": {
    "kind": "namespaces"
  },
  "code": 403
</code></pre>

<p>The response suggests an unknown user, but I confirmed the ServiceAccount exists and is in the Subjects of the ClusterRoleBinding. Is it possible to define a ServiceAccount in this way for GKE?</p>

<p>I am using the exact process successfully on kubernetes clusters we run in our datacenters.</p>

Daniel Watrous
<p>GKE should have the same process. Does your <code>kubectl</code> version match that of the GKE cluster? Not sure if this is the issue but the <code>ClusterRole</code> needs plurals for the resources and the resources are represented as lists:</p>

<pre><code>apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: onboarding
rules:
- apiGroups:
  - '*'
  resources:
  - namespaces
  - roles
  - rolebindings
  - resourcequotas
  verbs:
  - '*'
</code></pre>

<p>Works for me on K8s 1.11.x:</p>

<pre><code>curl -k -X GET -H "Authorization: Bearer [REDACTED]" https://127.0.0.1:6443/api/v1/namespaces
{
  "kind": "NamespaceList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces",
    "resourceVersion": "12345678"
  },
  ...
</code></pre>
