NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

在 Kubeadm 中使用 pod 安全策略

  • 2019-11-20
  • 本文字数:6803 字

    阅读完需:约 22 分钟

在Kubeadm中使用pod安全策略

Pod 安全策略是一种机制,用于限制容器在 k8s 上运行时可执行的操作,例如防止其作为特权容器的运行,和主机网络运行等。


本文内容较多,所以在此做了一个完整的简介说明:


  • 在 master 节点运行 kubeadm init 并启用 PodSecurityPolicy admission controller;

  • 使用 RBAC 配置添加一些 pod 安全策略 - 足够启动 CNI 和 DNS 等;

  • 没有它,CNI daemonsets 将无法启动

  • 应用您的 CNI 插件,该插件可以使用以前创建的一个 pod 安全策略

  • 通过 kubeadm join 完成向集群添加节点的配置

  • 在向集群添加更多工作负载时,请检查是否需要额外的 pod 安全策略和 RBAC 配置

我们将要做什么

以下是在 kubeadm 上安装运行 pod 安全策略所采取的步骤:


  1. 为 master 节点的初始化配置 pod 安全策略 admission controller

  2. 为网络层组件配置一些 pod 安全策略

  3. 配置 CNI 插件 - 这里将使用 flannel

  4. 然后将使用下面的代码演示一些其他的 pod 安全策略方案

  5. 安装一个具有一些特定要求的 nginx-ingress controller - 这只是为了说明添加额外的策略

  6. 安装没有特定 pod 安全策略要求的常规服务 - 基于 httpbin.org

环境

  • 将只在单个节点说明,而不是具有高可用集群的多节点集群

  • Ubuntu:根据 kubeadm 的要求切换,为 UTC 配置时区

  • Docker:假设当前用户在 docker 组中

  • kubernetes 1.11.3 - 使用 RBAC

master 节点配置

按照说明安装 kubeadm


安装 jq,用它来进行一些 json 输出处理


sudo apt-get update  sudo apt-get install -y jq
复制代码


验证 kubeadm 的版本


sudo kubeadm version
复制代码


接着我们将为下面创建的内容创建一个目录,在以下所有说明中我们假设您在此目录中


mkdir ~/psp-inv  cd ~/psp-inv
复制代码

kubeadm 配置文件

将创建这个文件,并将其用于 master 上的 kubeadm init,使用此内容创建一个 kubeadm-config.yaml 文件 - 请注意我们必须为 flannel 指定 pod 子网为 10.244.0.0/16


请注意,此文件对于此演示是最小的,如果您使用更高版本的 kubeadm,则可能需要更改 apiVersion


apiVersion: kubeadm.k8s.io/v1alpha2  kind: MasterConfiguration  apiServerExtraArgs:   enable-admission-plugins: PodSecurityPolicy  controllerManagerExtraArgs:  address: 0.0.0.0  kubernetesVersion: v1.11.3  networking:  podSubnet: 10.244.0.0/16  schedulerExtraArgs:  address: 0.0.0.0
复制代码

Master init

 
复制代码


根据上面命令输出的说明获取您自己的 kubeconfig 文件副本,如果要将工作节点添加到集群,请注意加入以下信息,并检查 master 节点的状态


NAME STATUS ROLES AGE VERSIONpmcgrath-k8s-master NotReady master 1m v1.11.3
复制代码


这说明节点还没有准备好,因为它正在等待 CNI,检查一下 pods


No resources found.
复制代码


所以,如果我们没有启用 pod security policy admission control,通常看不到任何正在运行的 pod,检查 docker


