Who has created a namespace and have access to it - kubernetes

I want to understand who has created a namespace and who has access to a specific namespace in Openshift.
This is specifically required as would require to block access and be very selective about access.

Who has created a specific namespace in OpenShift, can be found checking the parent Project annotations:
$ oc describe project example-project
Name: example-project
Created: 15 months ago
Labels: <none>
Annotations: alm-manager=operator-lifecycle-manager.olm-operator
openshift.io/display-name=Example Project
openshift.io/requester=**here is the username**
...
Who has access to a specific namespace: depends on what you mean by this. The oc client would allow you to review privileges for a given verb, in a given namespace, ... something like this:
$ oc adm policy who-can get pods -n specific-namespace
resourceaccessreviewresponse.authorization.openshift.io/<unknown>
Namespace: specific-namespace
Verb: get
Resource: pods
Users: username1
username2
...
system:admin
system:kube-scheduler
system:serviceaccount:default:router
system:serviceaccount:kube-service-catalog:default
Groups: system:cluster-admins
system:cluster-readers
system:masters

Related

kubectl: create replicaset without a yml file

I am trying to create a replicaset with kubernetes. This time, I don't have a yml file and this is why I am trying to create the replicaset using a command line.
Why kubectl create replicaset somename --image=nginx raise an error, and how to fix this?
You cannot create replicaset using the command line. Only the following resource creation is possible using kubectl create:
kubectl create --help |awk '/Available Commands:/,/^$/'
Available Commands:
clusterrole Create a cluster role
clusterrolebinding Create a cluster role binding for a particular cluster role
configmap Create a config map from a local file, directory or literal value
cronjob Create a cron job with the specified name
deployment Create a deployment with the specified name
ingress Create an ingress with the specified name
job Create a job with the specified name
namespace Create a namespace with the specified name
poddisruptionbudget Create a pod disruption budget with the specified name
priorityclass Create a priority class with the specified name
quota Create a quota with the specified name
role Create a role with single rule
rolebinding Create a role binding for a particular role or cluster role
secret Create a secret using specified subcommand
service Create a service using a specified subcommand
serviceaccount Create a service account with the specified name
Although, You may use the following way to create the replica set, in the below example, kubectl create -f is fed with stdout(-):
echo "apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
# modify replicas according to your case
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: gcr.io/google_samples/gb-frontend:v3
" |kubectl create -f -
Hello, hope you are enjoying your kubernetes journey !
In fact, you cannot create a RS directly, but if you really don't want to use manifest, you can surely create it via a deployment:
❯ kubectl create deployment --image nginx:1.21 --port 80 test-rs
deployment.apps/test-rs created
here it is:
❯ kubectl get rs
NAME DESIRED CURRENT READY AGE
test-rs-5c99c9b8c 1 1 1 15s
bguess

Problem deploying cockroachdb-client-secure

