--- layout: post title: 'Step 4: RBAC & Security' date: 2025-12-28 06:00:00 -0400 categories: - blog_app highlight: true --- [[2025-12-27-part-3]] # 4. Cluster Management & Security ## 4.1 RBAC: Admin user In Kubernetes, a **ServiceAccount** is an identity for a process or a human to talk to the API. We created an `admin-user` but identities have no power by default. We must link them to a **ClusterRole** (a set of permissions) using a **ClusterRoleBinding**. - **ServiceAccount**: Creates the `admin-user` identity in the dashboard namespace. - **ClusterRoleBinding**: Grants this specific user the `cluster-admin` role (Full access to the entire cluster). **`infra/dashboard/dashboard-admin.yaml`**: ```yaml apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard ``` ## 4.2 Authentication: Permanent Tokens Modern Kubernetes no longer generates tokens automatically for ServiceAccounts. To log into the UI, we need a static, long-lived credential. **`infra/dashboard/permanent-token.yaml`**: ```yaml apiVersion: v1 kind: Secret metadata: name: admin-user-token namespace: kubernetes-dashboard annotations: kubernetes.io/service-account.name: 'admin-user' type: kubernetes.io/service-account-token ``` This creates a **Secret** of type `kubernetes.io/service-account-token`. By adding the annotation `kubernetes.io/service-account.name: "admin-user"`, K8s automatically populates the Secret with a signed JWT token that we can use to bypass the login screen. ## 4.3 Localhost: Ingress & Cookies The Kubernetes Dashboard requires HTTPS, which creates issues with self-signed certificates on `localhost`. We need to reconfigure **Traefik** (the internal reverse proxy bundled with K3s) to allow insecure backends. **Helm & CRDs** K3s installs Traefik using **Helm** (the Kubernetes Package Manager). Usually, you manage Helm via CLI (`helm install`). However, K3s includes a **Helm Controller** that lets us manage charts using YAML files called **HelmChartConfigs** (a Custom Resource Definition or CRD). This allows us to reconfigure a complex Helm deployment using a simple declarative file. **`infra/dashboard/traefik-config.yaml`** ```yaml apiVersion: helm.cattle.io/v1 kind: HelmChartConfig metadata: name: traefik namespace: kube-system spec: valuesContent: |- additionalArguments: # Tell Traefik to ignore SSL errors when talking to internal services - "--serversTransport.insecureSkipVerify=true" ``` ## 4.4. Stress Testing & Verification We used **Apache Bench (`ab`)** to generate massive concurrency capable of triggering the HPA. This test results in tens of thousands of requests which triggers the RPS rule in out HPA configuration. ```bash # Generate 50 concurrent users for 5 minutes ab -k -c 50 -t 300 -H "Host: blog.localhost" http://127.0.0.1:8080/ ```