これは、このセクションの複数ページの印刷可能なビューです。 印刷するには、ここをクリックしてください.

このページの通常のビューに戻る.

Documentation

Kuestaは、クラウドネイティブなアプローチでネットワークのInfrastructure as Codeを可能にするオープンソースのフレームワークです。 ネットワークの高レベルなモデルへの抽象化とCUE言語を用いたデータマッピング、Kubernetesカスタムオペレータを用いたGitOpsなどで構成され、 ソフトウェア開発のIaCやGitOpsで培われたプラクティスをネットワークに適用し、高度なネットワーク設定の自動化を実現します。

1 - Getting Started

Kuestaを動かしてみよう

このチュートリアルでは、以下のステップでKuestaを構築し、動作確認を行います。

  1. ローカルのKubernetesクラスターを作成する
  2. Kuestaをインストールする
  3. 装置エミュレータを立ち上げる
  4. 新しいServiceコンフィグを作成して、GitOpsを介して装置エミュレータに設定を投入する

事前準備

  1. golang (v1.20.4+)) をインストールしてください。カスタムコントローラーのツール類を使用するために必要です。
  2. docker (v20.10.24+) をインストールしてください。kindの実行に必要です。
  3. kind (v0.12.0+) をインストールしてください。ローカルのKubernetesクラスタの構築に使用します。
  4. kubectl (v1.25.4+) をインストールしてください。Kubernetesクラスタに対してコマンドを実行する際に使用します。
  5. cue (v0.4.x) をインストールしてください。Kuestaのインストールスクリプトの実行に必要です。
  6. gnmic (v0.26.0+) をインストールしてください。Kuestaサーバに対してgNMIリクエストを行うために必要です。

ローカルKubernetesクラスタの立ち上げ

以下のコマンドを実行して、ローカルのKubernetesクラスタを立ち上げます。

kind create cluster

実行が完了したら、以下のコマンドを実行して、Kubernetesクラスタが正常に作成されたことを確認します。

kubectl cluster-info

以下のような出力が表示されたら、ローカルクラスタは正常に動作しています。

Kubernetes control plane is running at https://127.0.0.1:52096
CoreDNS is running at https://127.0.0.1:52096/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

検証用のGithubレポジトリの作成

KuestaのGitOpsを用いてネットワーク装置に設定を行うには、2つのGitHubレポジトリを作成する必要があります。 1つ目はGitOpsの起点となるコンフィグ管理レポジトリで、2つ目はネットワーク装置の実際のコンフィグの変更履歴を管理するレポジトリです。 Kuesta Example レポジトリをテンプレートとして使用することで、これらのレポジトリを簡単に作成できます。 レポジトリ名は、小文字の英数字、’-‘または’.‘で構成され、英数字で始まり、英数字で終わる必要があります。

以下を2回実行して、2つのGitHubレポジトリを作成してください。

  1. Kuesta Example レポジトリの Use this template ボタンをクリックしてください。

  2. レポジトリ名を入力して、 Create repository from template ボタンをクリックしてください。レポジトリの公開・非公開については、好きな方を選択してください。

Kuestaと検証用サンプルリソースのインストール

Kuestaと、検証用のドライバオペレータや装置エミュレータなどのサンプルリソースをインストールするには、以下のコマンドを実行してください。

git clone https://github.com/nttcom/kuesta.git
cd kuesta/tool/install
cue install

プロンプトが表示されますので、指示に従ってパラメータを入力してください。 GitHub repository for config GitHub repository for statusは前項で作成した2つの検証用のGithubレポジトリをそれぞれ指定してください。

GitHub repository for config: https://github.com/<your_org>/<your_config_repo>
GitHub repository for status: https://github.com/<your_org>/<your_status_repo>
GitHub username: <your_username>
GitHub private access token: <your_private_access_token>
Are these git repositories private? (yes|no): no
Do you need sample driver and emulator for trial?: (yes|no) yes

---
GitHub Config Repository: https://github.com/<your_org>/<your_config_repo>
GitHub Status Repository: https://github.com/<your_org>/<your_status_repo>
GitHub Username: <your_username>
GitHub Access Token: ***
Use Private Repo: true

Image Registry: ghcr.io/nttcom/kuesta
Version: latest
Deploy sample driver and emulator: true
---

Continue? (yes|no) yes

