Backstageとは
Backstageとは元はSpotifyが開発したOSSで、オフィシャルドキュメントを引用すると、
Backstage は、開発者ポータルを構築するためのオープンプラットフォームです。一元化されたソフトウェア・カタログを搭載したBackstageは、マイクロサービスやインフラの秩序を回復し、製品チームが自律性を損なうことなく、高品質のコードを迅速に出荷することを可能にします。
とあり、開発者向けのポータルを提供してくれることが分かる。
主要な機能は以下となる。
今回はBackstageを起動し、ソフトウェアカタログの機能からKubernetesのリソースの状態を取得してみる。
検証環境
今回は以下の環境で試している。
- Backstageの動作環境:Ubuntu 20.04.6 LTS
- ソースコード置き場:GitHub
- Kubernetes:EKS
事前準備
GitHubとの連携
公式ドキュメントはこちら。
OAuthを使ってGitHubと認証してソースコードを取得する。
最初にGitHubのClient IDとClient Secretを取得する。
アカウントのSettings
->Developer settings
->OAuth Apps
からNew OAuth App
を選択し、
以下のような感じでOAuth applicationを作成する。
IPはBackstageを起動するホストのIPとなる。IPやPortの部分は各自の環境に置き換えること。localhost
で実行する場合はlocalhost
にして問題ない。
以下コピペ用。
Homepage URL: http://localhost:3000
Authorization callback URL: http://localhost:7007/api/auth/github/handler/frame
作成後、Client Secretを作成し、Client IDと一緒に環境変数に設定しておく。
export AUTH_GITHUB_CLIENT_ID=xxxxx
export AUTH_GITHUB_CLIENT_SECRET=xxxxx
Databaseの用意
DBなしでも利用できるが、起動し直すたびにデータが消えるので、DBは用意しておいた方がいい。
こちらの記事のdocker-compose.ymlを利用させていただき、以下のような感じで起動しておく。
docker compose up -d
無事起動したら、以下の環境変数を設定しておく。
export POSTGRES_HOST=<ホストのIPアドレス>
export POSTGRES_PORT=5432
export POSTGRES_USER=postgres
export POSTGRES_PASSWORD=postgres
なお、ここのPOSTGRES_HOST
のIPはGitHubのapplicationで指定したIPと一致させておいた方がいい。
Backstageのインストール
前提パッケージを入れる。Node.jsはv16かv18じゃないと上手く動かないっぽいので注意。
sudo apt-get update -y
sudo apt install npm -y
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\
sudo apt-get install -y nodejs
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt update && sudo apt install yarn
インストールする。
npx @backstage/create-app@latest
なお、前提パッケージが不足していると以下のようなエラーでコケる。
npx: installed 70 in 6.005s
TypeError: this.breakLines(...).flat is not a function
前提パッケージが足りていれば、以下のような感じでappの名前を聞かれる。
$ npx @backstage/create-app
? Enter a name for the app [required]
ここではGetting Startedにあわせてmy-backstage-app
を入力した。
この後少し待つと(自環境では5分くらい掛かった)、以下のようなメッセージが出てインストールが完了する。
🥇 Successfully created my-backstage-app
指定したappの名前でディレクトリが作成されているので、移動する。
cd my-backstage-app/
デフォルトではfrontendをlocalhost:3000で公開する。これをIPによるアクセスに変更したいため設定ファイルを変更する。設定ファイルはapp-config.yamlという名前でディレクトリ内に配置されている。以下の3箇所を変更する。
app:
baseUrl: http://10.151.195.88:3000
backend:
baseUrl: http://10.151.195.88:7007
cors:
origin: http://10.151.195.88:3000
変更後、Backstageを起動する。
yarn dev
ブラウザでbaseUrlに指定したURLにアクセスすると、以下のような画面が表示される。
一度止めて、
- GitHubの認証情報の設定
- Postgresの設定
をapp-config.yaml
に追加する。
GitHubの認証情報の設定内容は以下。
auth:
environment: development
providers:
github:
development:
clientId: ${AUTH_GITHUB_CLIENT_ID}
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
Postgresの設定内容は以下。
backend:
database:
- client: better-sqlite3
- connection: ':memory:'
+ client: pg
+ connection:
+ host: ${POSTGRES_HOST}
+ port: ${POSTGRES_PORT}
+ user: ${POSTGRES_USER}
+ password: ${POSTGRES_PASSWORD}
追記後、再度yarn dev
で起動し直す。
動作確認
適当なGitHubのリポジトリを作成し、それをカタログに追加してみる。
Backstage起動後、右上のCREATE
をクリックし、REGISTER EXISTING COMPONENT
をクリックする。
Select URL
では本来はカタログを定義したyamlのパスを指定するが、初回はそのyamlがないので、リポジトリのURLを指定しANALYZE
をクリックする。
Entity Owner
はguests
が選べるのでこちらを選択し、CREATE PR
をクリックすると、Pull Requestが発行されるのでMergeすると、catalog-info.yamlがpushされる。
Kubernetes Pluginの動作確認
BackstageのPluginは非常に種類が豊富である。
ここではKubernetes Pluginを試してみる。
Kubernetes Pluginのインストール
オフィシャルサイトはこちら。
Pluginをインストールする。
yarn add --cwd packages/app @backstage/plugin-kubernetes
エンティティのページを修正する。
packages/app/src/components/catalog/EntityPage.tsx
をエディタで開き、以下を追加する。
import { EntityKubernetesContent } from '@backstage/plugin-kubernetes';
また、既存のserviceEntityPage
に以下のように追加する。
const serviceEntityPage = (
<EntityLayout>
{/* other tabs... */}
+ <EntityLayout.Route path="/kubernetes" title="Kubernetes">
+ <EntityKubernetesContent refreshIntervalMs={30000} />
+ </EntityLayout.Route>
</EntityLayout>
);
これにより、該当するカタログがKubernetesリソースを持っている場合、以下の様にタブが表示されるようになる。
なお、パラメータのrefreshIntervalMs
の意味はコンテンツの自動更新の間隔で設定しない場合は10秒になる模様。
次にバックエンド側にもPluginを追加する。
Pluginをインストールする。
yarn add --cwd packages/backend @backstage/plugin-kubernetes-backend
KubernetesのバックエンドのPluginを呼び出すファイルを作成する。
cat << EOF > ./packages/backend/src/plugins/kubernetes.ts
import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend';
import { Router } from 'express';
import { PluginEnvironment } from '../types';
import { CatalogClient } from '@backstage/catalog-client';
export default async function createPlugin(
env: PluginEnvironment,
): Promise<Router> {
const catalogApi = new CatalogClient({ discoveryApi: env.discovery });
const { router } = await KubernetesBuilder.createBuilder({
logger: env.logger,
config: env.config,
catalogApi,
permissions: env.permissions,
}).build();
return router;
}
EOF
バックエンドのindex.tsにKubernetesプラグインを利用するよう修正する。
packages/backend/src/index.ts
をエディタで開いて以下を追加する。
import kubernetes from './plugins/kubernetes';
次に同じファイルのmain
の中で以下を追加する。
async function main() {
// ...
+ const kubernetesEnv = useHotMemoize(module, () => createEnv('kubernetes'));
// ...
+ apiRouter.use('/kubernetes', await kubernetes(kubernetesEnv));
クラスタ情報の設定(app-config.yaml)
後ほどKubernetes Pluginを使った検証を行うために、EKSとの連携設定を入れる。
公式ドキュメントで設定方法が見つけられず、stackoverflowのこちらを参考にした。
EKSにコンテキストをあわせ、kubectl cluster-info
でクラスタのエンドポイントのURLを取得する。
$ kubectl cluster-info
Kubernetes control plane is running at https://xxxxxxxxxx.gr7.us-east-1.eks.amazonaws.com
取得したURLを使ってapp-config.yaml
に設定を追記する。以下のurl
、name
を自環境のものに修正する。また、環境変数AWS_ACCESS_KEY_ID
とAWS_SECRET_ACCESS_KEY
を使っていない場合はexportしておく。
kubernetes:
serviceLocatorMethod:
type: 'multiTenant'
clusterLocatorMethods:
- type: 'config'
clusters:
- url: https://xxxxxxxxxx.gr7.us-east-1.eks.amazonaws.com
name: my-cluster-eks
authProvider: 'aws'
skipTLSVerify: true
skipMetricsLookup: true
auth:
environment: 'development'
providers:
aws:
development:
accessKeyId: ${AWS_ACCESS_KEY_ID}
secretAccessKey: ${AWS_SECRET_ACCESS_KEY}
設定後、backstageを再起動する。
動作確認
先程適当なGitHubリポジトリ内に作成したcatalog-info.yaml
を以下のように修正する。
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: hello-tanzu-backstage
annotations:
github.com/project-slug: imurata/hello-tanzu-backstage
+ 'backstage.io/kubernetes-label-selector': 'app=hello-tanzu-backstage'
spec:
- type: other
+ type: service
lifecycle: unknown
owner: guests
上記の設定により、labelにapp=hello-tanzu-backstage
を持つリソースはカタログ上で表示されるようになる。
また、type
を変更しないとカタログ上にKubernetesのタブが出てこないので、こちらも合わせて変更する。
なお、kind: Component
の説明はこちらを参照するとよい。
修正してpushしてしばらく待つと、カタログ上のtypeがserviceに書き換わる。
deploymentリソースをコマンドで作成した場合、自動的にapp=<deployment名>
でラベルが付与されるため、コマンドでリソースを作成してみる。
kubectl create deploy hello-tanzu-backstage --image nginx --replicas 3 -n demo
しばらく待つと、カタログのKUBERNETES
タブの中にラベルが一致するリソースの状態が出力される。
まとめ
BackstageのデプロイからKubernetes Pluginの導入まで体験し、クラスタ内のカタログに紐づくリソースが確認できるところまで確認できた。
導入の敷居が高いので、将来的に導入が楽になることを期待したい。