依赖检查
#1. 依赖检查
主要功能采集K8s所有容器的流量,目前容器部署只支持K8s环境。
#2. 采集配置 [deepflow-agent]
deepflow-agent.yaml 配置文件:
- 推荐:将
vtap-group-id-request设置为系统-采集器-组页面的某个ID字段值,使得采集器被发现时可自动加入特定的采集器组
系统-采集器-配置页面:
采集网口配置为采集流量的网口的正则表达式,请添加^强制匹配开头,例如:^(eth|veth).*eth.*:当K8s的CNI跨节点通信使用隧道时,需要配置采集网口包含K8s节点的出网口(例如物理机的物理网口),以展现虚拟网络链路追踪能力veth.*:POD的虚拟网卡lo: 当两个HostNetwork的POD互访时时走lo口- 注意:采集网口配置必须遵循只看两端不看中间的原则,除lo接口上的本机流量以外,仅采集容器POD、KVM宿主机或物理交换机进出容器节点的流量,请勿配置除此之外的其他网口,否则会导致采集压力上升,并导致页面显示数据错误。
隧道解封装配置为正确的SDN隧道协议,以展示虚拟网络链路追踪能力- 当K8s的CNI跨节点通信使用隧道时,根据隧道类型选择
VXLAN或IPIP - 目前不支持其他隧道封装协议
- 当K8s的CNI跨节点通信使用隧道时,根据隧道类型选择
#3. 采集器资源限制
在 K8s 环境下,页面配置的 CPU/MEM 将会自动由 deepflow-agent 配置到 K8s 的 resources.limit 字段中。
#4. 权限要求
#4.1.1 deepflow-agent 权限需求
#4.1.1.1 运行权限
- 采集 K8s 信息需要的权限包括(必须)
- 内核权限:
SYS_ADMIN、SYS_PTRACE - 容器权限:
HOST_PID
- 内核权限:
- 采集 AF_PACKET 流量需要的权限包括(必须)
- 内核权限:
NET_RAW、NET_ADMIN - 容器权限:
HOST_NET
- 内核权限:
- 采集 AF_PACKET 流量需要的权限包括(可选,若不具备权限会打印 WARN 日志提醒 cBPF 性能会受到显著影响)
- 内核权限:
IPC_LOCK(MAP_LOCKED、MAP_NORESERVE)
- 内核权限:
- 采集 eBPF 数据需要的权限包括(必须)
- 内核权限:
SYS_ADMIN、SYS_RESOURCE - 系统权限:
SELINUX = disabled
- 内核权限:
- 采集 eBPF 数据需要的文件读写权限
- 文件读写权限:
/proc/sys/net/core/bpf_jit_enable(可选,不具备且内容不符合预期时会显著降低性能,可提前设置好内容)- 当该值为 1 时,deepflow-agent 不需要做任何动作(但会读取该值,若不具备读取权限会打印 WARN 日志提醒 eBPF 性能会受到显著影响)
- 当该值不为 1 时,deepflow-agent 会尝试修改为 1,若修改失败会打印 WARN 日志提醒 eBPF 性能会受到显著影响
- K8s 下 deepflow-agent DaemonSet 会默认开启一个特权 init container 将该值设置为 1 以保证 deepflow-agent 运行于非特权模式下,可关闭
- 为了避免赋予
写权限并获得良好的 eBPF 性能,用户可提前将该值设置为 1
- 目录只读权限:
/sys/kernel/debug/(必须,若不具备只读权限则无法开启 eBPF )- 由于 eBPF kprobe、uprobe 类型探测点的 attach/detach 操作依赖于内核的 debug 子系统,因此 /sys/kernel/debug/ 需要只读权限
- 由于该目录只能 root 用户访问,所以 deepflow-agent 只能以 root 用户运行
- 文件读写权限:
#4.1.1.2 K8s API 权限
deepflow-agent 同步 K8s 资源和 Label 信息时需要以下资源的 get/list/watch 权限:
nodesnamespacesconfigmapsservicespodsreplicationcontrollersdaemonsetsdeploymentsreplicasetsstatefulsetsingressesroutes
#4.1.2 Agent 权限需求
#4.1.2.1 运行权限
HostNetwork (必须)
决定容器是否共享宿主的net命名空间,设置为true后容器不会使用单独的net命名空间。Agent 采集主机命名空间中vEth Pair接口、Node接口流量需要该权限。
HostPID (必须)
决定容器是否共享宿主的PID命名空间,设置为true后容器内可以看到宿主上所有的进程。Agent 需要该权限是在使用
setns前需要通过PID拿到相应的命名空间。
容器默认以非特权模式运行,无法访问任何设备。使用 --privileged 开关可以将容器运行在特权模式,此时容器拥有的权限基本和容器外的宿主上一致。非特权模式默认给予了一部分权限,可以通过 --cap-drop 去掉;相对的也可以通过 --cap-add 增加权限参考此链接 (opens new window)。
SYS_ADMIN (必须)
这个权限最初设计是用于系统管理,但随着 Linux 发展变成了比较繁杂的一个权限。具体的权限列表见此链接 (opens new window)。特权模式和该权限的区别之一是,特权模式会将
/dev/和/sys以读写模式挂载,而SYS_ADMIN会挂载为只读,前者对系统中的设备有完整的访问权限。Agent 需要该权限是为了在 Kubernetes 环境中调用setns切换命名空间,以获取 net 命名空间中的接口 MAC 和 IP 地址。SYS_PTRACE (必须)
该权限用于在pod间共享命名空间。由于 Agent 在获取接口信息时需要访问其他 pod 的网络命名空间,所以该权限需要开启。
NET_ADMIN (必须)
该权限用于配置 pod 网络,如接口配置,开启混杂模式。
提示
agent 也可以在非 SYS_ADMIN、SYS_PTRACE 或 HostPID 模式下运行,此时平台信息采集会采用从接口流量获取的方式,时效性和准确率不如特权模式,且子网信息无法推断。 :::
警告
在极少数场景下发现即使赋予了 SYS_ADMIN 和 SYS_PTRACE 权限,agent 依然无法访问某些 pod 的网络命名空间,此时 agent 日志中会打印如下信息:
WARN: kubernetes poller priviledges: set_ns=true readlink_ns=false
WARN: kubernetes poller in passive mode
2
在启动容器采集器前,在容器节点上使用以下命令确认 SYS_ADMIN 和 SYS_PTRACE 权限是否足够
docker run --cap-add SYS_ADMIN --cap-add SYS_PTRACE --cap-add NET_ADMIN --pid host --network host deepflow-agent:{version} agent --check-privileges
若权限不足(表现为在资源-容器资源-容器POD列表中部分POD无法显示MAC地址信息),建议改为使用 privileged 权限,对 daemonset 的配置需手动修改如下(可参考 daemonset 配置文件中的注释):
securityContext:
privileged: true
2
#4.1.2.2 K8s API 权限
Agent 同步 K8s 资源和 Label 信息时需要以下资源的 get/list/watch 权限:
- nodes
- namespaces
- kube-system命名空间configmaps
- services
- pods
- replicationcontrollers
- deployments
- statefulsets
- daemonsets
- replicasets
- ingresses (kubernetes) | routes (openshift)
一个示例配置如下:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: deepflow-agent-role
rules:
- apiGroups: [""]
resources:
- nodes
- namespaces
- configmaps
- services
- pods
- replicationcontrollers
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs: ["get", "list", "watch"]
- apiGroups: ["networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
- apiGroups: ["route.openshift.io"]
resources: ["routes"]
verbs: ["get", "list", "watch"]
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#5. OpenShift 部署注意事项
- 配置
ClusterRole时需要注意 OpenShift 中没有ingress资源,与之对应的是route资源kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: deepflow-agent-role rules: - apiGroups: [""] resources: - nodes - namespaces - configmaps - services - pods - replicationcontrollers verbs: ["get", "list", "watch"] - apiGroups: ["apps"] resources: - daemonsets - deployments - replicasets - statefulsets verbs: ["get", "list", "watch"] - apiGroups: ["route.openshift.io"] resources: ["routes"] verbs: ["get", "list", "watch"]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 - 需要使用以下命令增加 SCC
oc adm policy add-scc-to-user privileged -n yunshan-deepflow -z default1
#6. 安装 deepflow-agent
- 获取镜像,在 extra-artifaces ,执行如下命令,安装
deepflow-agentRPM 包:# deepflow-agent yum --disablerepo=* --enablerepo=deepflow -y install1
2 - 修改 deepflow-agent-cm.yaml 配置文件:编辑
# deepflow-agent 与下述操作相同1deepflow-agent-cm.yaml文件:controller_ips: - 127.0.0.1 # 修改为主控制器的IP - 127.0.0.2 # 修改为备控制器的IP ## 注意:如下两行仅在mac-vlan模式下需要修改 # tap-mode: 1 # 指定为mirror模式 # tap_interface_regex: ethx # ethx为mac-vlan的物理口(`src-interfaces`已被弃用,统一使用`tap_interface_regex`) kubernetes-cluster-id: xxx # 修改从“资源-资源池-云平台”中查看到的ID,形如"cl-xxxxxxxxxx" ingress-flavour: kubernetes/openshift # 修改为对应的容器平台1
2
3
4
5
6
7
8 - 创建 namespace
yunshan-deepflow,供 agent 的 DaemonSet 使用:kubectl create namespace yunshan-deepflow1 - 创建 K8S ConfigMap 资源(用于管理容器内部的配置文件,可以理解为Linux中/etc目录):
kubectl apply -f deepflow-agent-cm.yaml1 - 上传 Agent image
- K8S 环境内,没有私有仓库,操作步骤如下:
- 将
deepflow-agent-*.tar文件copy到k8s所有node节点:scp deepflow-agent-*.tar $node:/root1 - 导入 agent 镜像
#登陆到每个node节点,并将 agent 镜像导入到本地 ssh $node docker load -i /root/deepflow-agent-*.tar1
2
3 - 为 agent 镜像打上标签,以deepflow-agent-1.0-1.tar为例:
docker tag deepflow-agent:1.0-1 deepflow-agent:latest1 - 修改deepflow-agent-ds.yaml文件
imagePullPolicy: Never #将此参数改为Never,表示使用本地镜像,默认为Never image: deepflow-agent:latest #修改为deepflow-agent:latest1
2
- 将
- k8s 环境内有私有仓库,部署步骤如下,该步骤可由客户操作,涉及到私有仓库的账号密码
- 将 agent 镜像导入到本地
docker load -i deepflow-agent-*.tar1 - 为 Agent 镜像打上标签,以 deepflow-agent-1.0-1.tar 为例:
docker tag deepflow-agent:1.0-1 $registry_ip:$registry_port/deepflow-agent:latest # registry_ip:私有仓库的IP地址,也可以是主机名,域名,需要从客户那边获取信息,如果是域名,无需指定registry_port # registry_port: 私有仓库绑定的端口号,需要从客户那边获取1
2
3 - 将打上标签的镜像上传到私有仓库
docker push $registry_ip:$registry_port/deepflow-agent:latest1 - 修改 deepflow-agent-ds.yaml 文件
imagePullPolicy: Always # 该参数修改为Always,表示永远更新远端的latest镜像,当远端没有对应标签的image时,会启动失败。 image: 10.0.0.12:5001/deepflow-agent:latest # 修改为打标签后的镜像为$registry_ip:$registry_port/deepflow-agent:latest1
2
- 将 agent 镜像导入到本地
- K8S 环境内,没有私有仓库,操作步骤如下:
- 启动容器
kubectl apply -f deepflow-agent-ds.yaml # 查看agent容器是否启动,$agentname修改containers.name中设置的名称即可 kubectl get pod $agentname -n yunshan-deepflow # 查看STATUS状态为running状态,即为启动,启动之后,可正常采集流量测试1
2
3
#7. 部署进程形态的 K8s 采集器
当无法直接在 Kubernetes 集群中以 Daemonset 形式部署采集器,但可在宿主机上直接部署二进制时,可使用该方法实现流量采集。
以 deployment 形态部署一个 deepflow-agent
- 通过设置环境变量 K8S_WATCH_POLICY 的值为 watch-only,该 agent 仅实现对 K8s 资源的 list-watch 及上送控制器的功能
- 这个 agent 的其他所有功能均会自动关闭
- agent 请求 server 时告知自己在 watch_k8s,server 会将此信息更新到 MySQL 数据库中
- 用做 Watcher 的采集器将不会出现在采集器列表中
在这个 K8s 集群中,以 Linux 进程的形态在所有 K8s Node 上运行一个 deepflow-agent,执行正常的 agent 功能
- 由于这些 agent 没有 IN_CONTAINER 环境变量,不会 list-watch K8s 资源
- 这些 agent 依然会获取 POD 的 IP 和 MAC
- 这些 agent 完成所有的数据采集功能
- server 向这些 agent 下发的采集器类型为 K8s
#7.1 部署方法
一 部署 deployment 模式采集器
- 复制下面 yaml 文件至客户集群,修改控制器
__FIX_ME_CONTROLLER_IP__后,使用kubectl apply -f部署进客户集群 - 部署后,将自动创建 Domain(对应此 K8s 集群),从页面
资源-资源池中获取云平台 ID,再继续下面的二进制安装
二 部署二进制进程采集器
- 参考二进制部署 deepflow-agent
- 修改 agent 配置文件
/etc/deepflow-agent.yaml,kubernetes-cluster-id填写上一步获取的云平台 ID
## deepflow-agent-watcher
## 注: 下面所有 namespace 参数 value 值不是 deepflow-agent 也行,但必须保持一致
## ClusterRoleBinding.subjects.namespace 是 ServiceAccount 的 namespace
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: deepflow-agent
namespace: deepflow
---
kind: ConfigMap
apiVersion: v1
metadata:
name: deepflow-agent
namespace: deepflow
labels:
app: deepflow
component: deepflow-agent
app.kubernetes.io/name: deepflow-agent
app.kubernetes.io/instance: deepflow
data:
deepflow-agent.yaml: |
controller-ips:
- __FIX_ME_CONTROLLER_IP__
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: deepflow-agent
rules:
- apiGroups: [""]
resources:
- nodes
- namespaces
- configmaps
- services
- pods
- replicationcontrollers
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs: ["get", "list", "watch"]
- apiGroups: ["extensions", "networking.k8s.io"]
resources: ["ingresses"]
verbs: ["get", "list", "watch"]
- apiGroups: ["route.openshift.io"]
resources: ["routes"]
verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: deepflow-agent
subjects:
- kind: ServiceAccount
name: deepflow-agent
namespace: deepflow
apiGroup: ""
roleRef:
kind: ClusterRole
name: deepflow-agent
apiGroup: ""
---
apiVersion: v1
kind: Service
metadata:
name: deepflow-agent
namespace: deepflow
labels:
app: deepflow
component: deepflow-agent
app.kubernetes.io/name: deepflow-agent
app.kubernetes.io/instance: deepflow
spec:
ports:
- name: receive
port: 80
targetPort: receive
protocol: TCP
selector:
app: deepflow
component: deepflow-agent
app.kubernetes.io/name: deepflow-agent
app.kubernetes.io/instance: deepflow
type: "ClusterIP"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deepflow-agent-watcher
namespace: deepflow
labels:
app: deepflow
component: deepflow-agent
app.kubernetes.io/name: deepflow-agent
app.kubernetes.io/instance: deepflow
spec:
replicas: 1
selector:
matchLabels:
app: deepflow
component: deepflow-agent
app.kubernetes.io/name: deepflow-agent
app.kubernetes.io/instance: deepflow
template:
metadata:
annotations:
container.apparmor.security.beta.kubernetes.io/deepflow-agent: unconfined
labels:
app: deepflow
component: deepflow-agent
app.kubernetes.io/name: deepflow-agent
app.kubernetes.io/instance: deepflow
spec:
dnsPolicy: ClusterFirst
imagePullSecrets:
- name: deepflow-registry
serviceAccountName: deepflow-agent
containers:
- name: deepflow-agent
image: "deepflow-agent:latest"
imagePullPolicy: Always
ports:
- name: receive
containerPort: 38086
protocol: TCP
# livenessProbe:
# tcpSocket:
# port: otel
# initialDelaySeconds: 5
# periodSeconds: 10
# readinessProbe:
# tcpSocket:
# port: otel
# initialDelaySeconds: 5
# periodSeconds: 10
env:
- name: K8S_WATCH_POLICY
value: "watch-only"
resources:
limits:
cpu: 1000m
memory: 768Mi
requests:
cpu: 100m
memory: 128Mi
volumeMounts:
- name: deepflow-agent-conf
mountPath: /etc/deepflow-agent
volumes:
- name: deepflow-agent-conf
configMap:
name: deepflow-agent
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#8. 调试方法
#8.1 在DeepFlow节点上安装kubectl
kubectl 安装(561 R2开始,kubectl的安装包会集成到ISO中):
yum install -y kubectl --disablerepo=* --enablerepo=deepflow
新建/root/.kube/config:vim /root/.kube/config,并录入如下内容(注意修改三行注释下的内容):
apiVersion: v1
clusters:
- cluster:
# 将 /etc/cloud-agent.yaml 文件中k8s配置部分的 apiserver_url 内容填入下面的 server 字段中
server: https://140.143.129.9:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubernetes-admin
name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
user:
# 将如下命令的输出填入下面的 client-certificate-data 字段中,注意命令中的crt文件会在k8s平台对接时拿到
# cat apiserver-kubelet-client.crt | base64
client-certificate-data:
# 将如下命令的输出填入下面的 client-key-data 字段中,注意命令中的key文件会在k8s平台对接时拿到
# cat apiserver-kubelet-client.key | base64
client-key-data:
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23