################## ベストプラクティス ################## ここでは、CNAP で GitOps を行うために参考となる Git リポジトリの構成や、 リポジトリ内でのフォルダ構成の例を紹介します。 構成の前提 ========== ここで紹介するケースは以下の前提のもとに構成されています。 デリバリ先環境 -------------- アプリケーション運用をおこなうデリバリ先の環境はそれぞれ、 以下の環境があることを想定しています。 +-------------+------------------------------------------------------------------------------------+ | 環境 | 概要 | +=============+====================================================================================+ | 本番(prod) | 本番運用用の環境 | | | | | | 自動更新は行なわず常にバージョンを指定してデリバリを行う。 | +-------------+------------------------------------------------------------------------------------+ | 検証(stage) | 開発環境で動作確認が取れたタイミングで運用検証を行うための環境 | | | | | | 設定変更の必要ないパッチバージョンの適用は自動で行なわれるようになっているが、 | | | 変更があった場合はバージョンを指定してデリバリを行う。 | +-------------+------------------------------------------------------------------------------------+ | 開発(dev) | 開発段階のアプリケーションのデリバリ先 | | | | | | 常に最新のコンテナや CNAP パッケージのバージョンが自動反映されるようになっている。 | | | 自動更新によるエラーが発生する可能性がある。 | +-------------+------------------------------------------------------------------------------------+ 開発環境で完全な自動更新を行うと、アプリケーションのリリースや CNAP パッケージのリリースによって エラー状態となる可能性がありますが、このエラーを解消していくことで、常に最新のバージョンに追従するための サイクルをまわすことができるようになります。 アプリケーションのコードと IaC のコードは分離する ------------------------------------------------- アプリケーションソースコードとデプロイ用のリポジトリを同じにしてしまうと、 コンテナの "リリース=環境へのデリバリ" となってしまい、 運用都合のタイミングと同期をとってコンテナのリリースを行う必要がでてきます。 リポジトリを分離することによって、開発者がコンテナのデリバリ時期を意識せずにコンテナのリリースを行えるようになり、 環境ごとに異なるバージョンのコンテナを稼動させることも可能になります。 コードの一貫性を保つ -------------------- 異なる環境へのデリバリであっても、同じアプリケーションのデリバリである場合は、 デリバリの都度コードの改変を行なわず、環境に依存する設定のみ適用して運用することができるように構成されています。 これによって、アプリケーション側の要求するパラメータに変更が無いかぎりは、 デリバリ作業において一切のコード改変を行う必要が無くなり、環境毎のコードの一貫性を保てるようになります。 本ベストプラクティスでは以下の点を考慮して構成されています。 * 誤った設定が適用されるのを防ぐため環境に依存する設定はベース設定から外し差分適用するようにします。 * デフォルト設定が存在し環境によって変わる可能性がある値は、より安全な設定値をデフォルトにします。 CNAP では差分の適用を実現するために、 kustomize_ を活用することができ、 本サンプルでは kustomize を利用した 差分適用のベストプラクティスにもなっています。 .. _kustomize-patch: 差分適用 ~~~~~~~~ 差分適用には主に kustomize_ の patch 機能を用います。 サンプルでは各フォルダに patch-xxx.yaml ファイルを作成して、kustomization.yaml でどの patch をどのマニフェストに適用するか指定しています。 ターゲットの指定には、 ``metadata.name`` の完全一致によるもの以外にも、 label セレクタを利用してまとめて指定することもできます。 Configmap の作成には kustomize の ConfigmapGenerator を利用し、 設定ファイルをそのまま Configmap に変換しています。 ConfigmapGenerator には data フィールドの差分をマージする機能を差分適用に利用しています。 以下のコマンドで kustomize によって出力されるマニフェストを確認することができます。 .. code-block:: console kubectl kustomize clusters/dev # kustomization.yaml のあるフォルダを指定 kustomize_ をインストールしている場合は以下でも確認できます。 .. code-block:: console kustomize build clusters/dev # kustomization.yaml のあるフォルダを指定 Namespace で環境を分けるケース ============================== Namespace を利用して 1 つのクラスタ内に、開発、検証、商用などの実行環境を配置するケースを紹介します。 最小限のクラスタリソースで DevOps サイクルを回すことができるようになりますが、 1つのクラスタ内で異るセキュリティ要件、ネットワーク要件を満すように考慮する必要があります。 全体構成 -------- .. drawio-figure:: /_static/drawio/best-practice.drawio :page-index: 0 この例ではマネージドデータベースのインスタンスを dev と stage 環境では共有し、 prod 分離するように構成しています。 Namespace が実行ステージとなっているため、複数のアプリケーションを運用する場合も、 同じ Namespace に配置することになるため、アプリケーションの数が増えてくると、 リソース名の競合管理など、運用が難しくなってきます。 アプリケーションリポジトリ構成 ------------------------------ この構成では、アプリケーションを管理するリポジトリを1つにまとめています。 多数のアプリケーションがある場合に、リポジトリを分割することも可能ですが、 その場合は同じ Namespace に配置されることを考慮して、 リソースの競合が起きないように注意する必要があります。 +------------+---------------------------------------------------------------------------------+ | リポジトリ | 概要 | +============+=================================================================================+ | admin-repo | UserConfig 他クラスタのユーザー設定を管理するためのリソースを管理するリポジトリ | +------------+---------------------------------------------------------------------------------+ | app-repo | アプリケーションの構成を管理するリポジトリ | +------------+---------------------------------------------------------------------------------+ `Namespace 分離構成サンプル`_ admin-repo 構成 ~~~~~~~~~~~~~~~ :: . ├── kustomization.yaml ├── namespace.yaml └── userconfig.yaml ``UserConfig`` 自体を配置する Namespace は UserConfig では作成できないため、 直接 Namespace を作成するマニフェストを使用します。 app-repo 構成 ~~~~~~~~~~~~~ :: . ├── applications │   ├── app │   │   ├── backend.yaml │   │   ├── frontend.yaml │   │   ├── kustomization.yaml │   │   └── rdb.env │   └── rdb │   ├── kustomization.yaml │   └── rdb.yaml └── namespaces ├── dev │   ├── app │   │   ├── kustomization.yaml │   │   ├── patch-back.yaml │   │   ├── patch-front.yaml │   │   └── rdb.env │   ├── kustomization.yaml │   └── rdb │   ├── kustomization.yaml │   └── patch-db.yaml ├── prod │   ├── app │   │   ├── kustomization.yaml │   │   ├── patch-back.yaml │   │   ├── patch-front.yaml │   │   └── rdb.env │   ├── kustomization.yaml │   └── rdb │   ├── kustomization.yaml │   └── patch-db.yaml └── stage ├── app │   ├── kustomization.yaml │   ├── patch-back.yaml │   ├── patch-front.yaml │   └── rdb.env ├── kustomization.yaml └── rdb └── kustomization.yaml リポジトリの ``applications`` フォルダでマニフェストのベースとなるコードを管理し、 ``namespaces`` フォルダ以下で各 Namespace ごとの :ref:`kustomize-patch` するように構成します。 ``applications`` 以下にアプリケーションごとのフォルダ階層を設けることで、 環境ごとにインストールするアプリケーションを選択できるようにします。 ``namespaces`` 以下のフォルダでデリバリ先の Namespace が決まるため、 ``applications`` では ``namespace`` フィールドの設定を行なわず、 各 Namespace フォルダで ``namespace`` の設定を行います。 Namespace で環境を分ける場合複雑化を避けるため Namespace はあくまで環境を抽象化したものとして扱い、 アプリケーションをグループ化したい場合などは、 label などを駆使して管理するようにします。 UserConfig ---------- ``UserConfig`` は1クラスタに1つしか設定できないため、アプリケーションとは独立したリポジトリで管理します。 基本はクラスタ作成時のヒアリングシートで指定したリポジトリを利用します。 UserConfig を利用してリポジトリを登録する際は、アプリケーションリポジトリの ``namespaces`` 以下のフォルダを path に指定します。 クラスタで環境を分けるケース ============================ クラスタ毎に開発、検証、商用などの実行環境を分離して、 アプリケーション構成ごとに Namespace を分離するケースを紹介します。 このケースでは複数のクラスタが必要になりますが、 クラスタ毎にネットワーク設定やセキュリティ設定が行えるため、 クラスタ内の設定がシンプルになります。 また、Namespace をアプリケーション毎に割り当てることができるため、 複数のアプリケーションを連携させる際に細かい設定が行えるようになります。 全体構成 -------- 用途ごとにクラスタを分け、Namespace は各クラスタ共通の構成で、 アプリケーションを構成するグループ単位に作成します。 .. drawio-figure:: /_static/drawio/best-practice.drawio :page-index: 1 この例ではマネージドデータベースのインスタンスを dev と stage 環境では共有し、 prod 分離するように構成しています。 クラスタ単位でネットワーク環境等が固定できるため、 各アプリケーションの設定は比較的シンプルにまとめることができます。 また、Namespace の設定に自由が効くため、アプリケーションのグループ単位で Namespace を 分割することによって、リソースの競合を避けやすくなります。 また、セキュリティ設定を Namespace 単位で行うことができるメリットもあります。 アプリケーションリポジトリ構成 ------------------------------ この構成では、アプリケーション毎にリポジトリを分割して管理します。 +------------+---------------------------------------------------------------------------------+ | リポジトリ | 概要 | +============+=================================================================================+ | admin-repo | UserConfig 他クラスタのユーザー設定を管理するためのリソースを管理するリポジトリ | +------------+---------------------------------------------------------------------------------+ | app1-repo | サンプルアプリケーション1の構成を管理するリポジトリ | +------------+---------------------------------------------------------------------------------+ | app2-repo | サンプルアプリケーション2の構成を管理するリポジトリ | +------------+---------------------------------------------------------------------------------+ `クラスタ分離構成サンプル`_ admin-repo 構成 ~~~~~~~~~~~~~~~ :: . ├── base │ ├── kustomization.yaml │ ├── namespace.yaml │ └── userconfig.yaml └── clusters ├── dev │ ├── kustomization.yaml │ └── patch.yaml ├── prod │ ├── kustomization.yaml │ └── patch.yaml └── stage ├── kustomization.yaml └── patch.yaml ``UserConfig`` 自体を配置する Namespace は UserConfig では作成できないため、 直接 Namespace を作成するマニフェストを使用します。 各クラスタ毎に UserConfig が必要となるため ベースとなる ``base`` フォルダとクラスタごとの :ref:`kustomize-patch` するための ``clusters`` フォルダに分けて管理します。 app1-repo 構成 ~~~~~~~~~~~~~~ :: . ├── README.md ├── applications │   ├── app1 │   │   ├── backend.yaml │   │   ├── frontend.yaml │   │   ├── kustomization.yaml │   │   └── rdb.env │   └── rdb │   ├── kustomization.yaml │   └── rdb.yaml └── clusters ├── dev │   ├── app │   │   ├── kustomization.yaml │   │   ├── patch-back.yaml │   │   ├── patch-front.yaml │   │   └── rdb.env │   ├── kustomization.yaml │   └── rdb │   ├── kustomization.yaml │   └── patch.yaml ├── prod │   ├── app │   │   ├── kustomization.yaml │   │   ├── patch-back.yaml │   │   ├── patch-front.yaml │   │   └── rdb.env │   ├── kustomization.yaml │   └── rdb │   ├── kustomization.yaml │   └── patch.yaml └── stage ├── app │   ├── kustomization.yaml │   ├── patch-back.yaml │   ├── patch-front.yaml │   └── rdb.env ├── kustomization.yaml └── rdb ├── kustomization.yaml └── patch.yaml リポジトリの ``applications`` フォルダでマニフェストのベースとなるコードを管理し、 ``clusters`` フォルダ以下で各クラスタごとの :ref:`kustomize-patch` するように構成します。 ``applications`` 以下にアプリケーションごとのフォルダ階層を設けることで、 環境ごとにインストールするアプリケーションを選択できるようにします。 app2-repo 構成 ~~~~~~~~~~~~~~ :: . ├── applications │ └── app2 │ ├── frontend.yaml │ └── kustomization.yaml └── clusters ├── dev │ ├── kustomization.yaml │ └── patch.yaml ├── prod │ ├── kustomization.yaml │ └── patch.yaml └── stage ├── kustomization.yaml └── patch.yaml app1 と同じ構成にします。 UserConfig ---------- ``UserConfig`` は1クラスタに1つしか設定できないため、アプリケーションとは独立したリポジトリで管理します。 基本はクラスタ作成時のヒアリングシートで指定したリポジトリを利用します。 このケースではクラスタ作成時のヒアリングシートのリポジトリ設定では admin-repo の ``clusters`` 以下の各環境用のフォルダのパスを指定するようにします。 UserConfig を利用してリポジトリを登録する際は、各アプリケーションリポジトリの ``clusters`` 以下のフォルダを path に指定します。 .. _kustomize: https://kubectl.docs.kubernetes.io/references/kustomize/ .. _`Namespace 分離構成サンプル`: https://github.com/sbopsv/cnap-examples/tree/master/best-practice/single .. _`クラスタ分離構成サンプル`: https://github.com/sbopsv/cnap-examples/tree/master/best-practice/multi