baron tech blog

学びをアウトプットしていきたいです

Project CalicoによるKubernetesのPod間ネットワーキングを試してみました

以前の記事の続きで、 Project CalicoによるKubernetesのPod間ネットワーキングを試してみました。 以前の記事ではflannelでVXLANを利用しましたが、CalicoではネイティブのIPネットワーキングを利用しました。

Calicoのデプロイ

calico.yaml の設定を変更して、KubernetesクラスタにCalicoをデプロイします。

まず、 calico.yaml をダウンロードします。今回はv3.5を利用します。

$ curl -LO https://docs.projectcalico.org/v3.5/getting-started/kubernetes/installation/hosted/calico.yaml

Calicoは、デフォルトでIP-in-IPのカプセル化が有効になっています。 以前の記事ではflannelを用いてVXLANカプセル化によるオーバレイネットワークで Pod間の到達性を確保しました。 今回は、VXLAN, IP-in-IPのようなカプセル化を使わず、 ネイティブのIPネットワーキングでPod間を疎通させます。

また、Kubernetesクラスタで利用するIPv4アドレスのプールを設定しておきます。

calico.yaml の変更点 (抜粋)

            - name: CALICO_IPV4POOL_IPIP
              value: "off"
            - name: CALICO_IPV4POOL_CIDR
              value: "10.244.0.0/16"

変更したyamlからCalicoをKubernetesクラスタにデプロイします。

$ kubectl apply -y calico.yaml

pod-01用 ( pod-01.yaml )

apiVersion: v1
kind: Pod
metadata:
  name: pod-01
spec:
  containers:
    - name: container-01
      image: borkmann/misc
      command: ["sleep", "3600"]
  nodeSelector:
    name: node-01

pod-02用 ( pod-02.yaml )

apiVersion: v1
kind: Pod
metadata:
  name: pod-02
spec:
  containers:
    - name: container-02
      image: borkmann/misc
      command: ["sleep", "3600"]
  nodeSelector:
    name: node-02
$ kubectl apply -f pod-01.yaml
$ kubectl apply -f pod-02.yaml

f:id:foobaron:20190426083608p:plain
Inter-pod networking (Project Calico)

デプロイすると、図のようになり、Podとクラスタノードの間にvethのペアが作成されます。

  • eth0 : Pod側のveth
  • caliXXXXXXXXXXX : クラスタノード側のveth

クラスタノード node-01 およびPod pod-01 にて経路情報を確認してみます。

まずは node-01 を確認します。

node-01:~ $ ip -4 route show
10.244.0.0/24 via 192.168.0.10 dev ens192 proto bird
blackhole 10.244.1.0/24 proto bird
10.244.1.3 dev cali7ba9d9e3e7f scope link
10.244.2.0/24 via 192.168.0.12 dev ens192 proto bird
192.168.0.0/24 dev ens192 proto kernel scope link src 192.168.0.11

node-01 は、 node-02 のPodに関する経路情報を、BGPルータであるBIRDから学習しています。 そして、/16CALICO_IPV4POOL_CIDR から切り出されたIPv4 prefix 10.244.1.0/24 のうち、 自ノード上のコンテナのIPアドレス 10.244.1.3 以外からの経路を blackhole で破棄しています。 自ノード上のコンテナの経路は /32 指定で学習しています。

次に pod-01 を確認します。

$ kubectl exec pod-01 ip -4 route show
default via 169.254.1.1 dev eth0
169.254.1.1 dev eth0 scope link

Podのデフォルトゲートウェイは、IPv4のリンクローカルアドレスである 169.254.1.1 が指定されています。 そのリンクローカルアドレスからMACアドレスを解決するために、 全クラスタノード上の caliXXXXXXXXXXX インタフェースではProxy ARPが有効になっています。 あるPodがMACアドレスを解決するためにARP requestを送信した場合、 そのPodが動作するクラスタノードの caliXXXXXXXXXXX が、ARP replyで自身のMACアドレスを返します。 そのため、Podからのパケットが caliXXXXXXXXXXX まで到達します。 そこからはBGPのよって学習した経路情報を利用して、宛先のPodまでパケットを転送します。

$ kubectl exec pod-01 cat /proc/sys/net/ipv4/conf/cali7ba9d9e3e7f/proxy_arp
1

これにより、CalicoではネイティブのIP通信でPod間の到達性を確保します。