docker container ls --format '{{ .Names }}'k8s\_kube-scheduler\_kube-scheduler-pmcgrath-k8s-master\_kube-system\_a00c35e56ebd0bdfcd77d53674a5d2a1\_0k8s\_kube-controller-manager\_kube-controller-manager-pmcgrath-k8s-master\_kube-system\_fd832ada507cef85e01885d1e1980c37\_0  k8s\_etcd\_etcd-pmcgrath-k8s-master\_kube-system\_16a8af6b4a79e9b0f81092f85eab37cf\_0  k8s\_kube-apiserver\_kube-apiserver-pmcgrath-k8s-master\_kube-system\_db201a8ecaf8e99623b425502a6ba627\_0  k8s\_POD\_kube-controller-manager-pmcgrath-k8s-master\_kube-system\_fd832ada507cef85e01885d1e1980c37\_0  k8s\_POD\_kube-scheduler-pmcgrath-k8s-master\_kube-system\_a00c35e56ebd0bdfcd77d53674a5d2a1\_0  k8s\_POD\_kube-apiserver-pmcgrath-k8s-master\_kube-system\_db201a8ecaf8e99623b425502a6ba627\_0  k8s\_POD\_etcd-pmcgrath-k8s-master\_kube-system\_16a8af6b4a79e9b0f81092f85eab37cf\_0
复制代码


所有容器都在运行,但这不是通过 kubectl 获取的信息,还需检查事件


 
复制代码


会看到类似这样的错误:pods “kube-proxy-“ is forbidden: no providers available to validate pod request

配置 pod 安全策略

当前已经配置了:


  • 任何工作负载都可以使用默认的 pod 安全策略,它没有什么特权,但应该适用于大多数工作负载

  • 将创建一个 RBAC ClusterRole

  • 将为所有经过身份验证的用户创建 RBAC ClusterRoleBinding

  • 我授予 kube-system 命名空间中的节点和所有服务帐户访问权限的特权 pod 安全策略

  • 考虑这个权限应该被限制在这个命名空间内

  • 应该只在此命名空间中运行 k8s 组件

  • 将创建一个 RBAC ClusterRole

  • 将在 kube-system 命名空间中创建 RBAC RoleBinding


使用此内容创建 default-psp-with-rbac.yaml 文件


apiVersion: policy/v1beta1  kind: PodSecurityPolicy  metadata:   annotations:   apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'   apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'   seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'   seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'   name: default  spec: allowedCapabilities: \[\] # default set of capabilities are implicitly allowed   allowPrivilegeEscalation: false   fsGroup:   rule: 'MustRunAs'   ranges:   # Forbid adding the root group.  \- min: 1   max: 65535   hostIPC: false   hostNetwork: false   hostPID: false   privileged: false   readOnlyRootFilesystem: false   runAsUser:   rule: 'MustRunAsNonRoot'   seLinux:   rule: 'RunAsNonRoot'   supplementalGroups:   rule: 'RunAsNonRoot'   ranges:   # Forbid adding the root group.  \- min: 1   max: 65535   volumes:  \- 'configMap'  \- 'downwardAPI'  \- 'emptyDir'  \- 'persistentVolumeClaim'  \- 'projected'  \- 'secret'   hostNetwork: false   runAsUser:   rule: 'RunAsAny'   seLinux:   rule: 'RunAsAny'   supplementalGroups:   rule: 'RunAsAny'   fsGroup:   rule: 'RunAsAny'\---\# Cluster role which grants access to the default pod security policy apiVersion: rbac.authorization.k8s.io/v1  kind: ClusterRole  metadata:   name: default-psp  rules:  \- apiGroups:   - policy   resourceNames:   - default   resources:   - podsecuritypolicies   verbs:   - use\---\# Cluster role binding for default pod security policy granting all authenticated users accessapiVersion: rbac.authorization.k8s.io/v1  kind: ClusterRoleBinding  metadata:   name: default-psp  roleRef:   apiGroup: rbac.authorization.k8s.io   kind: ClusterRole   name: default-psp  subjects:  \- apiGroup: rbac.authorization.k8s.io   kind: Group   name: system:authenticated
复制代码


使用此内容创建 privileged-psp-with-rbac.yaml 文件


