---
# System prepended metadata

title: SUSE Rancher - Useful notes

---

# SUSE Rancher - Useful notes

## Install Rancher with `k3d`

This guide allows you easily install Rancher in a `k3d` based cluster.
This setup uses the [Rancher-generated TLS certificate](https://ranchermanager.docs.rancher.com/getting-started/installation-and-upgrade/install-upgrade-on-a-kubernetes-cluster#3-choose-your-ssl-configuration) SSL configuration.

Create a cluster with `k3d`:

```shell
k3d cluster create test-cluster
```

For the specific Kubernetes version:

```shell
k3d cluster create test-cluster --image rancher/k3s:v1.30.0-rc1-k3s1
```

Add `rancher` chart repo (`latest`) with `helm`:

```shell
helm repo add rancher-latest https://releases.rancher.com/server-charts/latest
```

Create the Kubernetes `Namespace` to host Rancher:

```shell
kubectl create namespace cattle-system
```

Install `cert-manager` with `helm`:

```shell
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --set installCRDs=true
```

Install Rancher with `helm`:

```shell
helm install rancher rancher-latest/rancher --namespace cattle-system --set hostname=rancher.my.org --set bootstrapPassword=admin
```

If you want to install a specific version:

```shell
helm install rancher rancher-latest/rancher --namespace cattle-system --set hostname=rancher.my.org --set bootstrapPassword=admin --version=2.9.3
```

Wait for Rancher to be rolled out:
```shell
kubectl -n cattle-system rollout status deploy/rancher
```

Set the domain name `rancher.my.org` in your `/etc/hosts` file (in order to be able to resolve it when requesting) and local forward traffic from the cluster:

```shell
kubectl expose deployment rancher --name=rancher-lb --port=443 --type=LoadBalancer -n cattle-system
```

Reach Rancher from the browser at: `https://rancher.my.org:4443/`

Alternatively, use the `port-forward` command from `kubectl`:

```
kubectl port-forward -n cattle-system svc/rancher 8000:443
```

To retrive the user password:

```
kubectl get secret --namespace cattle-system bootstrap-secret -o go-template='{{ .data.bootstrapPassword|base64decode}}{{ "\n" }}'
```

## Rancher RBAC

Rancher's offers several RBAC features which are designed to help users manage permissions more easily than with standard k8s RBAC.

In details:

* `GlobalRole` are used to grant access to the local clusters (except the `inheritedClusterRole` field which grants access to all downstream clusters)
* `RoleTemplate` can be used to grant access to a downstream cluster (`ClusterRoleTemplateBinding`) or project (`ProjectRoleTemplateBinding`)

![image](https://hackmd.io/_uploads/H1vdF3qP0.png)

Reference: https://github.com/rancherlabs/engineering-infra/tree/main/docs/rbac

## Setup Keycloak with Rancher (OIDC)

Run **Keycloak**:

```shell
docker run -it --rm -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KEYCLOAK_LOGLEVEL=DEBUG quay.io/keycloak/keycloak:24.0.5 start-dev
```

To provision **Keycloak** automatically, type the following command:

```shell
docker run -it --rm -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KEYCLOAK_LOGLEVEL=DEBUG -v /home/alessio/Documents/github/work/keycloak-config/:/opt/keycloak/data/import quay.io/keycloak/keycloak:24.0.5 start-dev --import-realm
```

In case you are using **ngrok**:
```shell
docker run -it --rm -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin -e KEYCLOAK_LOGLEVEL=DEBUG -e KC_HOSTNAME_URL=https://0a80b2bbac1f.ngrok.app/ -e KC_HOSTNAME_ADMIN_URL=https://0a80b2bbac1f.ngrok.app/ -v /home/alessio/Documents/github/work/keycloak-config/:/opt/keycloak/data/import quay.io/keycloak/keycloak:24.0.5 start-dev --import-realm
```

Run **Rancher**:

```shell
sudo docker run --privileged -it --rm -p 80:80 -p 443:443 --dns 1.1.1.1 -e CATTLE_BOOTSTRAP_PASSWORD=password rancher/rancher
```

Run **Rancher** and use local `kubectl`:
```shell
docker run --privileged -it --rm -p 80:80 -p 443:443 -p 6443:6443 --dns 1.1.1.1 -e CATTLE_BOOTSTRAP_PASSWORD=password rancher/rancher
docker cp <container_id>:/etc/rancher/k3s ./kube/
export KUBECONFIG=./kube/k3s/k3s.yaml
```

Get **Rancher** and **Keycloak** IP addresses:

```shell
docker ps
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container-id>
```

### Configure Keycloak

To configure **Keycloak** follow these instructions or follow this guide: https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/authentication-permissions-and-global-configuration/authentication-config/configure-keycloak-oidc

* Create the realm
* Create the user
* Create credentials for the user (disable Temporary button)
* Create client
    * Client Scopes
    * Select "rancher-dedicated"
    * Select Add Mapper (By configuration)
        * Create Groups Mapper
        * Create Client Audience
        * Create Groups Path

### Configure Rancher

* [Users & Auth] -> [Auth] -> [Keycloak OIDC]

**Keycloak** URL: `https://<keycloak-ngrok>:8080`

**Rancher** URL: `https://<rancher-ngrok>`

**Issuer** URL: `http://<keycloak-ngrok>/realms/myrealm`

**Auth Endpoint** URL: `http://<keycloak-ngrok>/realms/myrealm/protocol/openid-connect/auth`

![image](https://hackmd.io/_uploads/SkmFWix5ye.png)

## Setup LDAP with Rancher

I followed this guide from Enrico's gists: https://gist.github.com/enrichman/f14a1689ae315f83d8d2efe28669ef9e

Use the following `docker-compose.yaml` to setup the environment

```yaml
---
version: '3.7'
services:
  openldap:
    image: osixia/openldap:1.5.0
    container_name: openldap
    hostname: openldap
    ports: 
      - "389:389"
      - "636:636"
    environment: 
      - LDAP_ORGANISATION=example
      - LDAP_DOMAIN=example.com
      - LDAP_ADMIN_USERNAME=admin
      - LDAP_ADMIN_PASSWORD=password
      - LDAP_CONFIG_PASSWORD=password
      - "LDAP_BASE_DN=dc=example,dc=com"
      - LDAP_READONLY_USER=true
      - LDAP_READONLY_USER_USERNAME=user-ro
      - LDAP_READONLY_USER_PASSWORD=ro_pass
    networks:
      - openldap
  
  phpldapadmin:
    image: osixia/phpldapadmin:0.9.0
    container_name: phpldapadmin
    hostname: phpldapadmin
    ports: 
      - "80:80"
    environment: 
      - PHPLDAPADMIN_LDAP_HOSTS=openldap
      - PHPLDAPADMIN_HTTPS=false
    depends_on:
      - openldap
    networks:
      - openldap

  rancher:
    image: rancher/rancher:latest
    container_name: rancher
    hostname: rancher
    privileged: true
    dns:
      - 1.1.1.1
    ports: 
      - "8080:80"
      - "443:443"
    environment: 
      - CATTLE_BOOTSTRAP_PASSWORD=password12345
    depends_on:
      - openldap
    networks:
      - openldap

networks:
  openldap:
    driver: bridge
```

Import this file on `phpldapadmin` (all the hashed password are: `password`):

```txt
# LDIF Export for dc=example,dc=com
# Server: openldap (openldap)
# Search Scope: sub
# Search Filter: (objectClass=*)
# Total Entries: 6
#
# Generated by phpLDAPadmin (http://phpldapadmin.sourceforge.net) on July 19, 2024 3:28 pm
# Version: 1.2.5

version: 1

# Entry 1: dc=example,dc=com
dn: dc=example,dc=com
dc: example
o: example
objectclass: top
objectclass: dcObject
objectclass: organization

# Entry 2: cn=user-ro,dc=example,dc=com
dn: cn=user-ro,dc=example,dc=com
cn: user-ro
description: LDAP read only user
objectclass: simpleSecurityObject
objectclass: organizationalRole
userpassword: {SSHA}SJbTe6zLxF1r0jMa4unwlO99ecomNtKW

# Entry 3: ou=groups,dc=example,dc=com
dn: ou=groups,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: groups

# Entry 4: cn=dev,ou=groups,dc=example,dc=com
dn: cn=dev,ou=groups,dc=example,dc=com
cn: dev
gidnumber: 500
objectclass: posixGroup
objectclass: top

# Entry 5: ou=users,dc=example,dc=com
dn: ou=users,dc=example,dc=com
objectclass: organizationalUnit
objectclass: top
ou: users

# Entry 6: cn=alessio,ou=users,dc=example,dc=com
dn: cn=alessio,ou=users,dc=example,dc=com
cn: alessio
gidnumber: 500
givenname: alessio
homedirectory: /home/users/alessio
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: top
sn: alessio
uid: alessio
uidnumber: 1000
userpassword: {MD5}X03MO1qnZdYdgyfeuILPmQ==
```

### From Rancher

* **Hostname/IP:** `localhost`
* **Service Account Distinguished Name:** `cn=admin,dc=example,dc=com`
* **Service Account Password:** `password`
* **User Search Base:** `ou=users,dc=example,dc=com`
* **Group Search Base:** `ou=groups,dc=example,dc=com`
* **Username:** `alessio`
* **Password:** `password`

## WIP: Join k3d as downstream cluster from Rancher (docker)

Setup the environment with `docker-compose` (`rancher`, `ldap`, etc.).

Then create a **kubernetes** cluster with `k3d`:

**N.B.** always remember to have `nameserver 8.8.8.8` in your `/etc/resolv.conf` to not face with weird DNS issues.

```bash
k3d cluster create --network ldap-config_openldap downstream-cluster -v ~/Documents/github/work/ldap-config/:/tmp@server:0 --image rancher/k3s:v1.26.4-k3s1
```

In this case we are joining the existing network (eg. `ldap-config_openldap`) and mounting a volume that contains static binaries such as `curl` that are not present in `k3d`.

Once `k3d` is ready, we can import it from **rancher**. Remember to add the environment variable to be injected in the `cattle-agent`:
* `CATTLE_AGENT_STRICT_VERIFY`: `false`
* `STRICT_VERIFY`: `false`

### Troubleshooting

In case the following error appear: 
Edit the **cattle-agent** `Deployment` with `dnsPolicy` parameter value from `ClusterFirst` to `Default`
(https://forums.rancher.com/t/waiting-for-api-to-be-available-for-downstream-eks-cluster/37898/3)

*NOTE*
The procedure is not working yet, needs some adjustment.

## Develop the terraform provider rancher2

In order to manually testing the `terraform-provider-rancher2`, once the plugin is built, you have to move it under the right directory in order to be picked up by `terraform`.
Create the right directory tree by:

```bash
mkdir -p ~/.terraform.d/plugins/terraform.local/local/rancher2/0.0.0/linux_amd64
```

Specify the custom plugin in the `terraform` script by adding this:

```hcl!
terraform {
  required_providers {
    rancher2 = {
      source = "terraform.local/local/rancher2" # same path as above ↑↑↑
      version = "0.0.0"
    }
  }
}
```

Run `terraform init` to setup the plugin.

## Create Cloud-init VM

I'm using a `cloud-init` VM in order to create a local node to install **k3s/rke2** on it.

Download the `cloud-init` image from: `https://cloud-images.ubuntu.com/`.

Run this command to create a dedicated disk with more capacity:

```shell
qemu-img create -b Downloads/noble-server-cloudimg-amd64.img -f qcow2 -F qcow2 downstream.img 35G
```

Create the files to setup the VM with `cloud-init`:
`user-data`:
```yaml
#cloud-config
users:
  - name: rancher
    passwd: "$5$v80c4leA1M4qdXbi$igc2QjPYcIwkqBe4O3l3itqy5eBkWkAiYYA1fs1CEG/" #passwd: password
    ssh_authorized_keys:
      - ssh-ed25519 ...
    shell: /bin/bash
    sudo: "ALL=(ALL) NOPASSWD:ALL"
    lock_passwd: false

ssh_pwauth: true
disable_root: false
```

`meta-data`:
```yaml
instance-id: downstream
local-hostname: downstream
```

Validate the configuration with the following command:

```shell
sudo cloud-init schema -c user-data --annotate
```

Create the `iso` image with this command:

```shell
genisoimage -output cloud-init.iso -V cidata -r -J user-data meta-data
```

Run `virt-manager` in order to complete the installation (remember to add the needed CD-ROM storage to load the `cloud-init.iso` file and move it as first boot option).

## Tips & Tricks

### Rebase forked branch with upstream branch

Eg. `local-branch` needs to be rebased with `release/v2.9` (some fixes have been added).

sync fork (branch `release/v2.9`) from github UI.

On the terminal:

```bash
git checkout release/v2.9
git pull
git checkout local-branch
git rebase release/v2.9
git push -f
```

### Add new branch from remote into fork

In case the upstream repo creates a new branch that I didn't fork (because this was not existing at the time I forked).

Eg. `main` branch didn't exists when I forked `rancher/rancher`

In order to update my fork `alegrey91/rancher` do as follow (from `alegrey91/rancher`):

```bash
git remote add upstream https://github.com/rancher/rancher
git fetch upstream
git checkout -b new-branch upstream/new-branch
git push -u origin new-branch
```

### Delete all the stopped containers

To delete all the created containers:

```bash
for c in $(docker ps -a |  tail -n +2 | awk '{print $1}'); do docker rm $c; done
```

### Mocks

If you want to generate mocks for a specific interface:

```bash
mockgen -destination=pkg/controllers/management/auth/zz_user_fakes.go -package=auth k8s.io/client-go/tools/cache Indexer
```

Where `k8s.io/client-go/tools/cache` is the package that holds the `Indexer` methods.

### Ngrok

If you are using **ngrok** to have a public IP with **rancher** behind, remember to to update the `server-url` setting on the rancher settings dashboard.

```shell
ngrok http https://localhost:8443
```

### Cherry-Picking

Usually to back port some commits from one branch to another, is helpful using the command `git cherry-pick`.
In order to back port a commit from a branch, go to the branch that already has the commit. Find the commit hash with `git log`, then `checkout` to the branch where you want to port the commit and run the command:

```shell
git cherry-pick <commit_hash>
```

Since you are importing a commit, there's no need to `git add` / `git commit` since it's already done.
The only thing you need to do is `git push`.