写点什么

在 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:11724

评论

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

出海 SaaS 企业增长修炼手册2:Kyligence 落地 PLG 是如何避坑的?

Kyligence

指标管理 SaaS 增长

如何制作二维码会议签到系统?

草料二维码

1024 有奖征名|来给矩阵起源办公室的新猫取名字呀~

MatrixOrigin

1024 MatrixOrigin MatrixOne

如何确定Apache Kafka的大小和规模

互联网工科生

kafka

揭示Lombok的代码设计缺陷:探索封装问题

树上有只程序猿

lombok Java 开发

协同发展,生态聚合丨1024程序员节暨「源聚一堂」开源技术沙龙(北京站)成功举办

开放原子开源基金会

1024程序员节|是时候,展示真正的实力了!

Openlab_cosmoplat

1024 1024程序员节

装备修理行业数智化转型之道

用友BIP

装备修理行业

TuGraph Analytics图建模研发:为图计算业务提速增效

TuGraphAnalytics

分布式 图计算 图平台 图研发 图运维

开箱即用!教你如何正确使用华为云编译构建服务CodeArts Build!

华为云PaaS服务小智

云计算 软件开发 华为云 编译构建

博睿动态|GOPS全球运维大会2023上海站即将开启!

博睿数据

可观测性

战略牵手OXY精英设计、朗生、MPE美亚,小度合作生态重构再迎重要时刻

新消费日报

挑战吧,HarmonyOS应用开发工程师

HarmonyOS开发者

HarmonyOS

多款国产操作系统安装数据库干货文档汇总(含Oracle/MySQL/国产数据库等)

墨天轮

MySQL 数据库 oracle 国产操作系统 麒麟软件

Op丨ARB链dapp代币合约质押项目系统开发

l8l259l3365

2023-10-25:用go语言,假如某公司目前推出了N个在售的金融产品(1<=N<=100) 对于张三,用ai表示他购买了ai(0<=ai<=10^4)份额的第i个产品(1<=i<=N) 现给出K(

福大大架构师每日一题

福大大架构师每日一题

大模型在数据分析场景下的能力评测

Kyligence

数据分析 Kyligence Copilot

​交易所开发 PancakeSwap DeFi 成功的秘密:您的 DEX 发展蓝图

区块链软件开发推广运营

交易所开发 dapp开发 区块链开发 链游开发 NFT开发

云图说|华为云CodeArts Build,云端化的编译构建平台

华为云开发者联盟

华为云 华为云开发者联盟 编译构建

把握效率与最优性:Dijkstra算法的探索

高端章鱼哥

算法 计算机 Dijkstra

一文了解企业云盘和大文件传输哪个更适合企业传输

镭速

大文件传输

一站式 DB2 数据管理解决方案

NineData

sql 数据 客户端 db2 NineData

等保测评后还要花很多钱做等保整改吗?

行云管家

等保 等级保护 等保测评 等保2.0

Acrobat Pro DC 2023中文直装版 专业PDF编辑

iMac小白

Acrobat Pro DC 2023 Adobe Acrobat Pro DC下载 Adobe Acrobat Pro DC破解

数智化浪潮中,广电行业收入管理流程该如何重构?

用友BIP

广电行业

跨国企业如何选择跨境数据传输平台,了解这篇就够了

镭速

跨境数据传输

和鲸赞助!第16届中国R会议暨2023 X-AGI大会通知

ModelWhale

机器学习 R 数据科学 X-AGI 统计之都

唱衰PHP?这些言论别太离谱~《PHP综合现状分析报告》来了

禅道项目管理

php

得物 Redis 设计与实践

得物技术

redis 架构 运维

Microsoft Remote Desktop for Mac 10.9.4中文版

iMac小白

microsoft remote desktop

焕新升级!新一代云原生可观测平台

华为云原生团队

云计算 容器 云原生 边缘计算

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