# Manual setup

{% hint style="info" %}
The following content assumes you have [**`kubectl` binary**](https://kubernetes.io/docs/tasks/tools/#kubectl) **installed**, as well as a **privileged access** to your cluster to create listed resources.
{% endhint %}

## :construction\_worker: Service account

We recommend to create a specific **ServiceAccount** object in your cluster to authenticate KuboVisor and grant it specific permissions, but nothing prevents you from using an already existing service account.

In this example, the service account `ksa-kubovisor` will be created in the `kubovisor` namespace. You are free to rename the service account and/or to create it in another namespace.

```bash
kubectl create namespace kubovisor
kubectl create serviceaccount ksa-kubovisor --namespace kubovisor
```

{% hint style="warning" %}
**Kubernetes ≥ 1.24**

If your cluster version equals or is over 1.24 (or if you have the *`LegacyServiceAccountTokenNoAutoGeneration`* feature gate enabled), you will have to manually generate an authentication token for the *ServiceAccount*.

To get your cluster’s Kubernetes version, you can use this `kubectl` command:

```bash
kubectl version --short=true
```

To generate an authentication token for the *ServiceAccount*, you need to create a *Secret* defined by the following YAML. Save its content in a **`kubovisor-secret.yaml`** file:

```yaml
apiVersion: v1
kind: Secret
metadata:
  namespace: kubovisor
  name: ksa-kubovisor
  annotations:
    kubernetes.io/service-account.name: ksa-kubovisor
type: kubernetes.io/service-account-token
```

Apply the *Secret* on your cluster to generate the *ServiceAccount* token:

```bash
kubectl apply -f kubovisor-secret.yaml
```

{% endhint %}

References:

* [Managing Service Accounts](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/)
* [Service account tokens](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#service-account-tokens)
* [ServiceAccount reference](https://kubernetes.io/docs/reference/kubernetes-api/authentication-resources/service-account-v1/)

## :scales: Permissions

{% hint style="info" %}
This section uses the `kubovisor` namespace to reference and create objects. Be sure to update the namespace references if you used another name.
{% endhint %}

We currently provide two different set of permissions:

* \*\*\*\*[**limited permissions**](#limited) that will allow us to **dig deeper** in our analysis of your cluster.
* \*\*\*\*[**read-only permissions**](#read-only) that will enable a **base set** of features.

{% hint style="warning" %}
Permissions may **evolve** as we introduce **new features**.

If you encounter permissions-related issues, be sure to review the minimum required permissions listed below before [asking for support](mailto:techsupport@kubolabs.io).

Note that we currently only provide permissions definition for [**Role Based Access Control**](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) authorization mode. Make sure that your cluster supports it.
{% endhint %}

### Limited write

This set of permissions grants us read-only access to all deployed resources on your cluster, in all namespaces, as well as read-write access to pods in `kubovisor` namespace. We won’t be able to temper with resources outside of `kubovisor` namespace, only see them.

To define these permissions, we use the **ClusterRole**, **ClusterRoleBinding**, **Role** and **RoleBinding** objects and link them to the service account we created earlier.

This is the YAML definition of these objects:

{% code title="kubovisor-limited-permissions.yaml" lineNumbers="true" %}

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kubovisor
rules:
  - apiGroups:
      - '*'
    resources:
      - '*'
    verbs:
      - list
      - get
      - watch
  - nonResourceURLs:
      - /metrics
    verbs:
      - get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubovisor
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubovisor
subjects:
  - kind: ServiceAccount
    name: ksa-kubovisor
    apiGroup: ''
    namespace: kubovisor
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: kubovisor
  name: kubovisor-limited
rules:
  - apiGroups:
      - ''
    resources:
      - pods
      - pods/log
    verbs:
      - create
      - get
      - delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: kubovisor
  name: kubovisor-limited
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubovisor-limited
subjects:
  - kind: ServiceAccount
    name: ksa-kubovisor
    apiGroup: ''
    namespace: kubovisor
```

{% endcode %}

You can create them by applying the YAML definition or with the following commands:

```bash
kubectl create clusterrole kubovisor \
  --verb=list,get,watch \
  --resource='*.*'
kubectl patch clusterrole kubovisor \
  --patch '{"rules":[{"apiGroups":["*"],"resources":["*"],"verbs":["list","get","watch"]},{"nonResourceURLs":["/metrics"],"verbs":["get"]}]}'
kubectl create clusterrolebinding kubovisor \
  --clusterrole=kubovisor \
  --serviceaccount=kubovisor:ksa-kubovisor
kubectl create role kubovisor-limited \
  --namespace kubovisor \
  --verb=create,get,delete \
  --resource=pods,pods/log
kubectl create rolebinding kubovisor-limited \
  --namespace kubovisor \
  --role=kubovisor-limited \
  --serviceaccount=kubovisor:ksa-kubovisor
```

### Read-only

This set of permissions grants us read-only access to all deployed resources on your cluster, in all namespaces. We won’t be able to temper with them, only see them.

To define these permissions, we use the **ClusterRole** and **ClusterRoleBinding** objects and link them to the service account we created earlier.

This is the YAML definition of these objects:

{% code title="kubovisor-readonly-permissions.yaml" lineNumbers="true" %}

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kubovisor
rules:
  - apiGroups:
      - '*'
    resources:
      - '*'
    verbs:
      - list
      - get
      - watch
  - nonResourceURLs:
      - /metrics
    verbs:
      - get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubovisor
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubovisor
subjects:
  - kind: ServiceAccount
    name: ksa-kubovisor
    apiGroup: ''
    namespace: kubovisor
```

{% endcode %}

You can create them by applying the YAML definition or with the following commands:

```bash
kubectl create clusterrole kubovisor \
  --verb=list,get,watch \
  --resource='*.*'
kubectl patch clusterrole kubovisor \
  --patch '{"rules":[{"apiGroups":["*"],"resources":["*"],"verbs":["list","get","watch"]},{"nonResourceURLs":["/metrics"],"verbs":["get"]}]}'
kubectl create clusterrolebinding kubovisor \
  --clusterrole=kubovisor \
  --serviceaccount=kubovisor:ksa-kubovisor
```

## :key: Credentials generation

Last step is to generate a *kubeconfig* file for the `ksa-kubovisor` *ServiceAccount* that we created earlier. You can use our [hand-crafted Bash script](https://download.kubolabs.io/scripts/create_kubeconfig) to quickly generate one:

{% hint style="warning" %}
If you want to use a different *ServiceAccount*, update the parameters provided to the script to match your *ServiceAccount* name and its *Namespace*.
{% endhint %}

```bash
curl -sO https://download.kubolabs.io/scripts/create_kubeconfig
chmod +x create_kubeconfig
./create_kubeconfig ksa-kubovisor --namespace kubovisor
```

{% hint style="info" %}
Learn more about what this script does on our [dedicated article](/guides/generate-kubernetes-credentials.md).
{% endhint %}

At the end of the execution, a *kubeconfig* file will be generated in the current directory. Use this *kubeconfig* on KuboVisor to [add your cluster](/getting-started/kubovisor/cloud-mode.md#add-your-cluster).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kubolabs.io/getting-started/kubovisor/cloud-mode/manual-setup.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
