RANCHER_DESKTOP.md 11 KB

Installing Rancher Desktop in your laptop

Index

Install Rancher Desktop

Install local path provisioner

Deploy a local registry

Install Rancher Desktop

Follow instructions in Rancher Desktop Web

Install local path provisioner

In order to be able to work with persitent storage, it is useful to deploy a local path provisioner so that all pvc created will assing their own persistent volume locally.

You can find intrunctions here

Basically, write a local-path-storage.yaml file with this content:

apiVersion: v1
kind: Namespace
metadata:
  name: local-path-storage

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: local-path-provisioner-service-account
  namespace: local-path-storage

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: local-path-provisioner-role
  namespace: local-path-storage
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: local-path-provisioner-role
rules:
  - apiGroups: [""]
    resources: ["nodes", "persistentvolumeclaims", "configmaps", "pods", "pods/log"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: local-path-provisioner-bind
  namespace: local-path-storage
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: local-path-provisioner-role
subjects:
  - kind: ServiceAccount
    name: local-path-provisioner-service-account
    namespace: local-path-storage

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: local-path-provisioner-bind
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: local-path-provisioner-role
subjects:
  - kind: ServiceAccount
    name: local-path-provisioner-service-account
    namespace: local-path-storage

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: local-path-provisioner
  namespace: local-path-storage
spec:
  replicas: 1
  selector:
    matchLabels:
      app: local-path-provisioner
  template:
    metadata:
      labels:
        app: local-path-provisioner
    spec:
      serviceAccountName: local-path-provisioner-service-account
      containers:
        - name: local-path-provisioner
          image: rancher/local-path-provisioner:v0.0.32
          imagePullPolicy: IfNotPresent
          command:
            - local-path-provisioner
            - --debug
            - start
            - --config
            - /etc/config/config.json
          volumeMounts:
            - name: config-volume
              mountPath: /etc/config/
          env:
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: CONFIG_MOUNT_PATH
              value: /etc/config/
      volumes:
        - name: config-volume
          configMap:
            name: local-path-config

---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: local-path
provisioner: rancher.io/local-path
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Delete

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: local-path-config
  namespace: local-path-storage
data:
  config.json: |-
    {
            "nodePathMap":[
            {
                    "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES",
                    "paths":["/opt/local-path-provisioner"]
            }
            ]
    }
  setup: |-
    #!/bin/sh
    set -eu
    mkdir -m 0777 -p "$VOL_DIR"
  teardown: |-
    #!/bin/sh
    set -eu
    rm -rf "$VOL_DIR"
  helperPod.yaml: |-
    apiVersion: v1
    kind: Pod
    metadata:
      name: helper-pod
    spec:
      priorityClassName: system-node-critical
      tolerations:
        - key: node.kubernetes.io/disk-pressure
          operator: Exists
          effect: NoSchedule
      containers:
      - name: helper-pod
        image: busybox
        imagePullPolicy: IfNotPresent

and

kubectl create -f local-path-storage.yaml

This will create the provisioner as well as a storage class named local-path

Set default storage class

kubectl get sc

NAME                 PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
hostpath (default)   docker.io/hostpath      Delete          Immediate              false                  76m
local-path           rancher.io/local-path   Delete          WaitForFirstConsumer   false                  2m10s

kubectl patch storageclass hostpath -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'

storageclass.storage.k8s.io/hostpath patched

kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

storageclass.storage.k8s.io/local-path patched

kubectl get sc

NAME                   PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
hostpath               docker.io/hostpath      Delete          Immediate              false                  76m
local-path (default)   rancher.io/local-path   Delete          WaitForFirstConsumer   false                  2m50s

Your PVCs either specify to use this storage class or don't specify anything and the default will be used.

Example specifying storageclass

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: local-path-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 128Mi

to use the default storage class, just remove the storageClassName directive

Bear in mind that the storage class is configured to WaitForFirstConsumer so the persistent volume will not be created until a pod request the PVC.

local path provisioner post-installation

For some reason, the local-path-provisioner pod keeps on crashing. Inspecting the logs it says:

kubectl logs deployment.apps/local-path-provisioner -n local-path-storage time="2021-02-24T10:39:15Z" level=fatal msg="Error starting daemon: invalid empty flag helper-pod-file and it also does not exist at ConfigMap local-path-storage/local-path-config with err: configmaps \"local-path-config\" is forbidden: User \"system:serviceaccount:local-path-storage:local-path-provisioner-service- ccount\" cannot get resource \"configmaps\" in API group \"\" in the namespace \"local-path-storage\""

to solve it, we need to apply a change to RBAC by creating a file role-local-path.yaml:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: local-path-provisioner-workaround
  namespace: local-path-storage
rules:
- apiGroups:
    - ''
  resources:
    - configmaps
  verbs:
    - get
    - list
    - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: local-path-provisioner-workaround
  namespace: local-path-storage
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: local-path-provisioner-workaround
subjects:
- kind: ServiceAccount
  name: local-path-provisioner-service-account

and applying (not creating) it with

kubectl apply -f role-local-path.yaml -n local-path-storage

then restarting the deployment:

kubectl rollout restart deployment.apps/local-path-provisioner -n local-path-storage

and finally checking that the pod doesn't crash:

kubectl get pod -n local-path-storage

which should result in:

NAME                                      READY   STATUS    RESTARTS  AGE
local-path-provisioner-5897596697-n2gcg   1/1     Running   0         6m40s

Deploy local registry

If you need to create your own images, you will need a registry.

You can use a public one, such as Dockehub and deal with with thinks like credentials and the like which is good if you want to go to production with your app, or you can deploy your own local registry withing Rancher Desktop. This is only recommended for development.

To deploy a local registry, first create a docker-registry.yaml file:

---
apiVersion: v1
kind: Service
metadata:
  name: docker-registry-service
  labels:
    app: docker-registry
spec:
  selector:
    app: docker-registry
  ports:
    - protocol: TCP
      port: 5000

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: docker-registry-pvc
  labels:
    app: docker-registry
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 10Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: docker-registry
  labels:
    app: docker-registry
spec:
  replicas: 1
  selector:
    matchLabels:
      app: docker-registry
template:
    metadata:
      labels:
        app: docker-registry
    spec:
      containers:
      - name: docker-registry
        image: registry
        ports:
        - containerPort: 5000
          protocol: TCP
        volumeMounts:
        - name: storage
          mountPath: /var/lib/registry
        env:
        - name: REGISTRY_HTTP_ADDR
          value: :5000
        - name: REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
          value: /var/lib/registry
      volumes:
      - name: storage
        persistentVolumeClaim:
          claimName: docker-registry-pvc

and an ingress.yaml:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: '0'
    name: docker-registry-ingress
spec:
    ingressClassName: nginx
    rules:
    - host: registry.rancher.lab
      http:
        paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: docker-registry-service
              port:
                number: 5000

then, create a namespace, the registry and the ingress:

kubectl create ns docker-registry
kubectl create -f docker-registry.yaml -f ingress.yaml