Kubernetes のヒントとコツ: ローカル開発とテレプレゼンスについて

Kubernetes のヒントとコツ: ローカル開発とテレプレゼンスについて

Kubernetes でのマイクロサービスの開発についての質問が増えています。 開発者、特にインタープリタ型言語の開発者は、お気に入りの IDE でコードをすばやく修正し、ビルド/デプロイメントを待たずに F5 キーを押すだけで結果を確認したいと考えています。 また、モノリシック アプリケーションに関しては、データベースと Web サーバー (Docker、VirtualBox など) をローカルにインストールするだけで十分で、すぐに開発を楽しむことができます。 モノリスがマイクロサービスに分割され、Kubernetes が登場すると、相互に依存するようになり、すべてが 少し難しくなりました。 これらのマイクロサービスが増えるほど、問題も増えます。 再び開発を楽しむには、XNUMX つや XNUMX つ以上、場合によっては XNUMX 個以上の Docker コンテナを起動する必要があります。一般に、コンテナを最新の状態に保つ必要があるため、これにはかなりの時間がかかります。 。

さまざまな時期に、私たちは問題に対してさまざまな解決策を試しました。 そして、蓄積された回避策、つまり単に「松葉杖」から始めます。

1.松葉杖

ほとんどの IDE には、FTP/SFTP を使用してサーバー上でコードを直接編集する機能があります。 この道は非常に明白なので、すぐにそれを使用することにしました。 その本質は次のとおりです。

  1. 開発環境のポッド (開発/レビュー) では、SSH アクセスを使用して追加のコンテナーが起動され、アプリケーションをコミット/デプロイする開発者の公開 SSH キーが転送されます。
  2. 初期段階(コンテナ内) prepare-app) コードをに転送します emptyDirアプリケーション コンテナおよび SSH サーバーからコードにアクセスできるようになります。

Kubernetes のヒントとコツ: ローカル開発とテレプレゼンスについて

このようなスキームの技術的な実装をより深く理解するために、Kubernetes での関連する YAML 構成の断片を提供します。

設定

1.1. 値.yaml

ssh_pub_key:
  vasya.pupkin: <ssh public key in base64> 

それは vasya.pupkin 変数の値です ${GITLAB_USER_LOGIN}.

1.2. デプロイメント.yaml

...
{{ if eq .Values.global.debug "yes" }}
      volumes:
      - name: ssh-pub-key
        secret:
          defaultMode: 0600
          secretName: {{ .Chart.Name }}-ssh-pub-key
      - name: app-data
        emptyDir: {}
      initContainers:
      - name: prepare-app
{{ tuple "backend" . | include "werf_container_image" | indent 8 }}
        volumeMounts:
        - name: app-data
          mountPath: /app-data
        command: ["bash", "-c", "cp -ar /app/* /app-data/" ]
{{ end }}
      containers:
{{ if eq .Values.global.debug "yes" }}
      - name: ssh
        image: corbinu/ssh-server
        volumeMounts:
        - name: ssh-pub-key
          readOnly: true
          mountPath: /root/.ssh/authorized_keys
          subPath: authorized_keys
        - name: app-data
          mountPath: /app
        ports:
        - name: ssh
          containerPort: 22
          protocol: TCP
{{ end }}
      - name: backend
        volumeMounts:
{{ if eq .Values.global.debug "yes" }}
        - name: app-data
          mountPath: /app
{{ end }}
        command: ["/usr/sbin/php-fpm7.2", "--fpm-config", "/etc/php/7.2/php-fpm.conf", "-F"]
...

1.3. シークレット.yaml

{{ if eq .Values.global.debug "yes" }}
apiVersion: v1
kind: Secret
metadata:
  name: {{ .Chart.Name }}-ssh-pub-key
type: Opaque
data:
  authorized_keys: "{{ first (pluck .Values.global.username .Values.ssh_pub_key) }}"
{{ end }}

最後の仕上げ

後は乗り換えだけです 必要な gitlab-ci.yml 変数:

dev:
  stage: deploy
  script:
   - type multiwerf && source <(multiwerf use 1.0 beta)
   - type werf && source <(werf ci-env gitlab --tagging-strategy tag-or-branch --verbose)
   - werf deploy
     --namespace ${CI_PROJECT_NAME}-stage
     --set "global.env=stage"
     --set "global.git_rev=${CI_COMMIT_SHA}"
     --set "global.debug=yes"
     --set "global.username=${GITLAB_USER_LOGIN}"
 tags:
   - build

出来上がり: デプロイメントを開始した開発者はサービス名で接続できます (クラスターへのアクセスを安全に許可する方法、 すでに言った) をデスクトップから SFTP 経由でダウンロードし、クラスターに配信されるのを待たずにコードを編集します。

これは完全に機能するソリューションですが、実装の観点から見ると明らかな欠点があります。

  • Helm チャートを改良する必要があるため、将来的には読みにくくなります。
  • サービスを展開した人のみが使用できます。
  • コードを含むローカル ディレクトリと同期し、Git にコミットすることを忘れないでください。

2. テレプレゼンス

プロジェクト テレプレゼンス かなり前から知られていましたが、彼らが言うように、私たちは「実際に真剣に試すことができませんでした」。 しかし、需要は十分に機能したため、特にハブにはテレプレゼンスに関する資料が他にないため、ブログの読者にとって役立つ可能性のある経験を共有できることを嬉しく思います。

