RBAC permissions for Helm
I this post I will demonstrate the basic mechanism of helm and Role-based access control (RBAC).
Parts of the Kubernetes series
- Part1a: Install K8S with ansible
- Part1b: Install K8S with kubeadm
- Part1c: Install K8S with kubeadm and containerd
- Part1d: Install K8S with kubeadm and allow swap
- Part1e: Install K8S with kubeadm in HA mode
- Part2: Intall metal-lb with K8S
- Part2: Intall metal-lb with BGP
- Part3: Install Nginx ingress to K8S
- Part4: Install cert-manager to K8S
- Part5a: Use local persisten volume with K8S
- Part5b: Use ceph persisten volume with K8S
- Part5c: Use ceph CSI persisten volume with K8S
- Part5d: Kubernetes CephFS volume with CSI driver
- Part5e: Use Project Longhorn as persisten volume with K8S
- Part5f: Use OpenEBS as persisten volume with K8S
- Part5f: vSphere persistent storage for K8S
- Part6: Kubernetes volume expansion with Ceph RBD CSI driver
- Part7a: Install k8s with IPVS mode
- Part7b: Install k8s with IPVS mode
- Part8: Use Helm with K8S
- Part9: Tillerless helm2 install
- Part10: Kubernetes Dashboard SSO
- Part11: Kuberos for K8S
- Part12: Gangway for K8S
- Part13a: Velero Backup for K8S
- Part13b: How to Backup Kubernetes to git?
- Part14a: K8S Logging And Monitoring
- Part14b: Install Grafana Loki with Helm3
I whant to use helm on Openshift but firt I startid with the basics of helm and Role-based access control (RBAC) on a simple Kubernestes cluster. Most people seem to be running Helm with their own credentials or a dedicated service account with cluster-admin permissions. This isn’t very good from a security perspective, especially so if it’s being run within CI/CD.
Helm
Helm is a package manager and teplating engine for Kubernetes. It based on tree main components:
- the helm cli client
- the helm server called tiller
- the template pcakage called halm chart
Helm with cluster-admin permissions
nano helm-cluster-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: tiller-admin
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tiller-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: tiller-admin
namespace: kube-system
Helm with namespace permissions
We are granting permissions on only the API groups and resources that Tiller needs to deploy and manage releases in its namespace.
nano helm-dev-namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
name: dev
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: tiller
namespace: dev
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tiller-manager
namespace: dev
rules:
- apiGroups: ["", "batch", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tiller-binding
namespace: dev
subjects:
- kind: ServiceAccount
name: tiller
namespace: dev
roleRef:
kind: Role
name: tiller-manager
apiGroup: rbac.authorization.k8s.io
nano helm-prod-namespace.yaml
kind: Namespace
apiVersion: v1
metadata:
name: prod
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: tiller
namespace: prod
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tiller-manager
namespace: prod
rules:
- apiGroups: ["", "batch", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tiller-binding
namespace: prod
subjects:
- kind: ServiceAccount
name: tiller
namespace: prod
roleRef:
kind: Role
name: tiller-manager
apiGroup: rbac.authorization.k8s.io
kubectl create -f helm-dev-namespace.yaml
kubectl create -f helm-prod-namespace.yaml
kubectl -n dev get sa
kubectl -n prod get sa
helm init --service-account tiller --tiller-namespace dev
helm init --service-account tiller --tiller-namespace prod
Helm with minimal cluster permissions
nano helm-cluster-role.yml
kind: Namespace
apiVersion: v1
metadata:
name: helm
---
kind: ServiceAccount
apiVersion: v1
metadata:
name: helm
namespace: helm
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: helm-clusterrole
rules:
- apiGroups: [""]
resources: ["pods/portforward"]
verbs: ["create"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["list", "get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: helm-clusterrolebinding
roleRef:
kind: ClusterRole
apiGroup: rbac.authorization.k8s.io
name: helm-clusterrole
subjects:
- kind: ServiceAccount
name: helm
namespace: helm
Generate a Kubeconfig file from the Helm Service Account
Credit to Ami Mahloof for this script.
NAMESPACE=helm
# Find the secret associated with the Service Account
SECRET=$(kubectl -n $NAMESPACE get sa helm -o jsonpath='{.secrets[].name}')
# Get the token from the secret
TOKEN=$(kubectl get secrets -n $NAMESPACE $SECRET -o jsonpath='{.data.token}' | base64 -D)
# Get the CA from the secret
kubectl get secrets -n $NAMESPACE $SECRET -o jsonpath='{.data.ca\.crt}' | base64 -D > ca.crt
CONTEXT=$(kubectl config current-context)
CLUSTER_NAME=$(kubectl config get-contexts $CONTEXT --no-headers=true | awk '{print $3}')
SERVER=$(kubectl config view -o jsonpath="{.clusters[?(@.name == \"${CLUSTER_NAME}\")].cluster.server}")
KUBECONFIG_FILE=config
USER=helm
CA=ca.crt
# Set up config
kubectl config set-cluster $CLUSTER_NAME \
--kubeconfig=$KUBECONFIG_FILE \
--server=$SERVER \
--certificate-authority=$CA \
--embed-certs=true
kubectl config set-credentials $USER \
--kubeconfig=$KUBECONFIG_FILE \
--token=$TOKEN
kubectl config set-context $USER \
--kubeconfig=$KUBECONFIG_FILE \
--cluster=$CLUSTER_NAME \
--user=$USER
kubectl config use-context $USER \
--kubeconfig=$KUBECONFIG_FILE