Skip to content

Commit

Permalink
Merge pull request #2514 from Icarus9913/fix/wk/multusName
Browse files Browse the repository at this point in the history
  • Loading branch information
weizhoublue authored Nov 6, 2023
2 parents 5a808a4 + 3183c43 commit 260a74c
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 3 deletions.
4 changes: 4 additions & 0 deletions cmd/spiderpool-agent/cmd/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ var envInfo = []envConf{
{"SPIDERPOOL_LOG_LEVEL", logutils.LogInfoLevelStr, true, &agentContext.Cfg.LogLevel, nil, nil},
{"SPIDERPOOL_ENABLED_METRIC", "false", false, nil, &agentContext.Cfg.EnableMetric, nil},
{"SPIDERPOOL_ENABLED_DEBUG_METRIC", "false", false, nil, &agentContext.Cfg.EnableDebugLevelMetric, nil},
{"SPIDERPOOL_POD_NAMESPACE", "", true, &agentContext.Cfg.AgentPodNamespace, nil, nil},
{"SPIDERPOOL_POD_NAME", "", true, &agentContext.Cfg.AgentPodName, nil, nil},
{"SPIDERPOOL_HEALTH_PORT", "5710", true, &agentContext.Cfg.HttpPort, nil, nil},
{"SPIDERPOOL_METRIC_HTTP_PORT", "5711", true, &agentContext.Cfg.MetricHttpPort, nil, nil},
{"SPIDERPOOL_GOPS_LISTEN_PORT", "5712", false, &agentContext.Cfg.GopsListenPort, nil, nil},
Expand All @@ -78,6 +80,8 @@ type Config struct {
LogLevel string
EnableMetric bool
EnableDebugLevelMetric bool
AgentPodNamespace string
AgentPodName string

HttpPort string
MetricHttpPort string
Expand Down
1 change: 1 addition & 0 deletions cmd/spiderpool-agent/cmd/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ func DaemonMain() {
EnableKubevirtStaticIP: agentContext.Cfg.EnableKubevirtStaticIP,
OperationRetries: agentContext.Cfg.WaitSubnetPoolMaxRetries,
OperationGapDuration: time.Duration(agentContext.Cfg.WaitSubnetPoolTime) * time.Second,
AgentNamespace: agentContext.Cfg.AgentPodNamespace,
}
if len(agentContext.Cfg.MultusClusterNetwork) != 0 {
ipamConfig.MultusClusterNetwork = pointer.String(agentContext.Cfg.MultusClusterNetwork)
Expand Down
71 changes: 70 additions & 1 deletion docs/usage/spider-affinity-zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ SpiderIPPool 资源代表 IP 地址的集合,一个 Subnet 中的不同 IP 地

[SpiderIPPool CRD](./../reference/crd-spiderippool.md) 里,我们有定义很多的字段来搭配亲和性使用,如:

- `spec.podAffinity` 字段可控制该池是否可被 Pod 使用
- `spec.podAffinity` 字段可控制该池是否可被 Pod 使用
- `spec.namespaceName``spec.namespaceAffinity` 字段会校验是否与 Pod 的Namespace相匹配,若不匹配则不可使用。(`namespaceName` 优先级高于 `namespaceAffinity`)
- `spec.nodeName``spec.nodeAffinity` 字段会校验是否与 Pod 所在的节点相匹配,若不匹配则不可使用。(`nodeName` 优先级高于 `nodeAffinity`)
- `multusName` 字段会判断当前网卡是否与 multus 的 net-attach-def 资源使用的 CNI 配置相匹配,若不匹配则不可使用。
Expand Down Expand Up @@ -495,6 +495,75 @@ NAMESPACE NAME READY STATUS REST
test-ns2 test-other-ns-56cc9b7d95-hx4b5 0/1 ContainerCreating 0 6m3s <none> node2 <none> <none>
```

## 网卡配置亲和性

当为应用创建多网卡时候,我们可以为**集群级别缺省池**指定 multus 的 net-attach-def 实例亲和性。该方法相比于通过注解 `ipam.spidernet.io/ippools` 显式指定网卡与 IPPool 资源的绑定关系更为简单。

首先为 IPPool 资源配置好各类属性,其中:

- `spec.default` 字段设置为 `true`, 以此减少为应用打上 `ipam.spidernet.io/ippool` 或 `ipam.spidernet.io/ippools` 注解,让体验更为简单。

- `spec.multusName` 字段配置该 IPPool 对应的 multus 网卡配置。(若您未指定对应 multus 的 net-attach-def 实例的 namespace,我们会默认视属于 spiderpool 安装时的命名空间)

```yaml
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderIPPool
metadata:
name: test-ippool-eth0
spec:
default: true
subnet: 10.6.0.0/16
ips:
- 10.6.168.151-10.6.168.160
multusName:
- default/macvlan-vlan0-eth0
---
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderIPPool
metadata:
name: test-ippool-eth1
spec:
default: true
subnet: 10.7.0.0/16
ips:
- 10.7.168.151-10.7.168.160
multusName:
- kube-system/macvlan-vlan0-eth1
```

创建多网卡的应用。我们只需以下的示例 Yaml 中, 会创建有两张网卡的 Deployment 应用 ,其中:

- `v1.multus-cni.io/default-network`:为创建的应用选择默认网卡配置信息。(若不指定该注解而直接使用 multus 集群默认网卡配置信息,请在 helm 安装 spiderpool 时通过参数指定默认网卡配置信息 `--set multus.multusCNI.defaultCniCRName=default/macvlan-vlan0-eth0`)

- `k8s.v1.cni.cncf.io/networks`:为创建的应用选择额外网卡的配置信息。

```bash
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: test-app
template:
metadata:
annotations:
v1.multus-cni.io/default-network: default/macvlan-vlan0-eth0
k8s.v1.cni.cncf.io/networks: kube-system/macvlan-vlan0-eth1
labels:
app: test-app
spec:
containers:
- name: test-app
image: nginx
imagePullPolicy: IfNotPresent
EOF
```

## 总结

SpiderIPPool 中的 IP 集合可大可小。能很好的应对 Underlay 网络的 IP 地址资源有限情况,且这种设计特点,能够通过各种亲和性规则让不同的应用、租户来绑定不同的 SpiderIPPool,也能分享相同的 SpiderIPPool,既能够让所有应用共享使用同一个 Subnet,又能够实现 "微隔离"。
80 changes: 80 additions & 0 deletions docs/usage/spider-affinity.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@

SpiderIPPool is a representation of a collection of IP addresses. It allows storing different IP addresses from the same subnet in separate IPPool instances, ensuring that there is no overlap between address sets. This design provides flexibility in managing IP resources within the underlay network, especially when faced with limited availability. SpiderIPPool offers the ability to assign different SpiderIPPool instances to various applications and tenants through affinity rules, allowing for both shared subnet usage and micro-isolation.

## Quick Start

In [SpiderIPPool CRD](./../reference/crd-spiderippool.md), we defined lots of properties to use with affinities:

- `spec.podAffinity` controls whether the pool can be used by the Pod.
- `spec.namespaceName` and `spec.namespaceAffinity` verify if they match the Namespace of the Pod. If there is no match, the pool cannot be used. (`namespaceName` takes precedence over `namespaceAffinity`).
- `spec.nodeName` and `spec.nodeAffinity` verify if they match the node where the Pod is located. If there is no match, the pool cannot be used. (`nodeName` takes precedence over `nodeAffinity`).
- `multusName` determines whether the current network card which using the pool matches the CNI configuration used by the multus net-attach-def resource. If there is no match, the pool cannot be used.

These fields not only serve as **filters** but also have a **sorting effect**. The more matching fields there are, the higher priority the IP pool has for usage.

## Application Affinity

Firewalls are commonly used in clusters to manage communication between internal and external networks (north-south communication). To enforce secure access control, firewalls inspect and filter communication traffic while restricting outbound communication. In order to align with firewall policies and enable north-south communication within the underlay network, certain Deployments require all Pods to be assigned IP addresses within a specific range.
Expand Down Expand Up @@ -458,3 +469,72 @@ Getting an IP address assignment fails as expected when the Pod belongs to a nam
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-ns2 test-other-ns-56cc9b7d95-hx4b5 0/1 ContainerCreating 0 6m3s <none> node2 <none> <none>
```
## Multus affinity
When creating multiple network interfaces for an application, we can specify the affinity of multus net-attach-def instance for the **cluster-level default pool**. This way is simpler compared to explicitly specifying the binding relationship between network interfaces and IPPool resources through the `ipam.spidernet.io/ippools` annotation.
First, configure various properties for the IPPool resource, including:
- Set the `spec.default` field to `true` to simplify the experience by reducing the need to annotate the application with `ipam.spidernet.io/ippool` or `ipam.spidernet.io/ippools`.
- Configure the `spec.multusName` field to specify the multus net-attach-def instance. (If you do not specify the namespace of the corresponding multus net-attach-def instance, we will default to the namespace where Spiderpool is installed.)
```yaml
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderIPPool
metadata:
name: test-ippool-eth0
spec:
default: true
subnet: 10.6.0.0/16
ips:
- 10.6.168.151-10.6.168.160
multusName:
- default/macvlan-vlan0-eth0
---
apiVersion: spiderpool.spidernet.io/v2beta1
kind: SpiderIPPool
metadata:
name: test-ippool-eth1
spec:
default: true
subnet: 10.7.0.0/16
ips:
- 10.7.168.151-10.7.168.160
multusName:
- kube-system/macvlan-vlan0-eth1
```
Create an application with multiple network interfaces, you can use the following example YAML:
- `v1.multus-cni.io/default-network`: Choose the default network configuration for the created application. (If you don't specify this annotation and directly use the clusterNetwork configuration of the multus, please specify the default network configuration during the installation of Spiderpool via Helm using the parameter `--set multus.multusCNI.defaultCniCRName=default/macvlan-vlan0-eth0`).

- `k8s.v1.cni.cncf.io/networks`: Selects the additional network configuration for the created application.

```bash
cat <<EOF | kubectl create -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-app
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: test-app
template:
metadata:
annotations:
v1.multus-cni.io/default-network: default/macvlan-vlan0-eth0
k8s.v1.cni.cncf.io/networks: kube-system/macvlan-vlan0-eth1
labels:
app: test-app
spec:
containers:
- name: test-app
image: nginx
imagePullPolicy: IfNotPresent
EOF
```
14 changes: 12 additions & 2 deletions pkg/ipam/allocate.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,9 @@ func (i *ipam) selectByPod(ctx context.Context, version types.IPVersion, ipPool

multusNS = netNsName
if multusNS == "" {
multusNS = pod.Namespace
// Reference from Multus source codes: The CRD object of default network should only be defined in multusNamespace
// In multus, multusNamespace serves for (clusterNetwork/defaultNetworks)
multusNS = i.config.AgentNamespace
}
multusName = networkName
} else {
Expand All @@ -578,6 +580,12 @@ func (i *ipam) selectByPod(ctx context.Context, version types.IPVersion, ipPool
}
}

// Refer from the multus-cni source codes, for annotation "k8s.v1.cni.cncf.io/networks" value without Namespace,
// we will regard the pod Namespace as the value's namespace
if multusNS == "" {
multusNS = pod.ObjectMeta.Namespace
}

// impossible
if !isFound {
return fmt.Errorf("%w: no matched multus object for NIC '%s'. The multus network-attachments: %v", constant.ErrUnknown, nic, podAnno[constant.MultusNetworkAttachmentAnnot])
Expand All @@ -587,7 +595,9 @@ func (i *ipam) selectByPod(ctx context.Context, version types.IPVersion, ipPool
for index := range ipPool.Spec.MultusName {
expectedMultusName := ipPool.Spec.MultusName[index]
if !strings.Contains(expectedMultusName, "/") {
expectedMultusName = fmt.Sprintf("%s/%s", pod.Namespace, expectedMultusName)
// for the ippool.spec.multusName property, if the user doesn't specify the net-attach-def resource namespace,
// we'll regard it in the Spiderpool installation namespace
expectedMultusName = fmt.Sprintf("%s/%s", i.config.AgentNamespace, expectedMultusName)
}

if strings.Compare(expectedMultusName, fmt.Sprintf("%s/%s", multusNS, multusName)) == 0 {
Expand Down
1 change: 1 addition & 0 deletions pkg/ipam/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type IPAMConfig struct {
OperationGapDuration time.Duration

MultusClusterNetwork *string
AgentNamespace string
}

func setDefaultsForIPAMConfig(config IPAMConfig) IPAMConfig {
Expand Down

0 comments on commit 260a74c

Please sign in to comment.