環境
- ubuntu:22.0.4.1 LTS
- kubernetes:1.28.2
- calico 3.26.3
検証環境
既存の検証環境は以下の通りです。
ここまでの構築方法、詳細は、以下をご参照ください。
ipPoolの導入
既存のipPoolの確認
まずは、ipPoolについてcalicoctl
を使って、確認してみます。
$ calicoctl get ipPool
NAME CIDR SELECTOR
default-ipv4-ippool 192.168.0.0/16 all()
現状、192.168.0.0/16
のアドレスレンジとなっており、新規でPodを作成すると、以下のように該当のアドレスレンジが使用されます。
# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-1 1/1 Running 0 8s 192.168.170.5 kube-controlplane-001 <none> <none>
test-2-1 1/1 Running 0 8s 192.168.181.7 kube-worker-001 <none> <none>
test-2-2 1/1 Running 0 7s 192.168.181.8 kube-worker-001 <none> <none>
既存のipPoolの削除
まずは、ipPoolについてcalicoctl
を使って、デフォルトのipPoolを削除します。
# calicoctl delete ipPool default-ipv4-ippool
Successfully deleted 1 'IPPool' resource(s)
# calicoctl get ipPool
NAME CIDR SELECTOR
新規ipPoolの作成
次に新規のipPoolを作成していきます。今回は、以下の要件とします。
特定のnamespace(ここれは「dev」ネームスペース)でPodを立ち上げた場合、以下のアドレスレンジを割り当てる。
192.168.129.0/24
上記以外のnamespaceでPodを立ち上げた場合、以下のアドレスレンジを割り当てる。
192.168.0.0/17
それぞれのipPoolを作成していきます。
デフォルトのipPoolのyamlは以下の通りです。
- apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: default-ipv4-ippool
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 24
cidr: 192.168.0.0/17
ipipMode: Never
nodeSelector: all()
vxlanMode: Never
kind: IPPoolList
では、kubectl
で'apply'してみます。
# kubectl apply -f ippool_default.yaml
ippool.projectcalico.org/default-ipv4-ippool created
calicoctl
を使って、確認します。
# calicoctl get ipPool -owide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 192.168.0.0/17 false Never Never false false all()
同様に特定のdevネームスペース用のipPoolを作成します。
label
は、なくても問題ないです。
apiVersion: projectcalico.org/v3
items:
- apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
name: namespace-dev-ippool
labels:
environment: dev
spec:
allowedUses:
- Workload
- Tunnel
blockSize: 24
cidr: 192.168.129.0/24
ipipMode: Never
vxlanMode: Never
kind: IPPoolList
では、再度ipPoolを確認してみます。
# calicoctl get ipPool -owide
NAME CIDR NAT IPIPMODE VXLANMODE DISABLED DISABLEBGPEXPORT SELECTOR
default-ipv4-ippool 192.168.0.0/17 false Never Never false false all()
namespace-dev-ippool 192.168.129.0/24 false Never Never false false all()
これで、ipPoolが作成できました。
新規namespaceの作成
次にdevネームスペースを作成していきます。
namespaceを作成する際に、cni.projectcalico.org/ipv4pools
のアノテーションをつけることで、特定のipPoolを使ったネームスペースを作成することができます。
今回、ipPool namespace-dev-ippool
を使いたいので、以下のようなマニフェストになります。
apiVersion: v1
kind: Namespace
metadata:
name: dev
annotations:
'cni.projectcalico.org/ipv4pools': '["namespace-dev-ippool"]'
labels:
environment: dev
spec: {}
status: {}
では、ネームスペースを作成します。
# kubectl apply -f namespace_dev.yaml
namespace/dev created
これで準備が整いました。
動作確認
既存Podの再起動
この時点で、すでに作成されているPodは既存のネットワークレンジのままになっているので、再起動(一度削除)する必要がります。
削除前のアドレスは、以下の通りでした。
# kubectl get pods -n kube-system -owide | grep coredns
coredns-5dd5756b68-cdtfh 1/1 Running 0 116s 192.168.181.6 kube-worker-001 <none> <none>
coredns-5dd5756b68-w448v 1/1 Running 0 2m56s 192.168.170.4 kube-controlplane-001 <none> <none>
ここで、static Podであるcorednsを削除してみます。
# kubectl delete pods -n kube-system coredns-5dd5756b68-cdtfh
pod "coredns-5dd5756b68-cdtfh" deleted
# kubectl delete pods -n kube-system coredns-5dd5756b68-w448v
pod "coredns-5dd5756b68-w448v" deleted
改めて、アドレスを確認すると、該当の192.168.0.0/17
のアドレスレンジになっていることが分かります。
kubectl get pods -n kube-system -o wide | grep coredns
coredns-5dd5756b68-gl5pq 1/1 Running 0 10s 192.168.102.1 kube-worker-001 <none> <none>
coredns-5dd5756b68-z827r 1/1 Running 0 2d6h 192.168.101.3 kube-worker-001 <none> <none>
Podの作成
デフォルトネームスペース
次に、実際にいくつかのネームスペースにPodを作成して、ipPoolの動作について確認してみます。
まずは、デフォルトのネームスペースにPodを作成してみます。
# kubectl run test-default --image nginx
pod/test-default created
アドレスを確認してみます。
# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-default 1/1 Running 0 2m58s 192.168.102.0 kube-worker-001 <none> <none>
割り当てのアルゴリズムについてはわかりませんが、期待通り192.168.0.0/17
のアドレスレンジに作成されていることが分かります。
次にcontrole-plane-node上のデフォルトのネームスペースにPodを作成してみます。
nodeSelector
を使用し、以下のマニフェストを作成し、'apply'してみます。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test-default-cp
name: test-default-cp
spec:
containers:
- image: nginx
name: test-default-cp
resources: {}
nodeSelector:
kubernetes.io/hostname: kube-controlplane-001
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
それではPodを立ち上げます。
# kubectl apply -f sample_pod-default-cp.yaml
pod/test-default-cp created
ではアドレスを確認してみます。
kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-default-cp 1/1 Running 0 38s 192.168.58.2 kube-controlplane-001 <none> <none>
こちらも期待通り192.168.0.0/17
のアドレスレンジに作成されていることが分かります。
devネームスペース
では次にdevネームスペースにPodを作成してみます。
# kubectl run test-dev -n dev --image nginx
pod/test-dev created
kubectl get pods -n dev -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-dev 1/1 Running 0 21s 192.168.129.0 kube-worker-001 <none> <none>
こちらも期待通り、192.168.129.0/24
のアドレスレンジに作成されていることが分かりました。ただ、なぜネットワークアドレスが使用されたのかは、調査中です。
次にcontrole-plane-node上のdevネームスペースにPodを作成してみます。
以下のマニフェストを作成し、'apply'してみます。
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: test-dev-cp
name: test-dev-cp
namespace: dev
spec:
containers:
- image: nginx
name: test-dev-cp
resources: {}
nodeSelector:
kubernetes.io/hostname: kube-controlplane-001
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
それではPodを立ち上げます。
# kubectl apply -f sample-dev-cp.yaml
pod/test-dev-cp created
ではアドレスを確認してみます。
kubectl get pods -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-dev 1/1 Running 0 22m 192.168.129.0 kube-worker-001 <none> <none>
test-dev-cp 1/1 Running 0 2m27s 192.168.129.1 kube-controlplane-001 <none> <none>
こちらも期待通り、192.168.129.0/24
のアドレスが割り当てられました。
ルーティング確認
次に上位のスイッチからルーティングを確認してみます。
#show ip route bgp detail
VRF: default
Codes: C - connected, S - static, K - kernel,
O - OSPF, IA - OSPF inter area, E1 - OSPF external type 1,
E2 - OSPF external type 2, N1 - OSPF NSSA external type 1,
N2 - OSPF NSSA external type2, B - Other BGP Routes,
B I - iBGP, B E - eBGP, R - RIP, I L1 - IS-IS level 1,
I L2 - IS-IS level 2, O3 - OSPFv3, A B - BGP Aggregate,
A O - OSPF Summary, NG - Nexthop Group Static Route,
V - VXLAN Control Service, M - Martian,
DH - DHCP client installed default route,
DP - Dynamic Policy Route, L - VRF Leaked,
G - gRIBI, RC - Route Cache Route,
CL - CBF Leaked Route
B I 192.16.0.0/12 [200/0] via 172.21.1.8, Vlan3002
B I 192.168.58.0/24 [200/0] via 172.21.1.8, Vlan3002
B I 192.168.101.3/32 [200/0] via 172.21.1.18, Vlan3002
B I 192.168.102.0/24 [200/0] via 172.21.1.18, Vlan3002
B I 192.168.129.1/32 [200/0] via 172.21.1.8, Vlan3002
B I 192.168.129.0/24 [200/0] via 172.21.1.18, Vlan3002
#show ip bgp detail
BGP routing table information for VRF default
Router identifier 1.1.1.1, local AS number 65535
BGP routing table entry for 192.16.0.0/12
Paths: 2 available
Local
172.21.1.8 from 172.21.1.8 (172.21.0.8)
Origin IGP, metric 0, localpref 100, IGP metric 0, weight 0, tag 0
Received 00:12:16 ago, valid, internal, best
Rx path id: 0x2
Rx SAFI: Unicast
Local
172.21.1.18 from 172.21.1.18 (172.21.0.18)
Origin IGP, metric 0, localpref 100, IGP metric 0, weight 0, tag 0
Received 00:12:16 ago, valid, internal
Rx path id: 0x2
Rx SAFI: Unicast
BGP routing table entry for 192.168.58.0/24
Paths: 1 available
Local
172.21.1.8 from 172.21.1.8 (172.21.0.8)
Origin IGP, metric 0, localpref 100, IGP metric 0, weight 0, tag 0
Received 00:12:16 ago, valid, internal, best
Community: 65535:120
Large Community: 65535:300:100
Rx path id: 0x2
Rx SAFI: Unicast
BGP routing table entry for 192.168.101.3/32
Paths: 1 available
Local
172.21.1.18 from 172.21.1.18 (172.21.0.18)
Origin IGP, metric 0, localpref 100, IGP metric 0, weight 0, tag 0
Received 00:12:16 ago, valid, internal, best
Community: 65535:120
Large Community: 65535:300:100
Rx path id: 0x3
Rx SAFI: Unicast
BGP routing table entry for 192.168.102.0/24
Paths: 1 available
Local
172.21.1.18 from 172.21.1.18 (172.21.0.18)
Origin IGP, metric 0, localpref 100, IGP metric 0, weight 0, tag 0
Received 00:12:16 ago, valid, internal, best
Community: 65535:120
Large Community: 65535:300:100
Rx path id: 0x2
Rx SAFI: Unicast
BGP routing table entry for 192.168.129.0/24
Paths: 1 available
Local
172.21.1.18 from 172.21.1.18 (172.21.0.18)
Origin IGP, metric 0, localpref 100, IGP metric 0, weight 0, tag 0
Received 00:12:16 ago, valid, internal, best
Community: 65535:120
Large Community: 65535:300:100
Rx path id: 0x2
Rx SAFI: Unicast
BGP routing table entry for 192.168.129.1/32
Paths: 1 available
Local
172.21.1.8 from 172.21.1.8 (172.21.0.8)
Origin IGP, metric 0, localpref 100, IGP metric 0, weight 0, tag 0
Received 00:12:16 ago, valid, internal, best
Community: 65535:120
Large Community: 65535:300:100
Rx path id: 0x3
Rx SAFI: Unicast
上記で登場した、test-default-cp
、test-default
、test-dev
、test-dev-cp
のそれぞれのネットワークはそれぞれクラスフルでルート集約されたネットワークが伝播されていることが分かりました。
但し、途中で再起動(一度削除)したcoredns
のみがルート集約されていないネットワークが伝播されておりました。ここのアルゴリズムについては、引き続き調査予定です。