Let Kubernetes Pod create a Deployment (Giving a Pod access to the Kubernetes API)
If you are running code inside of a Kubernetes Pod
which needs to create a Kubernetes Deployment
, Service, etc., by default, you will get the following error.
Unhandled exception. Microsoft.Rest.HttpOperationException: Operation returned an invalid status code 'Forbidden'
at k8s.Kubernetes.SendRequestRaw(String requestContent, HttpRequestMessage httpRequest, CancellationToken cancellationToken)
at k8s.Kubernetes.CreateNamespacedDeploymentWithHttpMessagesAsync(V1Deployment body, String namespaceParameter, String dryRun, String fieldManager, String fieldValidation, Nullable`1 pretty, IDictionary`2 customHeaders, CancellationToken cancellationToken)
at k8s.KubernetesExtensions.CreateNamespacedDeploymentAsync(IKubernetes operations, V1Deployment body, String namespaceParameter, String dryRun, String fieldManager, String fieldValidation, Nullable`1 pretty, CancellationToken cancellationToken)
at Program.<Main>$(String[] args) in /src/Program.cs:line 68
at Program.<Main>(String[] args)
This is otherwise known as giving a pod access to the Kubernetes API. This will break down exactly what you need to do to give your pod the right permissions.
See the examples repo for a working example demonstrating how to create a deployment within a pod.
Step 1: Create a Kubernetes Service Account
See https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ for more information on Service Accounts.
apiVersion: v1
kind: ServiceAccount
metadata:
name: manager
namespace: default
Step 2: Create a Kubernetes Role
This will give permissions for the ClusterRole to create deployments.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: manager-role
rules:
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
Step 3: Create a Kubernetes Role Binding
See https://kubernetes.io/docs/reference/access-authn-authz/rbac/#clusterrolebinding-example for more info on Role Bindings.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: manager-role
subjects:
- kind: ServiceAccount
name: manager
namespace: default
Step 4: Modify your Kubernetes Deployment to use the Service Account
kind: Deployment
apiVersion: apps/v1
metadata:
name: app
labels:
app.kubernetes.io/name: app
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: app
template:
metadata:
labels:
app.kubernetes.io/name: app
spec:
serviceAccountName: manager # This is the part to modify
containers:
- name: hello-world
image: jkotalik/let-pod-create-deployment:latest
env:
- name: DOTNET_LOGGING__CONSOLE__DISABLECOLORS
value: 'true'
- name: ASPNETCORE_URLS
value: 'http://*'
ports:
- containerPort: 80