openshift/ingress-node-firewall
GitHub: openshift/ingress-node-firewall
这是一个基于 Kubernetes 的 Operator,利用 eBPF XDP 技术实现高性能的节点级无状态入站流量防火墙。
Stars: 71 | Forks: 32
# Ingress Node Firewall
这是 Ingress node Firewall Operator,实现了用于在 kubernetes 集群上部署 Ingress node firewall daemon 的 [Operator 模式](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/)。
它使用 [Controllers](https://kubernetes.io/docs/concepts/architecture/controller/)
它提供了一个协调函数,负责同步资源,直到集群达到所需状态
[]() [](https://github.com/openshift/ingress-node-firewall/blob/master/LICENSE) [](https://quay.io/openshift/ingress-node-firewall-operator:4.13) [](https://goreportcard.com/report/github.com/openshift/ingress-node-firewall) [](https://bestpractices.coreinfrastructure.org/projects/6726)
## 用法
安装 Ingress Node Firewall Operator 后,您必须创建一个 `IngressNodeFirewallConfig` 自定义资源来部署 Operator 的 DaemonSet。
`IngressNodeFirewallConfig` 自定义资源需要在 `ingress-node-firewall-system` 命名空间内创建,并命名为 `ingressnodefirewallconfig`。一个集群中只能存在一个 `IngressNodeFirewallConfig` 资源。
该 operator 将使用此资源并创建 ingress node firewall daemonset `daemon`,它运行在所有匹配 `nodeSelector` 的节点上。
以下是 `IngressNodeFirewallConfig` 资源的示例:
```
apiVersion: ingressnodefirewall.openshift.io/v1alpha1
kind: IngressNodeFirewallConfig
metadata:
name: ingressnodefirewallconfig
namespace: ingress-node-firewall-system
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
```
之后,部署一个或多个 `IngressNodeFirewall` 资源以将防火墙规则应用于您的节点。确保 `nodeSelector` 匹配一组节点。Ingress Node Firewall Operator 将为每个被至少一个 `IngressNodeFirewall` 资源匹配的节点创建 `IngressNodeFirewallNodeState` 类型的对象:
```
apiVersion: ingressnodefirewall.openshift.io/v1alpha1
kind: IngressNodeFirewall
metadata:
name: ingressnodefirewall-demo-1
spec:
interfaces:
- eth0
nodeSelector:
node-role.kubernetes.io/worker: ""
ingress:
- sourceCIDRs:
- 1.1.1.1/24
- 100:1::1/64
rules:
- order: 10
protocolConfig:
protocol: TCP
tcp:
ports: "100-200"
action: Allow
```
您可以使用以下快捷方式部署示例,包括 `IngressNodeFirewallConfig` 和 `IngressNodeFirewall` 资源:
```
make deploy-samples
```
为了卸载它们:
```
make undeploy-samples
```
## 部署 operator
### 前置条件
您需要安装以下软件包:
operator-sdk 1.22.0
controller-gen v0.9.0+
对于 fedora,您将需要以下软件包
```
sudo dnf install glibc-devel glibc-devel.i686
```
### 在 KinD 集群上运行
#### 创建一个安装了 operator 的 kind 集群
##### 一步完成
1. 下载最新的 [KinD](https://kind.sigs.k8s.io/docs/user/quick-start) 稳定版本
2. 安装 KinD 和 operator 并导出 KUBECONFIG
```
make create-and-deploy-kind-cluster
export KUBECONFIG=$(pwd)/hack/kubeconfig
```
**注意:** 如果出现提示,请手动编辑文件 `config/manager/env.yaml` 并设置环境变量
`DAEMONSET_IMAGE` 的值。这仅在找不到 `yq` 时才会发生。
##### 手动部署 kind 和 operator
1. 下载最新的 [KinD](https://kind.sigs.k8s.io/docs/user/quick-start) 稳定版本
2. 安装 KinD 并导出 KUBECONFIG
```
make create-kind-cluster
export KUBECONFIG=$(pwd)/hack/kubeconfig
```
3. 安装自定义资源定义
```
make install
```
4. 构建 controller 容器镜像
```
make docker-build IMG=
/ingress-node-firewall-controller:latest
```
5. 将 controller 容器镜像加载到 KinD 容器
```
kind load docker-image /ingress-node-firewall-controller:latest
```
6. 构建 daemon 容器镜像
```
make docker-build-daemon DAEMON_IMG=/ingress-node-firewall-daemon:latest
```
7. 将 daemon 容器镜像加载到 KinD 容器
```
kind load docker-image /ingress-node-firewall-daemon:latest
```
8. 设置 daemon 镜像名称
```
hack/set-daemon-image.sh /ingress-node-firewall-daemon:latest
```
9. 将资源部署到 KinD 集群
```
make deploy-kind IMG=/ingress-node-firewall-controller:latest
```
#### 使用 Bpfman 进行 eBPF 程序管理部署
完成上一节中的所有步骤并部署 ingress node firewall operator 后,
您必须部署 bpfman-operator:
```
git clone https://github.com/bpfman/bpfman-operator.git
cd bpfman-operator
make deploy
```
这将部署 `bpfman-operator` 并启动 `bpfman-daemon` pods。
```
oc get pods -n bpfman
NAME READY STATUS RESTARTS AGE
bpfman-daemon-45jtk 3/3 Running 0 63s
bpfman-daemon-8x9j7 3/3 Running 0 63s
bpfman-daemon-c9td4 3/3 Running 0 63s
bpfman-operator-7f67bc7c57-5cpqr 2/2 Running 0 75s
```
要选择 bpfman 来管理 INFW 程序,请在 `IngressNodeFirewallConfig` 中将 `ebpfProgramManagerMode` 设置为 true。
```
apiVersion: ingressnodefirewall.openshift.io/v1alpha1
kind: IngressNodeFirewallConfig
metadata:
name: ingressnodefirewallconfig
namespace: ingress-node-firewall-system
spec:
nodeSelector:
node-role.kubernetes.io/worker: ""
ebpfProgramManagerMode: true
```
如果 eBPF 程序有任何更新,那么我们需要构建并推送字节码镜像
```
make build-and-push-bc-image
```
#### 从 kind 集群中移除 operator
为了移除 operator:
1. 从 KinD 集群中取消部署资源
```
make undeploy-kind
```
2. 卸载自定义资源定义:
```
make uninstall
```
#### 删除 kind 集群
为了删除 kind 集群:
```
make destroy-kind-cluster
```
### 在 OCP 集群上运行
为了在 OpenShift 上运行此 operator,可以从 manifests 部署或从 OLM 部署。
在这两种情况下,请先遵循 [通用步骤](README.md#common-steps),然后遵循 [从 manifests 部署](README.md#deploy-from-manifests) 或 [使用 OLM 部署](README.md#deploy-with-olm)。
#### 通用步骤
1. 创建 OCP 集群
2. 构建 controller 容器镜像
```
make docker-build IMG=/ingress-node-firewall-controller:latest
# 或执行 make podman-build IMG=/ingress-node-firewall-controller:latest
```
3. 将 controller 容器镜像推送到镜像仓库
```
make docker-push IMG=/ingress-node-firewall-controller:latest
# 或执行 make podman-push IMG=/ingress-node-firewall-controller:latest
```
4. 构建 daemon 容器镜像
```
make docker-build-daemon DAEMON_IMG=/ingress-node-firewall-daemon:latest
# 或执行 make podman-build-daemon DAEMON_IMG=/ingress-node-firewall-daemon:latest
```
5. 将 controller 容器镜像推送到镜像仓库
```
make docker-push-daemon DAEMON_IMG=/ingress-node-firewall-daemon:latest
# 或执行 make podman-push-daemon DAEMON_IMG=/ingress-node-firewall-daemon:latest
```
6. 设置 daemon 镜像名称
```
hack/set-daemon-image.sh /ingress-node-firewall-daemon:latest
```
#### 从 manifests 部署
7. 安装自定义资源定义
```
make install
```
8. 将资源部署到 OpenShift 集群
```
make deploy IMG=/ingress-node-firewall-controller:latest
```
##### 卸载
从 OCP 集群中取消部署资源
```
make undeploy
```
卸载自定义资源定义
```
make uninstall
```
#### 使用 OLM 部署
7. 构建并推送 bundle 和 index 镜像到镜像仓库。
```
make build-and-push-bundle-images \
IMG=/ingress-node-firewall-controller:latest \
BUNDLE_IMG=/ingress-node-firewall-bundle:latest \
BUNDLE_INDEX_IMG=/ingress-node-firewall-index:latest
# 或执行 make podman-build-and-push-bundle-images \
# IMG=/ingress-node-firewall-controller:latest \
# BUNDLE_IMG=/ingress-node-firewall-bundle:latest \
# BUNDLE_INDEX_IMG=/ingress-node-firewall-index:latest
```
8. 使用 OLM 部署
```
make deploy-with-olm \
NAMESPACE=openshift-ingress-node-firewall \
BUNDLE_INDEX_IMG=/ingress-node-firewall-index:latest
```
##### 卸载
从 OCP 集群中取消部署资源
```
oc delete ns openshift-ingress-node-firewall
```
卸载自定义资源定义
```
make uninstall
```
## 测试
### 运行测试
要运行 ingress-node-firewall-operator 单元测试(不需要集群),请执行以下操作:
```
make test
```
要测试竞态条件,请运行:
```
make test-race
```
### 运行 E2E 测试
1. 启动 KinD 集群并按照前面概述的步骤部署 ingress node firewall operator。
2. 运行完整的 E2E 测试
```
make test-e2e
```
注意:有关测试选项和已知问题,请参阅 test README.md。
## 统计信息
当数据包被允许或拒绝时,BPF 程序会生成统计信息,输出允许和拒绝的总数据包数以及处理的字节数。这些统计信息由节点守护进程在用户空间捕获,并以 prometheus 格式指标公开,然后由 OCP 上的 prometheus 抓取。我们不使用 KinD 设置脚本部署 Prometheus,但指标仍然可以从名为 `ingress-node-firewall-daemon-metrics` 的服务或从节点守护进程本身查询:
1. 进入其中一个节点守护进程
```
kubectl exec -n ${OPERATOR_NAMESPACE} -it ${NODE_DAEMON_NAME} sh
```
2. 检索 Prometheus 格式的指标
```
Curl 127.0.0.1:39401/metrics
```
在 OCP 中,您可以使用 OCP 控制台访问 promql 控制台以搜索以下指标:
- ingressnodefirewall_node_packet_allow_total
- ingressnodefirewall_node_packet_allow_bytes
- ingressnodefirewall_node_packet_deny_total
- ingressnodefirewall_node_packet_deny_bytes
## 有用的命令和技巧
### 生成 operator bundle
为了生成 operator bundle,请运行以下命令:
```
make bundle
make manifests
```
### 构建 DaemonSet 镜像
此 operator 依赖于 DaemonSet 镜像。您可以使用以下命令构建此镜像并将其推送到您的仓库:
```
make docker-build-daemon DAEMON_IMG=/:
# 或执行 make podman-build-daemon DAEMON_IMG=/:
make docker-push-daemon DAEMON_IMG=/:
# 或执行 make podman-push-daemon DAEMON_IMG=/:
```
### 本地运行 operator
1. 导出您的 kubernetes 凭据
2. 创建项目和服务帐户
```
oc new-project ingress-node-firewall-system
oc create sa ingress-node-firewall-daemon
oc adm policy add-scc-to-user privileged -z ingress-node-firewall-daemon
```
3. 使用以下命令在本地运行此 operator:
```
export DAEMONSET_IMAGE=/:
export DAEMONSET_NAMESPACE=ingress-node-firewall-system
export KUBE_RBAC_PROXY_IMAGE=quay.io/openshift/origin-kube-rbac-proxy:latest
make install run
```
4. 创建 `IngressNodeFirewallConfig` CR。标签:CNI, DaemonSet, Docker镜像, Go语言, Ingress Node Firewall, OpenShift, Operator, Web截图, XDP, 内核级防护, 子域名突变, 客户端加密, 容器安全, 控制器, 无状态防火墙, 日志审计, 程序破解, 网络安全, 网络过滤, 自定义请求头, 自定义资源, 节点防护, 防火墙, 隐私保护