OpenShift 4.3 でMultus を使って、Pod にNIC を追加してみる


低レイヤーのネットワークエンジアで、SDN周りの技術(OpenFlowやONOS)に関わり、OpenStackも少し味見した経験を持っています。これからはコンテナかなと考えていたので、K8s やOpenShift を試してみようと思い立ちました。コンテナ技術は初心者なので、認識違い等があると思います。間違い等があれば、ご指摘いただければ嬉しいです。

環境構築にあたり、Qiitaを始め沢山のネット上の情報を活用しました。今回はそのお礼も込めて、記事してみました。

環境作り

k8s でMultus を使って、pod にNIC 追加する検証が終わったので、次はOpenShift で試してみます。
そこで、何も考えず、Redhatさんが公開しているhatenaブログを参考にして、ベアメタルでOpenShift環境(4.2)を作ってみました。ベアメタルと言っても、物理サーバが不足しているので、ESXi上に構築、なお、全ゲストOS(今回はCoreOSのみ)にクラスタ用とMultus用のNICを1つずつ持たせただけで、ESXiには特別な設定等々は入れていません(念のため仮想SWを無差別モードにし、フラットなL2セグメントとしました)。



構成図が抜けていたので、追記しました(2020年5月11日)

物理構成

論理構成

GUIコンソール用のwindows 10やDNS, DHCP, HAProxy を持ったjumpサーバを作り終えた後、boostrap からmaster, worker の順にVMを作っていきます。CoreOSのインストール時の手順は、先のhatenaブログとは少々違っていたので、GUIではなくCLIでパラメータを指定。

とても簡単に、master ノードを3台、worker ノードを2台の最小構成で完成。

Multus を使うために

再度、Redhat さんが公開しているhatenaブログを参考にして、構築したOpenShift4.2 環境内にMultusを追加。しかし、上手くいかない。。。
Redhatの知人に聞いてみると、Multus は4.3 からサポートとのこと。じゃ、4.3 に上げてみるか!と安易に考え、OpenShift のGUI をいじったり、ググってみると、簡単にupdate できることが判明。しかし、当時(3月頃?) 4.2 からstable-4.3 へのupdate できないようで、fast-4.3 を選択し、無事4.2.26 から4.3.10 にupdate完了。

プロプントはrhel8-jump となっていますが、途中jump-0 に変更しました。

再度、hatenaブログを参考にして、macvlanのCNO用とPod用のYAMLを作り、無事Multus が出来上がった。疎通も確認できた。と思ったら、、、

ある日突然

4.3.13 が出たよとGUI上に通知があり、何も考えず、update、ここから大変。まずGUIにアクセスできない。CLIで確認すると、clusteroperators のconsole がfalse に。
今回は、環境構築感とMultus の動作感を知りたいだけで、プロダクション用ではないので、最新の4.3.13で再構築を試みた。しかし、次は、clusteroperators のauthentication がunknown に。。。。なぜだ。。。。始めは証明書問題かと思ったが、切り分けできず。

何度も環境を作り直したけど、完成出来るときもあれば、出来ないときもある。あと、単純にopenshift-installer を持ってきて、ign ファイルを作ってもだめで、利用したいバージョンのインストーラーを使用せよのこと(Redhat の知人情報)。

頭を冷やすために、ちょっと時間をあけることに。そこで、気づいたのが、HAproxy とdnsmasq の設定と状態。確認できたのは、
1. dnsmasq でIPアドレスを配っていないと、HAproxy は当該のホストがないためfailし、プロセスが立ち上がらない。具体的には、/var/lib/dnsmasq/dnsmasq.leases にホストが登録されていないと、ダメっぽい
2. OpenShift4.2 からmaster ノードもworker ノードにスケジュールされるため、HAproxy 設定内のbackend httpとhttps にmaster ノードを追加する必要がある
知っている人には当たり前のことかもしれないけど、dnsmasq を初めて使うし、HAproxy は慣れていないので、結構戸惑った。HAproxy の設定ファイルの抜粋は

(抜粋)
backend http-80
    mode tcp
    balance     roundrobin
    server  master-0 master-0.test.example.local:80 check
    server  master-1 master-1.test.example.local:80 check
    server  master-2 master-2.test.example.local:80 check
    server  worker-0 worker-0.test.example.local:80 check
    server  worker-1 worker-1.test.example.local:80 check

backend https-443
    mode tcp
    balance     roundrobin
    option      ssl-hello-chk
    server  master-0 master-0.test.example.local:443 check
    server  master-1 master-1.test.example.local:443 check
    server  master-2 master-2.test.example.local:443 check
    server  worker-0 worker-0.test.example.local:443 check
    server  worker-1 worker-1.test.example.local:443 check

HAproxy とdnsmasq を適切に設定し、無事OpenShift4.3.10 環境が出来上がりました。ひよって最新の4.3.13 にしていません。。。

その他、hosts をいじると、dnsmasq プロセスを再起動。当たり前と言えば、当たり前ですが。。。

Multusの追加、アゲイン

ようやく環境できたので、Multus を入れてみる。しかし、先に成功していたCNO の設定が通らない。openshift-network-operator でエラー。

openshift-network-operator のエラー

