Kubernetes でのマイクロサービスの開発についての質問が増えています。 開発者、特にインタープリタ型言語の開発者は、お気に入りの IDE でコードをすばやく修正し、ビルド/デプロイメントを待たずに F5 キーを押すだけで結果を確認したいと考えています。 また、モノリシック アプリケーションに関しては、データベースと Web サーバー (Docker、VirtualBox など) をローカルにインストールするだけで十分で、すぐに開発を楽しむことができます。 モノリスがマイクロサービスに分割され、Kubernetes が登場すると、相互に依存するようになり、すべてが
さまざまな時期に、私たちは問題に対してさまざまな解決策を試しました。 そして、蓄積された回避策、つまり単に「松葉杖」から始めます。
1.松葉杖
ほとんどの IDE には、FTP/SFTP を使用してサーバー上でコードを直接編集する機能があります。 この道は非常に明白なので、すぐにそれを使用することにしました。 その本質は次のとおりです。
- 開発環境のポッド (開発/レビュー) では、SSH アクセスを使用して追加のコンテナーが起動され、アプリケーションをコミット/デプロイする開発者の公開 SSH キーが転送されます。
- 初期段階(コンテナ内)
prepare-app
) コードをに転送しますemptyDir
アプリケーション コンテナおよび SSH サーバーからコードにアクセスできるようになります。
このようなスキームの技術的な実装をより深く理解するために、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 }}
最後の仕上げ
後は乗り換えだけです
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
出来上がり: デプロイメントを開始した開発者はサービス名で接続できます (クラスターへのアクセスを安全に許可する方法、
これは完全に機能するソリューションですが、実装の観点から見ると明らかな欠点があります。
- 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 を使用したローカル開発は、このプラットフォームの普及に比例して解決策が拡大している問題です。 開発者 (クライアント) から関連するリクエストを受け取り、私たちは最初に利用可能な手段でそれらの解決に取り組み始めましたが、長期的にはその効果が証明されませんでした。 幸いなことに、これは今だけでなく、私たちにとっても明らかになったので、より適切な手段がすでに世の中に現れており、テレプレゼンスはその中で最も有名です(ちなみに、
PS
K8s のヒントとテクニック シリーズのその他:
- «
Kubernetes のヒントとテクニック: NGINX Ingress のカスタム エラー ページ "; - «
クラスター内で実行されているリソースを Helm 2 管理に転送する "; - «
Web アプリケーションのノード割り当てと負荷について "; - «
開発サイトへのアクセス "; - «
大規模データベースのブートストラップを高速化する '。
出所: habr.com