Calico on Ubuntu K8s — BGPルーティングとネットワークポリシーの設定

Kubernetes

この記事のポイント

  • Calico は Kubernetes のCNIプラグインとして最も広く使われており、kubectl apply -f calico.yaml 一発でインストールできます
  • 2026-06-20 時点の最新安定版は Calico v3.29.1(LTS)/ 最新版 v3.32.0、Kubernetes v1.30.14 で動作確認済み
  • BGP設定は calicoctlBGPConfiguration / BGPPeer リソースで管理します
  • NetworkPolicy はラベルベースのセレクタで Pod 間通信を制御——設定ミスが一番多いのは podSelector の書き方です

Ubuntu 24.04 で Kubernetes クラスタを組んだあと、「なんとなく Flannel を入れたけど Calico のほうが良いらしい」という話を聞いて調べ始める方は多いと思います。私もそのパターンでした。

Calico が選ばれる理由は主に2つです。BGPによるスケーラブルなルーティングと、Kubernetes 標準の NetworkPolicy を完全サポートするきめ細かい通信制御。本記事では Ubuntu 24.04 LTS 上で実際に Kubernetes 1.30 + Calico 3.29 を構成し、BGP設定とNetworkPolicyの両方を解説します。

動作確認済み環境

Ubuntu 24.04.4 LTS(Noble Numbat)/ Kubernetes v1.30.14 / Calico v3.29.1 / calicoctl v3.29.1。2026-06-20 に Docker コンテナ内でパッケージ取得・バージョンを実測確認しました。

Ubuntu 24.04 / kubectl v1.30.14 / calicoctl v3.29.1 のバージョン確認(実測)
Ubuntu 24.04 / kubectl v1.30.14 / calicoctl v3.29.1 のバージョン確認(実測)

目次

  1. Calicoとは——Flannel・Weave との違い
  2. 前提環境と準備
  3. Kubernetesクラスタのセットアップ
  4. Calicoのインストール
  5. BGP設定——BGPConfiguration と BGPPeer
  6. NetworkPolicy で通信を制御する
  7. よくあるエラーと解決策
  8. まとめ

Calicoとは——Flannel・Weave との違い

Kubernetes のネットワークは自前では実装されておらず、CNI(Container Network Interface)プラグインを別途インストールして使います。代表的なものに Flannel・Weave・Cilium・Calico があり、それぞれ特徴が異なります。

CNI ルーティング方式 NetworkPolicy スケール 特徴
Calico BGP / VXLAN 完全対応 大規模向き 本番環境で最も広く採用
Flannel VXLAN / host-gw 非対応 小〜中規模 設定が簡単、シンプル重視
Cilium eBPF 完全対応 大規模向き eBPFによる高性能、Kernel 5.4+
Weave VXLAN / UDP 対応 中規模まで 暗号化機能あり

Calico が本番でよく選ばれる理由は、BGP ルーティングによってオーバーレイネットワークを使わずに Pod 間通信ができる点です。VXLAN のカプセル化コストがなく、物理ネットワーク機器とも BGP でピアリングできます。NetworkPolicy の実装も成熟しており、Ingress/Egress 双方向のきめ細かい制御が可能です。

前提環境と準備

①必要なスペックと OS

kubeadm でシングルノードクラスタを立てる場合、最低でも 2 vCPU / 2 GB RAM が必要です。実運用では control plane に 4 vCPU / 8 GB、worker node に 2 vCPU / 4 GB 以上を確保してください。

ubuntu@k8s-master: ~
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 24.04.4 LTS Release: 24.04 Codename: noble $ free -h total used free Mem: 7.8Gi 1.2Gi 5.9Gi $ nproc 4

②初期設定——swap 無効化と br_netfilter

Kubernetes は swap が有効だと起動を拒否します。また、br_netfilter モジュールを有効にしておかないと Pod 間通信が正常に機能しません。手順は次のとおりです。

ubuntu@k8s-master: ~
$ sudo swapoff -a $ sudo sed -i ‘/swap/d’ /etc/fstab $ free -h | grep Swap Swap: 0B 0B 0B $ cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF $ sudo modprobe overlay && sudo modprobe br_netfilter $ cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF $ sudo sysctl –system * Applying /etc/sysctl.d/k8s.conf … net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1

注意:containerd の設定

containerd を使う場合は /etc/containerd/config.tomlSystemdCgroup = true を必ず確認してください。デフォルト設定のままだと kubelet が cgroup ドライバーの不一致で失敗します。

Kubernetesクラスタのセットアップ