I am following this helm + secure - guide:
https://www.cockroachlabs.com/docs/stable/orchestrate-cockroachdb-with-kubernetes.html#helm
I deployed the cluster with this command: $ helm install my-release --values my-values.yaml cockroachdb/cockroachdb --namespace=thesis-crdb
This is how it looks: $ helm list --namespace=thesis-crdb
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-release thesis-crdb 1 2021-01-31 17:38:52.8102378 +0100 CET deployed cockroachdb-5.0.4 20.2.4
Here is how it looks using: $ kubectl get all --namespace=thesis-crdb
NAME READY STATUS RESTARTS AGE
pod/my-release-cockroachdb-0 1/1 Running 0 7m35s
pod/my-release-cockroachdb-1 1/1 Running 0 7m35s
pod/my-release-cockroachdb-2 1/1 Running 0 7m35s
pod/my-release-cockroachdb-init-fhzdn 0/1 Completed 0 7m35s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/my-release-cockroachdb ClusterIP None <none> 26257/TCP,8080/TCP 7m35s
service/my-release-cockroachdb-public ClusterIP 10.xx.xx.x <none> 26257/TCP,8080/TCP 7m35s
NAME READY AGE
statefulset.apps/my-release-cockroachdb 3/3 7m35s
NAME COMPLETIONS DURATION AGE
job.batch/my-release-cockroachdb-init 1/1 43s 7m36s
In the my-values.yaml-file I only changed the tls from false to true:
tls:
enabled: true
So far so good, but from here on the guide isn't really working for me anymore. I try as they say with getting the csr: kubectl get csr --namespace=thesis-crdb
No resources found
Ok, perhaps not needed. I carry on to deploy the client-secure
I download the file: https://raw.githubusercontent.com/cockroachdb/cockroach/master/cloud/kubernetes/client-secure.yaml
And changes the serviceAccountName: cockroachdb to serviceAccountName: my-release-cockroachdb.
I try to deploy it with $ kubectl create -f client-secure.yaml --namespace=thesis-crdb but it throws this error:
Error from server (Forbidden): error when creating "client-secure.yaml": pods "cockroachdb-client-secure" is forbidden: error looking up service account thesis-crdb/my-release-cockroachdb: serviceaccount "my-release-cockroachdb" not found
Anyone got an idea how to solve this? I'm fairly sure it's something with the namespace that is messing it up.
I have tried to put the namespace in the metadata-section
metadata:
namespace: thesis-crdb
And then try to deploy it with: kubectl create -f client-secure.yaml but to no avail:
Error from server (Forbidden): error when creating "client-secure.yaml": pods "cockroachdb-client-secure" is forbidden: error looking up service account thesis-crdb/my-release-cockroachdb: serviceaccount "my-release-cockroachdb" not found
You mention in question that you have changed serviceAccountName in YAML.
And changes the serviceAccountName: cockroachdb to serviceAccountName: my-release-cockroachdb.
So Root Cause of your issue is related with ServiceAccount misconfiguration.
Background
In your cluster you have something called ServiceAccount.
When you (a human) access the cluster (for example, using kubectl), you are authenticated by the apiserver as a particular User Account (currently this is usually admin, unless your cluster administrator has customized your cluster). Processes in containers inside pods can also contact the apiserver. When they do, they are authenticated as a particular Service Account (for example, default).
To ServiceAccount you also should configure RBAC which grants you permissions to create resources.
Role-based access control (RBAC) is a method of regulating access to computer or network resources based on the roles of individual users within your organization.
RBAC authorization uses the rbac.authorization.k8s.io API group to drive authorization decisions, allowing you to dynamically configure policies through the Kubernetes API.
If you don't have proper RBAC permissions you will not be able to create resources.
In Kubernetes you can find Role and ClusterRole. Role sets permissions within a particular namespace and ClusterRole sets permissions in whole cluster.
Besides that, you also need to bind roles using RoleBinding and ClusterRoleBinding.
In addition, if you would use Cloud environment, you would also need special rights in project. Your guide provides instructions to do it here.
Root cause
I've checked cockroachdb chart and it creates ServiceAccount, Role, ClusterRole, RoleBinding and ClusterRoleBinding for cockroachdb and prometheus. There is no configuration for my-release-cockroachdb.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cockroachdb
...
verbs:
- create
- get
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cockroachdb
labels:
app: cockroachdb
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cockroachdb
...
In client-secure.yaml you change serviceAccountName to my-release-cockroachdb and Kubernetes cannot find that ServiceAccount as it was not created by cluster administrator or cockroachdb chart.
To list ServiceAccounts in default namespace you can use command $ kubectl get ServiceAccount, however if you would check all ServiceAccounts in cluster you should add -A to your command - $ kubectl get ServiceAccount -A.
Solution
Option 1 is to use existing ServiceAccount with proper permissions like SA created by cockroachdb chart which is cockroachdb, not my-release-cockroachdb.
Option 2 is to create ServiceAccount, Role/ClusterRole and RoleBinding/ClusterRoleBinding for my-release-cockroachdb.

Cannot list resource "configmaps" in API group when deploying Weaviate k8s setup on GCP

When running (on GCP):
$ helm upgrade \
--values ./values.yaml \
--install \
--namespace "weaviate" \
"weaviate" \
weaviate.tgz
It returns;
UPGRADE FAILED
Error: configmaps is forbidden: User "system:serviceaccount:kube-system:default" cannot list resource "configmaps" in API group "" in the namespace "ku
be-system"
Error: UPGRADE FAILED: configmaps is forbidden: User "system:serviceaccount:kube-system:default" cannot list resource "configmaps" in API group "" in t
he namespace "kube-system"
UPDATE: based on solution
$ vim rbac-config.yaml
Add to the file:
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tiller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller
namespace: kube-system
Run:
$ kubectl create -f rbac-config.yaml
$ helm init --service-account tiller --upgrade
Note: based on Helm v2.
tl;dr: Setup Helm with the appropriate authorization settings for your cluster, see https://v2.helm.sh/docs/using_helm/#role-based-access-control
Long Answer
Your experience is not specific to the Weaviate Helm chart, rather it looks like Helm is not setup according to the cluster authorization settings. Other Helm commands should fail with the same or a similar error.
The following error
Error: configmaps is forbidden: User "system:serviceaccount:kube-system:default" cannot list resource "configmaps" in API group "" in the namespace "ku
be-system"
means that the default service account in the kube-system namespace is lacking permissions. I assume you have installed Helm/Tiller in the kube-system namespace as this is the default if no other arguments are specified on helm init. Since you haven't created a specific Service Account for Tiller to use it defaults to the default service account.
Since you are mentioning that you are running on GCP, I assume this means you are using GKE. GKE by default has RBAC Authorization enabled. In an RBAC setting no one has any rights by default, all rights need to be explicitly granted.
The helm docs list several options on how to make Helm/Tiller work in an RBAC-enabled setting. If the cluster has the sole purpose of running Weaviate you can choose the simplest option: Service Account with cluster-admin role. The process described there essentially creates a dedicated service account for Tiller, and adds the required ClusterRoleBinding to the existing cluster-admin ClusterRole. Note that this effectively makes Helm/Tiller an admin of the entire cluster.
If you are running a multi-tenant cluster and/or want to limit Tillers permissions to a specific namespace, you need to choose one of the alternatives.

