By adding specific privileges, you can execute kubectl
within a container to operate on clusters.
The standard Kubernetes way for managing container privileges is using Role
resource.
For the assurance of RBAC and scalability, directly assigning a Role
to a Pod
is not possible. Instead, you need both RoleBinding
and ServiceAccount
, creating the following references:
Role <- RoleBinding -> ServiceAccount <- Pod
Additionally, some hosting platforms like GKE may provide authentication separate from the standard Kubernetes accounting.
As described later, authorization using Role
allows granular permission assignments on an individual resource basis and is suitable for scenarios where the target of operations is clear.
Authentication in GKE, for example, is well-suited for controlling a wide range of cluster resources or controlling GCP functions outside the cluster through API when the target is not explicitly within the Kubernetes API.
In very old Kubernetes clusters, the RBAC authorization feature itself may not be enabled. In such cases, version upgrades or configuration changes may be necessary.
kubectl for containers
kubectl command that you ultimately want to run should be added to the container image in advance.
It can operate with either package additions provided by the distribution or
officially distributed binaries.
With Role
setup, additional authentication plugins are not required since it utilizes the standard Kubernetes API.
Role
The resource spec for Role
is thoroughly explained in the
official guide.
As mentioned earlier, Role
defines authorization permissions:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
In a container granted the above permission set, kubectl get pods
will work as intended.
Defining the permissions available in rules
block can be challenging without an easy way to know the keywords to specify.
rules.[].apiGroups
specifies the resource classification, using the URI obtained by removing the version from each resource’sapiVersion
string.- Core APIs, including operations like Pod manipulation, can be specified using the shorthand notation
""
. While it is concise as a string, the concept is not immediately evident. For instance, sincenetworking.k8s.io
is not a core API, it won’t work without explicitly mentioning the URI, making it less intuitive.
- Core APIs, including operations like Pod manipulation, can be specified using the shorthand notation
rules.[].resources
denotes the specific target of operations. In this example, sub-resources are not immediately obvious.- This item specifies the path in the HTTP API of Kubernetes, and one could identify it with an HTTP API reference.
rules.[].verbs
represents operation categories in a manner similar to HTTP methods. Although it corresponds tokubectl
subcommands, it is not entirely the same label, making it less obvious.- For example, the resource update operation corresponding to
kubectl apply
requires eitherupdate
orpatch
permissions, but there is no straightforward means to determine.
- For example, the resource update operation corresponding to
Role or ClusterRole
The permissions specified by Role
are limited to resources within the metadata.namespace
.
To grant permissions for broader resources in one go, you would use ClusterRole
and its corresponding ClusterBinding
.
If you can pinpoint the target of operations, using the narrower-scoped Role
is more secure.
ServiceAccount
ServiceAccount is an unattended user. Basically, it defines labels that represent its purpose.
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-serviceaccount
namespace: default
By specifying serviceAccountName
in the podSpec of resources like Deployment, the Pod operates with the designated ServiceAccount.
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
serviceAccountName: my-serviceaccount
containers:
- name: nginx
image: nginx:latest
RoleBinding
In this example, RoleBinding
is a resource that associates ServiceAccount
with Role
, and it simply references them once their names are determined appropriately.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: ServiceAccount
name: my-serviceaccount
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-and-pod-logs-reader
apiGroup: rbac.authorization.k8s.io
In this example, it may seem like there is simply an added overhead because there is only one ServiceAccount
. However, the design is intended to minimize unexpected security vulnerabilities by allowing changes to the subjects
list at any time and keeping the roleRef
fixed.
Chuma Takahiro