Kubernetes クラスター内の古い機能ブランチの削除

Kubernetes クラスター内の古い機能ブランチの削除

Привет! 機能ブランチ (別名デプロイ プレビュー、レビュー アプリ) - これは、マスター ブランチがデプロイされるだけでなく、一意の URL への各プル リクエストもデプロイされるときです。 コードが実稼働環境で動作するかどうかを確認でき、その機能を他のプログラマーや製品スペシャリストに見せることができます。 プル リクエストで作業している間、古いコードの現在のデプロイが新しいコミットごとに削除され、新しいコードの新しいデプロイがロールアウトされます。 プル リクエストを master ブランチにマージするときに疑問が生じる場合があります。 フィーチャー ブランチは必要なくなりましたが、Kubernetes リソースはクラスター内に残ります。

機能ブランチの詳細

Kubernetes で機能ブランチを作成する XNUMX つのアプローチは、名前空間を使用することです。 つまり、運用環境の構成は次のようになります。

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end
spec:
  replicas: 3
...

機能ブランチの場合、名前空間はその識別子 (プル リクエスト番号など) と何らかのプレフィックス/ポストフィックス (たとえば、 -pr-):

kind: Namespace
apiVersion: v1
metadata:
  name: habr-back-end-pr-17
...

kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: habr-back-end-pr-17
spec:
  replicas: 1
...

一般的に、私は書きました Kubernetesオペレーター (クラスターリソースにアクセスできるアプリケーション)、 Github 上のプロジェクトへのリンク。 古い機能ブランチに属する名前空間が削除されます。 Kubernetes では、名前空間を削除すると、その名前空間内の他のリソースも自動的に削除されます。

$ kubectl get pods --all-namespaces | grep -e "-pr-"
NAMESPACE            ... AGE
habr-back-end-pr-264 ... 4d8h
habr-back-end-pr-265 ... 5d7h

クラスターに機能ブランチを実装する方法について読むことができます。 ここで и ここで.

動機

継続的インテグレーションを使用した典型的なプル リクエストのライフサイクルを見てみましょう (continuous integration):

  1. 新しいコミットをブランチにプッシュします。
  2. ビルドでは、リンターやテストが実行されます。
  3. Kubernetes プル リクエスト構成はオンザフライで生成されます (たとえば、その番号は完成したテンプレートに挿入されます)。
  4. kubectl apply を使用して、構成がクラスターに追加されます (デプロイ)。
  5. プル リクエストは master ブランチにマージされます。

プル リクエストで作業している間、古いコードの現在のデプロイが新しいコミットごとに削除され、新しいコードの新しいデプロイがロールアウトされます。 ただし、プル リクエストが master ブランチにマージされると、master ブランチのみが構築されます。 その結果、プル リクエストのことはすでに忘れており、その Kubernetes リソースはまだクラスター内にあることがわかりました。

使用方法を

以下のコマンドを使用してプロジェクトをインストールします。

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml

次の内容のファイルを作成し、次の方法でインストールします。 kubectl apply -f:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 3

パラメーター 名前空間サブストリング 他の名前空間からのプル リクエストの名前空間をフィルタリングするために必要です。 たとえば、クラスターに次の名前空間があるとします。 habr-back-end, habr-front-end, habr-back-end-pr-17, habr-back-end-pr-33の場合、削除候補は habr-back-end-pr-17, habr-back-end-pr-33.

パラメーター AfterDaysWithoutDeploy 古い名前空間を削除するために必要です。 たとえば、名前空間が作成された場合 3 дня 1 час 戻り、パラメータは次のことを示します 3 дня、この名前空間は削除されます。 名前空間が作成された場合は、逆方向にも機能します。 2 дня 23 часа 戻り、パラメータは次のことを示します 3 дня、この名前空間は削除されません。

もう XNUMX つパラメータがあります。これは、すべての名前空間をスキャンし、デプロイメントのない日数をチェックする頻度を決定します。 毎分チェック。 デフォルトでは等しいです 30 минутам.

これはどう動かすのですか

実際には、次のものが必要になります。

  1. デッカー 隔離された環境で作業するため。
  2. Minikube Kubernetes クラスターをローカルで起動します。
  3. キューブクル — クラスター管理用のコマンド ライン インターフェイス。

Kubernetes クラスターをローカルに構築します。

$ minikube start --vm-driver=docker
minikube v1.11.0 on Darwin 10.15.5
Using the docker driver based on existing profile.
Starting control plane node minikube in cluster minikube.

特定 kubectl デフォルトでローカルクラスターを使用します。

$ kubectl config use-context minikube
Switched to context "minikube".

実稼働環境用の構成をダウンロードします。

$ curl https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/configs/production.yml > stale-feature-branch-production-configs.yml

実稼働構成は古い名前空間をチェックするように構成されており、新しく生成されたクラスターには古い名前空間が存在しないため、環境変数を置き換えます。 IS_DEBUG на true。 この値を使用すると、パラメータ afterDaysWithoutDeploy は考慮されず、デプロイが行われない日はネームスペースがチェックされず、部分文字列 (-pr-).

オンの場合 Linux:

$ sed -i 's|false|true|g' stale-feature-branch-production-configs.yml

オンの場合 macOS:

$ sed -i "" 's|false|true|g' stale-feature-branch-production-configs.yml

プロジェクトのインストール:

$ kubectl apply -f stale-feature-branch-production-configs.yml

リソースがクラスターに出現していることを確認する StaleFeatureBranch:

$ kubectl api-resources | grep stalefeaturebranches
NAME                 ... APIGROUP                             ... KIND
stalefeaturebranches ... feature-branch.dmytrostriletskyi.com ... StaleFeatureBranch