How I create new namespace in Kubernetes

I work in a multi-tenant node app, I know to create a new namespace in Kubernetes is possible to run a kubectl command as follow:
kubectl create namespace <namespace name>
How can I create a new namespace from node Microservices when a new customer make a sign up for a new account?
Is there some kubectl API to make a request from an external app?
Is necessary for the user to log out from app, destroy the pods created in kubernetes?
It could be as simple as calling from a shell in your app:
kubectl create namespace <your-namespace-name>
Essentially, kubectl talks to the kube-apiserver.
You can also directly call the kube-apiserver. This is an example to list the pods:
$ curl -k -H 'Authorization: Bearer <token>' \
https://$KUBERNETES_SERVICE_HOST:6443/api/<api-version>/namespaces/default/pods
More specifically to create a namespace:
$ curl -k -H -X POST -H 'Content-Type: application/json' \
-H 'Authorization: Bearer <token>' \
https://$KUBERNETES_SERVICE_HOST:6443/api/v1/namespaces/ -d '
{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": {
"name": "mynewnamespace"
}
}'
In case you are wondering about the <token>, it's a Kubernetes Secret typically belonging to a ServiceAccount and bound to a ClusterRole that allows you to create namespaces.
You can create a Service Account like this:
$ kubectl create serviceaccount namespace-creator
Then you'll see the token like this (a token is automatically generated):
$ kubectl describe sa namespace-creator
Name: namespace-creator
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: namespace-creator-token-xxxxx
Tokens: namespace-creator-token-xxxxx
Events: <none>
Then you would get the secret:
$ kubectl describe secret namespace-creator-token-xxxxx
Name: namespace-creator-token-xxxx
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: namespace-creator
kubernetes.io/service-account.uid: <redacted>
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 7 bytes
token: <REDACTED> <== This is the token you need for Authorization: Bearer
Your ClusterRole should look something like this:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace-creator
rules:
- apiGroups: ["*"]
resources: ["namespaces"]
verbs: ["create"]
Then you would bind it like this:
$ kubectl create clusterrolebinding namespace-creator-binding --clusterrole=namespace-creator --serviceaccount=namespace-creator
When it comes to writing code you can use any HTTP client library in any language to call the same endpoints.
There are also libraries like the client-go library that takes care of the plumbing of connecting to a kube-apiserver.
you can create namespace using below command:
kubectl create namespace << namespace_name>>.
Please find below some examples
kubectl create namespace dev
kubectl create namespace test
kubectl create namespace prod
To see namespace created:
kubectl get namespace
or
kubectl get ns
or
kubectl get namespaces
To avoid mentioning namespace in every kubectl command execution like while creating pod,deployment or any other kubernetes object, set namespace like as mentioned below:
kubectl config set-context --current --namespace=test
I hope this helped!!
Depends on the language in whcih your Microservice is implemeneted , you can just use the Client library inside that Microservice or write a new microservice in language of your choice, and as Answered above , use a service account with ClusterRoleBinding that can create namespaces. and you are good to go.
Client Libraries here:
Python
Go
Java
Javascript
You can create a name space either on the command line or using a definition file:
To create a namespace using the command line:
kubectl create namespace dev
Another way to create a namespace is using the definition file:
Note: Although the above methods create the namespace "dev", your default namespace may still be "default". (meaning your default namespace is NOT dev).
If you want to change your default namespace to dev so that you don't have to always specify it, you can do the following:
kubectl config set-context $(kubectl config current-context) --namespace=dev
This command first identifies the current context and then sets the namespace to the desired one.
Now that you have changed your default namespace to dev when you run
kubectl get pods
It will list all the pods in the dev namespace.

How to edit Kubernetes ServiceAccount's namespace

I have service account name: myservice
$ kubectl get serviceaccount
NAME SECRETS AGE
default 1 15d
myservice 1 15d
$ kubectl get serviceaccount myservice -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: 2018-06-13T12:41:18Z
name: myservice
namespace: default
...
I want to change the service's namespace default to development.
I tried to edit it with:
kubectl edit serviceaccount myservice
After saving it I received:
A copy of your changes has been stored to "/tmp/kubectl-edit-gjae6.yaml"
error: the namespace from the provided object "development" does not match the namespace "default". You must pass '--namespace=development' to perform this operation.
So I tried like they wrote and it still didn't work:
$ kubectl edit serviceaccount myservice --namespace=development
Error from server (NotFound): serviceaccounts "myservice" not found
The namespace development is exist and also the service myservice.
It seems you should create new myservice SA in development NS instead modifying existing SA in default namespace. Create new myservice in development NS, then remove one in default NS. The error cause the nonexistent myservice even is in development NS.