KuestaはGitへのプッシュやプルリクエストの作成を行うため、GitHubの personal access token (PAT) が必要です(classic推奨)。 ここで入力されたPATは、ローカルのKubernetesクラスタ内のSecretリソースにのみ保存されます。ローカルのKubernetesクラスタを削除することで、どこにもデータを残さずに完全に削除できます。

インストールスクリプトの実行が完了したら、 kubectl コマンドを実行することで何がインストールされたかを確認できます。

1: Custom Resource Definitions(CRDs):

kubectl get customresourcedefinitions.apiextensions.k8s.io
NAME                                        CREATED AT
buckets.source.toolkit.fluxcd.io            2023-01-10T06:31:20Z
certificaterequests.cert-manager.io         2023-01-10T06:31:19Z
certificates.cert-manager.io                2023-01-10T06:31:19Z
challenges.acme.cert-manager.io             2023-01-10T06:31:19Z
clusterissuers.cert-manager.io              2023-01-10T06:31:19Z
devicerollouts.kuesta.hrk091.dev            2023-01-10T06:43:30Z
gitrepositories.source.toolkit.fluxcd.io    2023-01-10T06:31:20Z
helmcharts.source.toolkit.fluxcd.io         2023-01-10T06:31:20Z
helmrepositories.source.toolkit.fluxcd.io   2023-01-10T06:31:20Z
issuers.cert-manager.io                     2023-01-10T06:31:19Z
ocdemoes.kuesta.hrk091.dev                  2023-01-10T06:43:36Z
ocirepositories.source.toolkit.fluxcd.io    2023-01-10T06:31:20Z
orders.acme.cert-manager.io                 2023-01-10T06:31:19Z

kuesta.hrk091.devsource.toolkit.fluxcd.iocert-manager.io に属するCRDが追加されていることが確認できます。

2: Pods:

kubectl get pods -A | grep -v 'kube-system'
NAMESPACE                NAME                                                  READY   STATUS    RESTARTS   AGE
cert-manager             cert-manager-7475574-t7qlm                            1/1     Running   0          12m
cert-manager             cert-manager-cainjector-d5dc6cd7f-wbh6r               1/1     Running   0          12m
cert-manager             cert-manager-webhook-6868bd8b7-kc85s                  1/1     Running   0          12m
device-operator-system   device-operator-controller-manager-5d8648469b-57x4l   2/2     Running   0          11s
flux-system              source-controller-7ff779586b-wsgf7                    1/1     Running   0          12m
kuesta-getting-started   gnmi-fake-oc01-79d4d679b4-tvm78                       1/1     Running   0          10s
kuesta-getting-started   gnmi-fake-oc02-69d9cc664d-56bsz                       1/1     Running   0          10s
kuesta-getting-started   subscriber-oc01                                       1/1     Running   0          9s
kuesta-getting-started   subscriber-oc02                                       1/1     Running   0          9s
kuesta-system            kuesta-aggregator-7586999c47-jj7m4                    1/1     Running   0          27s
kuesta-system            kuesta-server-85fc4f8646-kq72c                        1/1     Running   0          27s
local-path-storage       local-path-provisioner-9cd9bd544-lk9w9                1/1     Running   0          16m
provisioner-system       provisioner-controller-manager-7675d487c8-w6f7x       1/2     Running   0          17s

全てのPodがRunningのステータスになっていたら、準備完了です。

以下の各namespaceに、Kuestaのコア機能として必要なサービスがデプロイされています。

  • kuesta-system
    • Kuestaのコア機能やAPIを提供するサーバ
  • provisioner-system
    • KuestaのKubernetesカスタムオペレータ。GitOpsやトランザクション管理に使用
  • flux-system
    • FluxCDのカスタムコントローラ
  • cert-manager
    • プライベートCAの認証局、およびmTLS用の証明書発行

また、以下のnamespaceには、本チュートリアル用のリソースがデプロイされています。

  • device-operator-system
    • チュートリアルで使用する装置エミュレータに対し設定投入を行うためのドライバとして振る舞うKubernetesカスタムオペレータ
  • kuesta-getting-started
    • チュートリアルで使用する装置エミュレータやエミュレータに設定を行うためのKubernetesカスタムリソースなど

以下の2つは、OpenConfig over gNMIで設定が可能な装置エミュレータです。本チュートリアルでは、 oc01oc02 の2つのエミュレータがデプロイされています。

kuesta-getting-started   gnmi-fake-oc01-79d4d679b4-tvm78                       1/1     Running   0          10s
kuesta-getting-started   gnmi-fake-oc02-69d9cc664d-56bsz                       1/1     Running   0          10s