# Should grant access to very few pods, i.e. kube-system system pods and possibly CNI pods  apiVersion: policy/v1beta1  kind: PodSecurityPolicy  metadata:   annotations:   # See https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp   seccomp.security.alpha.kubernetes.io/allowedProfileNames: '\*'   name: privileged  spec:   allowedCapabilities:  \- '\*'   allowPrivilegeEscalation: true   fsGroup:   rule: 'RunAsAny'   hostIPC: true   hostNetwork: true   hostPID: true   hostPorts:  \- min: 0   max: 65535   privileged: true   readOnlyRootFilesystem: false   runAsUser:   rule: 'RunAsAny'   seLinux:   rule: 'RunAsAny'   supplementalGroups:   rule: 'RunAsAny'   volumes:  \- '\*'\---\# Cluster role which grants access to the privileged pod security policy apiVersion: rbac.authorization.k8s.io/v1  kind: ClusterRole  metadata:   name: privileged-psp  rules:  \- apiGroups:   - policy   resourceNames:   - privileged   resources:   - podsecuritypolicies   verbs:   - use\---\# Role binding for kube-system - allow nodes and kube-system service accounts - should take care of CNI i.e. flannel running in the kube-system namespace \# Assumes access to the kube-system is restricted  apiVersion: rbac.authorization.k8s.io/v1  kind: RoleBinding  metadata:   name: kube-system-psp   namespace: kube-system  roleRef:   apiGroup: rbac.authorization.k8s.io   kind: ClusterRole   name: privileged-psp  subjects:  \# For the kubeadm kube-system nodes  \- apiGroup: rbac.authorization.k8s.io   kind: Group   name: system:nodes  \# For all service accounts in the kube-system namespace  \- apiGroup: rbac.authorization.k8s.io   kind: Group   name: system:serviceaccounts:kube-system
复制代码

使用 RBAC 配置应用上述 pod 安全策略

kubectl apply -f default-psp-with-rbac.yaml  kubectl apply -f privileged-psp-with-rbac.yaml
复制代码

校验

一段时间后,网络层 pods 将处于运行状态,coredns pods 将挂起-等待 CNI


kubectl get pods --all-namespaces --output wide --watch
复制代码


在配置 CNI 之前,网络层 pods 将再次启动失败,因为节点仍未准备就绪

安装 flannel**

只有当前存在有特权 pod 安全策略才能完成此操作,并且 kube-system 中的 flannel 服务帐户将能够使用,如果使用不同的 CNI 插件,则应使用其安装说明,可能需要修改用于 kubeadm init 的 kubeadm-config.yaml 文件中的 podSubnet。


延伸链接


kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
复制代码

再次校验

kubectl get pods --all-namespaces --output wide --watch

复制代码


所有 pods 最终将进入运行状态,包括 coredns pod(s)


kubectl get nodes
复制代码


节点现已准备就绪。

允许 master 上的工作负载

如果想要启动工作节点,可以正常使用 kubeadm join 命令,利用 kubeadm init 输出,在这里跳过。


这些工作节点上没有特别需要加入集群 pod 安全策略,允许 master 节点上的工作负载,因为我们只是尝试在单个节点集群上进行验证。


kubectl taint nodes --all node-role.kubernetes.io/master-
复制代码

nginx ingress

使用下方链接的清单


创建一个新的命名空间和单个实例 ingress controller,足以说明额外的 pod 安全策略。


由于命名空间尚不存在,因此我们可以创建,以便引用服务帐户


kubectl create namespace ingress-nginx

创建一个 pod 安全策略

本 pod 安全策略基于 deployment 清单,使用此内容创建文件 nginx-ingress-psp-with-rbac.yaml


