16
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

この記事は デジタル創作サークル UniProject Advent Calendar 2025 および Kubernetes Advent Calendar 2025 18 日目の記事です。

はじめに

つい先日、Cilium に大きな新機能が登場しました。

まさかの、IPv6 外部広告が NDP に対応したのです。

弊サークルに限らず、IPv6 で外部に広告できることを望んでいた方はとても多かったはずです。
しかし、従来は BGP+ を使う他なく、それに対応した機器となると、とても高価で我々のようなサークルには手が出せませんでした。

今回 L2 に対応したということで、早速試していきたいと思います。

この記事では、Cilium の Preview 版を使用します

前提

この環境は、以下のような構成で構築されています。

  • Ubuntu 24
  • CRI-O 1.34.3
  • Kubeadm で構築した K8s v1.34.3
  • IPv6 DualStack の構成は K8s のドキュメント通り行っているものとします

準備

まずは、IPv6 を広告するにあたって、パケット転送などを有効化します。

/etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables=1
net.bridge.bridge-nf-call-ip6tables=1
net.ipv4.ip_forward=1
net.ipv6.conf.default.forwarding = 1
net.ipv6.conf.all.forwarding = 1

設定を反映します。

sudo sysctl -p

kube-proxy を消し去る

Cilium で外部 IP を広告する場合、kube-proxy を置き換える必要があります

まずは、DaemonSet を削除します。

kubectl -n kube-system delete ds kube-proxy
# Delete the configmap as well to avoid kube-proxy being reinstalled during a Kubeadm upgrade
kubectl -n kube-system delete cm kube-proxy

また、すべてのノードで下記コマンドを実行して、iptables に残ったデータを抹消します。

# Run on each node with root permissions:
iptables-save | grep -v KUBE | iptables-restore

この段階で、すべてのノードが NotReady になりますが、この後の Cilium のインストールで Ready に戻るので問題ありません。

Cilium のインストール

Cilium は helm でインストールしていきます。

まず、helm repo の追加をしましょう。

helm repo add cilium https://helm.cilium.io/

helm で使用する values.yaml は以下の通りに記述しましょう。

values.yaml
cluster:
  name: kubernetes
externalIPs:
  enabled: true

# Kube API サーバーの IP を指定する
# 今回は HA 構成なので、ロードバランサーの IP を指定した
k8sServiceHost: 172.16.110.100
k8sServicePort: 6443

kubeProxyReplacement: true
l2announcements:
  enabled: true
operator:
  replicas: 1
routingMode: tunnel
tunnelProtocol: vxlan
ipv6:
  enabled: true
l2NeighDiscovery:
  enabled: true

さて、インストールしていきましょう。
まだ Preview 版でのみ配信されている機能なので、1.19.0-pre.3 を指定します。

sudo helm upgrade --install cilium cilium/cilium \
     -n kube-system -f values.yaml \
     --version 1.19.0-pre.3

確認してみる

Cilium CLI を使って確認しましょう。

Cilium CLI のインストールはこちらを確認してください。
この記事では割愛します。

cilium status --wait

以下のように、Cilium: OKなどとなっていれば OK です。

    /¯¯\
 /¯¯\__/¯¯\    Cilium:             OK
 \__/¯¯\__/    Operator:           OK
 /¯¯\__/¯¯\    Envoy DaemonSet:    OK
 \__/¯¯\__/    Hubble Relay:       OK
    \__/       ClusterMesh:        disabled

DaemonSet              cilium                   Desired: 3, Ready: 3/3, Available: 3/3
DaemonSet              cilium-envoy             Desired: 3, Ready: 3/3, Available: 3/3
Deployment             cilium-operator          Desired: 1, Ready: 1/1, Available: 1/1
Deployment             hubble-relay             Desired: 1, Ready: 1/1, Available: 1/1
Deployment             hubble-ui                Desired: 1, Ready: 1/1, Available: 1/1
Containers:            cilium                   Running: 3
                       cilium-envoy             Running: 3
                       cilium-operator          Running: 1
                       clustermesh-apiserver
                       hubble-relay             Running: 1
                       hubble-ui                Running: 1
