OpenBaoのトラブルシューティング
- プラン: Premium、Ultimate
- 提供形態: GitLab Self-Managed
- ステータス: ベータ版
リカバリーキーのタスクとブレークグラスルートトークンについては、リカバリーキー管理を参照してください。Geoフェイルオーバーについては、Geoディザスターリカバリーを参照してください。
OpenBaoの実行場所
GitLabがLinuxパッケージを使用している場合でも、OpenBaoは常にKubernetesで実行されます。ネームスペースとデプロイ名はインストール方法によって異なります:
| インストール方法 | ネームスペース | デプロイ | ポッドコンテナ |
|---|---|---|---|
| クラウドネイティブGitLab | gitlab | gitlab-openbao | openbao-server |
| Linuxパッケージ | openbao | openbao | openbao-server |
これらの例では、クラウドネイティブネームスペースgitlabを使用しています。Linuxパッケージインストールの場合、kubectlコマンドでgitlabをopenbaoに置き換えてください。
OpenBaoポッドはラベルapp.kubernetes.io/name=openbaoを持ちます。アクティブノードもopenbao-active=trueを持ちます。
OpenBaoログの検索
kubectl logsでOpenBaoのログを読み取ります。関連するGitLab RailsおよびSidekiqログは、インストール方法に応じて個別に保存されます:
| ソース | クラウドネイティブGitLab | Linuxパッケージ |
|---|---|---|
| OpenBaoサーバー | openbao-serverコンテナ上のkubectl logs | openbao-serverコンテナ上のkubectl logs |
| GitLab Rails | webserviceポッド上のkubectl logs | /var/log/gitlab/gitlab-rails/production_json.log |
| Sidekiq | sidekiqポッド上のkubectl logs | /var/log/gitlab/sidekiq/current |
| GitLab Runner | GitLab UIのCI/CDジョブログ | GitLab UIのCI/CDジョブログ |
OpenBaoは監査イベントをGitLabにポストし、OpenBaoポッドログにも書き込みます。
OpenBaoポッドを見つける
OpenBaoポッドをリストし、どのアクティブノードであるかを確認するには:
kubectl get pods -n gitlab -l app.kubernetes.io/name=openbao \
--label-columns openbao-active,openbao-sealedOPENBAO-ACTIVEがtrueに設定されているポッドがアクティブノードです。その他はスタンバイノードです。
OpenBaoステータスを確認する
OpenBaoはリクエストを処理するためにアンシールされている必要があります。確認するには、ポッドでbao statusを実行します:
OPENBAO_POD=$(kubectl get pods -n gitlab -l app.kubernetes.io/name=openbao -o name | head -1)
kubectl exec -n gitlab "$OPENBAO_POD" -c openbao-server -- \
sh -c "BAO_ADDR=http://127.0.0.1:8200 bao status"出力では、Sealedはfalseである必要があります。アクティブノードはHA Mode activeを表示し、スタンバイノードはHA Mode standbyを表示します:
Seal Type static
Initialized true
Sealed false
Storage Type postgresql
HA Enabled true
HA Mode activesys/seal-statusエンドポイントは"sealed":falseと同じ状態を報告します:
kubectl exec -n gitlab "$OPENBAO_POD" -c openbao-server -- \
sh -c "BAO_ADDR=http://127.0.0.1:8200 bao read sys/seal-status"baoバイナリはポッド内に存在します。ポッド内からのエンドポイントクエリにはbao readを使用します。
ログでは、アンシールに成功したノードはvault is unsealedをログに記録します。アクティブノードはacquired lock, enabling active operationをログに記録し、スタンバイノードはentering standby modeをログに記録します:
OPENBAO_POD=$(kubectl get pods -n gitlab -l app.kubernetes.io/name=openbao -o name | head -1)
kubectl logs -n gitlab "$OPENBAO_POD" -c openbao-server \
| grep -E "acquired lock, enabling active operation|entering standby mode"時間枠内のエラーの検索
時間枠からOpenBaoログを読み取るには、--sinceを使用します:
OPENBAO_POD=$(kubectl get pods -n gitlab -l app.kubernetes.io/name=openbao -o name | head -1)
kubectl logs -n gitlab "$OPENBAO_POD" -c openbao-server --since=30m \
| grep -iE "error|warn|failed"Linuxパッケージインストールの場合、RailsおよびSidekiqログファイルを時間で検索します。ログはJSON形式で、1行に1つのイベントがあります。
OpenBaoはすべての出力を標準エラーに書き込むため、一部のログプラットフォームではすべての行をエラーとしてタグ付けします。プラットフォームのラベルではなく、メッセージ本文のレベル([info]、[warn])を信頼してください。
GitLab Railsログ
Railsログには、UIおよびGraphQL APIからのシークレット操作と、OpenBaoからの監査コールバックが含まれます。
クラウドネイティブインストールの場合:
kubectl logs -n gitlab -l app=webservice -c webservice \
| grep -E "Projects::SecretsController|Groups::SecretsController|secrets_manager/audit_logs"Linuxパッケージインストールの場合:
grep -E "Projects::SecretsController|Groups::SecretsController|secrets_manager/audit_logs" \
/var/log/gitlab/gitlab-rails/production_json.logGraphQL操作は、caller_id(graphql:createProjectSecretやgraphql:getGroupSecretsなど)とともに表示されます。監査コールバックはパス/api/v4/internal/secrets_manager/audit_logsとして表示されます。
Sidekiqログ
プロビジョニング、デプロビジョニング、およびシークレットマネージャーレコードを維持するワーカーは、SecretsManagement::ネームスペースの下で実行されます。
クラウドネイティブインストールの場合:
kubectl logs -n gitlab -l app=sidekiq -c sidekiq | grep "SecretsManagement::"Linuxパッケージインストールの場合:
grep "SecretsManagement::" /var/log/gitlab/sidekiq/currentプロビジョニングの問題については、ProvisionProjectSecretsManagerWorkerまたはProvisionGroupSecretsManagerWorkerでフィルタリングしてください。
Runnerログ
CI/CDジョブがシークレットのフェッチに失敗すると、原因はGitLab UIのジョブログに表示されます。これらの文字列についてジョブログを検索します:
| 文字列 | 意味 |
|---|---|
Resolving secrets | Runnerはジョブのシークレットの解決を開始しました。 |
Using "gitlab_secrets_manager" secret resolver | RunnerはGitLab Secrets Managerリゾルバーを選択しました。 |
not initialized or sealed Vault server | OpenBaoはシールされているか、初期化されていません。 |
api error: status code 403: permission denied | OpenBaoはリクエストを拒否しました。これは多くの場合、オーディエンスまたは権限の問題です。 |
inline auth JWT is required | Runnerは認証リクエストをビルドできませんでした。 |
正常な起動ログ
再起動後、アクティブノードはこのシーケンスをログに記録します。スタンバイノードはvault is unsealedで停止し、その後entering standby modeをログに記録します。行形式は設定によって異なるため、プレフィックスではなくメッセージテキストを照合してください。
| ログメッセージ | 意味 | 不足している場合 |
|---|---|---|
==> OpenBao server started! | プロセスが開始され、設定が読み込まれました。 | ポッドの起動に失敗しました。ポッドイベントを確認してください。 |
vault is unsealed | 自動アンシールに成功しました。 | 自動アンシールに失敗しました。アンシールシークレットまたはKMSを確認してください。 |
acquired lock, enabling active operation | このノードがアクティブになりました。 | アクティブなノードはありません。データベースとHAロックを確認してください。 |
post-unseal setup complete | アクティブノードがセットアップを完了しました。 | セットアップが完了しませんでした。データベース接続を確認してください。 |
エラーメッセージ
OpenBaoメッセージはopenbao-serverコンテナから発信されます。GitLabメッセージはRailsまたはSidekiqログから発信されます。
| コンテナ | メッセージ | 説明 | アクション |
|---|---|---|---|
openbao-server | cipher: message authentication failed | シールキーが保存されているデータを復号化できません。 | 静的アンシールの場合は、プライマリサイトからアンシールシークレットをコピーしてください。KMSシールの場合は、KMSキーを確認してください。Geoデプロイのトラブルシューティングを参照してください。 |
openbao-server | unknown key ID | 静的アンシールキーIDがデータベースのデータと一致しません。 | プライマリサイトからアンシールシークレットをコピーしてください。Geoデプロイのトラブルシューティングを参照してください。 |
openbao-server | failed to acquire lock | スタンバイノードは読み取り専用データベースのHAロックを取得できません。 | Geoセカンダリでは予期された動作です。アクションは不要です。 |
openbao-server | cannot execute INSERT in a read-only transaction | スタンバイノードが読み取りレプリカへの書き込みを試行しました。 | Geoセカンダリでは予期された動作です。それ以外の場合は、OpenBaoがデータベースへの書き込みアクセス権を持っていることを確認し、データベースのアクセス許可を確認してください。 |
openbao-server | post-unseal upgrade seal keys failed: error="no recovery key found" | リカバリーキーが一度も保存されていませんでした。 | 無害です。recovery_key:storeを実行します。 |
| RailsまたはSidekiq | [OpenBao] health check returned unhealthy | OpenBaoは応答しましたが、異常な状態を報告しました。 | bao statusとOpenBaoログを確認してください。 |
| RailsまたはSidekiq | [OpenBao] health check failed | GitLabはOpenBaoに接続できませんでした。 | 接続を確認してください。GitLabがOpenBaoに接続できないを参照してください。 |
| RailsまたはSidekiq | Failed to authenticate with OpenBao | OpenBaoはJWTを拒否しました。 | オーディエンスを確認してください。JWT認証に失敗するを参照してください。 |
| RailsまたはSidekiq | Failed to open TCP connection to <host>:443 (execution expired) | SidekiqがOpenBao URLに到達できませんでした。 | SidekiqポッドからDNSとOpenBao URLを確認してください。 |
| RailsまたはSidekiq | SSL_connect ... state=error: wrong version number | https URLがhttpを提供するOpenBaoリスナーを指しています。 | URLスキームをリスナーと一致させてください。GitLabがOpenBaoに接続できないを参照してください。 |
| RailsまたはSidekiq | Retrying failed secrets_manager maintenance task | プロビジョニングまたはデプロビジョニングタスクが再試行されています。 | 同じログ内のワーカーエラーを確認してください。再試行は3回後に停止します。 |
シークレットマネージャーがプロビジョニングでスタックする
シークレットマネージャーを有効にすると、切替はprovisioningのステータスで読み込み状態のままになることがあります。シークレットマネージャーにはfailed状態がないため、アクティベーション前に失敗したステップはレコードをスタックさせます。通常、原因はSidekiqがOpenBaoに到達できないことです。
診断するには:
プロビジョニングワーカーのSidekiqログを確認してください:
kubectl logs -n gitlab -l app=sidekiq -c sidekiq \ | grep -E "ProvisionProjectSecretsManagerWorker|ProvisionGroupSecretsManagerWorker"Sidekiqポッドまたはノードから、SidekiqがOpenBaoに到達できるかテストしてください:
curl "https://openbao.example.com/v1/sys/health"
メンテナンスワーカーは古いタスクを最大3回再試行し、その後停止します。その後、レコードは自動リカバリーなしでprovisioning状態のままになり、再試行ログにはRetrying failed secrets_manager maintenance taskと表示されます。
接続を修正した後、シークレットマネージャーを無効にしてから再度有効にして、再度プロビジョニングします。
自己初期化後に認証マウントが見つからない
複数のOpenBaoポッドがある新規インストールでは、自己初期化の競合により、OpenBaoがアンシールされていてもgitlab_rails_jwt/認証マウントなしで残されることがあります。ポッドは正常に見えますが、シークレット操作は権限拒否で失敗します。マウントが存在することを確認するために、ルートトークンを使用してbao auth listを実行します。競合を防ぐために、単一レプリカで新規インストールを開始し、初期化が完了することを確認してからスケールアップします。
GitLabがOpenBaoに接続できない
GitLab RailsおよびSidekiqはHTTP経由でOpenBaoに接続します。Railsはinternal_urlを使用し、internal_urlが設定されていない場合はurlにフォールバックします。設定を検査するには、Railsコンソールでこれを実行します:
Gitlab.config.openbao.to_h一般的な原因:
https://URLがhttpを提供するOpenBaoリスナーに対して機能するとwrong version numberで失敗します。global.openbao.httpsはGitLabが接続するスキームを設定し、OpenBaoリスナーTLSは設定しません。リスナーはデフォルトでプレーンHTTPを提供します。一致させるにはglobal.openbao.httpsを設定しないままにするか、openbao.config.tlsDisable: falseでリスナーTLSを有効にし、global.openbao.httpsをtrueに設定してください。- OIDC検出および監査ログ記録は、信頼されていないTLS証明書のために失敗します。GitLabが信頼する証明書を使用してください。
- OpenBao監査イベントを生成しないリクエストは、認証バックエンドに到達しませんでした。Ingressまたはリバースプロキシを確認してください。
クラウドネイティブインストールの場合、機能する設定は次のようになります:
global:
openbao:
enabled: true
url: http://gitlab-openbao-active:8200
internal_url: http://gitlab-openbao-active:8200Linuxパッケージインストールの場合、GitLabは/etc/gitlab/gitlab.rbのgitlab_rails['openbao']['url']設定を使用してOpenBaoに接続します。バンドルされたNGINXリバースプロキシは、oak['components']['openbao']設定でOpenBaoにルーティングします。詳細については、Linuxパッケージデプロイ用のOpenBaoのインストールを参照してください。
JWT認証に失敗する
GitLabはJWTでOpenBaoを認証します。JWTのaud(オーディエンス)クレームは、OpenBao認証ロールのbound_audiences値と完全に一致する必要があります。末尾のスラッシュ、httpとhttpsの比較、またはポートなどの違いがあると、認証に失敗します。
OpenBaoは、初期化時にOpenBao URLから派生したbound_audiencesを保存します。保存された値は、後でURLを変更しても変更されません。したがって、URLを変更すると、保存されたbound_audiencesがGitLabが送信するaudと一致しなくなるため、認証が機能しなくなります。接続URLとは独立してオーディエンスを設定するには、global.openbao.jwt_audienceを使用します。
GitLabが送信するオーディエンスを見つけるには、Railsコンソールでこれを実行します:
SecretsManagement::ProjectSecretsManager.jwt_audienceこのメソッドは、jwt_audienceが設定されていない場合はOpenBaoのurlを、そうでない場合は設定済みのjwt_audienceを返します。保存された値を検査するには、ルートトークンで認証ロールを読み取り、bound_audiencesをそのオーディエンスと比較してください。
特権アクセスなしではこれを修正することはできません。ルートトークンは自己初期化後に失効され、アンシールキーは代替ではありません。アンシールシークレットにはアンシールキーのみが含まれ、ルートトークンは含まれません。
保存されたシークレットを削除せずに不一致を修正するには、リカバリーキーで認証を再設定します。手順については、リカバリーキーで認証を再設定を参照してください。
リカバリーキーがない場合は、OpenBaoデータをリセットしてください。これにより、保存されているすべてのシークレットが削除されます。
OpenBaoポッドがシールされる
起動時にbao statusがSealed trueと報告された場合、自動アンシールに失敗しました:
- デフォルトの静的アンシールでは、通常、原因はアンシールシークレットの欠落または誤りです。シークレットはクラウドネイティブインストールでは
gitlab-openbao-unseal、Linuxパッケージインストールではopenbao-static-unsealです。 - KMS自動アンシール(現在のところAWS KMS (
awskms))では、通常、OpenBaoがKMSに到達できないことが原因です。
シールのステータスを確認するには、OpenBaoステータスを確認を参照してください。
以前のキーを保持せずに静的アンシールキーをローテーションすると、OpenBaoは既存のデータを復号化できません。以前のキーを新しいキーと並行して追加し、すべてのポッドが新しいキーで実行されるようになってから削除してください。
データベースの問題
OpenBaoには独自のPostgreSQLデータベースが必要です。GitLabチャートは、専用のデータベースなしでOpenBaoを有効にした場合、インストールまたはアップグレードに失敗します。
その他のデータベースの問題:
- 接続プール枯渇または高いレイテンシーは、間欠的なタイムアウトを引き起こします。
- LinuxパッケージPostgreSQL設定で誤った
md5_auth_cidr_addresses、sslMode、またはパスワード値が設定されていると、OpenBaoポッドはCrashLoopBackOff状態になります。正しい設定については、Linuxパッケージデプロイ用のOpenBaoのインストールを参照してください。
監査イベントが不足している
OpenBaoは/api/v4/internal/secrets_manager/audit_logsに監査イベントをGitLabにポストします。GitLabチャートは、デフォルトで監査ログ記録を有効にします。監査イベントが到達しない場合:
config.audit.http.enabledをfalseに設定すると、OpenBaoがイベントをポストしなくなります。監査ログ記録が有効になっていることを確認してください。- 共有監査ログトークンの不一致は、監査イベントエンドポイントで
401を返します。GitLabとOpenBaoが同じ監査ログトークンを使用していることを確認してください。
Geoデプロイのトラブルシューティング
OpenBaoはプライマリGeoサイトでアクティブノードとして、各セカンダリサイトでスタンバイノードとして実行されます。セカンダリノードは読み取り専用のPostgreSQLレプリカに接続するため、failed to acquire lockとcannot execute INSERT in a read-only transactionをログに記録します。これらのメッセージは予期されたものです。
セカンダリノードがcipher: message authentication failedまたはunknown key IDをログに記録する場合、そのシールキーはプライマリと一致しません。修正はシールメカニズムによって異なります:
静的アンシールの場合、プライマリクラスターから
gitlab-openbao-unsealシークレットをセカンダリクラスターにコピーし、OpenBaoポッドを再起動してください:kubectl -n gitlab get secret gitlab-openbao-unseal -o yamlKMSシールの場合、両方のサイトで同じKMSキーを使用するように設定します。
フェイルオーバー後にJWT認証に失敗した場合、オーディエンスが保存されているbound_audiencesと一致しなくなります。修正はドメインによって異なります:
- 両方のサイトがプライマリOpenBao URLを使用する場合、両方のサイトで
jwt_audienceをプライマリOpenBao URLに設定します。セカンダリサイトへのOpenBaoのインストールを参照してください。 - セカンダリサイトが異なるドメインを使用する場合、この設定はサポートされていません。オーディエンスを再設定しても認証は復元されません。これは、すべてのプロジェクトおよびグループネームスペースも再プロビジョニングする必要があるためです。プライマリドメインが昇格されたセカンダリを指すようにDNSを更新してください。詳細については、Geoデプロイを参照してください。
遅いシークレット操作を診断する
CI/CDジョブのシークレットのフェッチが遅い場合や、シークレット操作がタイムアウトする場合は、以下のクエリを使用して原因を特定してください。これらのクエリを、OpenBaoメトリクスをスクレイプするPrometheusまたはGrafanaインスタンスで実行します。これらのメトリクスを公開するには、OpenBaoメトリクスを参照してください。
レイテンシーが高いことを確認する
平均要求レイテンシーをミリ秒単位で測定するには、次のクエリを使用します。このクエリは、低トラフィックデプロイを含むあらゆるトラフィックレベルで機能します:
rate(openbao_core_handle_request_sum[5m])
/
rate(openbao_core_handle_request_count[5m])通常負荷では、すべてのリクエストタイプの平均レイテンシーは通常3〜7ミリ秒です。平均レイテンシーが継続的に20ミリ秒を超える場合は調査してください。
OpenBaoがアクティブに処理中のリクエストの場合は、P99レイテンシーに次のクエリを使用します:
openbao_core_handle_request{quantile="0.99"}通常のP99は10ミリ秒未満です。OpenBaoがアイドル状態の場合、サマリーウィンドウに最近の観測がないため、このクエリはNaNを返します。その場合はレートベースのクエリを使用してください。
潜在的な問題を特定する
| 潜在的な問題 | 確認事項 | クエリ | しきい値 | アクション |
|---|---|---|---|---|
| CPU制限が低すぎる | CFSスロットル比 | CPUスロットリングクエリ | 25%超 | CPU制限を増やす |
| 需要がCPU容量を超える | CPU使用率 | CPU使用率クエリ | リクエストの50%超 | サイジングテーブルの次の行にスケールする |
| リクエストの急増 | 処理中のリクエスト | openbao_core_in_flight_requests | 5を継続的に超える | 一時的。再発を監視する。 |
| PostgreSQLボトルネック | 平均PostgreSQL読み取りレイテンシー | rate(openbao_postgres_get_sum[5m]) / rate(openbao_postgres_get_count[5m]) | 5ミリ秒超 | PostgreSQLリソースと接続プールを確認 |
| メモリ負荷 | メモリ使用率 | メモリ使用率クエリ | メモリリクエストに近い | ネームスペース数式を使用してメモリを増やす |
PostgreSQLのレイテンシーが上昇している場合は、接続プールが飽和しているかどうかを確認してください。すべての接続がビジー状態の場合、追加のリクエストがキューに入れられ、レイテンシーが発生します。接続プールの設定については、データベースリソースを参照してください。