LoginSignup
0
0

Kubernetes with CALICOでノードとルータを兼用させる

Posted at

以前Kubernetes with CALICOでコントロールノードとルータを兼用させたいといっていて、当時は結局兼用できずに仮想的に別サーバに分けることで解決したわけだが、先日再挑戦して無事できたので設定について晒す。

初めに

本記事の目的

  • 稼働中の自作ルータに直接kubernetesを導入し、(マスター)ノード化する

本記事で扱うもの

  • ルータとしての以下の機能をCalicoに移譲するための設定
    • デフォルトゲートウェイ向けのNAT/IPマスカレード1
    • BGPによる中継サーバとのルーティング2

本記事で扱わないもの

  • CalicoやKubernetesのインストール
    公式のドキュメント通りでできたので
  • Calicoの設定の詳細な説明
    現時点で期待通り動いているだけで、なぜこの設定で動いているのか細かいところはよくわかっていないので
  • ファイアーウォールとしてのCalicoの設定
    今回はとにかくNATとルーティングをしたかった(がなかなかうまくいかなかった)都合上、ネットワークポリシーは全部通すザル設定

構成

Nodeバージョン一覧

$ kubectl get node -o wide
NAME         STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE                           KERNEL-VERSION          CONTAINER-RUNTIME
router       Ready    control-plane   21d    v1.28.8   10.0.0.1        <none>        Debian GNU/Linux 12 (bookworm)     6.1.0-18-amd64          containerd://1.6.20
worker1      Ready    <none>          206d   v1.28.8   10.0.0.2        <none>        Debian GNU/Linux 12 (bookworm)     6.1.0-18-arm64          containerd://1.6.20
worker2      Ready    <none>          206d   v1.28.8   10.0.0.3        <none>        Debian GNU/Linux 12 (bookworm)     6.1.0-18-arm64          containerd://1.6.20

ネットワーク図

Internet                                                           
─┬────────────────────┬──────────────────────────┬─────────┬─        
 │                    │                          │         │         
┌┴────────────────┐ ┌─┴───────────────────┐    ┌─┴─────┐ ┌─┴─────┐ 
│Rental ONU/Router│ │Jump Server          │    │Client1│ │Client2│ 
└──────────────┬──┘ └─┬──────────────┬────┘    └────┬──┘ └┬──────┘ 
               │      │              │              │     │        
Home Network   │      │ Router VPN   │ Client VPN   │     │        
192.168.0.0/24 │      │ 10.1.0.0/24  │ 10.1.1.0/24  │     │        
───────────────┼───  ─┴────────┬─── ─┴──────────────┴─────┴────────
               │               │                                   
┌──────────────┼───────────────┼──────────────────────────┐        
│ Home build   │               │                          │        
│ Router     ┌─┴────────────┐ ┌┴──────────┐ ┌───────────┐ │        
│            │wan0          │ │wg0        │ │lan0       │ │        
│            │192.168.0.2/24│ │10.1.0.2/24│ │10.0.0.1/et│ │        
│            └──────────────┘ └───────────┘ └────┬──────┘ │        
│                                                │        │        
└────────────────────────────────────────────────┼────────┘        
                                                 │                 
Clusteer Network                                 │                 
10.0.0.0/24                                      │                 
───┬────────────┬────────────────────────────────┴─────────        
   │            │                                                  
┌──┴─────┐    ┌─┴──────┐                                           
│Worker1 │    │Worker 2│                                           
└────────┘    └────────┘                                           

以下ノードやネットワークの解説

レンタルルータ

  • 普通のレンタルルータ兼ONU
  • Home NetworkにDHCPやDNSを提供している

自宅ネットワーク

  • 普通の家庭のネットワーク
  • 自作ルータもこの配下に位置している

クラスタネットワーク

  • 自作ルータの下流に位置するネットワーク
  • kubernetesクラスタを構築するホスト間の物理ネットワーク

自作ルータ(ルータ兼管理ノード)

  • 自宅ネットワークおよび中継サーバとクラスターネットワークの中間に位置するルータ
  • デフォルトゲートウェイはレンタルルータ側で、中継ネットワークはクライアントからのアクセスのみで使う
  • BGPで中継サーバと中継ネットワークとクラスターネットワークのルートの交換をしている
  • クラスターネットワークにDHCPやDNSを提供している
  • 実際には微妙に異なる構成の管理ノードが3台あり、keepalivedでクラスター内のデフォルトゲートウェイを冗長化したりしているが、本記事では省略して1台として扱っている