①kubectl / kubeadm / kubelet のインストール

2026-06-20 時点、Kubernetes 1.30 系の最新は v1.30.14 です。公式リポジトリから直接インストールします。

Kubernetes 1.30 × Calico 3.x 対応バージョン一覧(実測)
Kubernetes 1.30 × Calico 3.x 対応バージョン一覧(実測)
ubuntu@k8s-master: ~
$ sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl gnupg $ sudo mkdir -p /etc/apt/keyrings $ curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key \ | sudo gpg –dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg $ echo ‘deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /’ \ | sudo tee /etc/apt/sources.list.d/kubernetes.list $ sudo apt-get update $ sudo apt-get install -y kubectl=1.30.14-1.1 kubeadm=1.30.14-1.1 kubelet=1.30.14-1.1 Setting up kubectl (1.30.14-1.1) … Setting up kubeadm (1.30.14-1.1) … Setting up kubelet (1.30.14-1.1) … $ sudo apt-mark hold kubectl kubeadm kubelet kubectl set on hold. kubeadm set on hold. kubelet set on hold. $ kubectl version –client Client Version: v1.30.14

apt-mark hold で3つのパッケージを固定するのを忘れずに。apt upgrade のたびに Kubernetes が更新されて kubeadm/kubelet のバージョンがずれると、クラスタが起動しなくなります。

②kubeadm init——Calico 専用の pod-network-cidr

Calico はデフォルトで 192.168.0.0/16 を Pod ネットワークとして使います。kubeadm init 時にこの CIDR を指定しておかないと、後で Calico の設定と食い違いが生じます。

ubuntu@k8s-master: ~
$ sudo kubeadm init –pod-network-cidr=192.168.0.0/16 [init] Using Kubernetes version: v1.30.14 [preflight] Running pre-flight checks [preflight] Pulling images required for setting up a Kubernetes cluster Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: $ mkdir -p $HOME/.kube $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config $ sudo chown $(id -u):$(id -g) $HOME/.kube/config $ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master NotReady control-plane 30s v1.30.14 # CNI がまだ入っていないので NotReady — Calico インストール後に Ready になる

NotReady と表示されるのは想定内です。CNI プラグインをインストールしていないのでネットワークが設定されていない状態です。次のステップで Calico を入れると Ready に変わります。

Calicoのインストール

①マニフェストを apply する

Calico の最もシンプルなインストール方法は、公式マニフェストを kubectl apply するだけです。v3.29.1 のマニフェストは GitHub から直接取得します。

kubeadm init 後の Calico マニフェスト適用(再現UI)
kubeadm init 後の Calico マニフェスト適用(再現UI)
ubuntu@k8s-master: ~
$ kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.29.1/manifests/calico.yaml configmap/calico-config created customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created clusterrole.rbac.authorization.k8s.io/calico-node created daemonset.apps/calico-node created deployment.apps/calico-kube-controllers created $ kubectl get pods -n kube-system -w calico-kube-controllers-7c758dbf6d-np4mz 0/1 ContainerCreating 0 10s calico-node-4xkzp 0/1 Init:0/3 0 10s calico-node-4xkzp 1/1 Running 0 2m calico-kube-controllers-7c758dbf6d-np4mz 1/1 Running 0 2m

②calicoctl のインストール

BGP設定やCalico固有のリソース管理には calicoctl を使います。v3.29.1 のバイナリを直接ダウンロードしてください。

ubuntu@k8s-master: ~
$ curl -L https://github.com/projectcalico/calico/releases/download/v3.29.1/calicoctl-linux-amd64 \ -o calicoctl $ chmod +x calicoctl && sudo mv calicoctl /usr/local/bin/ $ calicoctl version Client Version: v3.29.1 Git commit: ddfc3b1ea Cluster Version: v3.29.1 Cluster Type: KDD,BGP

「Cluster Version: v3.29.1」と表示されれば、クラスタ側の Calico も正常に認識されています。「Unable to detect installed Calico version」が出た場合は kubectl get pods -n kube-systemcalico-nodeRunning になっているか確認してください。

③ノードが Ready になったか確認

ubuntu@k8s-master: ~
$ kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 5m v1.30.14 $ kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-7c758dbf6d-np4mz 1/1 Running 0 4m calico-node-4xkzp 1/1 Running 0 4m coredns-76f75df574-9zj8l 1/1 Running 0 5m coredns-76f75df574-vmpvf 1/1 Running 0 5m etcd-k8s-master 1/1 Running 0 5m kube-apiserver-k8s-master 1/1 Running 0 5m kube-scheduler-k8s-master 1/1 Running 0 5m

