云原生
Kubernetes基础
容器技术介绍
Docker快速入门
Containerd快速入门
K8S主要资源罗列
认识YAML
API资源对象
Kubernetes安全掌控
Kubernetes网络
Kubernetes高级调度
Kubernetes 存储
Kubernetes集群维护
Skywalking全链路监控
ConfigMap&Secret场景应用
Kubernetes基础概念及核心组件
水平自动扩容和缩容HPA
Jenkins
k8s中部署jenkins并利用master-slave模式实现CICD
Jenkins构建过程中常见问题排查与解决
Jenkins部署在k8s集群之外使用动态slave模式
Jenkins基于Helm的应用发布
Jenkins Pipeline语法
EFKStack
EFK日志平台部署管理
海量数据下的EFK架构优化升级
基于Loki的日志收集系统
Ingress
基于Kubernetes的Ingress-Nginx解决方案
Ingress-Nginx高级配置
使用 Ingress-Nginx 进行灰度(金丝雀)发布
Ingress-nginx优化配置
APM
Skywalking全链路监控
基于Helm部署Skywalking
应用接入Skywalking
服务网格
Istio
基于Istio的微服务可观察性
基于Istio的微服务Gateway实战
Kubernetes高可用集群部署
Kuberntes部署MetalLB负载均衡器
Ceph
使用cephadm部署ceph集群
使用Rook部署Ceph存储集群
openstack
glance上传镜像失败
mariadb运行不起来
创建域和项目错误_1
创建域和项目错误_2
安装计算节点
时钟源
网络创建失败
本文档使用 MrDoc 发布
-
+
首页
Kubernetes安全掌控
# 1、API资源对象Networkpolicy NetworkPolicy用来控制Pod与Pod之间的网络通信,它也支持针对Namespace进行限制。基于白名单模式,符合规则的对象通过,不符合的拒绝。 应用场景举例: - Pod A不能访问Pod B; - 开发环境所有Pod不能访问测试命名空间; - 提供对外访问时,限制外部IP; 官方NetworkPolicy YAML示例: ``` apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: test-network-policy namespace: default spec: podSelector: matchLabels: role: db policyTypes: - Ingress - Egress ingress: - from: - ipBlock: cidr: 172.17.0.0/16 except: - 172.17.1.0/24 - namespaceSelector: matchLabels: project: myproject - podSelector: matchLabels: role: frontend ports: - protocol: TCP port: 6379 egress: - to: - ipBlock: cidr: 10.0.0.0/24 ports: - protocol: TCP port: 5978 ``` 说明:必需字段:`apiVersion`、 `kind` 和 `metadata` 字段。 - podSelector:定义目标Pod的匹配标签,即哪些Pod会生效此策略; - policyTypes:表示给定的策略是应用于目标Pod的入站流量(Ingress)还是出站流量(Egress),或两者兼有。 如果NetworkPolicy未指定policyTypes则默认情况下始终设置Ingress。 - ingress:定义入流量限制规则,from用来定义白名单对象,比如网段、命名空间、Pod标签,Ports定义目标端口。 - egress:定义出流量限制规则,定义可以访问哪些IP和端口 ## 案例一: 需求:aming命名空间下所有Pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问aming命名空间Pod。 首先创建几个Pod: ``` $ kubectl run busybox --image=busybox -- sleep 3600 ## default命名空间里创建busybox Pod $ kubectl run busybox --image=busybox -n aming -- sleep 3600 ## aming命名空间里创建busybox Pod $ kubectl run web --image=nginx:1.23.2 -n aming ## aming命名空间里创建web pod ``` 在没有创建NetworkPolicy的情况下测试 ``` $ kubectl exec busybox -n aming -- ping 10.18.235.161 ##aming命名空间的busybox ping default命名空间的busybox IP $ kubectl exec busybox -n aming -- ping 10.18.235.162 ##aming命名空间的busybox ping aming命名空间的web IP $ kubectl exec busybox -- ping 10.18.235.162 ##default命名空间的busybox ping aming命名空间的web IP ``` 创建networkpolicy的YAML ``` $ vi deny-all-namespaces.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-namespaces namespace: aming spec: podSelector: {} # 为空,表示匹配本命名空间所有Pod policyTypes: - Ingress ingress: - from: - podSelector: {} # 为空,表示匹配该命名空间所有Pod,即允许该命名空间所有Pod访问,没有定义namespaceSelector,也就是说不允许其它namespace的Pod访问。 ``` 应用YAML ``` $ kubectl apply -f deny-all-namespaces.yaml ``` 测试: ``` $ kubectl exec busybox -n aming -- ping 10.18.235.161 ##aming命名空间的busybox ping default命名空间的busybox IP $ kubectl exec busybox -n aming -- ping 10.18.235.162 ##aming命名空间的busybox ping aming命名空间的web IP $ kubectl exec busybox -- ping 10.18.235.162 ##default命名空间的busybox ping aming命名空间的web IP ``` 将刚刚创建的所有资源删除: ``` $ kubectl delete po busybox --force $ kubectl delete po busybox -n aming --force $ kubectl delete po web -n aming $ kubectl delete -f deny-all-namespaces.yaml ``` ## 案例二: 通过PodSelector限制 ``` $ vi pod-selector.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: app-to-app namespace: aming spec: podSelector: matchLabels: app: test policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: dev ports: - protocol: TCP port: 80 ``` - 只有带dev标签的pod才可以访问aming命名空间中带test标签的pod 应用YAML ``` $ kubectl apply -f pod-selector.yaml ``` 创建测试pod ``` $ kubectl run web01 --image=nginx:1.23.2 -n aming -l 'app=test' #创建Pod时,指定label $ kubectl get pod web01 -n aming --show-labels # 查看label # 如果label创建错了,也可以修改,在本实验中不需要做如下操作 $ kubectl label pod busybox app=test123 --overwrite $ kubectl run app01 --image=nginx:1.23.2 -n aming -l 'app=dev' $ kubectl run app02 --image=nginx:1.23.2 -n aming ``` 查看标签 ``` $ kubectl get po app01 -n aming --show-labels ``` 查看web01的IP ``` $ kubectl describe po web01 -n aming |grep -i ip ``` 测试 ``` $ kubectl exec -n aming app01 -- curl 10.18.235.170 $ kubectl exec -n aming app02 -- curl 10.18.235.170 ``` 测试成功后,删除掉刚刚创建的资源 ``` $ kubectl delete po app01 -n aming $ kubectl delete po app02 -n aming $ kubectl delete po web01 -n aming $ kubectl delete -f pod-selector.yaml ``` ## 案例三: 限制namespace ``` $ vi allow-ns.yaml apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-ns namespace: aming spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: test ports: - protocol: TCP port: 80 ``` - 只有带test标签的命名空间才可以访问aming命名空间的pod 应用YAML ``` $ kubectl apply -f allow-ns.yaml ``` 创建测试ns ``` $ kubectl create ns test ``` 创建测试pod ``` $ kubectl run web01 --image=nginx:1.23.2 -n aming $ kubectl run web02 --image=nginx:1.23.2 -n test $ kubectl run web03 --image=nginx:1.23.2 $ kubectl run web04 --image=nginx:1.23.2 -n aming ``` 查看web01的IP ``` $ kubectl describe po web01 -n aming |grep -i ip ``` 查看ns label ``` $ kubectl get ns --show-labels ``` 给ns设置标签 ``` $ kubectl label namespace test name=test ``` 测试: ``` $ kubectl -n test exec web02 -- curl 10.18.235.172 #可以访问 $ kubectl exec web03 -- curl 10.18.235.172 #不可以访问 $ kubectl -n aming exec web04 -- curl 10.18.235.172 #不可以访问,即使同一个命名空间也无法访问 ``` # 2、Kubernetes用户安全控制 - 1)安全控制三阶段 三阶段: 认证(Authentication)、授权(Authorization)、准入控制(Admission Control)  - ① 所谓认证,就是先验证用户的身份是否合法,比如看看其证书是否合法有效,看看其Token是否正确; - ② 所谓授权,就是看看这个用户是否有权限来访问或者操作K8s的资源; - ③ 所谓准入控制,就是检查对应客户端的请求是否符合对应请求或操作API规范,检查传递参数是否是正确的。比如创建Pod,它会检查提交的信息是否符合创建Pod的规范,如果不符合规范就拒绝。另外,准入控制还会帮助我们把我们没有明确指定的字段信息,通过默认值的方式把对应的字段填充到客户端请求中,然后把填充好的信息一并由APIserver把客户端请求更新到对应资源在etcd中的对应信息上。 - 2)K8s认证(Authentication) 两种认证方式: - ① Kubeconfig 这种是基于https ca证书认证,咱们命令行管理K8s用的就是这种认证 - ② Token 这种通过一个Token来识别用户,比如前面我们讲dashboard时,有创建一个serviceaccount,然后再获取其token - 3)K8s授权(Authorization) 授权模式: * AlwaysDeny:表示拒绝所有的请求,一般用于测试 * AlwaysAllow:允许接收所有请求,如果集群不需要授权流程,则可以采用该策略 * ABAC(Attribute-Based Access Control):基于属性的访问控制,表示使用用户配置的授权规则对用户请求进行匹配和控制(老版本采用的方式,也就是定义属性的访问类型,如果用户拥有这个属性就能访问对应的资源。需要定义一长串的属性,并且ABAC修改完之后并不能生效,现在淘汰了) * Webbook:通过调用外部 REST 服务对用户进行授权(在集群外部对集群鉴权) * RBAC(Role-Based Access Control):基于角色的访问控制,现行的默认规则(拥有角色就代表拥有访问资源某些权限) 查看你的K8s授权模式: ``` $ cat /etc/kubernetes/manifests/kube-apiserver.yaml |grep authorization-mode - --authorization-mode=Node,RBAC ``` ## RBAC 授权模式 RBAC(Role-Based Access Control)基于角色的访问控制,在 Kubernetes 1.5 中引入,现行版本成为默认标准。相对其它访问控制方式,拥有以下优势: - 对集群中的资源(pod deploy cpu…)和非资源(元信息如pod状态)均拥有完整的覆盖 - 整个 RBAC 完全由几个 API 对象完成,同其它 API 对象一样,可以用 kubectl 或 API 进行操作 - 可以在运行时进行调整,无需重启API Server即可生效 ## RBAC 的 API 资源对象说明 RBAC资源对象:Subject(包括:User, Group, ServiceAccount)Role(角色)、ClusterRole(集群角色)、RoleBinding(角色绑定)、ClusterRoleBinding(集群角色绑定) - 主体(subject) - User:用户 - Group:用户组 - ServiceAccount:服务账号 - 角色 - Role:授权特定命名空间的访问权限 - ClusterRole:授权所有命名空间的访问权限 - 角色绑定 - RoleBinding:将角色绑定到主体(即subject) - ClusterRoleBinding:将集群角色绑定到主体  - 4)K8s准入控制(Adminssion Control) Adminssion Control实际上是一个准入控制器插件列表,发送到API Server的请求都需要经过这个列表中的每个准入控制器插件的检查,检查不通过,则拒绝请求。 查看可以启用的准入控制器列表: ``` $ kubectl exec kube-apiserver-aminglinux01 -n kube-system -- kube-apiserver -h | grep ' --enable-admission-plugins' ``` 查看当前K8s启用的准入控制器: ``` $ grep 'admission' /etc/kubernetes/manifests/kube-apiserver.yaml 或者 $ ps aux|grep apiserver|grep admission ``` 启用准入控制器: ``` kubectl exec kube-apiserver-k8s01 -n kube-system -- kube-apiserver --enable-admission-plugins=NamespaceLifecycle,LimitRanger,... ``` 关闭准入控制器: ``` kubectl exec kube-apiserver-k8s-01 -n kube-system -- kube-apiserver --disable-admission-plugins=PodNodeSelector,AlwaysDeny,... ``` 更改准入控制器: ``` $ vi /etc/kubernetes/manifests/kube-apiserver.yaml #找到--enable-admission-plugins那一行,直接修改 --enable-admission-plugins=NodeRestriction,SecurityContextDeny ``` 以下为admission控制器列表以及说明 | Admission 控制器 | 说明 | | -------------------------------- | ------------------------------------------------------------ | | AlwaysPullImages | 强制要求每个容器始终从镜像仓库拉取最新的镜像。 | | DenyEscalatingExec | 防止容器执行特权操作,例如以root用户执行exec命令。 | | ExtendedResourceToleration | 允许 Pod 通过指定容忍性来请求使用扩展资源,如GPU。 | | InitialResources | 自动为 Pod 分配初始资源,例如 CPU 和内存。 | | LimitPodHardAntiAffinityTopology | 在同一拓扑域中,强制对 Pod 应用硬亲和度规则,以保证高可用性和冗余性。 | | LimitRanger | 实现资源限制(如 CPU、内存、存储等)的默认值和最大值,限制 Pod 和容器的资源使用。 | | MutatingAdmissionWebhook | 在资源提交到 API Server 之前,用于对请求进行修改,例如注入辅助容器、自动挂载存储等。 | | NamespaceLifecycle | 管理命名空间的生命周期,拦截 Kubernetes API 服务器对命名空间的创建、删除和更新请求,并在进行处理之前进行验证和审查。 | | NodeRestriction | 用于保护节点安全,限制 Pod 的访问权限以确保节点的安全性。 | | PodNodeSelector | 强制将 Pod 调度到与其节点选择器匹配的节点上。 | | PodPreset | 在创建 Pod 时,从预定义的资源清单中注入额外的容器配置或环境变量。 | | PodSecurityPolicy | 通过定义 Pod 所允许的行为,帮助管理员确保容器在运行时遵守安全最佳实践。 | | Priority | 通过定义优先级,帮助 Kubernetes 确定 Pod 调度顺序。 | | ReplicaSet | 对 ReplicaSet 资源的请求进行验证和审查,例如确保模板的正确性和匹配标签选择器。 | | ResourceQuota | 管理 Kubernetes 中的资源配额,限制命名空间中的资源使用量。 | | SecurityContextDeny | 防止 Pod 和容器在启动时执行不安全的操作,例如使用特权模式、访问主机网络等。 | | ServiceAccount | 用于自动为每个命名空间创建默认的 ServiceAccount,并为 ServiceAccount 分配适当的权限。 | | ServiceAccountTTL | 为 ServiceAccount 指定生存期,以避免积累不需要的 ServiceAccount。 | | ValidatingAdmissionWebhook | 在资源提交到 API Server 之前,用于对请求进行验证和审查,以确保符合预期的策略和规则。 | | ValidatingPodWebhook | 在 Pod 提交到 API Server 之前, 用于对 Pod 对象进行验证和审查。例如审查Pod 的标签、注释、容器规范和卷规范等,以确保它们符合预期和安全性最佳实践。 | | VolumeBinding | 强制在调度期间将 Pod 中的所有卷绑定到可用的节点上,以确保卷的可用性。 | | VolumeSubpath | 允许将子路径添加到 Pod 中的卷,从而更灵活地控制卷的使用方式。 | | ValidatingMutation | 在资源提交到 API Server 之前,用于对请求进行验证和修改。相较于 MutatingAdmissionWebhook,该插件不仅可以修改请求,还可以拒绝它。 | | PodOverhead | 允许 Kubernetes 在计算 Pod 资源使用量时考虑它们的开销。 | | PodSecurityPolicyReview | 在 PodSecurityPolicy 中增加了 Review 操作。可以使用 kubectl create、apply 和 delete 命令,以进行审计和测试。 | | RuntimeClass | 允许运行时类别动态定义 Kubernetes 节点上容器运行的属性和配置。 | | VolumeSnapshotDataSource | 允许使用 Snapshot 数据源创建 PV,以简化卷恢复过程。 | | CertificateApproval | 允许批准和拒绝凭证签发请求,确保凭证的安全性和正确性。 | | Certificates.k8s.io | 提供了一组用于管理和创建证书和私钥的 API,例如 CertificateSigningRequest 和 CertificateSigningRequestApproval。 | | CSI | 允许扩展 Kubernetes 的存储解决方案。CSI(Container Storage Interface)为存储厂商提供了一种通用的接口,从而简化了存储插件的开发和部署。 | | ImagePolicyWebhook | 在拉取镜像之前,用于对镜像进行验证和审查,以确保它们符合安全最佳实践和策略。 | | PodDisruptionBudget | 确保在进行计划性维护、故障排除和升级时,Pod 可以正常运行,防止应用程序的不可用。 | | PodPresets | 允许在创建 Pod 时注入容器配置和环境变量。 | | ValidatingResourceQuota | 允许管理员创建规则以确保 Kubernetes 中的资源分配和使用符合预期。 | | ValidatingSecurityContext | 在 Pod 提交到 API Server 之前,用于对安全上下文进行验证和审查,以确保 Pod 与集群中其他资源的安全性相匹配。 | | ValidatingVolumeMounts | 验证 Pod 中的卷是否正确挂载。 | # 3、Kubernetets创建普通用户 - 需求1:创建一个Role和ServiceAccount并把他们绑定起来。ServiceAccount有get、list、watch的权限 创建YAML文件 ``` cat > testsa.yaml <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: testsa --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: testsa-role rules: - apiGroups: # api组,例如apps组,空值表示是核心API组,像namespace、pod、service、pv、pvc都在里面 - "" resources: #资源名称(复数),例如pods, deployments, services - pods verbs: # 允许的操作,这里允许get, list, watch - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: testsa-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: testsa-role subjects: - kind: ServiceAccount name: testsa EOF ``` 应用此YAML ``` $ kubectl apply -f testsa.yaml ``` 生成token ``` $ kubectl create token testsa ``` - 需求2: 给user1用户授权aming命名空间Pod读取权限 ① 生成ca证书 ``` cd /etc/kubernetes/pki/ openssl genrsa -out user1.key 2048 openssl req -new -key user1.key -out user1.csr -subj "/CN=user1" openssl x509 -req -in user1.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out user1.crt -days 3650 ``` ② 生成kubeconfig授权文件 ``` # 设置集群 kubectl config set-cluster myk8s --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true --server=https://192.168.222.101:6443 --kubeconfig=/root/user1.kubecfg # 查看user1配置,users和context都为空 kubectl config view --kubeconfig=/root/user1.kubecfg # 设置客户端认证 kubectl config set-credentials user1 --client-key=user1.key --client-certificate=user1.crt --embed-certs=true --kubeconfig=/root/user1.kubecfg # 查看user1配置,users有内容了 kubectl config view --kubeconfig=/root/user1.kubecfg # 设置context kubectl config set-context user1@myk8s --cluster=myk8s --user=user1 --kubeconfig=/root/user1.kubecfg # 查看user1配置,context已经有内容了 kubectl config view --kubeconfig=/root/user1.kubecfg # 切换context kubectl config use-context user1@myk8s --kubeconfig=/root/user1.kubecfg ``` ③ 创建角色 ``` cat > user1-role.yaml <<EOF apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: aming name: user1-role rules: - apiGroups: - "" resources: - pods verbs: - get - list - watch EOF kubectl apply -f user1-role.yaml ``` ④ 将用户与角色绑定 ``` cat > user1-rolebinding.yaml <<EOF apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: user1-rolebinding namespace: aming roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: user1-role subjects: - kind: User name: user1 apiGroup: rbac.authorization.k8s.io EOF kubectl apply -f user1-rolebinding.yaml ``` ⑤ 创建系统用户并使用user1的配置 ``` $ useradd aming $ mkdir /home/aming/.kube $ cp /root/user1.kubecfg /home/aming/.kube/config $ chown -R aming.aming /home/aming/.kube/ ``` ⑥ 切换到普通用下并访问k8s ``` $ su - aming $ kubectl get po $ kubectl get po -n aming $ kubectl get deploy -n aming ```
阿星
2024年1月6日 15:32
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码