K8s 相关问题集锦(四)
6 安全类
6.1 管理访问控制
通过 RBAC(Role-Based Access Control)管理用户和服务账户的权限,描述 Role、ClusterRole、RoleBinding、ClusterRoleBinding 的作用。
Kubernetes 中的访问控制管理通过 RBAC(基于角色的访问控制)来实现,RBAC 允许你对集群中资源的访问进行控制。RBAC 的管理主要依赖于以下几个对象:Role、ClusterRole、RoleBinding、ClusterRoleBinding。
1. Role 和 ClusterRole
- Role 是在命名空间内定义的访问权限集合,用于控制特定命名空间内资源的访问权限。
- 例如,允许用户在命名空间
dev中读取所有的 pod。- ClusterRole 则作用于整个集群,可以用于跨多个命名空间,或者在没有特定命名空间的资源(如节点)上进行权限控制。
- 例如,允许用户在整个集群中读取所有命名空间的 pod。
示例:
```yaml
定义一个 Role,允许用户在 dev 命名空间中读取 Pod 资源
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: dev name: pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] ```
```yaml
定义一个 ClusterRole,允许用户读取集群中所有命名空间的 Pod
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-pod-reader rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list", "watch"] ```
2. RoleBinding 和 ClusterRoleBinding
- RoleBinding 将 Role 绑定到一个用户或服务账户上,从而赋予该用户对特定命名空间的资源的访问权限。
- ClusterRoleBinding 将 ClusterRole 绑定到一个用户或服务账户上,从而赋予该用户对整个集群的资源的访问权限。
示例:
```yaml
定义一个 RoleBinding,将 pod-reader Role 绑定到一个用户(或服务账户)上
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: read-pods-binding namespace: dev subjects: - kind: User name: jane # 用户名称 apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: pod-reader apiGroup: rbac.authorization.k8s.io ```
```yaml
定义一个 ClusterRoleBinding,将 cluster-pod-reader ClusterRole 绑定到一个用户上
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: cluster-read-pods-binding subjects: - kind: User name: john # 用户名称 apiGroup: rbac.authorization.k8s.io roleRef: kind: ClusterRole name: cluster-pod-reader apiGroup: rbac.authorization.k8s.io ```
操作步骤
创建 Role 或 ClusterRole:
使用
kubectl apply -f role.yaml命令创建 Role。- 使用
kubectl apply -f clusterrole.yaml命令创建 ClusterRole。创建 RoleBinding 或 ClusterRoleBinding:
使用
kubectl apply -f rolebinding.yaml创建 RoleBinding,将 Role 绑定到用户。- 使用
kubectl apply -f clusterrolebinding.yaml创建 ClusterRoleBinding,将 ClusterRole 绑定到用户。验证权限:
你可以使用
kubectl auth can-i命令来验证一个用户是否具有特定操作权限。例如:sh kubectl auth can-i list pods --namespace dev --as jane- 以上命令会返回
yes或no,表示jane用户是否有权限列出dev命名空间的 Pod。总结
- Role:为某个命名空间定义权限。
- ClusterRole:为集群中所有命名空间或集群级资源定义权限。
- RoleBinding:将一个 Role 绑定到用户或服务账户上,使其在命名空间中获得相应权限。
- ClusterRoleBinding:将 ClusterRole 绑定到用户或服务账户上,使其获得集群级权限。
通过灵活地配置这些资源,Kubernetes 的访问控制可以很好地实现最小权限原则,从而保障集群的安全性。
6.2 PodSecurityPolicy 是什么?
PodSecurityPolicy 是什么?- PodSecurityPolicy 用于定义和控制 Pod 的安全策略,比如是否允许特权容器、挂载卷的类型等。
PodSecurityPolicy(PSP)是 Kubernetes 提供的一种用于控制和定义 Pod 安全性设置的策略对象。通过 PodSecurityPolicy,管理员可以对 Pod 的安全相关属性进行限制,确保集群中的 Pod 遵循安全策略,减少潜在的安全风险。
1. PodSecurityPolicy 的作用
PodSecurityPolicy 主要用于定义和控制 Pod 的以下安全设置:
- 特权容器:是否允许 Pod 运行为特权容器。
- 卷挂载类型:限制 Pod 可挂载的卷类型,如
hostPath、NFS等。- 宿主机文件系统:控制是否允许 Pod 挂载宿主机上的目录。
- Linux 能力:限制容器中添加的 Linux 能力(Capabilities)。
- 用户和组:控制运行容器的用户和组 ID,确保 Pod 不会以特权用户身份运行。
- Root 权限:限制容器是否能以 root 身份运行。
- SELinux:限制 Pod 的 SELinux 上下文。
- AppArmor:定义容器的 AppArmor 安全配置。
通过 PSP,可以控制哪些 Pod 能够在集群中部署,限制特定行为(例如使用特权容器),以防止某些恶意行为或误操作对集群造成的潜在威胁。
2. PodSecurityPolicy 示例
以下是一个简单的 PodSecurityPolicy YAML 文件示例:
yaml apiVersion: policy/v1beta1 kind: PodSecurityPolicy metadata: name: restricted spec: privileged: false # 不允许使用特权容器 allowPrivilegeEscalation: false # 不允许权限提升 seLinux: rule: RunAsAny # SELinux 配置规则 runAsUser: rule: MustRunAsNonRoot # 必须以非 root 用户运行 fsGroup: rule: MustRunAs ranges: - min: 1 max: 65535 volumes: - 'configMap' - 'emptyDir' - 'projected' - 'secret'这个策略禁止使用特权容器,不允许权限提升,要求 Pod 以非 root 用户身份运行,并限制 Pod 能够挂载的卷类型。
3. 启用和使用 PodSecurityPolicy
启用 PodSecurityPolicy:
在 Kubernetes 1.21 及之前版本中,可以通过 API server 参数
--enable-admission-plugins启用PodSecurityPolicy。创建 PodSecurityPolicy:
使用上面的 YAML 文件定义 PodSecurityPolicy,然后通过
kubectl apply -f psp.yaml创建它。创建 RBAC 绑定:
PSP 本身并不会自动生效,必须通过 RBAC(Role-Based Access Control)将其与特定的用户或服务账户绑定。可以通过 RoleBinding 或 ClusterRoleBinding 将 PodSecurityPolicy 赋予特定用户。
yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: use-psp namespace: default rules: - apiGroups: - policy resourceNames: - restricted # PodSecurityPolicy 的名称 resources: - podsecuritypolicies verbs: - use
yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: use-psp-binding namespace: default roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: use-psp subjects: - kind: ServiceAccount name: default namespace: default4. PodSecurityPolicy 的弃用
需要注意的是,从 Kubernetes 1.21 开始,PodSecurityPolicy 已被标记为废弃,并计划在 Kubernetes 1.25 中移除。为了替代 PSP,Kubernetes 社区推荐使用更现代化的解决方案,如 Pod Security Admission(一种新的安全模式)或第三方工具,例如 Open Policy Agent(OPA)、Kyverno 等。
Pod Security Admission 使用三种策略来控制 Pod 的安全性:
- Privileged(特权级):允许所有的 Pod,安全限制较少。
- Baseline(基线级):阻止使用不安全的配置,例如特权容器,但允许普通应用程序的常见配置。
- Restricted(受限级):对 Pod 进行最严格的安全限制,适用于高度安全的环境。
总结
- PodSecurityPolicy 是一种用于控制 Pod 安全性的策略,帮助管理员对 Pod 的安全属性进行配置和限制。
- 它控制了如特权容器、挂载卷类型、用户 ID、权限提升等安全设置,确保 Pod 运行时遵循集群的安全标准。
- 从 Kubernetes 1.21 开始,PSP 已被废弃,推荐使用 Pod Security Admission 或其他现代化的替代方案。
6.3 配置 HTTPS
在 Kubernetes 集群中启用 HTTPS 是确保集群通信安全的重要步骤,通常包括以下两部分:
- 为集群的 API Server 配置安全连接(HTTPS)。
- 使用证书管理工具(例如 cert-manager)为集群中的应用程序自动管理和配置 HTTPS。
下面分别讨论如何实现这些目标:
1. 为 Kubernetes API Server 配置 HTTPS
Kubernetes API Server 是集群的核心组件,它为其他组件提供交互接口。为 API Server 配置 HTTPS,确保集群通信的安全性,可以按照以下步骤进行:
1.1 生成证书和密钥
首先,API Server 需要使用 TLS 证书进行加密。你可以使用
openssl或其他证书管理工具来生成证书和私钥。使用
openssl生成自签名证书示例:```sh
生成 CA 证书和私钥
openssl genrsa -out ca.key 2048 openssl req -x509 -new -nodes -key ca.key -subj "/CN=kubernetes-ca" -days 365 -out ca.crt
生成 API Server 私钥
openssl genrsa -out apiserver.key 2048
生成 API Server CSR(证书签名请求)
openssl req -new -key apiserver.key -subj "/CN=kubernetes-apiserver" -out apiserver.csr
使用 CA 签署 API Server 证书
openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out apiserver.crt -days 365 ```
1.2 配置 API Server 使用证书
将生成的证书和私钥放置在 Kubernetes API Server 所在的节点上。你需要编辑 Kubernetes API Server 的启动配置(通常是一个配置文件或服务启动参数),添加如下参数:
sh --tls-cert-file=/path/to/apiserver.crt --tls-private-key-file=/path/to/apiserver.key --client-ca-file=/path/to/ca.crt
--tls-cert-file:指定 API Server 使用的 TLS 证书路径。--tls-private-key-file:指定 API Server 使用的私钥路径。--client-ca-file:用于对客户端证书进行验证的 CA 证书。编辑完配置文件后,重启 API Server 服务以使新配置生效。
2. 使用 cert-manager 管理证书
在 Kubernetes 集群中,不仅需要为 API Server 启用 HTTPS,还需要为应用程序启用 HTTPS。cert-manager 是 Kubernetes 集群中非常流行的自动化证书管理工具。
2.1 cert-manager 简介
cert-manager 是 Kubernetes 上的一个控制器,用于自动管理和颁发 SSL/TLS 证书。它可以使用像 Let’s Encrypt 这样的证书颁发机构(CA)来申请和自动更新证书,确保集群中的服务始终使用有效的 HTTPS 连接。
2.2 cert-manager 安装
可以使用
kubectl和Helm安装 cert-manager。以下是 Helm 安装示例:
- 添加 cert-manager 的 Helm 仓库:
sh helm repo add jetstack https://charts.jetstack.io helm repo update2. 使用 Helm 安装 cert-manager:
sh kubectl create namespace cert-manager helm install cert-manager jetstack/cert-manager --namespace cert-manager --version v1.9.1 \ --set installCRDs=true安装完成后,cert-manager 将部署在
cert-manager命名空间中,并在集群中运行以管理证书。2.3 创建 Issuer 和 ClusterIssuer
Issuer 和 ClusterIssuer 是 cert-manager 中定义的资源,用于指定证书颁发机构(CA)。Issuer 用于特定命名空间,而 ClusterIssuer 可以在整个集群中使用。
下面是一个使用 Let’s Encrypt 创建 ClusterIssuer 的示例:
yaml apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: your-email@example.com # 申请证书的邮箱 privateKeySecretRef: name: letsencrypt-prod-private-key solvers: - http01: ingress: class: nginx # 指定 Ingress 控制器2.4 为 Ingress 配置 HTTPS
要为 Kubernetes 中的服务启用 HTTPS,通常结合 Ingress 使用。在 Ingress 中引用 cert-manager 生成的证书,确保服务通过 HTTPS 对外暴露。
以下是一个 Ingress 配置示例,使用 cert-manager 申请证书:
yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: example-ingress namespace: default annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" nginx.ingress.kubernetes.io/force-ssl-redirect: "true" spec: tls: - hosts: - example.com secretName: example-com-tls # cert-manager 将自动创建这个 secret rules: - host: example.com http: paths: - path: / pathType: Prefix backend: service: name: example-service port: number: 80在这个配置中:
cert-manager.io/cluster-issuer:指定使用的 ClusterIssuer。tls:定义使用 TLS 并创建一个secret,存储证书和私钥。nginx.ingress.kubernetes.io/force-ssl-redirect:强制 HTTP 请求重定向到 HTTPS。当创建了这个 Ingress 后,cert-manager 将自动向 Let’s Encrypt 申请证书,并在
example-com-tlsSecret 中保存证书和密钥。总结
- 为 Kubernetes API Server 配置 HTTPS,可以通过生成自签名证书并配置 API Server 启动参数来实现。
- cert-manager 是 Kubernetes 集群中用于管理 SSL/TLS 证书的自动化工具,可以与 Ingress 一起为集群中的应用服务配置和管理 HTTPS。
- 使用 cert-manager 可以显著简化证书的申请、续期和管理过程,确保集群中的服务始终保持安全通信。