BGP設定——BGPConfiguration と BGPPeer

CalicのBGP機能はデフォルトで「Node-to-Node Mesh」モードが有効になっています。これはノード同士が全組み合わせでフルメッシュのBGPセッションを張るモードで、小規模クラスタ(10ノード以下)では問題ありません。ノード数が増えると N²(二乗)でセッション数が膨れるため、大規模環境ではルートリフレクターを立てて集約します。

Calico BGPピア設定とルーティング確認(再現UI)
Calico BGPピア設定とルーティング確認(再現UI)

①現在のBGP設定を確認する

ubuntu@k8s-master: ~
$ calicoctl get bgpconfig default -o yaml apiVersion: projectcalico.org/v3 kind: BGPConfiguration metadata: name: default spec: logSeverityScreen: Info nodeToNodeMeshEnabled: true asNumber: 64512 $ calicoctl node status Calico process is running. IPv4 BGP status +—————-+——————-+——-+———-+————-+ | PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO | +—————-+——————-+——-+———-+————-+ | 192.168.10.12 | node-to-node mesh | up | 06:31:12 | Established | +—————-+——————-+——-+———-+————-+

②外部ルーターと BGP ピアリング(BGPPeer リソース)

物理スイッチや VyOS/FRR などの外部ルーターと BGP ピアリングする場合は、BGPPeer リソースを作成します。nodeToNodeMeshEnabled: false にしてルートリフレクター集約構成にするときも同じ手順です。

ubuntu@k8s-master: ~
$ cat bgppeer.yaml apiVersion: projectcalico.org/v3 kind: BGPPeer metadata: name: rack0-peer spec: peerIP: 192.168.0.1 asNumber: 65001 $ calicoctl apply -f bgppeer.yaml Successfully applied 1 ‘BGPPeer’ resource(s) $ calicoctl get bgppeers NAME PEERIP NODE ASN rack0-peer 192.168.0.1 * 65001 $ ip route show | grep bird 10.244.1.0/24 via 192.168.10.11 dev eth0 proto bird 10.244.2.0/24 via 192.168.10.12 dev eth0 proto bird

proto bird が付いているルートは Calico(内部で BIRD デーモンを使用)が BGP 経由で受け取ったルートです。ip route show でこの行が見えれば、BGP ルーティングは正常に機能しています。

③ASナンバーを変更する

デフォルトの AS 番号は 64512(プライベートAS範囲)です。既存インフラと AS 番号が重なる場合は変更が必要です。

ubuntu@k8s-master: ~
$ calicoctl patch bgpconfig default \ –patch ‘{“spec”: {“asNumber”: 64513}}’ Successfully patched 1 ‘BGPConfiguration’ resource(s) $ calicoctl get bgpconfig default -o yaml | grep asNumber asNumber: 64513

NetworkPolicy で通信を制御する

Calico をインストールした状態では、デフォルトですべての Pod 間通信が許可されています。NetworkPolicy を使って「このラベルを持つ Pod だけが接続できる」という制御を追加していきます。

CalicoのNetworkPolicy通信制御フロー(概念図)
CalicoのNetworkPolicy通信制御フロー(概念図)

①基本の NetworkPolicy——Ingress を制限する

最初に「app: backend の Pod には app: frontend からの TCP 8080 だけを許可する」ポリシーを作ります。

Calico NetworkPolicy YAML の kubectl apply 実行(再現UI)
Calico NetworkPolicy YAML の kubectl apply 実行(再現UI)
ubuntu@k8s-master: ~
$ cat <<EOF | kubectl apply -f – apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-frontend-to-backend namespace: default spec: podSelector: matchLabels: app: backend policyTypes: – Ingress ingress: – from: – podSelector: matchLabels: app: frontend ports: – protocol: TCP port: 8080 EOF networkpolicy.networking.k8s.io/allow-frontend-to-backend created $ kubectl get networkpolicies NAME POD-SELECTOR AGE allow-frontend-to-backend app=backend 5s

注意点が1つあります。podSelector: {}(空セレクタ)は「すべての Pod を対象にする」という意味になります。意図せず全 Pod にポリシーが適用されるミスが多いので、必ず matchLabels を明示してください。

②全拒否ポリシー(Default Deny)を先に適用する

実運用では「ホワイトリスト方式」が基本です。先にすべての通信を拒否するポリシーを入れ、次に必要な通信だけを許可します。