ポートフォワーディングして gnmic からリクエストを行うことで設定されているコンフィグを確認できますので、必要に応じて実施してください。 以下のコマンドで、装置エミュレータ内のコンフィグの確認ができます。

# oc01のコンフィグを取得
kubectl -n kuesta-getting-started port-forward svc/gnmi-fake-oc01 9339:9339
gnmic -a :9339 -u admin -p admin get --path "" --encoding JSON --skip-verify

Serviceコンフィグを作成し、GitOpsを走らせる

Service は、ネットワークコンフィグを高レベルに抽象化したモデルです。Serviceを作成/変更することで、関連する複数のネットワーク装置にまとめて設定を投入することができます。

本チュートリアル用のサンプルレポジトリの中には、 oc-circuit という名のServiceが設定されていますので、これを用いて動作確認を行います。 ServiceはCUEで記述されます。例として、 oc-circuit Serviceの定義を以下に示します。

package oc_circuit

import (
	ocdemo "github.com/hrk091/kuesta-testdata/pkg/ocdemo"
)

#Input: {
	// kuesta:"key=1"
	vlanID: uint32
	endpoints: [...{
		device: string
		port:   uint32
	}]
}

#Template: {
	input: #Input

	output: devices: {
		for _, ep in input.endpoints {
			"\(ep.device)": config: {
				ocdemo.#Device

				let _portName = "Ethernet\(ep.port)"
				Interface: "\(_portName)": SubInterface: "\(input.vlanID)": {
					Ifindex:     ep.port
					Index:       input.vlanID
					Name:        "\(_portName).\(input.vlanID)"
					AdminStatus: 1
					OperStatus:  1
				}

				Vlan: "\(input.vlanID)": {
					VlanId: input.vlanID
					Name:   "VLAN\(input.vlanID)"
					Status: ocdemo.#Vlan_Status_ACTIVE
					Tpid:   ocdemo.#OpenconfigVlanTypes_TPID_TYPES_UNSET
				}
			}
		}
	}
}

oc-circuit Serviceは、#Template フィールドに定義された内容に従い、受け取った #Template.input(Serviceコンフィグ)を #Template.output (複数のネットワーク装置のコンフィグ)に変換します。 #Input の定義されているServiceのインターフェーススキーマを見ると、oc-circuit Serviceを使用するためには、 VLAN ID と複数のネットワーク装置のポートが必要なことがわかります。 これらを指定して oc-circuit Serviceを作成すると、 #Template のマッピング定義に従い、VLAN定義と指定したポートのVLANサブインターフェースが作成されます。

以下の手順にしたがって、oc-circuit Serviceを作成してください。

1: oc-circuit Serviceの作成をリクエストするために、以下のJSONファイルを oc-circuit-vlan100.json という名前で保存してください。 このServiceでは、oc01とoc02の両エミュレータに対して、ポート番号1のインターフェイスにVLAN ID=100のVLANサブインターフェースを作成することをリクエストしています。

{
    "vlanID": 100,
    "endpoints": [
        {
            "device": "oc01",
            "port": 1
        },
        {
            "device": "oc02",
            "port": 1
        }
    ]
}

httpインターフェースを利用する場合、上に代わって以下JSONを作成してください。(pathにはServiceのパス、valueには投入するServiceの値を指定)

{
    "path": "/services/oc_circuit/100",
    "value": {
        "vlanID": 100,
        "endpoints": [
            {
                "device": "oc01",
                "port": 1
            },
            {
                "device": "oc02",
                "port": 1
            }
        ]
    }
}

2: ローカルのKubernetesクラスタで動作しているKuestaサーバのPodに対してポートフォワーディングしてください。

kubectl -n kuesta-system port-forward svc/kuesta-server 9339:9339

httpインターフェースを利用する場合は以下です。

kubectl -n kuesta-system port-forward svc/kuesta-server 8080:8080

3: gnmicを用いて、Kuestaサーバに対してgNMI SetRequestを送ってください。

gnmic -a :9339 -u dummy -p dummy set --replace-path "/services/service[kind=oc_circuit][vlanID=100]" --encoding JSON --insecure --replace-file oc-circuit-vlan100.json

httpインターフェースを利用する場合は、curlを用いてKuestaサーバに対して以下POST Requestを送ってください。

curl -X POST -H "Content-Type: application/json" -d @oc-circuit-vlan100.json http://localhost:8080/set

