k8s云安全

k8s云安全
Takakek8s云安全
1.k8s架构
做k8s横向移动首先我们需要搞懂k8s的基础架构。
Kubernetes(k8s)的基础架构是一个分布式系统,由控制平面(Master节点)和工作节点(Node节点)组成,各组件协同工作以实现容器化应用的自动化部署、扩展和管理。以下是其核心架构的详细说明:
1. 控制平面(Control Plane / Master 节点)
主节点可以理解为一台实际运行的主机,具有集群中最高的控制权限。
负责集群的全局决策和资源调度,通常包含以下组件:
1.1 API Server(kube-apiserver)
- 作用:集群的前端接口,处理所有REST请求(如
kubectl
命令),验证并更新集群状态到etcd
。 - 特点:唯一直接与
etcd
交互的组件,支持水平扩展。
1.2 Scheduler(kube-scheduler)
- 作用:将新创建的Pod调度到合适的Node上,基于资源需求(CPU/内存)、亲和性规则、数据位置等策略。
- 流程:监听API Server的未调度Pod,选择最优节点。
1.3 Controller Manager(kube-controller-manager)
- 作用:运行多种控制器,确保集群状态符合用户声明的期望值。常见控制器包括:
- 节点控制器(Node Controller):监控节点状态(如心跳检测)。
- 副本控制器(Replication Controller):维护Pod副本数(如Deployment)。
- 端点控制器(Endpoints Controller):关联Service与Pod。
- 服务账户和令牌控制器:管理Service Account访问权限。
1.4 etcd
- 作用:分布式键值存储数据库,保存集群的所有配置和状态数据(如Pod、Service、Secret等)。
- 特点:高可用性需通过多节点部署保障,是集群的“唯一真实来源”(Single Source of Truth)。
2. 工作节点(Worker Nodes)
节点可以理解成一台实际运行的主机,主机中包含各个组件和容器运行时,容器运行时里包含各个运行的pod。
负责运行容器化应用,包含以下核心组件:
2.1 Kubelet
- 作用:节点代理,与API Server通信,管理本节点的Pod生命周期(如启动/停止容器),报告节点状态。
- 职责:确保Pod中的容器按预期运行,挂载存储卷,执行健康检查等。
2.2 Kube-Proxy
- 作用:维护节点的网络规则(如iptables/IPVS),实现Service的负载均衡和流量路由。
- 功能:将Service的虚拟IP映射到后端Pod,支持ClusterIP、NodePort等类型。
2.3 容器运行时(Container Runtime)
- 作用:实际运行容器的引擎,如Docker、containerd、CRI-O等。
- 标准:遵循Kubernetes CRI(Container Runtime Interface)规范。
3. 核心概念与附加组件
3.1 Pod
pod是容器的抽象。
最小部署单元,包含一个或多个共享网络/存储的容器,是调度的基本单位。
3.2 Service 和 Ingress
- Service:定义一组Pod的访问策略(如ClusterIP、NodePort、LoadBalancer)。
- Ingress:通过HTTP/HTTPS路由外部流量到Service,需配合Ingress控制器(如Nginx、Traefik)。
3.3 网络模型
- CNI(Container Network Interface)插件:如Calico、Flannel,负责Pod跨节点通信和网络策略。
- Pod网络:每个Pod拥有唯一IP,可直接跨节点通信。
3.4 存储管理
- Persistent Volume(PV):集群级别的存储资源。
- Persistent Volume Claim(PVC):用户对存储资源的请求。
3.5 扩展组件
- CoreDNS:集群内部DNS服务,解析Service名称。
- Dashboard:Web管理界面。
- Metrics Server:收集资源指标,支持HPA(Horizontal Pod Autoscaler)。
3.6 安全性
- RBAC(基于角色的访问控制):限制用户/服务的权限。
- Secrets/ConfigMaps:管理敏感数据和配置。
4. 用户交互方式
- kubectl:命令行工具,通过API Server操作集群。
- 声明式配置:YAML/JSON文件定义资源(如Deployment、Service),由Kubernetes确保实际状态匹配期望状态。
架构图示例
1 | +-----------------------+ |
2.kubectl常用命令
以下是 kubectl 的常用命令,涵盖集群管理、资源操作、调试和配置等功能。掌握这些命令可以高效操作 Kubernetes 集群。
一、基础命令
命令 | 作用 | 示例 |
---|---|---|
kubectl get |
查看资源列表 | kubectl get pods (查看所有 Pod)kubectl get nodes (查看节点)kubectl get svc (查看 Service) |
kubectl describe |
查看资源详情 | kubectl describe pod <pod-name> (显示 Pod 详细信息) |
kubectl create |
通过文件或命令行创建资源 | kubectl create -f deployment.yaml (从 YAML 创建)kubectl create namespace test (创建命名空间) |
kubectl apply |
声明式更新资源(推荐) | kubectl apply -f deployment.yaml |
kubectl delete |
删除资源 | kubectl delete pod <pod-name> kubectl delete -f deployment.yaml |
kubectl edit |
直接编辑资源配置 | kubectl edit deployment/my-app |
二、调试与日志
命令 | 作用 | 示例 |
---|---|---|
kubectl logs |
查看容器日志 | kubectl logs <pod-name> kubectl logs -f <pod-name> (实时日志)kubectl logs <pod-name> -c <container-name> (多容器 Pod) |
kubectl exec |
进入容器执行命令 | kubectl exec -it <pod-name> -- /bin/bash (进入容器终端) |
kubectl port-forward |
端口转发到本地 | kubectl port-forward pod/<pod-name> 8080:80 (将 Pod 的 80 端口转发到本地 8080) |
kubectl top |
查看资源使用率 | kubectl top nodes (节点资源)kubectl top pods (Pod 资源) |
三、部署与扩缩容
命令 | 作用 | 示例 |
---|---|---|
kubectl rollout |
管理部署的滚动更新 | kubectl rollout status deployment/my-app (查看状态)kubectl rollout undo deployment/my-app (回滚版本) |
kubectl scale |
扩缩容副本数 | kubectl scale deployment/my-app --replicas=3 (设置副本数为 3) |
kubectl autoscale |
自动扩缩容(HPA) | kubectl autoscale deployment/my-app --min=2 --max=5 --cpu-percent=80 |
四、配置与上下文管理
命令 | 作用 | 示例 |
---|---|---|
kubectl config |
管理 kubeconfig 配置 | kubectl config view (查看配置)kubectl config use-context <context-name> (切换集群/命名空间) |
kubectl cp |
复制文件到容器或从容器复制 | kubectl cp /local/file <pod-name>:/container/path (复制到容器) |
kubectl label |
给资源打标签 | kubectl label pod <pod-name> env=prod |
kubectl annotate |
给资源添加注解 | kubectl annotate pod <pod-name> description="test" |
五、高级操作
命令 | 作用 | 示例 |
---|---|---|
kubectl api-resources |
查看所有 API 资源类型 | kubectl api-resources |
kubectl explain |
查看资源字段说明 | kubectl explain pod.spec.containers |
kubectl patch |
直接修改资源字段 | kubectl patch deployment/my-app -p '{"spec":{"replicas":2}}' |
kubectl replace |
替换资源配置 | kubectl replace -f deployment.yaml |
kubectl proxy |
启动 API Server 代理 | kubectl proxy --port=8080 (通过 localhost:8080 访问 API) |
六、常用组合命令
快速清理命名空间:
1
kubectl delete all --all -n <namespace> # 删除命名空间下所有资源
强制删除卡在 Terminating 的 Pod:
1
kubectl delete pod <pod-name> --grace-period=0 --force
查看 Pod 的事件和状态:
1
kubectl get events --sort-by='.metadata.creationTimestamp' # 按时间排序事件
导出资源配置到文件:
1
kubectl get deployment/my-app -o yaml > deployment.yaml
查看 Service 的 Endpoints:
1
kubectl get endpoints <service-name>
七、实用技巧
别名简化命令:
1
2alias k="kubectl"
alias kgp="kubectl get pods"自动补全:
1
2
3
4
5
6# Bash 用户
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc
# Zsh 用户
source <(kubectl completion zsh)**使用
-o wide
或-o yaml/json
**:1
2kubectl get pods -o wide # 显示更多列(如 IP、节点)
kubectl get pod <name> -o yaml > pod.yaml # 导出 YAML
3.k8s横向移动
在k8s横向移动中通常场景
- 拿到了某一个工作节点种的pod的权限,然后看当前pod的容器是否能够支持容器逃逸,如果不支持,那只能通过10.x网段横向移动到其他pod,看其他pod能否进行逃逸,直到找到一个能够逃逸到宿主机,也就是工作节点的pod,然后通过子节点去执行kubectl或者docker命令,去进入到其他的pod内部执行命令查看其是否有高权限token。然后利用这个高权限token,去获取整个容器的控制权。
一阶段 进入pod
- 假设我们通过漏洞获取了Pod一个容器的shell,那么我们如何通过我们当前的shell环境判断当前是否属于pod环境呢?
- Kubernetes 会在 Pod 中挂载 Service Account 和默认配置文件
1 | # 检查 Service Account 相关文件是否存在 |
- Kubernetes 会为 Pod 注入特定的环境变量
1 | # 查看是否包含 Kubernetes 服务相关的环境变量 |
- 如果 Pod 具有访问 API Server 的权限(默认允许),可直接调用 Kubernetes API
1 | # 使用 Service Account 的 token 访问 API |
二阶段 逃逸到子节点
关于docker逃逸技术,已经在上一篇的内容中进行了讲解了
通过容器逃逸技术加横向渗透技术逃逸到了某个工作子节点
如何判断当前环境是否为节点环境
每一个节点都有自己的conf文件,运维人员就是通过这个conf文件来管理节点中的pod。
文件位置默认在/etc/kubernetes/kubelet.conf
1 | apiVersion: v1 |
或者尝试使用kubectl执行命令。
- 寻找高权限token
逃逸到子节点后你默认就拥有了子节点下所有Pod的进入权限。
你可以依次进入每个pod中,从中依次访问/var/run/secrets/kubernetes.io/serviceaccount/token
文件,获取文件中的token,如果其中存在高权限的token,那么就能进行进一步的渗透。
我们可以利用docker命令进入pod也可以利用kubectl命令进入pod。
也可以编写shell脚本获取token。
1 | # 提取token |
- 如何权限测试
在此之前如何获得apisever的地址呢?
1 | 通过运行的进程查看目标接口的地址 |
三阶段 获取高权限服务账户
如果获得了token那么可以使用以下命令测试能否获得Secret 资源列表。
1 | kubectl --insecure-skip-tls-verify=true --server="http://[apisever:6443]" --token="eyj....." get secrets --all-namespaces |
此命令会返回 Kubernetes 集群中所有命名空间下的 Secret 资源列表,包括以下字段:
- NAMESPACE:Secret 所属的命名空间。
- NAME:Secret 的名称。
- TYPE:Secret 的类型(如
Opaque
、kubernetes.io/tls
等)。 - DATA:Secret 中存储的键值对数量(显示为键的数量,如
2
)。 - AGE:Secret 的创建时间。
Secrets/ConfigMaps:管理敏感数据和配置的组件,就和nacos差不多。
如果能获取到大量数据说明就已经基本和master节点权限一致,那么后续就可以利用这个token去上线pod了、控制master。
总结
其实k8s渗透的思路很明确,基本上是首先上线pod,然后通过横向移动和docker逃逸技术到子节点上,然后利用节点具有管理其下所有pod的权限的机制,获取pod中可能具有的高权限token,然后利用此token来执行kubectl控制整个集群服务。