apiVersion: policy/v1beta1  kind: PodSecurityPolicy  metadata:   annotations:   # Assumes apparmor available   apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default'   apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default'   seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default'   seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default'   name: ingress-nginx  spec:   # See nginx-ingress-controller deployment at https://github.com/kubernetes/ingress-nginx/blob/master/deploy/mandatory.yaml   # See also https://github.com/kubernetes-incubator/kubespray/blob/master/roles/kubernetes-apps/ingress\_controller/ingress\_nginx/templates/psp-ingress-nginx.yml.j2   allowedCapabilities:  \- NET\_BIND\_SERVICE   allowPrivilegeEscalation: true   fsGroup:   rule: 'MustRunAs'   ranges:  \- min: 1   max: 65535   hostIPC: false   hostNetwork: false   hostPID: false   hostPorts:  \- min: 80   max: 65535   privileged: false   readOnlyRootFilesystem: false   runAsUser:   rule: 'MustRunAsNonRoot'   ranges:  \- min: 33   max: 65535   seLinux:   rule: 'RunAsAny'   supplementalGroups:   rule: 'MustRunAs'   ranges:   # Forbid adding the root group.  \- min: 1   max: 65535   volumes:  \- 'configMap'  \- 'downwardAPI'  \- 'emptyDir'  \- 'projected'  \- 'secret'
\---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role metadata: name: ingress-nginx-psp namespace: ingress-nginx rules: \- apiGroups: - policy resourceNames: - ingress-nginx resources: - podsecuritypolicies verbs: - use\---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding metadata: name: ingress-nginx-psp namespace: ingress-nginx roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: ingress-nginx-psp subjects: \# Lets cover default and nginx-ingress-serviceaccount service accounts \# Could have altered default-http-backend deployment to use the same service acccount to avoid granting the default service account access \- kind: ServiceAccount name: default \- kind: ServiceAccount name: nginx-ingress-serviceaccount
复制代码


即创建


kubectl apply -f nginx-ingress-psp-with-rbac.yaml
复制代码

创建 nginx-ingress 工作负载

删除 controller-publish-service arg,因为在这里不需要


curl -s https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/mandatory.yaml | sed '/--publish-service/d' | kubectl apply -f -
复制代码


检查 pods


kubectl get pods --namespace ingress-nginx --watch
复制代码


现在可以看到 pod 安全策略附加了注释


kubectl get pods --namespace ingress-nginx --selector app.kubernetes.io/name=ingress-nginx -o json | jq -r '.items\[0\].metadata.annotations."kubernetes.io/psp"'

复制代码

Httpbin.org 工作负载

部署一个工作负载,默认的 pod 安全策略就足够了,使用此内容创建一个 httpbin.yaml 文件


apiVersion: apps/v1  kind: Deployment  metadata:   labels:   app.kubernetes.io/name: httpbin   name: httpbin  spec:   replicas: 1   selector:   matchLabels:   app.kubernetes.io/name: httpbin   template:   metadata:   labels:   app.kubernetes.io/name: httpbin   spec:   containers:  \- args: \["-b", "0.0.0.0:8080", "httpbin:app"\]   command: \["gunicorn"\]   image: docker.io/kennethreitz/httpbin:latest   imagePullPolicy: Always   name: httpbin   ports:  \- containerPort: 8080   name: http   restartPolicy: Always\---
apiVersion: extensions/v1beta1
kind: Ingress metadata: annotations: kubernetes.io/ingress.class: "nginx" labels: app.kubernetes.io/name: httpbin name: httpbin spec: rules: - host: my.httpbin.com http: paths: - path: backend: serviceName: httpbin servicePort: 8080\---
apiVersion: v1
kind: Service metadata: labels: app.kubernetes.io/name: httpbin name: httpbin spec: ports: - name: http port: 8080 selector: app.kubernetes.io/name: httpbin
复制代码


创建命名空间并在工作负载里运行


kubectl create namespace demo  kubectl apply --namespace demo -f httpbin.yaml
复制代码


检查 pod 是否存在以及是否使用了默认策略


kubectl get pods --namespace demo  kubectl get pods --namespace demo --selector app.kubernetes.io/name=httpbin -o json | jq -r '.items\[0\].metadata.annotations."kubernetes.io/psp"'
复制代码

测试工作负载

通过调用 ingress controller pod 实例


\# Get nginx ingress controller pod IP  nginx\_ip=$(kubectl get pods --namespace ingress-nginx --selector app.kubernetes.io/name=ingress-nginx --output json | jq -r .items\[0\].status.podIP)\# Test ingress and out httpbin workloadcurl -H 'Host: my.httpbin.com' http://$nginx\_ip/get
复制代码