4: GitHubのWebコンソールを用いて、本チュートリアル向けに作成したコンフィグ用のGitHubレポジトリのプルリクエスト(PullRequest: PR)を確認してください。 PR一覧 にアクセスすると、 [kuesta] Automated PR というタイトルのPRが確認できます。 PRのコメントを見ると、どのServiceとどのネットワーク装置が変更されたのかがわかりますし、 Files changed タブを確認すると詳細な変更点が確認できます。

5: PRブランチをマージする前に、ローカルのKubernetesクラスターで DeviceRollout リソースをモニターしてください。 DeviceRollout リソースは、Gitレポジトリからプルしたコンフィグを各ネットワーク装置に設定する際の状態管理を行っています。以下のコマンドを実行してください。

kubectl -n kuesta-getting-started get devicerollouts.kuesta.hrk091.dev -w

DeviceRollout リソースが一つ表示され、その STATUSCompleted になっていれば、GitOpsによるデリバリプロセスを流す準備は完了です。

NAME              PHASE     STATUS
kuesta-testdata   Healthy   Completed

6: GitHubのWebコンソール上で、PRをマージしてください。その後、 DeviceRollout をモニターしているターミナル画面に移動してください。 1分以内に、 DeviceRolloutSTATUSRunning に変わり、その後 Completed に変わることを確認してください。

NAME              PHASE     STATUS
kuesta-testdata   Healthy   Completed
kuesta-testdata   Healthy   Completed
kuesta-testdata   Healthy   Running
kuesta-testdata   Healthy   Running
kuesta-testdata   Healthy   Running
kuesta-testdata   Healthy   Completed

7: 装置コンフィグが本当に更新されたのかを確認します。 gnmic を用いて、gNMI GetRequestをKuestaサーバに対して送り、装置コンフィグ全体を取得してください。

gnmic -a :9339 -u admin -p admin get --path "/devices/device[name=oc01]" --path "/devices/device[name=oc02]" --encoding JSON --insecure

httpインターフェースを利用する場合は、curlを用いてKuestaサーバに対して以下POST Requestを送ってください。

curl -X POST -H "Content-Type: application/json" -d '{"paths": ["/devices/oc01", "/devices/oc02"]}'  http://localhost:8080/get

以下のようなレスポンスが表示されます。

