Kubernetesベースの開発



Kubernetesベースの開発
最新のアプリケーションは、マイクロサービスでますます基礎を形成します.より大きな部分に大きなアプリケーションを分割すると、より保守性が高く、開発が容易になります.しかし、大きなモノリスを開発する代わりに、我々は小さなアプリケーションの束に取り組んで、それをデバッグし、システム全体を展開するには、より困難になります.幸いにも、私たちを助けるためにそこに多くのツールがあります.それらのいくつかの興味深い比較を見つけることができますhere . 以下では、我々はKubernetesベースの開発を行うことがいかに簡単かを見たいと思いますdevspace .

マイクロサービスアプリケーション
例えば、我々がマイクロサービスアプリケーションを開発していると仮定してください.本質的に、我々の電子商店はAPIを通してバックエンドと通信するフロントエンドアプリケーションから成ります.簡単のため、バックエンドは以下のようになります.

ユーザー管理はiam-service . 命令はmessage-queue . 我々のバックエンドのビジネスロジックのほとんどは、Serverlessな機能によって提供されますfaas . 当社のアプリケーションの状態は、当社の状態に保持されますdatabase . 最後に、いくつかの良い理由(例えばテストセットアップの容易さ)については、当社のソフトウェアを開発しているmonorepo .
時間とともに、我々のMicro Servicesアプリケーションは、さらにより多くのマイクロサービス・コードまたはServerlessな機能で詰め込まれる多くのビジネス・ロジックを含みます.例えば、我々の間でコネクタサービスが必要になるかもしれませんmessage-queue アンドfaas , またはいくつかの論理を持つ資産サービスは、制御された方法で新しい資産を追加します.私たちのマイクロサービスをホストするための非常に便利な方法は、それらをDockerizeし、Kubernetesにそれらを編成することです.
通常、我々のIAMサービスは、サードパーティのようなものですkeycloak or fusionauth 私たちは簡単にKubernetesに展開することができますhelm chart . Helm Kubernetesのための非常に実用的なパッケージマネージャです.例えば、典型的なfusionauth展開はこれらの行に沿った何かのようになります.
helm repo add fusionauth https://fusionauth.github.io/charts
helm install fusionauth --create-namespace fusionauth/fusionauth --namespace auth \
    --set database.protocol=postgresql \
    --set database.user=<username> \
    --set database.password=<password> \
    --set database.host=<hostname> \
    --set database.port=5432 \
    --set database.name=<database-name> \
    --set database.root.user=<root-user> \
    --set database.root.password=<root-password> \
    --set app.runtimeMode=production \
    --set search.engine=database
メッセージキューはおそらくredismq , rabbitmq or kubemq , 我々はまた、簡単にヘルムチャートを見つけるために.
その後、独自のカスタムサービスを私たち自身のKubernetesリソース(展開、サービス、インガーションなど)を記述する必要があります.最後に、すべての必要なヘルムチャートをインストールし、Kubernetesリソースを適用するスクリプトを書くことができます.
我々のソフトウェアが敏感なデータを扱うので、我々のビジネスを作るので、我々は新しいリリースを展開するとき、注意する必要があります.したがって、我々はそれをリリースする前に、どうにか、それをテストしたいです.確かに、我々は2つの環境、テストのための1つと生産のための1つを想像することができます.テスト(またはステージング)環境は、当社のソフトウェアリポジトリmain ブランチは生産環境が我々のレポのペンダントになる間production 枝.私たちはmain ブランチ、そして、Q & Aがそこに押されるソフトウェアに満足するとすぐに、我々はそれを押しますproduction .
我々は現在、我々は開発マシン上で我々のソフトウェアを開発し、ほぼ生産的な環境で何とかそれをテストし、生産環境にそれをリリースする複雑な状況にある.これは、3つの異なるビルドと展開手順につながります.開発マシンでは、我々は確かに短命のデータベースと対話したい.さらに、我々のマイクロサービス(資産サービスのような)へのログイン資格証明は些細であるべきです.ステージングに関しては、デバッグのためにいくつかのサービスに対して保護されていないアクセス権を与えたいと思うかもしれません.生産に関しては、できるだけ安全にして隠したい.
最終的に、我々の開発環境が生産環境に近い場合、我々はステージングや生産への展開に続く驚きの量を最小限に抑え、生産性を高めるだろう.

入力する
Devspace コンテナイメージのビルドと展開の両方を自動化できるCLIツールです.加えて、そのツールは、私たちのMakefileやDockerの構成を置き換える代わりに、Kubernetesベースの開発を行う能力を提供します.後者の能力のために、我々は我々の開発マシンで小さなクラスタをセットしたと仮定しましょう.ワンクリックで、あなたのための開発クラスタを設定することができます

非常にシンプルなインターフェイス