[root@jump-0 openshift]# oc -n openshift-network-operator logs -f network-operator-xxxxx
(snip)
2020/04/** 01:53:51 httpProxy, httpsProxy and noProxy not defined for proxy 'cluster'; validation will be skipped
2020/04/** 01:53:51 Starting render phase
E0507 01:53:51.040613       1 runtime.go:78] Observed a panic: "invalid memory address or nil pointer dereference" (runtime error: invalid memory address or nil pointer dereference)

CNOの見直し

色々試してみる。まずはCNOを見直し。公開されているOpenshiftのマニュアルを見る、でもよく理解できない。。。
- https://docs.openshift.com/container-platform/4.3/networking/multiple_networks/configuring-macvlan.html
- https://docs.openshift.com/container-platform/4.3/networking/multiple_networks/attaching-pod.html#attaching-pod
この2つのページを参照して作成したCNO設定を、「oc edit networks.operator.openshift.io cluster」 で追記。

spec:
  additionalNetworks:
  - name: network-macvlan
    type: Raw
    rawCNIConfig: '{
      "cniVersion": "0.3.1",
      "type": "macvlan",
      "capabilities": {"ips": true},
      "master": "ens224",
      "ipam": {
        "type": "static"
      }
    }'

エラーは出ず、CNOも確認できたので、Pod 作成に取りかかる。

[root@jump-0 openshift]# oc get network-attachment-definitions
NAME              AGE
network-macvlan   164m
[root@jump-0 openshift]#

Pod用のYAML

apiVersion: v1
kind: Pod
metadata:
  name: macvlan-1
  labels:
    app: multus-macvlan
  annotations:
    k8s.v1.cni.cncf.io/networks: '[
    {
      "name": "network-macvlan",
      "ips": [ "10.0.201.29/24" ]
    }
    ]'
spec:
  containers:
  - name: centos-tools
    image: docker.io/centos/tools:latest
    command:
    - /sbin/init
    securityContext:
      privileged: true
  nodeSelector:
    kubernetes.io/hostname: worker-0

PodにNICを追加できた

[root@jump-0 openshift]# oc get pod/macvlan-1 -oyaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    k8s.v1.cni.cncf.io/networks: '[ { "name": "network-macvlan", "ips": [ "10.0.201.29/24"
      ] } ]'
    k8s.v1.cni.cncf.io/networks-status: |-
      [{
          "name": "openshift-sdn",
          "interface": "eth0",
          "ips": [
              "10.128.2.16"
          ],
          "dns": {},
          "default-route": [
              "10.128.2.1"
          ]
      },{
          "name": "network-macvlan",
          "interface": "net1",
          "ips": [
              "10.0.201.29"
          ],
          "mac": "6a:1b:1b:a1:15:ef",
          "dns": {}
      }]
(snip)

Podを2つ作成→状態を確認→疎通もOK

Multusで使うIPアドレスを変えて、同じようなyaml ファイルを作成後、create。その後、状態確認し、疎通も確認

[root@jump-0 openshift]# oc rsh macvlan-1 ip -d a s dev net1
4: net1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 6a:1b:1b:a1:15:ef brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0
    macvlan mode bridge numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet 10.0.201.29/24 brd 10.0.201.255 scope global net1
       valid_lft forever preferred_lft forever
    inet6 fe80::681b:1bff:fea1:15ef/64 scope link
       valid_lft forever preferred_lft forever
[root@jump-0 openshift]#
[root@jump-0 openshift]# oc rsh macvlan-2 ip -d a s dev net1
4: net1@if3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:ed:f7:26:87:7b brd ff:ff:ff:ff:ff:ff link-netnsid 0 promiscuity 0
    macvlan mode bridge numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet 10.0.201.30/24 brd 10.0.201.255 scope global net1
       valid_lft forever preferred_lft forever
    inet6 fe80::ed:f7ff:fe26:877b/64 scope link
       valid_lft forever preferred_lft forever

[root@jump-0 openshift]#
[root@jump-0 openshift]# oc rsh macvlan-1 ping -c 3 10.0.201.30
PING 10.0.201.30 (10.0.201.30) 56(84) bytes of data.
64 bytes from 10.0.201.30: icmp_seq=1 ttl=64 time=0.175 ms
64 bytes from 10.0.201.30: icmp_seq=2 ttl=64 time=0.205 ms
64 bytes from 10.0.201.30: icmp_seq=3 ttl=64 time=0.341 ms

--- 10.0.201.30 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2046ms
rtt min/avg/max/mdev = 0.175/0.240/0.341/0.073 ms
[root@jump-0 openshift]#
[root@jump-0 openshift]# oc rsh macvlan-2 ping -c 3 10.0.201.29
PING 10.0.201.29 (10.0.201.29) 56(84) bytes of data.
64 bytes from 10.0.201.29: icmp_seq=1 ttl=64 time=0.231 ms
64 bytes from 10.0.201.29: icmp_seq=2 ttl=64 time=0.237 ms
64 bytes from 10.0.201.29: icmp_seq=3 ttl=64 time=0.215 ms

--- 10.0.201.29 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2087ms
rtt min/avg/max/mdev = 0.215/0.227/0.237/0.019 ms
[root@jump-0 openshift]#

結果

本来の目的を達成しようと、試したい技術を評価してみるものの、その技術の周辺で問題が発生し、想定通りに動作しない状況を過去何度か経験してきました。個人的にはインフラあるあるとしていますが、今回も正しく発動しました。まだまだスキルが不足し、視野が狭いと実感したここ1ヶ月でした。これからも腕を磨き、視野を広げる活動を続けていこうと思います。

(追伸) 可用性が高いK8s 環境

etcdをmaster ノードから切り離し、3台のetcd と2台のHAproxy を使って、可用性を高めた構成を2020年の初めに作りました。この環境に、Juniper vMX とCalico を使って、外部からの接続をBGPで負荷分散する機能も追加済み。機会があれば、記事にしようかと思います。