Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
- 1. LAB环境
- 2. L2公告策略
- 2.1 部署Death Star
- 2.2 访问服务
- 2.3 部署L2公告策略
- 2.4 服务宣告
- 3. 可视化 ARP 流量
- 3.1 部署新服务
- 3.2 准备可视化
- 3.3 再次请求
- 4. 自动IPAM
- 4.1 IPAM Pool
- 4.2 配置L2策略
- 4.3 创建服务
- 5. 弹性负载均衡
- 5.1 监控ARP
- 5.2 删除节点
- 5.3 检查回退
- 5.4 小测验
- 6. 测试
- 6.1 需求
- 6.2 解题
1. LAB环境
LAB环境访问地址
https://isovalent.com/labs/cilium-lb-ipam-l2-announcements/
kind安装1个1控制节点2worker节点
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:disableDefaultCNI: truekubeProxyMode: "none"
nodes:- role: control-planeextraPortMappings:# Hubble relay- containerPort: 31234hostPort: 31234# Hubble UI- containerPort: 31235hostPort: 31235- role: worker- role: worker
cilium安装
cilium install \--version v1.17.1 \--set kubeProxyReplacement=true \--set k8sServiceHost="kind-control-plane" \--set k8sServicePort=6443 \--set l2announcements.enabled=true \--set l2announcements.leaseDuration="3s" \--set l2announcements.leaseRenewDeadline="1s" \--set l2announcements.leaseRetryPeriod="500ms" \--set devices="{eth0,net0}" \--set externalIPs.enabled=true \--set operator.replicas=2
启用 Hubble 以进行可视化:
cilium hubble enable --ui
检查 Cilium 是否正常运行:
cilium status --wait
检查 L2 公告设置:
cilium config view | grep l2
输出结果:
root@server:~# yq cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:disableDefaultCNI: truekubeProxyMode: "none"
nodes:- role: control-planeextraPortMappings:# Hubble relay- containerPort: 31234hostPort: 31234# Hubble UI- containerPort: 31235hostPort: 31235- role: worker- role: worker
root@server:~# cilium install \--version v1.17.1 \--set kubeProxyReplacement=true \--set k8sServiceHost="kind-control-plane" \--set k8sServicePort=6443 \--set l2announcements.enabled=true \--set l2announcements.leaseDuration="3s" \--set l2announcements.leaseRenewDeadline="1s" \--set l2announcements.leaseRetryPeriod="500ms" \--set devices="{eth0,net0}" \--set externalIPs.enabled=true \--set operator.replicas=2
🔮 Auto-detected Kubernetes kind: kind
ℹ️ Using Cilium version 1.17.1
🔮 Auto-detected cluster name: kind-kind
ℹ️ Detecting real Kubernetes API server addr and port on Kind
🔮 Auto-detected kube-proxy has not been installed
ℹ️ Cilium will fully replace all functionalities of kube-proxy
root@server:~# cilium hubble enable --ui
root@server:~# cilium status --wait/¯¯\/¯¯\__/¯¯\ Cilium: OK\__/¯¯\__/ Operator: OK/¯¯\__/¯¯\ Envoy DaemonSet: OK\__/¯¯\__/ Hubble Relay: OK\__/ ClusterMesh: disabledDaemonSet cilium Desired: 3, Ready: 3/3, Available: 3/3
DaemonSet cilium-envoy Desired: 3, Ready: 3/3, Available: 3/3
Deployment cilium-operator Desired: 2, Ready: 2/2, Available: 2/2
Deployment hubble-relay Desired: 1, Ready: 1/1, Available: 1/1
Deployment hubble-ui Desired: 1, Ready: 1/1, Available: 1/1
Containers: cilium Running: 3cilium-envoy Running: 3cilium-operator Running: 2clustermesh-apiserver hubble-relay Running: 1hubble-ui Running: 1
Cluster Pods: 5/5 managed by Cilium
Helm chart version: 1.17.1
Image versions cilium quay.io/cilium/cilium:v1.17.1@sha256:8969bfd9c87cbea91e40665f8ebe327268c99d844ca26d7d12165de07f702866: 3cilium-envoy quay.io/cilium/cilium-envoy:v1.31.5-1739264036-958bef243c6c66fcfd73ca319f2eb49fff1eb2ae@sha256:fc708bd36973d306412b2e50c924cd8333de67e0167802c9b48506f9d772f521: 3cilium-operator quay.io/cilium/operator-generic:v1.17.1@sha256:628becaeb3e4742a1c36c4897721092375891b58bae2bfcae48bbf4420aaee97: 2hubble-relay quay.io/cilium/hubble-relay:v1.17.1@sha256:397e8fbb188157f744390a7b272a1dec31234e605bcbe22d8919a166d202a3dc: 1hubble-ui quay.io/cilium/hubble-ui-backend:v0.13.1@sha256:0e0eed917653441fded4e7cdb096b7be6a3bddded5a2dd10812a27b1fc6ed95b: 1hubble-ui quay.io/cilium/hubble-ui:v0.13.1@sha256:e2e9313eb7caf64b0061d9da0efbdad59c6c461f6ca1752768942bfeda0796c6: 1
root@server:~# cilium config view | grep l2
enable-l2-announcements true
enable-l2-neigh-discovery true
l2-announcements-lease-duration 3s
l2-announcements-renew-deadline 1s
l2-announcements-retry-period 500ms
全部符合我们的预期
2. L2公告策略
2.1 部署Death Star
部署 Death Star 工作负载和相应的服务:
root@server:~# yq deathstar.yaml
---
apiVersion: v1
kind: Service
metadata:name: deathstarlabels:color: red
spec:type: ClusterIPports:- port: 80selector:org: empireclass: deathstar
---
apiVersion: apps/v1
kind: Deployment
metadata:name: deathstar
spec:selector:matchLabels:org: empireclass: deathstarreplicas: 2template:metadata:labels:org: empireclass: deathstarname: deathstarspec:containers:- name: deathstarimage: docker.io/cilium/starwarsimagePullPolicy: IfNotPresent
root@server:~# kubectl apply -f deathstar.yaml
service/deathstar created
deployment.apps/deathstar created
等待 Death Star 部署准备就绪:
kubectl rollout status deployment deathstar
检查服务:
kubectl get svc deathstar --show-labels
我们想从集群外部访问 Death Star。为此,我们可以向服务添加外部 IP。现在,让我们在其上手动设置 IP 地址。我们将使用 12.0.0.100
作为外部 IP 地址:
SVC_IP=12.0.0.100
kubectl patch service deathstar -p '{"spec":{"externalIPs":["'$SVC_IP'"]}}'
验证服务是否具有正确的外部 IP:
kubectl get svc deathstar
输出结果如下:
root@server:~# kubectl apply -f deathstar.yaml
service/deathstar created
deployment.apps/deathstar created
root@server:~# kubectl rollout status deployment deathstar
deployment "deathstar" successfully rolled out
root@server:~# kubectl get svc deathstar --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
deathstar ClusterIP 10.96.28.40 <none> 80/TCP 2m21s color=red
root@server:~# SVC_IP=12.0.0.100
kubectl patch service deathstar -p '{"spec":{"externalIPs":["'$SVC_IP'"]}}'
service/deathstar patched
root@server:~# kubectl get svc deathstar
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
deathstar ClusterIP 10.96.28.40 12.0.0.100 80/TCP 2m52s
2.2 访问服务
名为 clab-garp-demo-neighbor
的 Docker 容器已部署在与分配给服务的 IP 相同的网络中。在其中执行一个 shell:
docker exec -e SVC_IP=$SVC_IP -ti clab-garp-demo-neighbor bash
尝试访问新创建的服务:
curl --connect-timeout 1 http://$SVC_IP/v1/
连接超时是因为此服务尚未通过 ARP 公布,因此容器不知道如何访问它。
root@neighbor:/# curl --connect-timeout 1 http://$SVC_IP/v1/
curl: (28) Connection timed out after 1000 milliseconds
2.3 部署L2公告策略
在节点上的 net0
接口上公布外部 IP(但不是负载均衡器 IP),并且它适用于带有标签 color=blue
的服务。
添加 nodeSelector
条目,以避免将 Control Plane 节点用作负载均衡器的入口点。
应用策略:
root@server:~# yq l2policy.yaml
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:name: policy1
spec:externalIPs: trueloadBalancerIPs: falseinterfaces:- net0serviceSelector:matchLabels:color: bluenodeSelector:matchExpressions:- key: node-role.kubernetes.io/control-planeoperator: DoesNotExist
root@server:~# kubectl apply -f l2policy.yaml
ciliuml2announcementpolicy.cilium.io/policy1 created
再次尝试访问
root@neighbor:/# curl --connect-timeout 1 http://$SVC_IP/v1/
curl: (28) Connection timed out after 1000 milliseconds
因为 L2 策略适用于标记为 color=blue
的服务,但 Death Star 服务当前标记为 color=red
,所以连接仍然超时 。
2.4 服务宣告
将服务修改为使用 color=blue
标签:
kubectl label svc deathstar color=blue --overwrite
并尝试再次连接:
root@neighbor:/# curl --connect-timeout 1 http://$SVC_IP/v1/|jq
{"name": "Death Star","hostname": "deathstar-65c8d4f687-cfzsz","model": "DS-1 Orbital Battle Station","manufacturer": "Imperial Department of Military Research, Sienar Fleet Systems","cost_in_credits": "1000000000000","length": "120000","crew": "342953","passengers": "843342","cargo_capacity": "1000000000000","hyperdrive_rating": "4.0","starship_class": "Deep Space Mobile Battlestation","api": ["GET /v1","GET /v1/healthz","POST /v1/request-landing","PUT /v1/cargobay","GET /v1/hyper-matter-reactor/status","PUT /v1/exhaust-port"]
}
现在可以访问该服务,因为 IP 是通过 ARP 向网络宣布的!
3. 可视化 ARP 流量
3.1 部署新服务
部署一个名为 deathstar-2
的新服务,它指向相同的 Death Star 服务:
root@server:~# yq deathstar-2.yaml
---
apiVersion: v1
kind: Service
metadata:name: deathstar-2labels:color: blue
spec:type: ClusterIPexternalIPs:- 12.0.0.101ports:- port: 80selector:org: empireclass: deathstar
root@server:~# kubectl apply -f deathstar-2.yaml
service/deathstar-2 created
root@server:~#
此服务已经有一个预定义的静态外部 IP 12.0.0.101
,并标有 color=blue
,因此它将由我们之前部署的 policy1
L2 公告策略进行通告。
验证服务:
root@server:~# kubectl get svc deathstar-2
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
deathstar-2 ClusterIP 10.96.116.132 12.0.0.101 80/TCP 30s
3.2 准备可视化
Cilium 在 kube-system
命名空间中为与服务关联的每个 L2 租约创建一个 Lease
资源。
查看 deathstar-2
服务的租约:
root@server:~# kubectl get leases -n kube-system cilium-l2announce-default-deathstar-2 -o yaml
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata:creationTimestamp: "2025-05-27T02:33:06Z"name: cilium-l2announce-default-deathstar-2namespace: kube-systemresourceVersion: "3410"uid: 75fefb56-0627-44d2-94fe-0097c66b92fa
spec:acquireTime: "2025-05-27T02:33:06.655416Z"holderIdentity: kind-worker2leaseDurationSeconds: 3leaseTransitions: 0renewTime: "2025-05-27T02:34:15.290214Z"
托管租约的节点在 spec.holderIdentity
中指定。检索它:
LEASE_NODE=$(kubectl -n kube-system get leases cilium-l2announce-default-deathstar-2 -o jsonpath='{.spec.holderIdentity}')
echo $LEASE_NODE
接下来,找到在该节点上运行的 Cilium 代理 pod:
LEASE_CILIUM_POD=$(kubectl -n kube-system get pod -l k8s-app=cilium --field-selector spec.nodeName=$LEASE_NODE -o name)
echo $LEASE_CILIUM_POD
现在,登录到 CIlium 代理 pod:
kubectl -n kube-system exec -ti $LEASE_CILIUM_POD -- bash
在 Pod 中安装 tcpdump 和 termshark:
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install tcpdump termshark
在 Pod 的后台启动 tcpdump
。过滤 ARP 数据包并将流写入 arp.pcap
文件:
tcpdump -i any arp -w arp.pcap
3.3 再次请求
再次向服务发出请求:
root@server:~# docker exec -ti clab-garp-demo-neighbor \curl --connect-timeout 1 http://12.0.0.101/v1/
{"name": "Death Star","hostname": "deathstar-65c8d4f687-fq7xd","model": "DS-1 Orbital Battle Station","manufacturer": "Imperial Department of Military Research, Sienar Fleet Systems","cost_in_credits": "1000000000000","length": "120000","crew": "342953","passengers": "843342","cargo_capacity": "1000000000000","hyperdrive_rating": "4.0","starship_class": "Deep Space Mobile Battlestation","api": ["GET /v1","GET /v1/healthz","POST /v1/request-landing","PUT /v1/cargobay","GET /v1/hyper-matter-reactor/status","PUT /v1/exhaust-port"]
}
启动termshark
mkdir -p /root/.config/termshark/
echo -e "[main]\ndark-mode = true" > /root/.config/termshark/termshark.toml
TERM=xterm-256color termshark -r arp.pcap
看到 12.0.0.101
的 ARP 请求和响应
4. 自动IPAM
4.1 IPAM Pool
将 IP 分配给服务,让我们为 color=blue
服务创建一个名为 pool-blue
的 IPAM 池。
应用此策略后,12.0.0.128/25
范围内的 IP 地址将被分配给与 color=blue
标签选择器匹配的 LoadBalancer 服务。
root@server:~# yq pool-blue.yaml
# # Second pool, label selector
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:name: "pool-blue"
spec:blocks:- cidr: "12.0.0.128/25"serviceSelector:matchLabels:color: blue
root@server:~# kubectl apply -f pool-blue.yaml
ciliumloadbalancerippool.cilium.io/pool-blue created
4.2 配置L2策略
root@server:~# cat l2policy.yaml
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:name: policy1
spec:externalIPs: true# config loadBalancerIPs values to true loadBalancerIPs: true interfaces:- net0serviceSelector:matchLabels:color: bluenodeSelector:matchExpressions:- key: node-role.kubernetes.io/control-planeoperator: DoesNotExist
root@server:~# kubectl apply -f l2policy.yaml
ciliuml2announcementpolicy.cilium.io/policy1 configured
root@server:~#
4.3 创建服务
为 Death Star Pod 创建一个名为 deathstar-3
的新服务,但没有为其分配静态 IP:
kubectl expose deployment deathstar --name deathstar-3 --port 80 --type LoadBalancer
检查服务:
root@server:~# kubectl expose deployment deathstar --name deathstar-3 --port 80 --type LoadBalancer
service/deathstar-3 exposed
root@server:~# kubectl get svc deathstar-3 --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
deathstar-3 LoadBalancer 10.96.197.206 <pending> 80:31590/TCP 5s <none>
目前没有外部 IP,因为它目前没有与 IPAM 池匹配的标签。
将 color=blue
标签添加到服务中:
kubectl label svc deathstar-3 color=blue
再次检查服务:
root@server:~# kubectl label svc deathstar-3 color=blue
service/deathstar-3 labeled
root@server:~# kubectl get svc deathstar-3 --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
deathstar-3 LoadBalancer 10.96.197.206 12.0.0.128 80:31590/TCP 86s color=blue
root@server:~#
它现在已收到与蓝色 IPAM 池关联的范围内的外部 IP。由于 color: blue
也与我们之前部署的 L2 公告策略相对应,因此此服务应该已经通过 ARP 提供。让我们检查一下:
root@server:~# SVC2_IP=$(kubectl get svc deathstar-3 -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
echo $SVC2_IP
docker exec -ti clab-garp-demo-neighbor curl --connect-timeout 1 $SVC2_IP/v1/
12.0.0.128
{"name": "Death Star","hostname": "deathstar-65c8d4f687-fq7xd","model": "DS-1 Orbital Battle Station","manufacturer": "Imperial Department of Military Research, Sienar Fleet Systems","cost_in_credits": "1000000000000","length": "120000","crew": "342953","passengers": "843342","cargo_capacity": "1000000000000","hyperdrive_rating": "4.0","starship_class": "Deep Space Mobile Battlestation","api": ["GET /v1","GET /v1/healthz","POST /v1/request-landing","PUT /v1/cargobay","GET /v1/hyper-matter-reactor/status","PUT /v1/exhaust-port"]
}
5. 弹性负载均衡
5.1 监控ARP
再次检索服务 IP,对其进行 arping 并在 Docker 容器中检查它的 ARP 响应。
docker exec -ti clab-garp-demo-neighbor arping 12.0.0.100
5.2 删除节点
Kubernetes 为每个服务提供 Leases
资源类型,其中包含该信息。
该资源存储在 kube-system
命名空间中,其名称格式 cilium-l2announce-<namespace>-<service>
为 。
由于我们的服务在 default
命名空间中称为 deathstar
,因此我们需要查找 cilium-l2announce-default-deathstar
.
查看租约资源的规范:
kubectl -n kube-system get leases cilium-l2announce-default-deathstar -o yaml | yq .spec
该资源具有 spec.holderIdentity
字段,该字段指示当前持有租约的节点是 kind-worker
。
由于我们的节点是 Docker 容器,因此删除节点不会完全关闭数据路径,因为它的 veth 对将留在后面。因此,为了模拟节点删除,我们需要识别 veth 对,以便我们可以关闭节点上的接口。
首先,检索租约的 MAC 地址。正如我们所看到的,我们可以通过使用 ARP 解析 IP 来获取该信息:
docker exec -ti clab-garp-demo-neighbor arp 12.0.0.100
接下来,让我们从节点获取 veth 对编号:
docker exec kind-worker ip a | grep -B1 aa:c1:ab:b7:2b:f7
最后,在 VM 上检索该 veth 对的接口名称:
ip a | grep if15
现在,让我们通过删除托管该节点上的 Docker 容器来模拟节点上的问题:
docker kill kind-worker
并删除 veth 接口:
ip link set net2 down
再次检查租约:
kubectl -n kube-system get leases cilium-l2announce-default-deathstar -o yaml | yq .spec.holderIdentity
输出如下:
root@server:~# kubectl -n kube-system get leases cilium-l2announce-default-deathstar -o yaml | yq .spec
acquireTime: "2025-05-27T02:30:39.025729Z"
holderIdentity: kind-worker
leaseDurationSeconds: 3
leaseTransitions: 0
renewTime: "2025-05-27T02:49:29.227768Z"
root@server:~# docker exec -ti clab-garp-demo-neighbor arp 12.0.0.100
Address HWtype HWaddress Flags Mask Iface
12.0.0.100 ether aa:c1:ab:b7:2b:f7 C net0
root@server:~# docker exec kind-worker ip a | grep -B1 aa:c1:ab:b7:2b:f7
15: net0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9500 qdisc noqueue state UP group default link/ether aa:c1:ab:b7:2b:f7 brd ff:ff:ff:ff:ff:ff link-netnsid 0
root@server:~# ip a | grep if15
16: net2@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9500 qdisc noqueue master br-garp-clab state UP group default
root@server:~# docker kill kind-worker
kind-worker
root@server:~# ip link set net2 down
root@server:~# kubectl -n kube-system get leases cilium-l2announce-default-deathstar -o yaml | yq .spec.holderIdentity
kind-worker2
root@server:~#
如我们预料,持有者身份变成了kind-worker2
5.3 检查回退
此时,几次超时后,arping 命令现在应解析为不同的 MAC 地址,表明负载均衡器租约已移至另一个节点:
58 bytes from aa:c1:ab:b7:2b:f7 (12.0.0.100): index=147 time=4.512 usec
58 bytes from aa:c1:ab:b7:2b:f7 (12.0.0.100): index=148 time=3.949 usec
58 bytes from aa:c1:ab:b7:2b:f7 (12.0.0.100): index=149 time=3.665 usec
58 bytes from aa:c1:ab:b7:2b:f7 (12.0.0.100): index=150 time=3.782 usec
58 bytes from aa:c1:ab:b7:2b:f7 (12.0.0.100): index=151 time=3.929 usec
Timeout
Timeout
Timeout
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=152 time=5.142 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=153 time=4.234 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=154 time=4.654 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=155 time=4.272 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=156 time=4.097 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=157 time=3.932 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=158 time=4.425 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=159 time=3.929 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=160 time=4.734 usec
58 bytes from aa:c1:ab:86:92:38 (12.0.0.100): index=161 time=4.047 usec
并尝试再次访问该服务:
root@server:~# docker exec -ti clab-garp-demo-neighbor curl 12.0.0.100/v1/
{"name": "Death Star","hostname": "deathstar-65c8d4f687-cfzsz","model": "DS-1 Orbital Battle Station","manufacturer": "Imperial Department of Military Research, Sienar Fleet Systems","cost_in_credits": "1000000000000","length": "120000","crew": "342953","passengers": "843342","cargo_capacity": "1000000000000","hyperdrive_rating": "4.0","starship_class": "Deep Space Mobile Battlestation","api": ["GET /v1","GET /v1/healthz","POST /v1/request-landing","PUT /v1/cargobay","GET /v1/hyper-matter-reactor/status","PUT /v1/exhaust-port"]
}
它可以正常工作了。
检查 Cilium 配置中的值:
root@server:~# cilium config view | grep l2-announcements
enable-l2-announcements true
l2-announcements-lease-duration 3s
l2-announcements-renew-deadline 1s
l2-announcements-retry-period 500ms
5.4 小测验
× L2 announcements is activated by default in Cilium
√ LB-IPAM is activated by default in Cilium
√ L2 announcements use ARP to announce service IPs outside of the cluster
√ L2 announcements can be used without an LB-IPAM ip pool
6. 测试
6.1 需求
- 在端口 80 上使用
LoadBalancer
类型的新服务公开 Death Star; - 创建一个新的 Cilium Load-Balancer IP Pool,将
172.18.42.0/29
范围内的 IP 分配给标记为org=empire
的服务; - 创建一个新的 L2 公告策略,以在接口
eth0
上为所有标记为announce=arp
的服务宣布服务 IP; - 检查是否可以使用带有
curl <SVC_IP>/v1/
的负载均衡器服务 IP 从 VM 访问服务。
6.2 解题
root@server:~# kubectl expose deployment deathstar --name deathstar --port 80 --type LoadBalancer
service/deathstar exposed
root@server:~# k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
deathstar LoadBalancer 10.96.47.105 <pending> 80:31555/TCP 3m10s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m10s
root@server:~# k label svc deathstar org=empire
service/deathstar labeled
root@server:~# k label svc deathstar announce=arp
service/deathstar labeled
root@server:~# k get svc --show-labels
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
deathstar LoadBalancer 10.96.47.105 172.18.42.0 80:31555/TCP 3m38s org=empire,announce=arp
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9m38s component=apiserver,provider=kubernetes
root@server:~# yq ippool.yaml
# # Second pool, label selector
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:name: empire
spec:blocks:- cidr: "172.18.42.0/29"serviceSelector:matchLabels:org: empire
root@server:~# yq l2policy.yaml
apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:name: empire
spec:externalIPs: falseloadBalancerIPs: true interfaces:- eth0serviceSelector:matchLabels:announce: arpnodeSelector:matchExpressions:- key: node-role.kubernetes.io/control-planeoperator: DoesNotExistroot@server:~# k apply -f ippool.yaml
ciliumloadbalancerippool.cilium.io/empire created
root@server:~# k apply -f l2policy.yaml
ciliuml2announcementpolicy.cilium.io/empire created
好了提交
新徽标GET!
相关文章:

Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...

MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
学习一下用鸿蒙DevEco Studio HarmonyOS5实现百度地图
在鸿蒙(HarmonyOS5)中集成百度地图,可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API,可以构建跨设备的定位、导航和地图展示功能。 1. 鸿蒙环境准备 开发工具:下载安装 De…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅
目录 前言 操作系统与驱动程序 是什么,为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中,我们在使用电子设备时,我们所输入执行的每一条指令最终大多都会作用到硬件上,比如下载一款软件最终会下载到硬盘上&am…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

【C++】纯虚函数类外可以写实现吗?
1. 答案 先说答案,可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...

认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
uniapp 集成腾讯云 IM 富媒体消息(地理位置/文件)
UniApp 集成腾讯云 IM 富媒体消息全攻略(地理位置/文件) 一、功能实现原理 腾讯云 IM 通过 消息扩展机制 支持富媒体类型,核心实现方式: 标准消息类型:直接使用 SDK 内置类型(文件、图片等)自…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...