または、手動で自分で設定することができますkind , minikube , or docker for desktop クラスタ.
DevSpaceをインストールする最も簡単な方法(あなたのKubernetesクラスタではなく、コードを開発するリモートマシン上で)…する
npm install -g devspace 
それから、我々のユースケースに応じて、我々は走るかもしれません
devspace init
と指示に従ってください.我々の特定のケースでは、我々は構築したい
  • API
  • カスタムマイクロサービスの束
  • 以下の設定を行います.
    version: v1beta10
    vars:
    - name: SOME_IMPORTANT_VARIABLE
      source: env
      default: the-important-value
    images:
      my-custom-service:
        image: my-repo/my-custom-service
        tags:
        - ${DEVSPACE_RANDOM}
        dockerfile: ./my-custom-service/Dockerfile
        context: .
        build:
          docker:
            options:
              target: app
              buildArgs:
                SOME_IMPORTANT_VARIABLE: ${SOME_IMPORTANT_VARIABLE}
      api:
        image: my-repo/api
        tags:
        - ${DEVSPACE_RANDOM}
        dockerfile: ./api/Dockerfile
        context: .
    
    上記の構成はAPIとマイクロサービスのビルド方法を定義します.それらがDockerレジストリに押されるとき、両方のDockerイメージは同じランダムタグ(ビルトイン変数によって定義される)を持ちますDEVSPACE_RANDOM ). Dockerデーモンを使用する代わりに、カスタムビルドコマンドを使用するか、kaniko . 環境変数を使うことができますSOME_IMPORTANT_VARIABLE とDocker画像をビルドするための通常のオプションを提供します.
    次に、展開したい
  • API
  • 当社のカスタムマイクロサービス
  • 様々なサードパーティサービス(IAM、メッセージキュー、FAAS、資産)
  • そのためには、前の設定を次のスニペットで完了します.
    deployments:
    # for the custom service, we have regular k8s manifests
    - name: my-custom-service
      kubectl:
        manifests:
        - my-custom-service/manifest.yaml
    # for the api, we have written a helm chart
    - name: api
      helm:
        chart:
          name: api/chart
        values:
          image: my-repo/api
          postgres:
            database: my-database
            hostname: postgres
            username: my-username
            password: my-password
    # the database service is a 3rd party
    - name: postgres
      helm:
        chart:
          name: postgresql
          repo: https://charts.bitnami.com/bitnami
        values:
          postgresqlDatabase: my-database
          postgresqlUsername: my-username
          postgresqlPassword: my-password
    # the iam service is a 3rd party
    - name: iam-service
      helm:
        chart:
          name: fusionauth/fusionauth
        values:
          database:
            protocol: postgresql
            user: iam-user
            password: iam-password
            host: postgres
            name: iam-database
              user: root-db-username
              password: root-db-password
          search:
            engine: database
    
    最初の展開my-custom-service , 量
    kubectl apply -f my-custom-service/manifest.yaml
    
    番目の展開api , 定期的なヘルムのインストールです.我々自身のヘルムチャートを書く代わりに、我々はビルトインを使用することができましたcomponent charts これは、私たち自身のヘルムチャートを定義し、我々のKubernetesリソースの設定を維持するの間の妥協を提供します.現在のdevspaceの設定で、開発環境を起動できます.
    devspace dev
    
    そのコマンドは私たちのDockerイメージを構築し、私たちの開発Kubernetesdefault 名前空間.我々は現在、我々の開発マシン上で我々のコードを開発することができますし、我々の開発Kubernetesクラスタにプッシュしている状況です.どちらともhot reloading or auto-reloading , 私たちも私たちのコードを修正することができますし、結果は自動的に我々のクラスタに伝播されます.

    複数の環境に配備
    現在、我々は開発のために働くセットアップを持っています.我々は、我々のステージング環境設定から非常に遠く離れていません.最初に、我々のDockerイメージは、パターンに続いてタグ付けされる必要があります<my-repo>/<my-service>:staging-<commit-short-sha> . 第二に、我々のステージング環境は、外部データベースとIAMサービスに基づいています.したがって、ステージングにそれらを配備したくないので、それらに依存するサービスを適応させる必要があります.devspaceでは定義できるprofiles . 今まで、我々の設定は、任意のプロファイルへの参照を持っていないので、それはdevelopment プロファイル.我々は定義することができますstaging プロフィール、それをベースにしましょうdevelopment プロファイルと私たちが説明したように適応します.そのためには、次の設定を追加しましょうdevspace.yaml :
    profiles:
    - name: staging
      patches:
      # images -> adapt tag
      - op: replace
        path: /images/0=${DEVSPACE_RANDOM}
        value:
        - staging-${DEVSPACE_GIT_COMMIT}
      # postgres -> remove, we have an external database
      - op: remove
        path: /deployments/name=postgres
      # iam service -> remove, we have an external iam service
      - op: remove
        path: /deployments/name=iam-service
      # api 
      # -> we need an ingress
      - op: replace
        path: /deployments/name=api/helm/values/ingress
        value:
          enabled: true
          annotations:
            kubernetes.io/ingress.class: nginx-cert
            cert-manager.io/cluster-issuer: letsencrypt-prod
          hosts:
          - host: api-staging.my-staging-domain.com
            paths:
            - /
          tls:
          - secretName: api-tls
            hosts:
            - api-staging.my-staging-domain.com
      # -> we need up-to-date database accesses
      - op: replace
        path: /deployments/name=api/helm/values/postgres
        value:
            database: my-external-database
            hostname: my-external-database-hostname
            username: my-external-username
            password: my-external-password
      # my-custom-service -> nothing to do
    
    私たちはもちろん、同じ哲学に従ってparent profiles 定義するproduction プロファイル.その後、ステージングや生産に構築し、展開するのと同じくらい簡単です
    devspace deploy -p staging
    devspace deploy -p production
    
    明らかに、これらのプロファイルをリモートでデバッグすることも可能です.

    我々は、表面をひっくり返しました.
    多くの機能は、カスタムコマンドの定義のように、ポート(逆)転送、ファイルの同期、コンテナのログのストリーミングなど、ご利用いただけますhere . CDI/CDパイプラインで賢明に使用され、DevSpaceは大幅にあなたのソフトウェアを解放する方法を簡素化することができます.