要するに、すべてがそれほど怖くないことが判明しました。 開発者側での実行が必要なすべてのアクションを、Helm チャート テキスト ファイルに配置しました。 NOTES.txt。 したがって、サービスを Kubernetes にデプロイした後、開発者は GitLab ジョブ ログでローカル開発環境を起動するための指示を確認します。

!!! Разработка сервиса локально, в составе Kubernetes !!!

* Настройка окружения
* * Должен быть доступ до кластера через VPN
* * На локальном ПК установлен kubectl ( https://kubernetes.io/docs/tasks/tools/install-kubectl/ )
* * Получить config-файл для kubectl (скопировать в ~/.kube/config)
* * На локальном ПК установлен telepresence ( https://www.telepresence.io/reference/install )
* * Должен быть установлен Docker
* * Необходим доступ уровня reporter или выше к репозиторию https://gitlab.site.com/group/app
* * Необходимо залогинится в registry с логином/паролем от GitLab (делается один раз):

#########################################################################
docker login registry.site.com
#########################################################################

* Запуск окружения

#########################################################################
telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name  }}:backend --mount=/tmp/app --docker-run -v `pwd`:/app -v /tmp/app/var/run/secrets:/var/run/secrets -ti registry.site.com/group/app/backend:v8
#########################################################################

この手順で説明されている手順については、最後の手順を除いて詳しく説明しません。 Telepresence の立ち上げ中に何が起こりますか?

テレプレゼンスを使用する

起動時に (上記の手順で指定された最後のコマンドを使用して)、次のように設定します。

  • マイクロサービスが実行されている名前空間。
  • 侵入するデプロイメントとコンテナーの名前。

残りの引数はオプションです。 当社のサービスが Kubernetes API と対話する場合、および Kubernetes API のために対話する場合 サービスアカウントが作成されました、デスクトップに証明書/トークンをマウントする必要があります。 これを行うには、オプションを使用します --mount=true (または --mount=/dst_path)、ルート (/) を Kubernetes コンテナーからデスクトップにマウントします。 この後、(OS とアプリケーションの起動方法に応じて) クラスターからの「キー」を使用できます。

まず、アプリケーションを実行するための最も汎用的なオプションである Docker コンテナーを見てみましょう。 これを行うには、キーを使用します --docker-run そして、コードを含むディレクトリをコンテナにマウントします。 -v `pwd`:/app

これはプロジェクト ディレクトリから実行することを前提としていることに注意してください。 アプリケーションコードはディレクトリにマウントされます /app コンテナの中。

次へ: -v /tmp/app/var/run/secrets:/var/run/secrets — 証明書/トークンを含むディレクトリをコンテナにマウントします。

このオプションの後には、アプリケーションが実行されるイメージが最後に続きます。 NB: イメージを構築するときは、指定する必要があります CMD または ENTRYPOINT!

次に具体的に何が起こるのでしょうか?

  • Kubernetes では、指定されたデプロイメントのレプリカの数が 0 に変更されます。代わりに、代替コンテナーを使用して新しいデプロイメントが起動されます。 backend.
  • デスクトップ上で 2 つのコンテナが起動します。XNUMX つ目は Telepresence (Kubernetes との間でリクエストをプロキシします) を使用し、XNUMX つ目は開発中のアプリケーションを使用します。
  • アプリケーションを含むコンテナーを実行すると、デプロイ中に Helm によって転送されたすべての ENV 変数が利用可能になり、すべてのサービスも利用できるようになります。 あとは、お気に入りの IDE でコードを編集し、その結果を楽しむだけです。
  • 作業の最後に、Telepresence が実行されているターミナルを閉じるだけで済みます (Ctrl+C でセッションを終了します)。Docker コンテナーはデスクトップ上で停止し、Kubernetes ではすべてが初期状態に戻ります。 残っているのは、コミットして MR を発行し、それをレビュー/マージ/… に転送することだけです (ワークフローに応じて)。

アプリケーションを Docker コンテナーで実行したくない場合 (たとえば、PHP ではなく Go で開発し、ローカルでビルドする場合)、Telepresence の起動はさらに簡単になります。

telepresence --namespace {{ .Values.global.env }} --swap-deployment {{ .Chart.Name  }}:backend --mount=true

アプリケーションが Kubernetes API にアクセスする場合は、keys ディレクトリ (https://www.telepresence.io/howto/volumes) をマウントする必要があります。 Linux用のユーティリティがあります プルート:

proot -b $TELEPRESENCE_ROOT/var/run/secrets/:/var/run/secrets bash

オプションを指定せずに Telepresence を起動した後 --docker-run すべての環境変数は現在のターミナルで使用できるため、アプリケーションはそのターミナルで起動する必要があります。

NB: たとえば、PHP を使用する場合は、開発のためにさまざまな op_cache、apc、およびその他のアクセラレータを忘れずに無効にする必要があります。無効にしないと、コードを編集しても望ましい結果が得られません。

結果

Kubernetes を使用したローカル開発は、このプラットフォームの普及に比例して解決策が拡大している問題です。 開発者 (クライアント) から関連するリクエストを受け取り、私たちは最初に利用可能な手段でそれらの解決に取り組み始めましたが、長期的にはその効果が証明されませんでした。 幸いなことに、これは今だけでなく、私たちにとっても明らかになったので、より適切な手段がすでに世の中に現れており、テレプレゼンスはその中で最も有名です(ちなみに、 足場 Googleより)。 私たちの使用経験はまだそれほど素晴らしいものではありませんが、すでに「店の同僚」に勧める理由ができています。ぜひ試してみてください。

PS

K8s のヒントとテクニック シリーズのその他:

出所: habr.com

コメントを追加します