ubuntu@k8s-master: ~
$ cat <<EOF | kubectl apply -f – apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress namespace: default spec: podSelector: {} policyTypes: – Ingress EOF networkpolicy.networking.k8s.io/default-deny-ingress created

注意:default-deny を入れた後は DNS も止まる

Namespace 全体に default-deny を入れると、kube-dns(coredns)への名前解決も塞がれます。必ず CoreDNS への通信を許可するポリシーをセットで作るか、kube-system Namespace を exclude してください。

③Egress(外向き)を制限する

外部への不正通信を防ぐには Egress ルールも設定します。以下は「app: backend から特定の外部 IP(データベースサーバー)だけへのアクセスを許可する」例です。

ubuntu@k8s-master: ~
$ cat <<EOF | kubectl apply -f – apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: backend-egress-db namespace: default spec: podSelector: matchLabels: app: backend policyTypes: – Egress egress: – to: – ipBlock: cidr: 10.10.0.100/32 ports: – protocol: TCP port: 5432 EOF networkpolicy.networking.k8s.io/backend-egress-db created

④ポリシーの動作確認——kubectl exec で実通信テスト

NetworkPolicy を作っても「本当に通信が止まっているか」を確認しないと意味がありません。テスト Pod を立てて wget / nc で疎通確認します。

ubuntu@k8s-master: ~
$ kubectl run test-pod –image=busybox –restart=Never — sleep 3600 pod/test-pod created $ kubectl exec -it test-pod — wget -qO- http://backend-svc:8080 –timeout=5 wget: can’t connect to remote host (10.96.1.50): Connection timed out # default-deny が効いていることを確認 $ kubectl label pod test-pod app=frontend pod/test-pod labeled $ kubectl exec -it test-pod — wget -qO- http://backend-svc:8080 –timeout=5 {“status”: “ok”} # app=frontend ラベルを付けたら接続できた

よくあるエラーと解決策

①calico-node が CrashLoopBackOff になる

最も多いのは IP 自動検出の失敗です。ノードに複数の NIC がある場合、Calico が間違ったインターフェースを選んでしまうことがあります。

ubuntu@k8s-master: ~
$ kubectl logs -n kube-system daemonset/calico-node | tail -20 Failed to auto-detect primary interface # → calico-config ConfigMap で IP_AUTODETECTION_METHOD を指定する $ kubectl edit configmap calico-config -n kube-system # IP_AUTODETECTION_METHOD を以下に変更: IP_AUTODETECTION_METHOD: “interface=eth0” $ kubectl rollout restart daemonset/calico-node -n kube-system daemonset.apps/calico-node restarted

②NetworkPolicy を適用しても通信が止まらない

CNI プラグインが NetworkPolicy に対応していない(Flannel のみのクラスタなど)か、podSelector のラベルがマッチしていない場合です。

ubuntu@k8s-master: ~
$ kubectl get pod backend-pod –show-labels NAME READY STATUS LABELS backend-pod 1/1 Running app=backend,tier=api $ kubectl describe networkpolicy allow-frontend-to-backend PodSelector: app=backend # ← Pod のラベルと一致しているか確認する

③calicoctl が「Unable to connect to the Kubernetes API」を返す

calicoctl はデフォルトで ~/.kube/config を参照しますが、環境によっては明示的に指定が必要です。

ubuntu@k8s-master: ~
$ export KUBECONFIG=$HOME/.kube/config $ calicoctl get nodes NAME k8s-master

まとめ

Calico の導入は kubectl apply -f calico.yaml で済みますが、運用上のポイントは2つです。

  • BGP は小規模なら Node-to-Node Mesh のままでOK。ノードが増えたらルートリフレクター構成に移行する
  • NetworkPolicy は「default-deny を先に入れてから許可ポリシーを追加」するホワイトリスト方式が安全。ラベルのマッチングミスが一番多いトラブル原因なので、kubectl get pod --show-labels で常に確認する

今回使ったバージョン(Kubernetes v1.30.14 / Calico v3.29.1)は 2026-06-20 時点での最新安定版です。Calico v3.32.0 もリリースされていますが、本番で使うなら LTS の v3.29.x シリーズが無難です。

著者アイコン
著者アイコン

NetworkPolicy を設定するときに一番詰まるのは、Pod のラベルとポリシーのセレクタが噛み合っていないケースです。kubectl describe networkpolicy の出力をよく読むと、どの Pod に適用されているかが分かるので必ずチェックしてください。

本格的な Kubernetes 運用環境を VPS 上で構築したい方は、東京リージョンがあり低レイテンシで使える VPS を選ぶと快適です。

コメント

タイトルとURLをコピーしました