在使用 Kubernetes 进行容器编排时,运行时安全问题是一个常见的挑战。因为 Kubernetes 管理多个容器和它们的互相通信,因此安全性至关重要。在本文中,我们将介绍 Kubernetes 运行时安全实践,包括如何配置和管理 Kubernetes 环境以确保安全性,并提供应用实例来展示这些原则的实效。
Kubernetes 安全实践
1. 使用最新版本的 Kubernetes
首先,最重要的是使用最新版本的 Kubernetes。Kubernetes 的安全修复程序随每个发布版本更新,这些修复可以在旧版本上无法访问。因此,保持更新是非常重要的。
2. 限制对 Kubernetes API 的访问
Kubernetes API 是管理 Kubernetes 群集的核心组件,因此访问控制是至关重要的。限制对 Kubernetes API 的访问,可以通过使用 RBAC 角色绑定来限制对 Kubernetes API 的访问。例如,可以为不同的开发人员或团队分配不同的角色,以实现功能按需和访问控制。
// javascriptcn.com 代码示例 kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: dev subjects: - kind: User name: dev apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: developer apiGroup: rbac.authorization.k8s.io
3. 在 Kubernetes 中使用网络策略
Kubernetes 中的网络策略允许在各个容器之间定义网络隔离,从而限制容器之间的网络流量,保护群集免受网络攻击。可以使用 Kubernetes 网络策略来定义允许和拒绝的进出流量。如下是一个网络策略的例子:
// javascriptcn.com 代码示例 apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-nginx spec: podSelector: matchLabels: app: nginx policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: name: trusted ports: - protocol: TCP port: 80 egress: - to: - podSelector: matchLabels: name: trusted ports: - protocol: TCP port: 80
4. 加密 Kubernetes 通信
Kubernetes 的节点和组件之间的通信需要加密,防止敏感信息被劫持。可以通过在 Kubernetes 集群中启用 TLS 证书来实现加密通信。还可以使用 Kubernetes 的 cert-manager 这样的工具自动化证书管理,从而简化证书颁发的管理。
5. 监控 Kubernetes 日志
Kubernetes 节点和组件的所有日志都应该被监控,这有助于发现异常情况并采取相应的措施。可以使用 EFK(Elasticsearch-Fluentd-Kibana)或 Splunk 等开源或商业日志解决方案来监控 Kubernetes 日志。不同的解决方案可以根据组织的个性化需求进行定制化设置。
Kubernetes 安全案例示例
下面我们将通过一个实例来说明 Kubernetes 安全实践的一般原则。考虑一个 Kubernetes 群集,其中有多个应用程序运行。每个应用程序都由多个容器组成。在这个例子中,我们将涵盖以下安全实践:
- 使用最新的 Kubernetes 版本;
- 限制对 Kubernetes API 的访问;
- 在 Kubernetes 中使用网络策略;
- 加密 Kubernetes 通信;
- 监控 Kubernetes 日志。
使用最新的 Kubernetes 版本
// javascriptcn.com 代码示例 # Example pod object specification apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: my-webapp image: my-webapp:latest ports: - containerPort: 8080
在这个示例中,我们可以看到,该 pod 的 image 版本指定为 "latest", "latest" 版本是最新的 Docker 镜像。使用最新版本的软件可以提高安全性,因为它通常包含最新的安全修复程序。因此,在这个例子中,我们鼓励开发人员使用最新版本的 Docker 镜像来保证安全性。
限制对 Kubernetes API 的访问
// javascriptcn.com 代码示例 # Example RBAC object specification apiVersion: v1 kind: ServiceAccount metadata: name: my-app --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: my-app-role subjects: - kind: ServiceAccount name: my-app namespace: my-namespace roleRef: kind: ClusterRole name: my-role apiGroup: rbac.authorization.k8s.io
在此示例中,我们使用 RBAC 角色绑定来控制对 Kubernetes API 的访问。我们为 my-app 应用程序创建一个 ServiceAccount,并分配一个名为 my-role 的 ClusterRole。我们将 my-app ServiceAccount 与 my-app-role 角色绑定。在这个例子中,我们只授予 my-app ServiceAccount 访问服务控制器的权限。
在 Kubernetes 中使用网络策略
// javascriptcn.com 代码示例 # Example Network Policy object specification apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: my-network-policy spec: podSelector: matchLabels: app: my-app ingress: - from: - podSelector: matchLabels: app: my-webapp ports: - protocol: TCP port: 80
在此示例中,我们为 my-app 创建了一个网络策略。通过这个策略,我们定义了可以从哪个容器访问 my-app 应用及其策略。我们定义了策略名称为 my-network-policy,并使用 podSelector 来选择将要受到网络策略的 pod。在 ingress 部分,我们定义了从哪些容器可以访问 my-app 应用的端口以及 TCP 协议和 80 端口。
加密 Kubernetes 通信
// javascriptcn.com 代码示例 # Example service object specification apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - name: http port: 80 targetPort: http tls: - secretName: my-service-tls-secret
在此示例中,我们将 tcp 80 端口定义为 http。我们还定义了一个 tls 对象,用于将 TLS 加密配置到流量中。我们将以下内容添加到 tls 对象中:
tls: - secretName: my-service-tls-secret
在此代码块中,我们指定 Kubernetes 密钥管理器存储的 TLS 密钥的名称,该 TLS 密钥将用于在服务期间加密流量。由于其他 Service 和 pod 无法查看此密钥,因此这种加密可以保护敏感流量免受劫持。
监控 Kubernetes 日志
要监控 Kubernetes 日志,我们需要使用一个能够将日志聚合到一个位置的解决方案。一个这样的解决方案是 EFK(Elasticsearch-Fluentd-Kibana)。
// javascriptcn.com 代码示例 # Example fluentd DaemonSet object specification apiVersion: apps/v1 kind: DaemonSet metadata: labels: k8s-app: fluentd-logging name: fluentd-logging spec: selector: matchLabels: name: fluentd template: metadata: labels: name: fluentd spec: containers: - name: fluentd image: fluentd volumeMounts: - name: logs mountPath: /fluentd/log - name: elasticsearch image: elasticsearch volumeMounts: - name: data mountPath: /data - name: config mountPath: /usr/share/elasticsearch/config/elasticsearch.yml subPath: elasticsearch.yml - name: kibana image: kibana ports: - name: http containerPort: 5601 volumeMounts: - name: data mountPath: /usr/share/kibana/config/kibana.yml subPath: kibana.yml - name: curator image: curator volumeMounts: - name: config mountPath: /config initContainers: - name: install image: busybox command: ['sh', '-c', 'wget -O /tmp/fluent.deb https://packages.fluentbit.io/ubuntu/20.04/fluent-bit-1.6.2-1_amd64.deb && dpkg -i /tmp/fluent.deb'] volumeMounts: - name: logs mountPath: /var/log/containers volumes: - name: logs hostPath: path: /var/log/pods type: "" - name: data hostPath: path: /data type: "" - name: config configMap: name: elasticsearch-config items: - key: elasticsearch.yml path: elasticsearch.yml - key: kibana.yml path: kibana.yml
这里我们使用 DaemonSet 来安装 fluentd,它将从主机上的 /var/log/pods 目录读取日志,然后将这些日志发送到 Elasticsearch 和 Kibana 进行分析和查看。
总结
在本文中,我们介绍了一些 Kubernetes 运行时安全实践,包括如何配置和管理 Kubernetes 环境以确保安全性,并提供了一个应用实例来展示这些原则的实效。当您设计和实施容器化应用时,请始终考虑安全,采取必要的步骤来确保您的应用及底层基础架构的安全。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6585cb77d2f5e1655d056251