Namespaces & RBAC - Multi-tenancy và Security

Tổng quan

Namespaces provide virtual clusters trong physical cluster. RBAC (Role-Based Access Control) controls access to Kubernetes resources.

Namespaces

Creating Namespaces

apiVersion: v1
kind: Namespace
metadata:
  name: development

Default Namespaces

  • default
  • kube-system
  • kube-public
  • kube-node-lease

Resource Quotas

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
  namespace: development
spec:
  hard:
    requests.cpu: "4"
    requests.memory: 8Gi
    persistentvolumeclaims: "10"

RBAC

Roles

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: development
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

ClusterRoles

Cluster-wide permissions.

RoleBindings

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: development
subjects:
- kind: User
  name: jane
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Service Accounts

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  namespace: development

Managing RBAC with Java (Fabric8 Kubernetes Client)

Bạn có thể quản lý các tài nguyên RBAC (Roles, RoleBindings, ServiceAccounts) trong Kubernetes bằng Java sử dụng Fabric8 Kubernetes Client.

import io.fabric8.kubernetes.api.model.rbac.Role;
import io.fabric8.kubernetes.api.model.rbac.RoleBinding;
import io.fabric8.kubernetes.api.model.rbac.RoleBindingBuilder;
import io.fabric8.kubernetes.api.model.rbac.RoleBuilder;
import io.fabric8.kubernetes.api.model.ServiceAccount;
import io.fabric8.kubernetes.api.model.ServiceAccountBuilder;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;

public class RbacManager {

    public static void main(String[] args) {
        try (KubernetesClient client = new DefaultKubernetesClient()) {
            String namespace = "my-secure-namespace";
            String serviceAccountName = "my-app-sa";
            String roleName = "pod-and-log-reader";
            String userName = "dev-user";

            // 1. Create a Namespace (if it doesn't exist)
            if (client.namespaces().withName(namespace).get() == null) {
                client.namespaces().createOrReplaceWithNew()
                        .withNewMetadata().withName(namespace).endMetadata()
                        .build();
                System.out.println("Namespace " + namespace + " created.");
            }

            // 2. Create a ServiceAccount
            ServiceAccount serviceAccount = new ServiceAccountBuilder()
                    .withNewMetadata().withName(serviceAccountName).endMetadata()
                    .build();
            client.serviceAccounts().inNamespace(namespace).createOrReplace(serviceAccount);
            System.out.println("ServiceAccount " + serviceAccountName + " created in " + namespace + ".");

            // 3. Create a Role
            Role role = new RoleBuilder()
                    .withNewMetadata().withName(roleName).endMetadata()
                    .addNewRule()
                        .withApiGroups("")
                        .withResources("pods", "pods/log")
                        .withVerbs("get", "list", "watch")
                    .endRule()
                    .build();
            client.rbac().roles().inNamespace(namespace).createOrReplace(role);
            System.out.println("Role " + roleName + " created in " + namespace + ".");

            // 4. Create a RoleBinding for the ServiceAccount
            RoleBinding saRoleBinding = new RoleBindingBuilder()
                    .withNewMetadata().withName(serviceAccountName + "-binding").endMetadata()
                    .withNewRoleRef()
                        .withApiGroup("rbac.authorization.k8s.io")
                        .withKind("Role")
                        .withName(roleName)
                    .endRoleRef()
                    .addNewSubject()
                        .withKind("ServiceAccount")
                        .withName(serviceAccountName)
                        .withNamespace(namespace)
                    .endSubject()
                    .build();
            client.rbac().roleBindings().inNamespace(namespace).createOrReplace(saRoleBinding);
            System.out.println("RoleBinding for ServiceAccount " + serviceAccountName + " created.");

            // 5. Create a RoleBinding for a User (example for external user)
            RoleBinding userRoleBinding = new RoleBindingBuilder()
                    .withNewMetadata().withName(userName + "-binding").endMetadata()
                    .withNewRoleRef()
                        .withApiGroup("rbac.authorization.k8s.io")
                        .withKind("Role")
                        .withName(roleName)
                    .endRoleRef()
                    .addNewSubject()
                        .withKind("User")
                        .withName(userName)
                        .withApiGroup("rbac.authorization.k8s.io")
                    .endSubject()
                    .build();
            client.rbac().roleBindings().inNamespace(namespace).createOrReplace(userRoleBinding);
            System.out.println("RoleBinding for User " + userName + " created.");

        } catch (Exception e) {
            System.err.println("Error managing RBAC: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

Security Best Practices

  • Principle of least privilege
  • Use dedicated namespaces cho environments
  • Regular RBAC audits
  • Service account token rotation
  • Network policies

Multi-tenancy Patterns

  • Namespace per team
  • Namespace per environment
  • Namespace per application

Nội dung đã được mở rộng với advanced RBAC patterns và security hardening, cùng các ví dụ Java.