kind创建集群,一个master节点即可
docker pull kindest/node:v1.27.1
kind create cluster --config - --image kindest/node:v1.27.1 <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: demo
nodes:
- role: control-plane
EOF
kindest/node:v1.27.1 版本需要cgroups v2
执行以下操作切换到 cgroups v2
# 编辑 GRUB 配置
sudo vi /etc/default/grub
#删除以下参数(如果存在)
systemd.unified_cgroup_hierarchy=0
#在 GRUB_CMDLINE_LINUX 中添加以下参数 确保追加到现有参数后
GRUB_CMDLINE_LINUX="... systemd.unified_cgroup_hierarchy=1"
#更新并重启
sudo update-grub && sudo reboot
#验证:
stat -fc %T /sys/fs/cgroup/ # 应输出 cgroup2fs tmpfs则表示cgroups v1
在不同命名空间中创建多个Services
#service.yaml
apiVersion: v1
kind: Service
metadata:
name: admin-service
namespace: default
spec:
selector:
app: admin
ports:
- name: admin
protocol: TCP
port: 6003
targetPort: 6003
---
apiVersion: v1
kind: Service
metadata:
name: airtable-service
namespace: kube-public
spec:
selector:
app: airtable
ports:
- name: airtable
protocol: TCP
port: 5006
targetPort: 5006
---
apiVersion: v1
kind: Service
metadata:
name: apple-service
namespace: kube-system
spec:
selector:
app: apple
ports:
- name: apple
protocol: TCP
port: 7005
targetPort: 7005
---
apiVersion: v1
kind: Service
metadata:
name: aws-service
namespace: default
spec:
selector:
app: aws
ports:
- name: aws
protocol: TCP
port: 5003
targetPort: 5003
---
apiVersion: v1
kind: Service
metadata:
name: class-service
namespace: kube-public
spec:
selector:
app: class
ports:
- name: class
protocol: TCP
port: 6005
targetPort: 6005
---
apiVersion: v1
kind: Service
metadata:
name: clip-service
namespace: kube-system
spec:
selector:
app: clip
ports:
- name: clip
protocol: TCP
port: 6004
targetPort: 6004
---
apiVersion: v1
kind: Service
metadata:
name: gateway-service
namespace: default
spec:
selector:
app: gateway
ports:
- name: gateway
protocol: TCP
port: 5001
targetPort: 5001
---
apiVersion: v1
kind: Service
metadata:
name: manager-service
namespace: kube-public
spec:
selector:
app: manager
ports:
- name: manager
protocol: TCP
port: 5004
targetPort: 5004
---
apiVersion: v1
kind: Service
metadata:
name: web3-service
namespace: kube-system
spec:
selector:
app: web3
ports:
- name: web3
protocol: TCP
port: 6010
targetPort: 6010
---
apiVersion: v1
kind: Service
metadata:
name: webhooks-service
namespace: default
spec:
selector:
app: webhooks
ports:
- name: webhooks
protocol: TCP
port: 5005
targetPort: 5005
---
apiVersion: v1
kind: Service
metadata:
name: http-https-service
namespace: kube-public
spec:
selector:
app: http-https
ports:
- name: http
protocol: TCP
port: 80
targetPort: http
- name: https
protocol: TCP
port: 443
targetPort: http
检查资源创建情况,kubectl get svc -A
默认情况下,Kubernetes Service 资源的 IP 范围为 10.96.0.0/12
创建一个 Pod,处于 default 命名空间,
docker pull alpine:latest
kind load docker-image --name demo alpine:latest
kubectl run test-pod --image=docker.io/library/alpine:latest --restart=Always --command -- /bin/sh -c "while true; do sleep 3600; done"
Service(服务)用于公开运行在一个或多个 Pod 上的应用程序。具体来说,Service 充当了 Pod 的负载均衡器,并为它们提供了统一的入口点,从而向外界公开应用程序。
Service 被分配了一个集群内部可访问的 IP 地址,这个 IP 地址称为集群 IP(Cluster IP),用于在集群内部将流量路由到 Service 后端的 Pod,Service 通常将一个或多个端口暴露给外部流量,以便外部用户或应用程序可以访问 Pod 上的应用程序。与 Service 相关联的 DNS 记录允许通过 Service 名称来访问 Service,而不必直接使用 IP 地址,这些 DNS 记录由集群的 DNS 解析器管理,从而允许使用Service 名称来解析到对应的 IP 地址。
默认情况下,Kubernetes Service 资源的 IP 范围为 10.96.0.0/12
。
当你创建一个 Service 对象时,Kubernetes 会自动在同一命名空间中的 Pod 中注入一些与这个 Service 相关的环境变量。这些环境变量包括了服务的地址和端口信息。跨命名空间的 Pod 不会自动获得其他命名空间中服务的地址和端口信息。 env | grep SERVICE_HOST
通过此方法我们就可以获取到部分service的网段
Kubernetes 中 DNS 解析器为集群中的 Service 自动创建的各种 DNS 记录,官网文档在DNS for Services and Pods | Kubernetes,
DNS 记录包括:
服务的 DNS 名称为 <service-name>.<namespace>.svc.cluster.local.
,例如集群中默认存在的Service: kubernetes.default.svc.cluster.local.
,这个是 Kubernetes 集群内部用于访问Kubernetes API 服务器的默认域名,
分解来看:
SRV 记录提供服务监听端口的详细信息, _<port-name>._<port-protocol>.<service-name>.<namespace>.svc.cluster.local
分解来看:
<port-name>
端口的名称<port-protocol>
端口的协议(例如 TCP 或 UDP)<service-name>
服务的名称<namespace>
服务所在的命名空间这些 DNS 记录使得在 Kubernetes 集群中的应用程序可以通过服务名称和端口进行发现和访问,而无需直接使用 IP 地址。
PTR记录是 DNS 中的一种反向解析记录,可以通过 IP 地址查找对应的域名(service的DNS名字)
先给 alpine 容器安装 dig 工具,
sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
apk add bind-tools
我们可以对已知 IP 进行反向 DNS 查找,例如获取 Kubernetes API 服务器的 IP:
env | grep KUBERNETES_SERVICE_HOST
#再反查 DNS
dig +short -x 10.96.0.1
我们可以对已知 DNS 名称查找 SRV 记录:
SRV 记录(Service Record)是 DNS 系统中的一种特殊记录类型,用于指定某个服务对应的服务器地址和端口号
我们可以通过DNS获取到服务的端口
dig +short SRV kubernetes.default.svc.cluster.local.
0
这是 SRV 记录的优先级,指示客户端尝试连接的顺序。在这里优先级为 0,表示没有特定的优先级。100
这是 SRV 记录的权重,用于负载均衡。权重越高,被选中的概率越大。443
这是 SRV 记录指定的服务端口号。在这里是 Kubernetes API 服务器的服务端口。kubernetes.default.svc.cluster.local.
该服务的 DNS 名称。如果我们正在一个 Pod 中,根据 PTR 记录和 SRV 记录的特点,可以得到一个对 Kubernetes Service 资产进行扫描的路径:对相关网段进行扫描,获取对应 IP 的 PTR 记录;对每一个 PTR 记录获取其 SRV 记录;也就是 service_ip
--> service_dns_name
--> service_port
--> service_host
,最终获取 Service 资产 service_host
昨天某师傅开源的工具: https://github.com/Esonhugh/k8spider 本文章则是为这个工具做铺垫的。
该工具的视角是 Pod 中,
一般来说可以先确定一部分 Service 的网段 env | grep SERVICE_HOST
,
再对该网段进行扫描 ./k8spider-linux-amd64-upx all -c 10.96.0.1/16
成功获取集群中所有的Service 资产。当然前提是模拟环境中所有 Service 资产都在 10.96.0.1/16 网段中,在实际情况下,需要对这个网段附近其他网段进行探测以获取更完整的服务列表。
对于业务不需要 PTR 与 SRV 记录的集群,可以禁用 CoreDNS 的 PTR 与 SRV 记录。
#修改CoreDNS的配置文件
kubectl edit configmap/coredns -n kube-system
加入如下两句配置,wq 修改保存后等待十几秒,
template IN PTR .
template IN SRV .
经过该配置,CoreDNS 会拦截掉 PTR 与 SRV 记录。