自宅ノード(ワーカーノード)

  • 主にラズパイが担当

中継サーバ

  • AWS Lightsail上で稼働
  • 自作ルータおよび各クライアントをVPNで橋渡ししている

BGP

中継サーバとBGPでルートの共有をし、中継サーバから自宅サーバへアクセスできるようにしていた。
今回、中継サーバの構成はそのままに、自作ルータ側をCalicoを使ってクラスタネットワークのアドレス(10.0.0.0/24)を共有する

BGP Configuration

apiVersion: projectcalico.org/v3
kind: BGPConfiguration
metadata:                                        
  name: default
spec:
  bindMode: None
  communities:
    - name: bgp-large-community
      value: 64512:000
  prefixAdvertisements:
    - cidr: 10.0.0.0/24
      communities:
        - bgp-large-community

クラスタネットワークネットワーク10.0.0.0/24をPrefixAdvertisementsに設定することで、中継サーバにこれを広告している。

BGP Filter

クラスタネットワーク10.0.0.0/24をエクスポート、中継ネットワーク10.1.0.0/16をインポートするようBGPフィルターを設定する。

apiVersion: projectcalico.org/v3
kind: BGPFilter [130]
metadata:n: projectcalico.org/v3
  name: bgp-filter
spec:
  exportV4:
    - action: Accept
      matchOperator: In
      cidr: 10.0.0.0/24
  importV4:
    - action: Accept
      matchOperator: In
      cidr: 10.1.0.0/16

BGP Peer

中継サーバとVPN上で隣接するノードは自作ルータのみなので、自作ルータが中継サーバとピアを組むよう設定する

apiVersion: projectcalico.org/v3
kind: BGPPeer
metadata:
  name: router
spec:
  peerIP: 10.1.0.1
  asNumber: 65048
  node: router
  filters:
    - bgp-filter
  sourceAddress: None
  keepOriginalNextHop: true

NAT

Host Endpoints

どうもCalicoではフォワーディングをホワイトリスト形式で行っているらしく、インターフェース間での転送にはそれぞれのインターフェースを設定する必要がある模様。

apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: router-wan
spec:
  interfaceName: wan0
  node: router
  expectedIPs:
    - 192.168.0.2
---
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: router-vpn
  labels: defaultgateway
spec:
  interfaceName: wg0
  node: router
  expectedIPs:
    - 10.1.0.2
---
apiVersion: projectcalico.org/v3
kind: HostEndpoint
metadata:
  name: router-cluster
  labels: defaultgateway
spec:
  interfaceName: lan0
  node: router
  expectedIPs:
    - 10.0.0.1

IP Pool

IP Poolはdisabledにすることで、kubernetes内部で使わないIPアドレスを宣言できる。ここでnatOutgoing: trueとすることで、クラスタネットワークから外部へのNATを有効にできる。

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: border-ipv4-ippool
spec:
  cidr: 10.0.0.0/24
  disabled: true
  natOutgoing: true

GlobalNetworkPolicy

クラスター全体のネットワークポリシー

本来ならファイアーウォールとして余計な通信を除くよう設定すべきだが、今回はとりあえず通信させたいのでIngressもEgressもすべて許可している。
注意点として、DNSやDHCPといったルータとしてのサービスもクラスター内に含まれる都合上、許可する必要がある。とくにApiserverのエンドポイントをドメインにしている状態でDNSをシャットダウンすると、kubectlでドメインが見つからず詰むので要注意。

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: border-ipv4-ippool
spec:
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: allow-forward
spec:
  applyOnForward: true
  types:
    - Ingress
    - Egress
  ingress:
    - action: Allow
  egress:
    - action: Allow

結果

中継サーバでクラスタネットワークへのルートが確認できる。

$ ip route | grep "10.0.0.0/24"
10.0.0.0/24 nhid 56 via 10.1.0.1 dev wg0 proto bgp metric 20 

ワーカーノードが自作ルータ経由で外部にアクセスできることが確認できる。

$ traceroute google.com
traceroute to google.com (172.217.26.238), 30 hops max, 60 byte packets
 1  10.0.0.1 (10.0.0.1)  0.288 ms  0.162 ms  0.118 ms
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  bom05s09-in-f14.1e100.net (172.217.26.238)  40.357 ms 108.170.242.129 (108.170.242.129)  40.114 ms nrt12s51-in-f14.1e100.net (172.217.26.238)  40.437 ms
  1. kubernetes導入前はfirewalldで行っていた。

  2. kubernetes導入前はfrrで行っていた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0