クラスターにオペレーターが出現していることを確認します。

$ kubectl get pods --namespace stale-feature-branch-operator
NAME                                           ... STATUS  ... AGE
stale-feature-branch-operator-6bfbfd4df8-m7sch ... Running ... 38s

ログを見ると、リソースを処理する準備ができています。 StaleFeatureBranch:

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Operator Version: 0.0.1"}
...
... "msg":"Starting EventSource", ... , "source":"kind source: /, Kind="}
... "msg":"Starting Controller", ...}
... "msg":"Starting workers", ..., "worker count":1}

既製品を取り付けます fixtures リソースの (クラスターリソースをモデル化するための既製の構成) StaleFeatureBranch:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/stale-feature-branch.yml

構成では、部分文字列を含む名前空間を検索することが示されています。 -pr- 一回 1 минуту.:

apiVersion: feature-branch.dmytrostriletskyi.com/v1
kind: StaleFeatureBranch
metadata:
  name: stale-feature-branch
spec:
  namespaceSubstring: -pr-
  afterDaysWithoutDeploy: 1 
  checkEveryMinutes: 1

オペレーターが応答し、名前空間をチェックする準備ができました。

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Stale feature branch is being processing.","namespaceSubstring":"-pr-","afterDaysWithoutDeploy":1,"checkEveryMinutes":1,"isDebug":"true"}

セット fixtures、XNUMX つの名前空間 (project-pr-1, project-pr-2) そして彼ら deployments, services, ingress、 等々:

$ kubectl apply -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/first-feature-branch.yml -f https://raw.githubusercontent.com/dmytrostriletskyi/stale-feature-branch-operator/master/fixtures/second-feature-branch.yml
...
namespace/project-pr-1 created
deployment.apps/project-pr-1 created
service/project-pr-1 created
horizontalpodautoscaler.autoscaling/project-pr-1 created
secret/project-pr-1 created
configmap/project-pr-1 created
ingress.extensions/project-pr-1 created
namespace/project-pr-2 created
deployment.apps/project-pr-2 created
service/project-pr-2 created
horizontalpodautoscaler.autoscaling/project-pr-2 created
secret/project-pr-2 created
configmap/project-pr-2 created
ingress.extensions/project-pr-2 created

上記のすべてのリソースが正常に作成されたことを確認します。

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...
NAME                              ... READY ... STATUS  ... AGE
pod/project-pr-1-848d5fdff6-rpmzw ... 1/1   ... Running ... 67s

NAME                         ... READY ... AVAILABLE ... AGE
deployment.apps/project-pr-1 ... 1/1   ... 1         ... 67s
...

を含めて以来 debug、名前空間 project-pr-1 и project-pr-2したがって、他のすべてのリソースは、パラメータを考慮せずにすぐに削除する必要があります。 afterDaysWithoutDeploy。 これはオペレーターのログで確認できます。

$ kubectl logs stale-feature-branch-operator-6bfbfd4df8-m7sch -n stale-feature-branch-operator
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-1"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-1","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-1"}
... "msg":"Namespace should be deleted due to debug mode is enabled.","namespaceName":"project-pr-2"}
... "msg":"Namespace is being processing.","namespaceName":"project-pr-2","namespaceCreationTimestamp":"2020-06-16 18:43:58 +0300 EEST"}
... "msg":"Namespace has been deleted.","namespaceName":"project-pr-2"}

リソースの空き状況を確認すると、次のステータスになります。 Terminating (削除プロセス)またはすでに削除されています(コマンド出力は空です)。

$ kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-1 && kubectl get namespace,pods,deployment,service,horizontalpodautoscaler,configmap,ingress -n project-pr-2
...

作成プロセスを繰り返すことができます fixtures 数回繰り返し、XNUMX 分以内に削除されていることを確認してください。

代替案

クラスター内で作業するオペレーターの代わりに何ができるでしょうか? いくつかのアプローチがありますが、それらはすべて不完全であり (欠点は主観的なものです)、特定のプロジェクトに何が最適であるかを誰もが自分で決定します。

  1. master ブランチの継続的統合ビルド中にフィーチャー ブランチを削除します。

    • これを行うには、どのプル リクエストがビルド中のコミットに関連しているかを知る必要があります。 フィーチャー ブランチの名前空間にはプル リクエストの識別子 (その番号またはブランチの名前) が含まれるため、識別子は常にコミットで指定する必要があります。
    • Master ブランチのビルドが失敗します。 たとえば、次の段階があります: プロジェクトのダウンロード、テストの実行、プロジェクトのビルド、リリースの作成、通知の送信、最後のプル リクエストの機能ブランチのクリア。 通知の送信時にビルドが失敗した場合は、クラスター内のすべてのリソースを手動で削除する必要があります。
    • 適切なコンテキストがなければ、マスター ビルド内の機能ブランチを削除することは明らかではありません。

  2. Webhook の使用 ().

    • これはあなたのアプローチではないかもしれません。 たとえば、 ジェンキンズの場合、構成をソース コードに保存する機能をサポートしているパイプラインは XNUMX 種類のみです。 Webhook を使用する場合、Webhook を処理する独自のスクリプトを作成する必要があります。 このスクリプトは Jenkins インターフェイスに配置する必要がありますが、メンテナンスが困難です。

  3. 書き込む クロンジョブ そして、Kubernetes クラスターを追加します。

    • 執筆とサポートに時間を費やします。
    • この演算子はすでに同様のスタイルで動作しており、文書化され、サポートされています。

記事にご注目いただきありがとうございます。 Github 上のプロジェクトへのリンク.

出所: habr.com

コメントを追加します