Cluster Pods:          35/35 managed by Cilium
Helm chart version:    1.19.0-pre.3
Image versions         cilium             quay.io/cilium/cilium:v1.19.0-pre.3@sha256:9ba932dcafcb30f44ae4835edb83081423ae4139b2a8e8b8c7245f47a60de925: 3
                       cilium-envoy       quay.io/cilium/cilium-envoy:v1.35.3-1764238404-a890eb288598920fc146308ef4b05004f2ee7bcf@sha256:5a5403c2847af60352f2ae0c69642b0484b741a8ca5c15b34737e10553c64e08: 3
                       cilium-operator    quay.io/cilium/operator-generic:v1.19.0-pre.3@sha256:c2796566b40cfdc4b59cc1d460d91b86436ded0b447ef82d4e3663f745db6671: 1
                       hubble-relay       quay.io/cilium/hubble-relay:v1.19.0-pre.3@sha256:6771ceb69dbe96e91950c474b146e3e9dc74c64340b6a87dea28be20ed6566fc: 1
                       hubble-ui          quay.io/cilium/hubble-ui-backend:v0.13.3@sha256:db1454e45dc39ca41fbf7cad31eec95d99e5b9949c39daaad0fa81ef29d56953: 1
                       hubble-ui          quay.io/cilium/hubble-ui:v0.13.3@sha256:661d5de7050182d495c6497ff0b007a7a1e379648e60830dd68c4d78ae21761d: 1

L2 Announce Policy を追加する

これは、Cilium がどのインターフェースを使って広告するかを設定するものです。

今回は以下のように設定しました。
コントロールプレーン外から広告したい場合は、nodeSelector を変更してください。

また、interfaces も、eth から始まっている場合などがあると思います。
適宜変更してください。

apiVersion: "cilium.io/v2alpha1"
kind: CiliumL2AnnouncementPolicy
metadata:
  name: policy1
spec:
  nodeSelector:
    matchExpressions:
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
  interfaces:
    - ^ens[0-9]+
  externalIPs: true
  loadBalancerIPs: true
kubectl apply policy.yaml

LB IPAM を作成する

これは、Cilium にどの範囲の IP を広告できるかを示すものです。
今回は以下のように設定しました。
(IPv6 は伏せています)

apiVersion: "cilium.io/v2"
kind: CiliumLoadBalancerIPPool
metadata:
  name: "default"
spec:
  # 0と225を指定したくない場合はNoにする
  allowFirstLastIPs: "No"
  blocks:
    - cidr: "172.16.152.0/24"
    - cidr: "24xx:xxxx:xxxx:xxxx:xxxx::/80"
kubectl apply ip-pool.yaml

Nginx をおいて確認してみる

下記マニュフェストファイルをデプロイしてみましょう。

deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  namespace: default
spec:
  progressDeadlineSeconds: 600
  replicas: 2
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      run: my-nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - image: nginx
        imagePullPolicy: Always
        name: my-nginx
        ports:
        - containerPort: 80
          protocol: TCP
      restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  labels:
    run: my-nginx
  name: my-nginx
  namespace: default
spec:
  ipFamilies:
  - IPv4
  - IPv6
  ipFamilyPolicy: PreferDualStack
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    run: my-nginx
  sessionAffinity: None
  type: LoadBalancer

確認してみると、External IP が割り振られていることがわかります。

NAME         TYPE           CLUSTER-IP       EXTERNAL-IP                              PORT(S)        AGE
kubernetes   ClusterIP      10.223.0.1       <none>                                   443/TCP        2d13h
my-nginx     LoadBalancer   10.223.245.118   172.16.152.1,xxx:xxxx:xxxx:xxxx::xxxx    80:30684/TCP   2d13h

実際にアクセスして確かめてみてください!

トラブルシューティング

今回私が遭遇したトラブルとして...
NDP は通っていて、SYN も通るのに応答が返ってこない現象が発生しました。
原因はよくわかりませんが、ノード自体を再起動することで解決しました。

もし IPv4 通るのに IPv6 通らないよ!という方がいれば試してみるといいかもしれません。

最後に

今回は、Cilium の最新機能を使って L2 で IPv6 を広告する方法を実践してみました。
お読みいただきありがとうございました!
いいね等々お願いします!

また、当サークルでは ProxmoxVE や Kubernetes を運用しています。
もし興味がありましたら、下記 URL へ飛んでいただければと思います!

⭐︎ 公式 HP ↓

⭐︎ Discord ↓

16
1
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
16
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?