[
  {
    "source": ":9339",
    "timestamp": 1673360105000000000,
    "time": "2023-01-10T23:15:05+09:00",
    "updates": [
      {
        "Path": "devices/device[name=oc01]",
        "values": {
          "devices/device": {
            "Interface": {
              "Ethernet1": {
                "AdminStatus": 1,
                "Description": "awesome interface!!",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet1",
                "OperStatus": 1,
                "Subinterface": {
                  "100": {
                    "AdminStatus": 1,
                    "Ifindex": 1,
                    "Index": 100,
                    "Name": "Ethernet1.100",
                    "OperStatus": 1
                  },
                  ...
                },
                ...
              },
              ...
            },
            "Vlan": {
              "100": {
                "Member": [],
                "Name": "VLAN100",
                "Status": 1,
                "Tpid": 0,
                "VlanId": 100
              },
              ...

httpインターフェースを使用した場合のレスポンスは以下です。

[
    {
        "Interface": {
            "Ethernet1": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet1",
                "OperStatus": 1,
                "SubInterface": {
                    "100": {
                        "AdminStatus": 1,
                        "Ifindex": 1,
                        "Index": 100,
                        "Name": "Ethernet1.100",
                        "OperStatus": 1
                    }
                },
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet2": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet2",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet3": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet3",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            }
        },
        "Vlan": {
            "100": {
                "Member": [],
                "Name": "VLAN100",
                "Status": 1,
                "Tpid": 0,
                "VlanId": 100
            }
        }
    },
    {
        "Interface": {
            "Ethernet1": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet1",
                "OperStatus": 1,
                "SubInterface": {
                    "100": {
                        "AdminStatus": 1,
                        "Ifindex": 1,
                        "Index": 100,
                        "Name": "Ethernet1.100",
                        "OperStatus": 1
                    }
                },
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet2": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet2",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            },
            "Ethernet3": {
                "AdminStatus": 1,
                "Description": "",
                "Enabled": false,
                "Mtu": 9000,
                "Name": "Ethernet3",
                "OperStatus": 1,
                "Subinterface": {},
                "Type": 80
            }
        },
        "Vlan": {
            "100": {
                "Member": [],
                "Name": "VLAN100",
                "Status": 1,
                "Tpid": 0,
                "VlanId": 100
            }
        }
    }
]

レスポンスを確認すると、oc01とoc02の両方の装置エミュレータに対して、VLAN ID=100のVLAN定義とVLANサブインターフェースが設定されていることが分かります。 また、これらの装置コンフィグの変更内容はチュートリアル向けに作成したステータス用のGitレポジトリに対してコミット・プッシュされています。ステータス用のGitレポジトリのメインブランチのHEADを見ると、変更が保存されていることが確認できます。

ローカルKubernetesクラスタの削除

このチュートリアルで作成したローカルのKubernetesクラスタを削除するには、以下のコマンドを実行してください。

kind delete cluster

プライベートレポジトリのアクセス用に作成したPATは、不要であれば忘れずに削除しましょう。

2 - Installation

Kuestaのインストール手順

Kuestaをインストールする手順を紹介します。

はじめに

バージョン1.24以上のKubernetesクラスターが必要です。

Kubernetesクラスターをお持ちでない場合は、kindを用いてローカルのKubernetesクラスターを作ることができます。 kindをインストール し、kind create cluster を実行してクラスターを作成してください。 これにより、ローカルで動作し cluster-admin 権限で操作出来るKubernetesクラスターが作成されます。

事前準備

  1. kubectl をインストールしてください。Kubernetesクラスタに対してコマンドを実行する際に使用します。 2cue をインストールしてください。Kuestaのインストールスクリプトの実行に必要です。

Kuestaのインストール

Kuestaをインストールするには、以下のコマンドを実行してください。

git clone https://github.com/nttcom/kuesta.git
cd kuesta/tool/install
cue install

リリースバージョンを指定したい場合、もしくは別のコンテナレジストリを使用してインストールしたい場合は、 version もしくは imageRegistry タグを使用してください。

cue -t imageRegistry=<your_image_registry> -t version=<your_version> install

プロンプトが表示されますので、指示に従ってパラメータを入力してください。

GitHub repository for config: https://github.com/<your_org>/<your_config_repo>
GitHub repository for status: https://github.com/<your_org>/<your_status_repo>
GitHub username: <your_username>
GitHub private access token: <your_private_access_token>
Are these git repositories private? (yes|no): no
Do you need sample driver and emulator for trial?: (yes|no) yes

---
GitHub Config Repository: https://github.com/<your_org>/<your_config_repo>
GitHub Status Repository: https://github.com/<your_org>/<your_status_repo>
GitHub Username: <your_username>
GitHub Access Token: ***
Use Private Repo: true

Image Registry: ghcr.io/nttcom/kuesta
Version: latest
Deploy sample driver and emulator: true
---

Continue? (yes|no) yes

KuestaはGitへのプッシュやプルリクエストの作成を行うため、GitHubの personal access token (PAT) が必要です。 上記で入力したPATは kuesta-system/kuesta-secrets という Secret リソースに保存され、kuestaサーバが git clone・pull・push・PullRequest作成を行うために使用されます。

また、非公開のGitレポジトリサーバに対してHTTPSで接続したい場合は、GitRepository を作成する際にこのPATを使うこともできます。Flux source-controllerにGitプライベートレポジトリへのアクセスを許可するために使用されます。

Flux source-controllerを用いてGitOpsを設定する

Flux source-controllerを用いてGitOpsを行うには、IaCマニフェストを取得するソースを定義するために GitRepository リソースを作成する必要があります。 以下は、getting-started チュートリアルで作成された GitRepository のサンプルです。

apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: kuesta-testdata
  namespace: kuesta-getting-started
spec:
  interval: 1m0s
  url: https://github.com/hrk091/kuesta-testdata
  ref:
    branch: main
  secretRef:
    name: kuesta-testdata-secret
  timeout: 60s

GitRepositoryに関するより詳細な情報が知りたければ、Fluxのドキュメントを参照してください。

Kuestaでは、GitRepositoryを作成するとKuestaのsource-watcherコントローラが検知して、対応する DeviceRollout を作成します。 DeviceRollout は、マルチデバイスのトランザクション管理を責務とするカスタムリソースです。 getting-started チュートリアルでは、以下の DeviceRollout が作成されます。

apiVersion: kuesta.hrk091.dev/v1alpha1
kind: DeviceRollout
metadata:
  name: kuesta-testdata
  namespace: kuesta-getting-started
spec:
  deviceConfigMap:
    oc01:
      checksum: 1524caf17ec4c133f6f275326a6c9742a0155007f8eaa28ea601ce7ac39c0566
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
    oc02:
      checksum: 0b03381195ba613e0dd20e5d2683711e9d6082f0634bee7c54014de2eadf0fc9
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
status:
  desiredDeviceConfigMap:
    oc01:
      checksum: 1524caf17ec4c133f6f275326a6c9742a0155007f8eaa28ea601ce7ac39c0566
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
    oc02:
      checksum: 0b03381195ba613e0dd20e5d2683711e9d6082f0634bee7c54014de2eadf0fc9
      gitRevision: main/30746f9beb48d237b6c0e0357708b3ed1f95cd1b
  deviceStatusMap:
    oc01: Completed
    oc02: Completed
  phase: Healthy
  status: Completed      

DeviceRollout の管理はライフサイクル全体を通じて自動化されていますので、作成や変更を行う必要はありません。

Installing Device Driver and configuring Device Custom Resource

以降の記述は、getting-started チュートリアルで使用されているサンプルのKubernetesカスタムオペレータを使用した場合に限定した内容になります。 Kuestaを用いて制御したいターゲットデバイスと、その制御のために実装したKubernetesカスタムオペレータによって、詳細な手順は異なります。

OpenConfig over gNMIをサポートしているデバイスに設定を投入したい場合は、kuesta/device-operator で開発されているサンプルのKubernetesカスタムオペレータを利用できます。 このサンプルのKubernetesカスタムオペレータは基本的なOpenConfig YANGセットをサポートしているデバイスに特化していますが、OpenConfigスタイルに準拠しているYANGであれば任意に追加して拡張することが可能です。

このKubernetesカスタムオペレータは make コマンドもしくは kubectl/kustomize を直接実行することでインストールできますが、 Kuestaのインストールスクリプトを使用するのが一番簡単です。Kuestaのインストールスクリプトを実行すると getting-started という名前でkustomizeのオーバレイディレクトリが作成されますので、これをテンプレートとして自由にカスタムできます。

getting-started オーバレイディレクトリを用いてKubernetesカスタムオペレータをインストールするには、以下のコマンドを実行します:

export IMG=ghcr.io/nttcom/kuesta/device-operator:latest
export KUSTOMIZE_ROOT=overlays/getting-started
make deploy

Kuestaからデバイスに対して設定投入するためには、Kubernetesカスタムオペレータに加えて、各デバイスごとにカスタムリソースを作成する必要があります。 getting-startedチュートリアルでは、gNMIエミュレータ oc01 に対して以下のような OcDemo カスタムリソースを作成します。

apiVersion: kuesta.hrk091.dev/v1alpha1
kind: OcDemo
metadata:
  name: oc01
  namespace: kuesta-getting-started
spec:
  address: gnmi-fake-oc01.kuesta-getting-started
  port: 9339
  rolloutRef: kuesta-testdata
  tls:
    secretName: oc01-cert
    skipVerify: true

OcDemo リソースでは、設定投入を行うターゲットデバイスの接続情報、アドレス、ポート、ユーザ名とパスワード、TLS関連設定、などを定義します。 .spec.rolloutRef フィールドは、Flux source-controllerのGitOpsによって提供されるコンフィグの更新通知を、どの DeviceRollout から取得するかを指定するフィールドであり、必須項目です。 OcDemo リソースの .spec についてより詳細な情報が知りたければ、 kubectl explain ocdemo.spec を実行して確認してください。

3 - Concepts

Kuestaのコンセプト、アーキテクチャ、その他の技術関連情報について

CUEを用いた Network Configuration as Code

Kuestaは、複雑なネットワーク装置のコンフィグを抽象化し、ユーザのインテントを簡単に記述できる高レベルのデータモデルとAPIを公開することをサポートします。ネットワーク装置のデータモデルは、数多のネットワーキング機能を提供するために詳細かつ複雑であり、Infrastructure as Codeのリソースモデルとして扱うには適していません。ユーザのインテントを簡単に表現できるデータモデルを提供するためには、複雑さを隠蔽しわかりやすく抽象化した高レベルなデータモデルが必要です。加えて、E2E接続のようなドメイン全体を抽象化したモデルを実現するには、複数のネットワーク装置をまたいで設定を行うデータモデルが必要になります。

このような上位モデルへの抽象化を行うと、上位モデルから低レベルな装置コンフィグへのデータマッピングは非常に複雑になります。 上位モデルと下位モデルは多対多の関係性を持つため、データマッピングに加えてデータの合成も同時に行う必要があります。このとき、データの欠損や競合、データ制約違反を起こさないように配慮しなければなりません。 Python/Jinjaを用いたシンプルなテキストテンプレートのアプローチでは、この複雑な問題を解くのは困難です。

Kuestaでは、上位モデルから下位モデルへのデータマッピングロジックを記述するプログラミング言語としてCUE を採用しています。 CUEは、データの合成と検証に強みを持つコンフィグ記述言語であり、次のような理由から上記のユースケースに適しています。

  • CUEは、複数のドキュメントツリーを任意の階層で統一することを可能にします。CUEは、交換律と結合律を満たし、冪等な演算が可能という特徴があり、データを合成する順序によらず、必ず同じ結果になるように設計されています。
  • CUEは、型と値を同一のものとして扱います。型とデータ制約も値の一種であり、両者の違いは具体的な値を持つか否かだけです。この新しいアプローチにより、コンフィグを記述するのと同時にスキーマとデータ制約と記述でき、シンプルかつ効率的に扱えます。
  • CUEは高いプログラマビリティを有しており、テンプレート化やモジュール化といったソフトウェアコーディングのプラクティスをサポートしています。汎用的な言語を使うのと同じようなメリットが得られます。

CUEの詳細についてより知りたければ、“cuelang.org” を参照してください。

GitOps

Kuestaは、ネットワーク装置コンフィグのためのGitOpsを提供します。ネットワーク全体のコンフィグを宣言的に記述し、Gitリポジトリでバージョン管理し、信頼できる唯一の情報源(Single Source of Truth: SSoT) とすることを目的としています。 コンフィグ設定プロセスは完全に自動化されており、Gitリポジトリのバージョンを指定することで、そのバージョンのコンフィグがネットワーク装置に自動で設定されます。 ネットワークの構成切り替えやロールバックをするには、GitブランチのHEADをデプロイしたいバージョンに変更するだけです。

Kuestaは、以下の理由からPullベースのアプローチを選択しています。

  • ネットワーク装置の設定が更新されるたびに、バージョン指定されたデプロイされるべき設定と、実際のネットワーク装置の設定との間のずれを検出するため。
  • SSoTのGitリポジトリに保存されているネットワーク全体のコンフィグが、あらかじめ整備されたデプロイパイプラインにより画一的に設定されることで、コンフィグの加工処理を挿入することなくネットワーク装置にデプロイされることを保証するため。
  • すべてのネットワーク装置のクレデンシャルが集約されることで設定システムの権限が過度に強力になり、セキュリティリスクが高まるのを避けるため。Kuestaではネットワーク装置のクレデンシャルはKubernetes Secretリソースとして保存されるため、ExternalSecrets OperatorなどのOSSツールを使ってパブリッククラウドのSecretManagerと統合し、セキュアにこれらのクレデンシャルを管理することができます。

GitOpsの詳細については、 “What is GitOps?” をご覧ください。

Kubernetesカスタムオペレータ

Kuestaは、Infrastructure as Codeを実現するエンジンとして、Kubernetesの「Reconciliation loop」と「Operatorパターン」を使用しています。 Kubernetesはコンテナのオーケストレーションツールとして有名ですが、あらゆる外部リソースのデプロイを自動化するために拡張することができます。ネットワーク装置も例外ではありません。 Kuestaは、複数のKubernetesカスタムオペレータで構成されており、それぞれGitOpsを行うためのエンジン、マルチデバイス間の分散トランザクションコーディネータ、ネットワーク装置を設定するためのドライバなどの役割を担っています。

新しいベンダーのデバイスや新しいバージョンのネットワーク装置をKuestaでサポートしたい場合は、対応するKubernetesカスタムオペレータを開発することで実現できます。

Kuestaのコンポーネント

Kuestaは以下のコンポーネントから構成されています。

  • kuesta-server は、KuestaのコアとなるAPIサーバです。外部のサードパーティシステムと連携するためにgNMIを公開し、上位モデルから下位モデルへのデータマッピングとデータ合成を行い、GitOpsのために新しいGitコミットを作成やプルリクエストの発行などを行います。

  • kuesta-aggregator は、ネットワーク装置の実際のコンフィグの変更を集約し、Gitコミットを作成して、設定変更の履歴をGitレポジトリに永続化します。

  • FluxCD source-controller は、GitRepository Kubernetesカスタムリソースで指定されたGitリポジトリにおけるマニフェストの変更を検出します。

  • kuesta-provisioner は、gitrepository-watcher コントローラと DeviceRollout Kubernetesカスタムリソースで構成されています。 gitrepository-watcherGitRepository の状態を監視してマニフェストの変更を検出し、変更が検出されると DeviceRollout のステータスをランニングに更新し、ネットワーク装置のコンフィグ更新のトランザクションをトリガします。

Kuestaを使用してネットワーク装置に設定をするには、対象となるネットワーク装置に設定を行うためのKubernetesカスタムオペレータを独自に用意する必要があります。Kubernetesカスタムオペレータを開発する際は、強力なフレームワークである kubebuilder を使用することがお勧めです。 また、“Getting started” で使用した device-operator は、OpenConfig/gNMIデバイスを設定するために設計されたKubernetesカスタムオペレータのサンプルであり、これをベースに開発を始めることも可能です。この開発でもkubebuilderが使用されています。

4 - Guides

作成中です。

5 - CLI

kuesta CLIの使い方

Kuestaでは、コンフィグIaCを更新する方式として、kuesta-serverを使ってAPI経由で更新する方式と kuesta CLIを用いる方式をサポートしています。 kuesta CLIは、 Kuestaを用いつつも手動でコンフィグレポジトリの管理をしたい場合や、GitHub ActionsやGitHub Appsなどと連携してCIを構成する場合に役立ちます。

インストール

Kuestaのtarファイルを、 kuesta Releases page からダウンロードしてください。 ダウンロードできたら展開して、PATHが通っているディレクトリに実行バイナリを配置してください。

# Replace YOUR-DOWNLOADED-FILE with the file path of your own.
sudo tar xvzf YOUR-DOWNLOADED-FILE -C /usr/local/bin/ kuesta

ソースコードからビルド

kuesta CLIをソースコードからビルドしたい場合は、Go1.18以上を用いた開発環境をセットアップしたのち、以下のコマンドを実行してください。

git clone https://github.com/nttcom/kuesta.git
cd kuesta
go build -o kuesta main.go

その後、ビルドされたバイナリをPATHが通っているディレクトリに配置してください。

使い方

kuesta-serverを使用せずに、kuesta CLIを用いてコンフィグIaCを更新するには、以下のステップを実行してください。

1: ネットワークコンフィグを管理しているGitHubマニフェストレポジトリを、クローンしてください。

2: Serviceコンフィグを更新してください。

3: 更新したServiceに git add を実行し、インデックスに追加してください。

4: Serviceコンフィグからネットワーク装置のコンフィグに変換するために、 kuesta service apply を以下の通り実行してください。

kuesta service apply -p=<path_to_config_repo_root>

Serviceコンフィグからネットワーク装置へのコンフィグ変換は、インデックスに追加されているServiceに限定して実行されます。 インデックスに追加されていないServiceの変更は全てスキップされます。

5: GitHubマニフェストレポジトリ上でプルリクエストを作成するために、 kuesta git commit を以下の通り実行してください。 もしgitプロバイダへの認証が必要な場合は、コマンドラインオプション --git-tokenKUESTA_GIT_TOKEN を用いて、認証済のアクセストークンを指定してください。

kuesta git commit -p <path_to_config_repo_root> -r <config_repo_url> 

その他の利用可能なコマンドや、コマンドラインオプションに関するより詳細な情報が知りたい場合は、 kuesta help を実行してください。

6 - Reference

Kuestaの参考情報

7 - Contribution Guidelines

How to contribute to Kuesta

Kuesta is an open source project and we love getting patches and contributions to make Kuesta and its docs even better.

Contributing to Kuesta

Creating PullRequest

All submissions, including submissions by project members, require review. We use GitHub PullRequest for this purpose. Consult GitHub Help for more information on using pull requests.

Creating issues

If you have found something that isn’t working the way you’d expect, but you’re not sure how to fix it yourself, please create an issue.

How to run the test suites

To run the whole test suites of all kuesta components:

make test-all

To run the specified component test suites only, run the following at the top of the component dir:

make test

For lint, install golangci-lint in advance, then run at the top of kuesta repo:

make lint-all

If you want to run Kuesta locally, see “Installtaion” page.