TECH PLAY

OpenShift

イベント

該当するコンテンツが見つかりませんでした

マガジン

該当するコンテンツが見つかりませんでした

技術ブログ

はじめに 前回はKubernetesのバックアップは、etcdとPV/PVCの二軸で、セットで行うことが重要であることを解説しました。しかし、ステートフルなアプリケーションのバージョンアップでは、データの互換性と整合性が課題となります。 本記事では、これらの複雑な課題を解消し、安全なリソースとデータのバックアップ・リストアを実現するソリューションである「Velero」について解説します。 Veleroの基本コンセプトとアーキテクチャ Velero(旧称 Heptio Ark)は、Kubernetesクラスターリソース(マニフェストファイル)と永続ボリューム(PV)のデータの両方をまとめてバックアップ/リストアを実現するツールです。 Kubernetesのバックアップでは、アプリケーションを構成するすべてのクラスターリソースをバックアップするだけでは不十分で、データ(永続ボリューム)も同時に保存する必要があります。これは、Veleroを使うことで実現可能です。 さらに、クラウドプロバイダーの変更やオンプレミスからクラウドへの移行、Kubernetesのメジャーバージョンアップに伴う新しいクラスターへのデータ移行といった複雑で時間がかかる作業もVeleroでは対応可能になります。 Veleroは以下の用途で利用できます。 クラスターのバックアップを取得し、データ損失が発生した場合にリストアを行う クラスターリソースを他のクラスターへ移行する 本番クラスターを開発/テストクラスターへ複製する Kubernetesのアップグレードなどのシステム操作を実行する前に、アプリケーションの状態をスナップショットする Veleroの主な特徴 クラスター内のすべてのオブジェクトをバックアップまたはリストアできる。オブジェクトタイプ、ネームスペース、ラベルによるフィルタリングも可能 バックアップ、リストア、スケジュールといったすべての操作の定義がKubernetesのカスタムリソースとして定義され、etcdに保存される クラウドプロバイダーまたはオンプレミスのKubernetes環境で動作可能 独自のカスタム機能をVeleroに追加できるプラグインシステムが提供されている PVのバックアップ方式 Veleroは、永続ボリューム(PV)のデータを保護するために、主に以下の3つの方式をサポートしています。ファイルシステムバックアップ(FSB)とスナップショットは、同一ボリュームに対して同時に実行されず、相互に排他的な関係になります。 方式 概要 主な用途 ボリュームスナップショット クラウドプロバイダー(AWS EBS, Azure Disk等)やCSIドライバーが提供するネイティブなスナップショット機能を利用する。 主要なクラウドプロバイダーやCSI準拠のストレージを利用している場合の標準的なデータ保護。 ファイルシステムバックアップ (FSB) Node Agent (Kopia Uploader) と呼ばれるDaemonSetが各ノードで稼働し、ボリュームのファイルシステムを直接読み取り、オブジェクトストレージにデータを保存する。 NFSのような共有ファイルシステムや、CSIドライバーが提供するスナップショット機能を持たないストレージのデータ保護。プロバイダー間の移行に利用可能。 CSIスナップショットデータムーバー CSIスナップショットで作成されたデータを、Node Agent経由でオブジェクトストレージに移動・コピーする。 クラウドプロバイダ間のデータ移行、オンプレミスからクラウドへのデータ移行、スナップショットデータの長期アーカイブ。 Veleroアーキテクチャ Veleroの主要リソースは以下の通りです。 バックアップ、リストア、スケジュールといった操作はクライアントのVelero CLIから実行します。 主要リソース 役割 実行環境 Velero サーバー メインコントロールプレーン。バックアップ/リストアのロジック、リソースの収集、オブジェクトストレージへの連携を担当する。 Kubernetesクラスター内のDeployment。 Node Agent ファイルシステムバックアップ(FSB)やCSIスナップショットデータムーバーなどのデータ転送を担う。 Kubernetesクラスター内のDaemonSet。 BackupStorageLocation (BSL) KubernetesリソースのメタデータやPVデータ(FSB/データムーバー利用時)の保存場所(オブジェクトストレージ)を定義する。 オブジェクトストレージ(AWS S3、Azure Blob、MinIOなど)。 VolumeSnapshotLocation (VSL) PVスナップショットの保存場所を定義。 CSIドライバー対応のスナップショットシステム。 バックアップのワークフロー VeleroによるKubernetesリソースと永続ボリュームのオンデマンドバックアップのワークフローは以下になります。 Image Source: https://velero.io/docs/v1.17/how-velero-works/ VeleroクライアントがKubernetes APIサーバーを呼び出してBackupオブジェクトを作成する BackupControllerが新しいBackupオブジェクトを認識して、検証を行う BackupControllerがバックアッププロセスを開始する。APIサーバーにリソースを照会してバックアップするデータを収集する 収集したオブジェクトをtar形式にアーカイブし、BackupControllerがオブジェクトストレージサービス(AWS S3など)を呼び出して、バックアップファイルをアップロードする 永続ボリューム(PV)が存在する場合、連携するストレージプロバイダのAPIを呼び出し、ボリュームのスナップショットを作成する フック(Backup Hooks)が設定されている場合、カスタムアクション処理の前(pre hook)または、すべてのカスタムアクション完了および追加アイテムのバックアップ完了後(post hook)に、Pod内のコンテナでコマンドが実行される スケジュールされたバックアップは、Cron式で指定された間隔で自動的に実行される Veleroのフック(Hook)機能とは? データベースのようなアプリケーションは、DBのバックアップ中にデータが書き換わると整合性が取れなくなる可能性があります。Veleroのフック(Hook)機能は、この問題を解決するために、バックアップ処理に合わせてコンテナ内で任意のコマンドを実行する機能です。例として、Veleroのフック機能は以下のようなことが可能です。 Pre-hook(直前):データの書き込みをロックし、静止点を作成 Post-hook(直後): バックアップ完了後にロックを解除し、通常稼働に復帰 Veleroでのリストア VeleroによるKubernetesリソースと永続ボリュームのリストアのワークフローは以下になります。 VeleroクライアントがKubernetes APIサーバーを呼び出してRestoreオブジェクトを作成する RestoreControllerが新しいRestoreオブジェクトを認識して、検証を行う RestoreControllerがオブジェクトストレージサービスからバックアップ情報を取得する。次に、バックアップされたリソースに対して前処理を行い、リソースが新しいクラスターで動作することを確認する RestoreControllerがリストアプロセスを開始する。依存関係を考慮した適切な順序で対象となるリソースが1つずつ復元される フック(Restore Hooks)が設定されている場合、以下のタイミングでリストアされるPod内のコンテナに対して実行される InitContainer:リストアされるPodにInitコンテナを追加して、アプリケーションコンテナが開始される前に必要なセットアップを実行する。PVと紐づく場合は、PVのリストア後に実行される Exec:リストアされたPodのコンテナが起動した後、コンテナ内でカスタムコマンドまたはスクリプトが実行される デフォルトではリストア時にターゲットクラスタ上のデータは削除されません。バックアップ内の同名リソースがターゲットクラスタ内に既に存在する場合は、そのリソースをスキップします。「update」フラグがある場合、リソースを更新します。 他のバックアップ手法との比較 VeleroはKubernetesネイティブなOSSバックアップソリューションです。他のKubernetesのバックアップソリューションとしては、Cohesity、Commvault、Rubrikが挙げられますが、いずれもエンタープライズ向け包括バックアップ製品の一機能としてKubernetesのバックアップ機能を提供しています。 Cohesity 初回以降は変更分のみをバックアップする永久増分バックアップを採用しており、バックアップ時間の短縮とネットワーク・ストレージ負荷の低減が強みです。 Commvault AKS/EKS/Openshiftなどのマルチクラウド、マルチディストリビューションのクラスターを1つの画面で統合管理できます。アプリ単体だけでなく、クラスタ全体を保護できる広範なバックアップが特徴です。 Rubrik 書き換え不可能な(不変)バックアップとゼロトラストアーキテクチャを採用し、ランサムウェア対策と整合性を提供しています。アプリとデータ状態の整合性を厳密に保ったままバックアップできる点が強みです。 Kubernetesだけを低コストでバックアップしたい場合はVeleroが第一候補に挙がります。既にCohesity、Commvault、Rubrikを使用している、またはKubernetes以外もバックアップ対象に含めたい場合は既存・導入予定のプラットフォームに寄せる方が現実的です。 まとめ 本記事では、Kubernetesのリソースと永続ボリュームを包括的に保護できるVeleroについて解説しました。Veleroは、Hook機能を利用してデータベースの整合性を確保できる点や、環境に応じてスナップショットとファイルシステムバックアップを使い分けられる柔軟性が強みです。 次回は、実際にVeleroをKubernetesへ導入するための構築手順と設定方法について詳しく解説します。 参考文献 https://velero.io/docs/v1.17/ https://github.com/vmware-tanzu/velero https://www.cohesity.com/ja-jp/solutions/kubernetes/ https://www.commvault.com/platform/kubernetes-backup https://www.rubrik.com/ja/solutions/kubernetes ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post Kubernetesバックアップツール「Velero」の概要 first appeared on SIOS Tech Lab .
はじめに 前回の記事では、GitLabとOpenShift、Gatekeeperを組み合わせたDevSecOpsモデルケース環境の構築方法を紹介しました。   本記事では、それらを組み合わせて閉域環境におけるDevSecOpsモデルケースを構築し、デモアプリを使ってCI/CDの流れにセキュリティがどのように組み込まれるのかを確認します。   金融や公共分野など高いセキュリティ要件が求められるシステムでは、インターネット非接続の環境であっても、開発のスピードと安全性を両立することが求められます。 GitLabとGatekeeperを活用することで、この課題をどのように解決できるのかを具体的に示すのが今回の目的です。 DevSecOpsとは、DevOpsの迅速な開発・運用プロセスに「セキュリティ」を組み込み、スピードと安全性を両立させる手法です。従来は「開発が完了した後にセキュリティチェックを行う」ことが一般的でした。しかしこの方法では、最終段階で脆弱性が見つかった際に大きな修正が必要となり、時間やコストの増大、リリースの遅延を招いてしまいます。 DevSecOpsでは、開発ライフサイクルの各段階にセキュリティを統合することで、早い段階からリスクを検知し、小規模な修正で対処できます。その結果、開発のスピードを維持しながら、コスト削減と安全性の向上を同時に実現できます。 DevSecOpsは、下図のように開発(Dev)と運用(Ops)のライフサイクルにセキュリティ(Sec)を組み込む考え方です。 DevSecOpsの詳細については以下の記事で解説していますので、ご参照ください。 DevSecOpsとは?安全性とスピードを両立する開発手法 | SIOS Tech. Lab 本記事のデモは、以下の流れで進めます。 ゴール 本記事のゴールは次のとおりです。 DevSecOpsのライフサイクルを実際のCI/CDパイプラインを通じて理解する GitLabとGatekeeperを組み合わせたセキュリティ統制の仕組みを把握する 前提条件 本記事のデモンストレーションは、以下の環境を前提としています。 GitLab サーバー(ソースコード管理・CI/CD実行) OpenShift クラスター(閉域環境にて構築済み、アプリケーション実行環境) GitLab Runner(OpenShift 内にデプロイ済み) Gatekeeper(OpenShift 内にデプロイ済み、リソース作成許可ポリシーを定義済み) 踏み台サーバー(クラスターへのアクセス用) これらは前回の記事「 構築編 」で構築したモデルケース環境に含まれています。 構築手順の詳細は「構築編」を参照してください。 デモアプリの仕様 ベースイメージ:nginx サービス提供ポート:8080 到達性:内部ネットワークのみアクセス可能(外部公開なし) デプロイ方式:Helm(Chart・valuesでイメージタグを切り替え) デモで使用するタグ:v1.0(初回デプロイ)、v1.1(修正デプロイ) パイプラインの実行フロー 今回利用するCI/CDパイプラインの実行フローは以下の通りです。 ビルド用パイプライン実行フロー 開発者がGitLabのビルド用プロジェクトにブランチをマージ マージをトリガーとして、GitLab CI/CDパイプラインが起動 GitLab CI/CDからOpenShiftクラスター内のGitLab Runnerへビルドジョブ実行リクエストを送信 RunnerがジョブPodを起動 ジョブPodがビルド用プロジェクトからアプリのソースコードをClone ジョブPodがdocker CLIなどを利用してコンテナイメージをビルド ジョブPodがビルドしたイメージをGitLabのビルド用プロジェクト内のレジストリにpush デプロイ用パイプライン実行フロー 開発者がGitLabのデプロイ用プロジェクトにブランチをマージ マージをトリガーとして、GitLab CI/CDパイプラインが起動 GitLab CI/CDからOpenShiftクラスター内のGitLab Runnerへデプロイジョブ実行リクエストを送信 RunnerがジョブPodを起動 ジョブPodがOpenShiftのAPIサーバーに対し、リソースのデプロイリクエストを送信 APIサーバーがGitLabのレジストリからアプリのイメージをpull APIサーバーがOpenShiftクラスター内にアプリをデプロイ DevSecOpsのデモンストレーション ここからは、構築済みのモデルケース環境を使って、実際にDevSecOpsの流れを確認します。 以下のように、アプリのデプロイを2回繰り返し、最後にGatekeeperによる制御を体験します。 アプリの初回アップロード(v1.0 デプロイ) アプリを修正して再度デプロイ(v1.1 デプロイ) Gatekeeperによる不正リソース作成の拒否 アプリケーションの初回デプロイ ここからは、DevSecOpsライフサイクルのCode → Operate(1週目)に対応します。 まず、アプリの初回デプロイを行います。 コードを ビルド用プロジェクト のfeatureブランチにpushし、developブランチへマージします。 developブランチにマージすると、コンテナイメージをビルドするパイプラインが起動します。 この操作によって、開発用のイメージ(dev-v1.0)がビルドされます。  続いて、 デプロイ用プロジェクト のfeatureブランチをdevelop ブランチへマージします。 これにより、先ほどビルドされたv1.0イメージを利用して、開発用Namespaceにアプリがデプロイされます。 $ oc get pod -n devsecops-develop -l app="nginx" NAME                                READY   STATUS    RESTARTS   AGE nginx-deployment-5d75b659c5-cqbqp   1/1     Running   0          118s 動作確認が完了したら、ビルド用プロジェクトのdevelopブランチからmainブランチへのマージリクエストを作成し、承認後にマージします。 mainブランチにマージすると、パイプラインが起動し、prod-v1.0イメージがレジストリに格納されます。 次にデプロイ用プロジェクトでdevelopブランチをmainブランチにマージすると、パイプラインが起動し、本番環境用のネームスペースにアプリをデプロイします。 その結果、本番環境にアプリがデプロイされ、表示内容を確認できれば、 Code → Operate の1週目(v1.0)が完了 です。 $ oc get pod -n devsecops-production -l app="nginx" NAME                                READY   STATUS    RESTARTS   AGE nginx-deployment-6c49676b47-m96pf   1/1     Running   0          29s nginx-deployment-6c49676b47-pzv96   1/1     Running   0          29s アプリケーションを修正して再度デプロイ ここからは、DevSecOpsライフサイクルのCode → Operate(2週目)に対応します。 アプリを修正します。ここではindex.htmlの内容を更新し、あわせて.gitlab-ci.ymlで定義しているコンテナイメージのタグをv1.1に変更します。 次に、 ビルド用プロジェクト のfeatureブランチにpushし、developブランチへマージします。 この操作によって、新しい開発用イメージ(v1.1)がビルドされます。 続いて、 デプロイ用プロジェクト のfeatureブランチでConfig/develop-values.yamlと Config/product-values.yamlのtagを修正し、反映します。その後、同様にdevelopブランチ へマージして変更を適用します。 これにより、先ほどビルドされたv1.1イメージを利用して、開発用Namespaceにアプリがデプロイされます。 $ oc describe pod -n devsecops-develop nginx-deployment-54d94596b6-8j8w6 | grep "Image:"     Image:          registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:dev-v1.1 動作確認が完了したら、developブランチからmainブランチへのマージリクエストを作成し、承認後にマージします。 その結果、本番環境に修正版アプリがデプロイされ、表示内容が更新されていることを確認できます。 $ oc describe pod -n devsecops-production nginx-deployment-59ddc6dbb6-lhd6b | grep "Image:"     Image:          registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:prod-v1.1 この時点で、 Code → Operate の2週目(v1.1)が完了 です。 Gatekeeperによる不正リソースの検知・拒否 ここからは、DevSecOpsライフサイクルのSecに対応します。 最後に、あえて不正な設定を持つリソースをNamespaceにデプロイしてみます。 Gatekeeperのポリシー設定で、 envラベルの値がデプロイ先のnamespace名と一致していないとPodの作成を許可しない 制約 を設定しています。 以下のように、 デプロイ用プロジェクト でdeploymentのlabelsでenvラベルを不正な値に書き換える修正を行い、developブランチにマージします。 このときGatekeeperのポリシーが働き、不正なリソースの作成は拒否されます。 実際のログやイベントを確認すると、Constraint によって違反が検出され、Podのデプロイが失敗していることが分かります。   一番下のReplicaSetはDesired 1に対して、Currentが0であり、Podがデプロイされていないことがわかります。 $ oc get replicasets.apps -n devsecops-develop  NAME                          DESIRED   CURRENT   READY   AGE nginx-deployment-54d94596b6   1         1         1       20m nginx-deployment-5d75b659c5   0         0         0       14h nginx-deployment-6bfd599796   1         0         0       3m48s PodがデプロイされていないReplicaSetのイベントを確認すると、Gatekeeperの 制約テンプレート で設定したエラーメッセージが表示されていることがわかります。 $ oc describe replicasets.apps -n devsecops-develop nginx-deployment-6bfd599796 Events:   Type     Reason        Age                 From                   Message   ----     ------        ----                ----                   -------   Warning  FailedCreate  4m13s               replicaset-controller  Error creating: admission webhook "validation.gatekeeper.sh" denied the request: [require-env-label-match-namespace] Pod 'nginx-deployment-6bfd599796-z7hgf' の 'env' ラベルの値は、Namespace名 'devsecops-develop' と一致する必要があります。現在の値は 'dummy-env' です。 このように、 開発者が意識しなくてもポリシー違反が自動的にブロックされる ことで、セキュリティを犠牲にせずに CI/CD のスピードを維持できることを体験できます。 まとめ 本記事では、GitLab、OpenShift、Gatekeeperを組み合わせて閉域環境にDevSecOpsモデルケースを構築し、デモアプリを用いて以下の流れを確認しました。 GitLab CI/CDによるアプリケーションデプロイの自動化   コード変更からの継続的デリバリー   Gatekeeperポリシーによるセキュリティ担保   このデモを通じて、次のポイントを押さえることができました。 DevOpsだけでは不十分 開発サイクルが迅速化しても、不正なリソースや設定が混入すれば安全性は損なわれる。 ポリシー制御の仕組みが重要 Gatekeeperを用いることで、開発の初期段階から不正なリソースを自動的に排除できる。 GitLabとOpenShiftの統合は実用的 インターネット非接続の閉域環境でも再現可能であり、金融・公共分野を含む実案件にも応用できる。 さらに実環境での利用を考えるなら、コンテナイメージのセキュリティスキャンや、より複雑なポリシー制御を組み合わせることで、より強固なDevSecOpsを実現できます。   まずは小規模なモデルケースから試し、徐々に自社の環境や要件に合わせて拡張していくことをおすすめします。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DevSecOps実践ガイド:セキュアなCI/CD運用の実践編 first appeared on SIOS Tech. Lab .
はじめに 前回までに、GitLabとOpenShift、Gatekeeperを閉域環境で構築する手順を紹介しました。 本記事では、その環境を基盤としてGitLabのプロジェクト作成や設定を追加し、CI/CDパイプラインとポリシー検証を組み合わせたDevSecOpsの実践例に向けた環境構築を行います。 特に、金融や公共分野のように高いセキュリティ要件が求められるシステムでは、インターネット非接続環境での開発・運用が前提となるケースが多くあります。本記事で取り上げる構成は、そうした制約下でも有効な実践例となります。 なお、本記事では構築の全手順を網羅するのではなく、モデルケースの全体像と主要な構成要素を中心に解説します。詳細な設定値やコードについては、 こちらのリポジトリ をご参照ください。 ゴール GitLabにビルド用・デプロイ用プロジェクトを作成する OpenShiftのNamespaceや権限を設定する Gatekeeperのポリシーを適用し、CI/CDパイプライン実行時にポリシー違反を検知できるようにする 次回のデモ実演に向けた基盤を完成させる DevSecOpsとは? DevSecOpsとは、DevOpsの迅速な開発・運用プロセスにセキュリティを統合することで、スピードと安全性を両立する手法です。 従来の「開発の後にセキュリティチェックを行う」アプローチではなく、開発ライフサイクルの各段階にセキュリティを組み込む点が特徴です。 詳細については以下の記事で解説していますので、ご参照ください。 DevSecOpsとは?安全性とスピードを両立する開発手法 | SIOS Tech. Lab 前提条件 以下の記事の手順に従って、環境構築が完了していること GitLabとコンテナプラットフォームの連携 | SIOS Tech. Lab OPA/Gatekeeperで始める安心OpenShift運用:構築編 デモアプリの仕様 ベースイメージ:nginx サービス提供ポート:8080 到達性:内部ネットワークのみアクセス可能(外部公開なし) デプロイ方式:Helm(Chart・valuesでイメージタグを切り替え) サンプル構成の全体像 プロジェクトの分割方針 devsecops-build-project(ビルド用) ソースコードとDockerfileを管理し、イメージをビルドしてGitLab Container Registryにpushします。 devsecops-deploy-project(デプロイ用) Helmチャートと環境別のvaluesファイルを管理し、Registryのイメージを参照してOpenShiftにデプロイします。 このように ビルドとデプロイを分けることで、開発コードの管理とデプロイ設定の管理を明確に切り分けられるようにしています。 リポジトリ構成(概要) ビルド用リポジトリ Containerfileとsrc/ : Nginxベースのアプリ .gitlab-ci.yml : イメージビルド&レジストリへpush デプロイ用リポジトリ devsecops-nginx-chart/ : Helmチャート develop-values.yamlとproduct-values.yaml : 環境別設定 .gitlab-ci.yml : Helmを使ったOpenShiftへのアプリのデプロイ ※詳細なディレクトリとファイル内容は こちらのリポジトリ をご覧ください。 ブランチ戦略 feature/* : 開発作業用ブランチ develop : 開発環境に対応 main : 本番環境に対応 feature → develop → main の流れでレビューを経たマージを行い、保護ブランチ設定によりdevelopやmainブランチへの直接pushは禁止しています。 パイプラインの流れ ビルドパイプライン(build-project) ソースコード変更を検知 Runnerがイメージをビルドし、レジストリにpush デプロイパイプライン(deploy-project) Helm設定変更を検知 Runnerがレジストリのイメージをpullし、OpenShiftにデプロイ Gatekeeperがポリシーを検証し、違反があればリソース作成を拒否 構築手順(概要) 手順の流れ 今回のサンプルケースでは以下の構成要素を準備します。 GitLabユーザー作成 ソースコード用プロジェクトの作成 デプロイ用プロジェクトの作成 OpenShift側のNamespaceと権限設定 Gatekeeperのポリシー設定 1. GitLabユーザー作成 管理者アカウントでGitLabにログインし、プロジェクト管理用ユーザーを作成します。 今回使用するプロジェクトのネームスペースはここで作成したユーザー名を指定します。 続いて、作成したプロジェクト管理用ユーザー(devsecops-user)にSSHキーを登録し、Gitでのアクセスを確認します。 作成したプロジェクト管理用ユーザーでログインし、サイドメニューからアバターアイコンを選択→[プロファイルを編集]をクリックして、ユーザー設定画面に移動します。 ユーザー設定画面のサイドメニューで[SSHキー]を選択し、このユーザー用に作成した公開鍵を登録します。 例:SSHキー生成とGitLab接続確認 $ ssh-keygen -t rsa -b 4096 -C "devsecops-user@gitlab.local" $ ssh -T git@gitlab-private.example.local 2. ソースコード用プロジェクト 先ほど作成したプロジェクト管理用ユーザーでログインし、GitLabで新規プロジェクトを作成します。 このプロジェクトはイメージのビルドとレジストリへのイメージ保存を担当します。 プロジェクト作成の詳細な手順は弊社ブログ記事 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab をご参照ください。 続いて、作成したビルド用プロジェクト内でmain と develop ブランチを用いし、保護ブランチの設定を行います。 ブランチの保護設定を行うことで、mainブランチ及びdevelopブランチへの直接pushを防止し、パイプラインの誤動作を防止します。 ブランチ保護設定手順の詳細につきましても、弊社ブログ記事 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab に記載しておりますので、ご参考になれば幸いです。 任意の開発者用ユーザーを作成し、プロジェクトにDeveloper権限で追加します。このユーザーはプロジェクト内でコードをコミットしたり、パイプラインを操作するために利用します。 プロジェクトにユーザーを招待する方法や主要なユーザー権限につきましては、 Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab に記載しておりますのでご参照ください。 プロジェクトに追加した開発用ユーザーでログインし、サンプルのアプリコードをリポジトリのfeatureブランチにpushし、管理を開始します。 アプリのベースイメージ(nginx:latestなど)をGitLab Container Registryにpushします。 ※この記事では、OpenShiftの環境を使用しているため、コンテナ管理ツールとしてPodmanを利用しています。Dockerを利用している環境ではpodman→dockerに読み替えてください。 $ podman login registry.gitlab.local.example.com $ podman pull nginx:latest $ podman tag nginx:latest registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:latest $ podman push registry.gitlab.local.example.com/devsecops-user/devsecops-build-project/nginx:latest 参考: Git & GitLab 入門 (7) ~Git マスターへの道~「GitLabのプロジェクトについて」 | SIOS Tech. Lab 3. デプロイ用プロジェクト プロジェクト管理用ユーザーでGitLabにログインし、今度はデプロイ用のGitLabプロジェクトを新規作成します。 このプロジェクトはレジストリのイメージを参照し、Helmを用いてOpenShiftにデプロイする役割を担います。 ビルド用プロジェクトを作成した時と同様に、mainとdevelopブランチに保護設定を行います。 今回はデプロイ手段としてHelmチャートを利用するため、このプロジェクトのレジストリにHelmが利用可能なコンテナイメージを格納します。 ※この記事では、OpenShiftの環境を使用しているため、コンテナ管理ツールとしてPodmanを利用しています。Dockerを利用している環境ではpodman→dockerに読み替えてください。 $ podman login registry.gitlab.local.example.com $ podman pull docker.io/alpine/helm:3 $ podman tag docker.io/alpine/helm:3 \   registry.gitlab.local.example.com/root/test-project/helm:3 $ podman push registry.gitlab.local.example.com/root/test-project/helm:3 デプロイ用プロジェクトのレジストリにHelmイメージを格納しておくと、パイプライン内で実行されるジョブPodのイメージを指定できます。この指定は、パイプライン定義ファイル(.gitlab-ci.yml)のimageプロパティで行います。 .default_deploy: &default_deploy   stage: deploy   image: registry.gitlab.local.example.com/devsecops-user/devsecops-deploy-project/helm:3   before_script:     - set -euo pipefail     - helm version     - |       if [ -n "${K8S_NAMESPACE:-}" ]; then         HELM_NS_ARG="-n ${K8S_NAMESPACE}"       else         echo "K8S_NAMESPACE variable not provided. Helm will use the current context's namespace."         HELM_NS_ARG=""       fi     - helm dependency update "$HELM_CHART_DIR" || true 今回使用するデプロイ用パイプラインは、ブランチに応じてデプロイ先のネームスペースを決定します。 たとえば、developブランチにマージした時はdevsecops-developネームスペースにアプリをデプロイし、mainブランチにマージした時はdevsecops-productionネームスペースにアプリをデプロイするなどの制御を行います。 deploy_develop:   <<: *default_deploy   tags:     - devsecops-runner   variables:     <<: *common_vars     VALUES_ENV: "deploy/Config/develop-values.yaml"     K8S_NAMESPACE: "$DEPLOY_PROJECT_NAME_DEVELOP"   rules:     - if: '$CI_COMMIT_BRANCH == "develop" && $CI_PIPELINE_SOURCE == "push"'   environment: { name: develop, deployment_tier: development }   script:     - |       set -euo pipefail       : "${HELM_RELEASE:=devsecops-nginx}"       : "${HELM_CHART_DIR:=deploy/devsecops-nginx-chart}"       : "${VALUES_COMMON:=deploy/devsecops-nginx-chart/values.yaml}"       : "${VALUES_ENV:?VALUES_ENV must be set}"       test -f "${HELM_CHART_DIR}/Chart.yaml" || { echo "Chart.yaml not found under ${HELM_CHART_DIR}"; exit 1; }       echo "[RUN] helm upgrade --install ${HELM_RELEASE} ${HELM_CHART_DIR} ${HELM_NS_ARG} -f ${VALUES_COMMON} -f ${VALUES_ENV}"       helm upgrade --install "${HELM_RELEASE}" "${HELM_CHART_DIR}" ${HELM_NS_ARG} -f "${VALUES_COMMON}" -f "${VALUES_ENV}" deploy_production:   <<: *default_deploy   tags:     - devsecops-runner   variables:     <<: *common_vars     VALUES_ENV: "deploy/Config/product-values.yaml"     K8S_NAMESPACE: "$DEPLOY_PROJECT_NAME_PRODUCTION"   rules:     - if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"'       allow_failure: false   environment: { name: production, deployment_tier: production }   script:     - |       set -euo pipefail       : "${HELM_RELEASE:=devsecops-nginx}"       : "${HELM_CHART_DIR:=deploy/devsecops-nginx-chart}"       : "${VALUES_COMMON:=deploy/devsecops-nginx-chart/values.yaml}"       : "${VALUES_ENV:?VALUES_ENV must be set}"       test -f "${HELM_CHART_DIR}/Chart.yaml" || { echo "Chart.yaml not found under ${HELM_CHART_DIR}"; exit 1; }       echo "[RUN] helm upgrade --install ${HELM_RELEASE} ${HELM_CHART_DIR} ${HELM_NS_ARG} -f ${VALUES_COMMON} -f ${VALUES_ENV}"       helm upgrade --install "${HELM_RELEASE}" "${HELM_CHART_DIR}" ${HELM_NS_ARG} -f "${VALUES_COMMON}" -f "${VALUES_ENV}" デプロイ用パイプラインが読み取れるCI/CD変数を登録します。 プロジェクト画面のサイドメニューから[設定] > [CI/CD]を選択し、[変数]のメニューを展開します。 [変数を追加]をクリックすると、CI/CDパイプラインが利用可能な環境変数を定義することができます。今回の例では、環境別のネームスペース名であるDEPLOY_PROJECT_NAME_DEVELOPとDEPLOY_PROJECT_NAME_PRODUCTIONを定義しています。他にも外部サービスのAPIキーなどを登録するなどの利用が可能です。 上記の作業が完了した後、デプロイ用のHelmチャートやマニフェストをfeatureブランチにpushします。 4. OpenShift設定 開発用 (develop) と本番用 (production) のNamespaceを作成し、ラベルを付与します。 ※tagのenvにはdevやprodなどデプロイ先の環境名を指定しています。 $ oc create namespace <namespace> $ oc label namespace <namespace> tag=<env> GitLab Runner用のServiceAccountを作成し、必要なRBAC権限とSCCを付与します。 開発用 (develop) と本番用 (production) のNamespaceのGitLab Runner用のServiceAccountに必要なRBAC権限を付与 GitLab Container RegistryへのPull SecretをNamespaceに登録します。 自己署名証明書を利用している場合はCA証明書をSecretとして登録します。 開発用 (develop) と本番用 (production) のNamespaceのdefault ServiceAccountにanyuidのSCCを付与します。 GitLab Runner用のNamespaceのServiceAccountにデプロイ先namespaceでのedit権限を付与します。 5. Gatekeeper設定 必要なConstraintTemplateを作成します(例:イメージタグに特定文字列を含める、Namespaceとラベルが一致していることなど)。 今回作成したポリシールールは こちらのリポジトリ をご参照ください。 開発環境、本番環境それぞれを対象としたConstraintsを作成します。 oc get コマンドでConstraintTemplateとConstraintsが正しく反映されていることを確認します。 参考: OPA/Gatekeeperで始める安心OpenShift運用:設定編 まとめ ここまでで、GitLabのビルド・デプロイ用プロジェクト、OpenShiftのNamespace設定、Gatekeeperのポリシー適用といった要素が揃い、セキュリティを組み込んだCI/CD基盤のモデルケースが完成しました。これにより、ソースコードの変更がパイプラインを通じて自動的にビルド・デプロイされるだけでなく、Gatekeeperによるポリシー検証によって不適切なリソースの作成を未然に防ぐことが可能になります。 本記事で紹介した構成は、高いセキュリティ要件が求められるシステムにおいても有効なアプローチです。次回の記事では、この環境を活用して実際のパイプライン実行からポリシー違反検知までの一連の流れをデモンストレーションします。 ご覧いただきありがとうございます! この投稿はお役に立ちましたか? 役に立った 役に立たなかった 0人がこの投稿は役に立ったと言っています。 The post DevSecOps実践ガイド:CI/CD環境の構築編 first appeared on SIOS Tech. Lab .

動画

該当するコンテンツが見つかりませんでした

書籍