Kubernetes 101: Kubernetes Storage and Security

Vipul VyasVipul Vyas
7 min read

Kubernetes is an open-source container orchestration platform that provides a robust framework for deploying, scaling, and managing containerized applications. In addition to its core features, Kubernetes also provides a range of advanced storage and security features that allow users to build secure, scalable, and resilient applications.

In this article, we will cover some of the key storage and security features of Kubernetes, including Persistent Volumes, Persistent Volume Claims, Storage Classes, StatefulSets, RBAC (Role-Based Access Control), Pod Security Policies, Secrets, Network Policies, and TLS (Transport Layer Security).

Persistent Volumes

Persistent Volumes (PVs) are a core Kubernetes feature that allows users to provision storage resources and use them as persistent data volumes for their applications. A Persistent Volume is a piece of storage that has been provisioned by an administrator or dynamically provisioned by Kubernetes itself. Once a Persistent Volume has been created, it can be used by one or more Pods within a cluster.

Here's an example of how to create a Persistent Volume in Kubernetes:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  nfs:
    server: my-nfs-server.example.com
    path: /exports/data

In this example, we are creating a Persistent Volume with a capacity of 1Gi, using the NFS storage backend. The Persistent Volume has a single access mode of ReadWriteOnce, which means that it can be mounted by a single node in read-write mode. The Persistent Volume also has a persistentVolumeReclaimPolicy of Retain, which means that the data stored on the volume will be retained even after the Pod that used the volume is deleted.

Persistent Volume Claims

Persistent Volume Claims (PVCs) are used to request access to a specific Persistent Volume that matches certain criteria, such as storage capacity or access mode. PVCs are used by Kubernetes Pods to request storage resources, and Kubernetes will dynamically provision a Persistent Volume that matches the criteria specified in the PVC.

Here's an example of how to create a PVC in Kubernetes:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: standard

In this example, we are creating a PVC with a capacity of 1Gi and an access mode of ReadWriteOnce. The PVC is associated with a Storage Class called "standard", which means that Kubernetes will dynamically provision a Persistent Volume that matches the criteria specified in the PVC.

Storage Classes

Storage Classes are used to define the different types of storage that are available to Kubernetes Pods. Each Storage Class is associated with one or more storage backends, and Kubernetes can dynamically provision Persistent Volumes based on the Storage Class that is requested by a PVC.

Here's an example of how to create a Storage Class in Kubernetes:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2

In this example, we are creating a Storage Class called "standard" that is associated with the AWS EBS storage backend. The Storage Class specifies that volumes should be provisioned using the gp2 storage type.

StatefulSets

StatefulSets are used to deploy stateful applications in Kubernetes, such as databases or other applications that require unique network identifiers, persistent storage, and ordered pod creation and termination. StatefulSets provide a way to ensure that each pod in the set is assigned a unique identifier and that each pod has access to its own persistent volume.

Here's an example of how to create a StatefulSet in Kubernetes:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: mysql-persistent-storage
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi
      storageClassName: standard

In this example, we are creating a StatefulSet for a MySQL database with three replicas. Each replica is assigned a unique identifier, and each pod is assigned its own persistent volume. The StatefulSet specifies a volumeClaimTemplate that is used to create PVCs for each pod.

RBAC (Role-Based Access Control)

Role-Based Access Control (RBAC) is a Kubernetes feature that allows administrators to define fine-grained access controls for Kubernetes resources. RBAC provides a way to control who can access and modify Kubernetes resources, such as pods, services, and config maps.

Here's an example of how to create a Role and a RoleBinding in Kubernetes:

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

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

In this example, we are creating a Role called "pod-reader" that grants read access to pods. We are also creating a RoleBinding that binds the "pod-reader" role to a specific user called "alice".

Pod Security Policies

Pod Security Policies are used to enforce security policies on Kubernetes Pods. Pod Security Policies define a set of security policies that must be met in order for a Pod to be created.

Here's an example of how to create a Pod Security Policy in Kubernetes:

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
spec:
  privileged: false
  allowPrivilegeEscalation: false
  runAsUser:
    rule: 'MustRunAsNonRoot'
  seLinux:
    rule: 'RunAsAny'
  fsGroup:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'RunAsAny'
  volumes:
  - 'configMap'
  - 'emptyDir'
  - 'projected'
  - 'secret'
  - 'downwardAPI'

In this example, we are creating a Pod Security Policy called "restricted" that specifies a set of security policies that must be met in order for a Pod to be created. The security policies include things like not allowing privileged containers, not allowing privilege escalation, and running as a non-root user.

Secrets

Kubernetes Secrets are used to store and manage sensitive information, such as passwords, keys, and tokens. Secrets are used to keep sensitive information out of the container image and to make it easier to manage secrets separately from the container.

Here's an example of how to create a Secret in Kubernetes:

apiVersion: v1
kind: Secret
metadata:
  name: db-password
type: Opaque
data:
  password: cGFzc3dvcmQ=

In this example, we are creating a Secret called "db-password" that contains a base64-encoded password. The Secret is of type "Opaque", which means that it can contain arbitrary data.

Network Policies

Network Policies are used to control traffic flow between Kubernetes Pods. Network Policies define a set of rules that specify how traffic should be allowed or denied between Pods.

Here's an example of how to create a Network Policy in Kubernetes:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-db-traffic
spec:
  podSelector:
    matchLabels:
      app: db
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: web

In this example, we are creating a Network Policy called "allow-db-traffic" that allows traffic from Pods with the label "app: web" to Pods with the label "app: db".

TLS (Transport Layer Security)

Transport Layer Security (TLS) is a cryptographic protocol used to secure network communications. Kubernetes supports TLS for securing communications between Pods and for securing communications with external services.

Here's an example of how to create a TLS certificate in Kubernetes:

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-tls-cert
spec:
  secretName: example-tls-secret
  duration: 2160h
  renewBefore: 360h
  commonName: example.com
  dnsNames:
  - example.com
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  privateKey:
    algorithm: RSA
    size: 2048

In this example, we are creating a TLS certificate called "example-tls-cert" that is issued by Let's Encrypt. The certificate is stored in a Secret called "example-tls-secret". The certificate is valid for the domain "example.com" and is valid for 90 days. The certificate is renewed automatically before it expires.

Conclusion

In this article, we covered some important Kubernetes features related to storage and security. We covered Persistent Volumes, Persistent Volume Claims, Storage Classes, and StatefulSets for managing persistent storage. We also covered RBAC, Pod Security Policies, Secrets, Network Policies, and TLS for securing Kubernetes resources. We provided code examples for each of these features to help you get started with Kubernetes. By understanding these features and how to use them, you can ensure that your Kubernetes workloads are secure, scalable, and reliable.

0
Subscribe to my newsletter

Read articles from Vipul Vyas directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Vipul Vyas
Vipul Vyas