Kubernetes Security Best Practices Overview

Traducciones al Español
Estamos traduciendo nuestros guías y tutoriales al Español. Es posible que usted esté viendo una traducción generada automáticamente. Estamos trabajando con traductores profesionales para verificar las traducciones de nuestro sitio web. Este proyecto es un trabajo en curso.
Create a Linode account to try this guide with a $ credit.
This credit will be applied to any valid services used during your first  days.

If you are deploying your first Kubernetes cluster, it’s important to consider the security best practices that are available to keep your workload safe. Kubernetes provides several out-of-the-box features to help secure your cluster. This guide provides an overview of three Kubernetes features to you can use to secure different components of a cluster. The three areas covered are Role-Based Access Control (RBAC), Secrets, and Network Policies.

Note
This guide assumes some familiarity with Kubernetes terminology and concepts. If you are newer to Kubernetes, refer to our A Beginner’s Guide to Kubernetes.

Use Security Policies and Role-Based Access Control

A Kubernetes cluster consists of many areas –services, networking, namespaces, pods, nodes, containers, and more. Limiting which users and services have access to different parts of your stack is an important step in keeping your cluster secure. Role-Based Access Control (RBAC) authorization is a Kubernetes feature that limits access to a cluster’s resources. With this method, no user or service has any more permissions than they need to function properly in the cluster. Administrators should use Kubernetes Roles or ClusterRoles to attach rules to a group and add users to the group. First, create a security policy and then, using RBAC, assign the role.

The example below defines a security policy that specifies the operations a user can execute and on which namespace.

File: role.yaml
1
2
3
4
5
6
7
8
9
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: office
  name: deployment-manager
rules:
- apiGroups: ["core", "extensions", "apps"]
  resources: ["deployments", "replicasets", "pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # You can also use ["*"]

The above Role allows users to execute operations on deployments, replicasets, and pods, but only within the core, apps, and extensions API groups, and within the office namespace. The example Role limits what a user can do if they are assigned to the Role.

A separate manifest binds that Role to a specific user. To continue the example, and bind the Role to a user named admin1, the corresponding manifest resembles the example below:

File: user-role.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deployment-manager-binding
  namespace: office
subjects:
- kind: User
  name: admin1
  apiGroup: ""
roleRef:
  kind: Role
  name: deployment-manager-binding
  apiGroup: ""

The manifest binds the admin1 user, within the office namespace. The user can execute operations on deployments, replicasets, and pods, within the core, apps, and extensions API groups.

RBAC authorization is one of the primary ways to keep your Kubernetes cluster secure. To learn more about the implementation details of RBAC, view the Using RBAC Authorization Kubernetes documentation page.

Use Kubernetes Secrets to Store Sensitive Data

A Kubernetes Secret is used to keep sensitive information —like passwords, tokens, and keys— out of your application code. Secrets prevent your sensitive data from being exposed during your development workflow. At its simplest, a Secret is an object that contains a key-value pair and metadata. The example below creates a Kubernetes secret that stores a user’s plain-text password:

File: secret.yaml
1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
  name: itsasecret
type: Opaque
data:
  username: admin1
  password: BU2Byyz2112

It is not a good security practice to store a plain-text password in a manifest file. Anyone with access to the Secret’s namespace can read the Secret. Similarly, anyone with access to the cluster’s API can read and modify the Secret. For this reason, you should encrypt any sensitive data that is stored in a Secret. Kubernetes supports encryption at rest which means your sensitive data will be stored in an encrypted format. To store your Secrets in an encrypted format, create an encryption at rest configuration similar to the example below:

File: encryption.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
  - secrets
  providers:
  - aescbc:
      keys:
      - name: secretkey1
      secret: <ENCODED SECRET>
  - identity: {}

Then, generate a random key and use base64 to encode it.

head -c 32 /dev/urandom | base64

You can then copy the returned output and store it in the secret field of your encryption at rest configuration.

File: role.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
  - secrets
  providers:
  - aescbc:
      keys:
      - name: secretkey1
      secret: piE9qJYzcavzUz5q+gH70uRjnPWsvMMsoTndPi7KzqA=
  - identity: {}

Finally, set --encryption-provider-config in the kube-apiserver so that it points to the encryption configuration file. To learn more about the different encryption providers that Kubernetes supports, see the Encrypting Secret Data at Rest documentation.

Restrict Traffic Between Pods With a Kubernetes Network Policy

By default, Pods running on a Kubernetes cluster accept traffic from any source. Network Policies allow you to control and secure network access between Pods and across your application.

A network policy spec consists of three main sections:

  • podSelector: Defines to which pods the rule(s) apply.
  • policyTypes: Defines whether the rules apply to incoming or outgoing traffic.
  • Ingress/Egress: Defines whether the traffic is incoming (ingress) or outgoing (egress).

The file below contains an example Kubernetes network policy:

File: role.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: simple-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: target-app
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
  - ipBlock:
      cidr: 192.0.2.0/16
  - namespaceSelector:
      matchLabels:
        name: namespace
  - podSelector:
      matchLabels:
        app: pod
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    - namespaceSelector:
        matchLabels:
          name: namespace
    - podSelector:
        matchLabels:
          app: pod
    ports:
    - protocol: TCP
      port: 5978

In the above manifest, each of the following items require values:

  • spec.podSelector.matchLabels.app: the target app for which the policy is applied.
  • spec.ingress.namespaceSelector.matchLabels.name: the namespace allowed to communicate with the app.
  • spec.ingress.podSelector.matchLabels.app: the Pod permitted to communicate with the app.
  • spec.egress.namespaceSelector.matchLabels.name: the namespace with which the app may communicate.
  • spec.egress.podSelector.matchLabels.app: the Pod with which the app may communicate.

To learn more about creating Network Policies for a Kubernetes cluster, see the Network Policies documentation page.

Conclusion

Kubernetes security is a vast topic, however, there are a few core areas that are essential. Aside from the three areas covered in this overview, you can consider limiting resource usage on a cluster, review the Kubernetes security reporting page, and review any third-party integrations used by your cluster. The Kubernetes Securing a Cluster documentation page provides a deeper discussion on these topics.

This page was originally published on


Your Feedback Is Important

Let us know if this guide was helpful to you.


Join the conversation.
Read other comments or post your own below. Comments must be respectful, constructive, and relevant to the topic of the guide. Do not post external links or advertisements. Before posting, consider if your comment would be better addressed by contacting our Support team or asking on our Community Site.
The Disqus commenting system for Linode Docs requires the acceptance of Functional Cookies, which allow us to analyze site usage so we can measure and improve performance. To view and create comments for this article, please update your Cookie Preferences on this website and refresh this web page. Please note: You must have JavaScript enabled in your browser.