如果打乱它,可以重置并重启


\# Note: Will loose PKI also which is fine here as kubeadm master init will re-create  sudo kubeadm reset\# Should flush iptable rules after a kubeadm reset, see https://blog.heptio.com/properly-resetting-your-kubeadm-bootstrapped-cluster-nodes-heptioprotip-473bd0b824aa sudo iptables -F && sudo iptables -t nat -F && sudo iptables -t mangle -F && sudo iptables -X
复制代码


参考文档


安全建议


GCE政策


添加小助手微信,加入【容器魔方】技术社群。



2019-11-20 19:11610

评论

发布
暂无评论
发现更多内容

Video-LLaMA:为AI大模型注入视听觉

百度开发者中心

人工智能 大模型

【第七在线】服装企业对于智能商品计划系统的误区有哪些?

第七在线

千万级数据深分页查询SQL性能优化实践

京东科技开发者

Pocket Yoga for mac(口袋瑜伽)v14.3.0激活版

影影绰绰一往直前

数据展现之道:精心打造可在线浏览的动态数据报表

EquatorCoco

数据库 动态数据

为什么要将应用微服务化?

伤感汤姆布利柏

程序员 微服务 低代码 架构师 JNPF

每日一题:LeetCode-209. 长度最小的子数组

半亩房顶

算法 LeetCode 二分查找 前缀和 滑动窗口

如何在苹果手机上进行文件管理

使用 Taro 开发鸿蒙原生应用 —— 快速上手,鸿蒙应用开发指南

京东科技开发者

重磅!参编我国首个图计算平台标准 引领图数据库行业新机遇

百度安全

MES生产执行系统在生产车间的主要作用

万界星空科技

工业互联网 MES系统 生产管理系统 mes 数字化车间

DxO ViewPoint 4 for Mac(照片修复校正工具)v4.13.0.282激活版

影影绰绰一往直前

Navicat Charts Creator for Mac(Navicat图表创建器)v1.2.15激活版

影影绰绰一往直前

Meta Llama大模型:引领人工智能创新

百度开发者中心

人工智能 深度学习 大模型

深入了解LLaMA大模型

百度开发者中心

深度学习 nlp 大模型

如何写好大模型提示词?来自大赛冠军的经验分享(基础篇)

Baihai IDP

人工智能 AI LLM Prompt Prompt Engineering

FotoMagico for Mac(专业幻灯片制作软件)v6.5.4激活版

影影绰绰一往直前

喜讯!无垠智能模糊测试系统入选“2023软件供应链优秀成果”

云起无垠

深入理解WebSocket ACK:关键技术提升数据传输的可靠性

Apifox

前端 后端 websocket 协议 WebSocket ACK

数字人源码独立部署的教程!

青否数字人

数字人

4K Video Downloader Plus Pro for Mac(4K视频下载器)v1.4.0激活版下载

影影绰绰一往直前

AI数字人源码部署,打造自己品牌!

青否数字人

如何提升时序数据多表低频场景的写入性能?一文详解

TDengine

tdengine 时序数据库

即时通讯技术文集(第32期):IM开发综合技术合集(Part5) [共12篇]

JackJiang

网络编程 即时通讯 IM

DxO PhotoLab 7 for Mac(专业照片编辑软件)v7.3.0.43激活版

影影绰绰一往直前

一文带你揭秘淘宝终端技术

阿里技术

基础设施 招聘 淘宝 终端技术

得物云原生容器技术探索与落地实践

得物技术

云原生 技术分享

AI数字人给教育行业带来机会!

青否数字人

DxO PureRAW for Mac(RAW照片处理器)v3.9.0中文激活版

影影绰绰一往直前

Code Llama:基于 Llama 2 的 AI 代码生成大模型

百度开发者中心

人工智能 大模型 代码生成

类似 Microsoft Project 的12款在线项目管理工具

PingCode

项目管理 项目经理 项目管理工具

在Kubeadm中使用pod安全策略_容器_华为云原生团队_InfoQ精选文章