DUICUO

この記事では、Helm Charts 開発の完全な例を示します。

Helm は比較的簡単に使用できますが、主に Go テンプレートの制限のため、独自の Chart パッケージを開発するのは非常に困難です。

構文ルールはユーザーフレンドリーではないため、完全な例を使用して Helm Chart パッケージの開発方法を説明します。

応用

ここでは、Ghostブログアプリケーションを例に、完全なHelm Chartパッケージの開発方法を説明します。Ghostは、Node.jsベースのオープンソースブログプラットフォームです。Helm Chartパッケージを開発する前に、最も重要なことは、アプリケーションの使用方法とデプロイ方法を理解することです。そうでなければ、対応するChartパッケージを作成することは不可能です。

Ghost を起動する最も簡単な方法は、イメージから直接起動することです。

  docker run -d --name my-ghost -p 2368: 2368 ゴースト

これで、http://localhost:2368 経由で Ghost ブログにアクセスできるようになります。Kubernetes クラスターに Ghost のレプリカを 2 つデプロイする場合は、以下のリソース マニフェスト ファイルを直接使用できます。

 # ゴースト/デプロイメント.yaml
apiバージョン: apps/ v1
種類: デプロイメント
メタデータ:
名前: ゴースト
仕様:
セレクタ:
一致ラベル:
アプリ: ゴーストアプリ
レプリカ: 2
テンプレート:
メタデータ:
ラベル:
アプリ: ゴーストアプリ
仕様:
コンテナ:
-名前: ゴーストアプリ
画像: ゴースト
ポート:
-コンテナポート: 2368
---
# ゴースト/サービス.yaml
apiバージョン: v1
種類: サービス
メタデータ:
名前: ゴースト
仕様:
タイプ: NodePort
セレクタ:
アプリ: ゴーストアプリ
ポート:
- プロトコル: TCP
ポート: 80
ターゲットポート: 2368

kubectl を使用して上記のリソース オブジェクトを直接適用できます。

  kubectl apply -f ghost/deployment.yaml ghost /service.yaml
deployment.apps/ ゴーストが作成されました
サービス/ ゴースト作成
kubectl get pod -l app= ghost-app
名前準備完了ステータス再起動年齢
ghost-dfd958cc9-4s9b9 1/ 1 ランニング0 2分54秒
ghost-dfd958cc9-84kmv 1/1 ランニング0 2分54秒
kubectl でサービスゴーストを取得
名前タイプクラスターIP 外部IP ポート年齢
ゴーストノードポート10.97.227. 160 <なし> 80:31950/ TCP 3分33秒

この方法では、http://:31950: 経由で Ghost にアクセスできます。

おばけ

Ghostのデプロイは非常にシンプルに見えますが、環境ごとに異なる設定が必要な場合はどうすればよいでしょうか?例えば、異なる環境(ステージング、本番環境)にデプロイする場合、Kubernetesリソースのマニフェストファイルを何度もコピーする必要があるでしょうか?これはほんの一例です。アプリケーションをデプロイする必要があるシナリオは他にもたくさんあり、このアプローチではメンテナンスが非常に困難です。そこでHelmが登場し、その負担を軽減してくれます。

基本テンプレート

それでは、新しいHelm Chartパッケージを作成しましょう。`helm create`コマンドを使用するだけです。

  ヘルム作成マイゴースト
my-ghostの作成
ツリーマイゴースト
私の幽霊
チャート.yaml
チャート
テンプレート
NOTES.txt
_helpers.tpl
デプロイメント.yaml
hpa.yaml
イングレス.yaml
サービス.yaml
サービスアカウント.yaml
テスト
テスト接続.yaml
.yaml
3つのディレクトリ10個のファイル

このコマンドは、デフォルトの Helm Chart パッケージのスキャフォールディングを作成し、次の未使用のファイルを削除できるようにします。

 テンプレート/ テスト/ テスト- connection.yaml
テンプレート/ serviceaccount.yaml
テンプレート/ イングレス.yaml
テンプレート/ hpa.yaml
テンプレート/ NOTES .txt

次に、templates/deployment.yaml テンプレート ファイルを変更します。

 # テンプレート/デプロイメント.yaml
apiバージョン: apps/ v1
種類: デプロイメント
メタデータ:
名前: ゴースト
仕様:
セレクタ:
一致ラベル:
アプリ: ゴーストアプリ
レプリカ: {{ .Values.replicaCount }}
テンプレート:
メタデータ:
ラベル:
アプリ: ゴーストアプリ
仕様:
コンテナ:
-名前: ゴーストアプリ
画像: {{ .Values. image }}
ポート:
-コンテナポート: 2368
環境:
-名前: NODE_ENV
値: {{ .Values. node_env | デフォルト"production" }}
{{ - if .Values. url }}
-名前: URL
値: http ://{{ .Values. url }}
{{ - 終わり}}

これは以前のリソースマニフェストファイルと非常に似ていますが、`replicas` の値が `.Values.replicaCount` テンプレートに置き換えられており、`replicaCount` の値がレンダリングに使用されることを示しています。環境変数を設定して Ghost を設定することもできます。同様に、`templates/service.yaml` テンプレートファイルの内容を変更します。

 # テンプレート/サービス.yaml
apiバージョン: v1
種類: サービス
メタデータ:
名前: ゴースト
仕様:
セレクタ:
アプリ: ゴーストアプリ
タイプ: {{ .Values.service.type }}
ポート:
- プロトコル: TCP
ターゲットポート: 2368
ポート: {{ .Values.service.port }}
{{ - if (and (or (eq .Values.service. type "NodePort" ) (eq .Values.service. type "LoadBalancer" ) ) (not (empty .Values.service. nodePort) ) ) }}
ノードポート: {{ .Values.service. nodePort }}
{{ - else if eq .Values.service. type "ClusterIP" }}
ノードポート: null
{{ - 終わり}}

複数のシナリオ間での互換性を確保するため、Serviceタイプをユーザーがカスタマイズできるようにしています。NodePortタイプの場合、nodePortの値も設定できます。ただし、NodePortとして設定されていても、ユーザーがnodePortを明示的に指定しない可能性があるため、条件チェックが必要です。そのため、テンプレートに条件チェックを組み込みました。

 {{ - if ( and ( or ( eq . Values . service . type "NodePort" ) ( eq . Values . service . type "LoadBalancer" )) ( not ( empty . Values . service . nodePort ))) }}

nodePort は、service.type が NodePort または LoadBalancer のいずれかであり、service.nodePort が空でない場合にのみレンダリングされます。

最も重要なことは、values.yaml ファイルにデフォルト値を提供することです。以下に示すのは、私たちが提供したデフォルト値です。

 # 値.yaml
レプリカ数: 1
画像: ゴースト
node_env: プロダクション
URL: ghost.k8s.local
サービス:
タイプ: NodePort
ポート: 80

次に、`helm template` コマンドを使用してテンプレート出力をレンダリングします。

  helm テンプレート--debug my-ghost
install.go:178: [デバッグ] 元のチャートのバージョン: ""
install.go:195: [デバッグ] チャートパス: /Users/ych/devs/workspace/yidianzhishi/course/k8strain3/content/helm/manifests/ my-ghost

---
# ソース: my-ghost/templates/service.yaml
apiバージョン: v1
種類: サービス
メタデータ:
名前: ゴースト
仕様:
セレクタ:
アプリ: ゴーストアプリ
タイプ: NodePort
ポート:
- プロトコル: TCP
ターゲットポート: 2368
ポート: 80
---
# ソース: my-ghost/templates/deployment.yaml
apiバージョン: apps/ v1
種類: デプロイメント
メタデータ:
名前: ゴースト
仕様:
セレクタ:
一致ラベル:
アプリ: ゴーストアプリ
レプリカ: 1
テンプレート:
メタデータ:
ラベル:
アプリ: ゴーストアプリ
仕様:
コンテナ:
-名前: ゴーストアプリ
画像: ゴースト
ポート:
-コンテナポート: 2368
環境:
-名前: NODE_ENV
価値: 生産
-名前: URL
値: http : //ghost.k8s.local

上記のレンダリング結果は、環境変数やサービス公開方法などを制御できるなど、柔軟性が向上していることを除けば、上記のリソース マニフェスト ファイルと基本的に同じです。

命名テンプレート

Helm Chartsテンプレートを使用してGhostをレンダリングおよびインストールできるようになりましたが、テンプレートにはまだ改善の余地が数多くあります。例えば、リソースオブジェクトの名前が固定されているため、同じ名前空間に複数のアプリケーションをインストールできません。そのため、通常はリソースオブジェクトの名前をChart名またはリリース名に置き換えています。

先ほど作成したデフォルトのテンプレートには、名前とタグに関連する命名テンプレートを含む_helpers.tplというファイルが含まれています。これらは直接使用できます。以下は、デフォルトで生成される命名テンプレートです。

 {{ /*
グラフの名前を展開します。
/* }}
{{ - "my-ghost.name" を定義- }}
{{ - default .Chart. Name .Values. nameOverride | trunc 63 | trimSuffix "-" }}
{{ - 終わり}}
{{ /*
デフォルトの完全修飾アプリ名を作成します。
一部の Kubernetes 名フィールドは 63 文字に制限されているため (DNS 命名仕様により)、63 文字で切り捨てられます。
リリース名にチャート名が含まれている場合は、それが完全な名前として使用されます。
/* }}
{{ - "my-ghost.fullname" を定義- }}
{{ - if .Values. fullnameOverride }}
{{ - .Values. fullnameOverride | trunc 63 | trimSuffix "-" }}
{{ - それ以外}}
{{ - $name := default .Chart. Name .Values. nameOverride }}
{{ - $name .Release.Name が含まれている場合} }
{{ - .Release. Name | trunc 63 | trimSuffix "-" }}
{{ - それ以外}}
{{ - printf "%s-%s" .Release. Name $name | trunc 63 | trimSuffix "-" }}
{{ - 終わり}}
{{ - 終わり}}
{{ - 終わり}}
{{ /*
チャート ラベルで使用されるチャート名とバージョンを作成します。
/* }}
{{ - "my-ghost.chart" を定義- }}
{{ - printf "%s-%s" .Chart. Name .Chart. Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{ - 終わり}}
{{ /*
一般的なラベル
/* }}
{{ - "my-ghost.labels" を定義- }}
helm.sh/chart: {{ "my-ghost.chart" を含めます。}}
{{ "my-ghost.selectorLabels" を含めます。}}
{{ - if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart. AppVersion | quote }}
{{ - 終わり}}
app.kubernetes.io/ 管理対象: {{ .Release. Service }}
{{ - 終わり}}
{{ /*
セレクタラベル
/* }}
{{ - "my-ghost.selectorLabels" を定義- }}
app.kubernetes.io/name: {{ "my-ghost.name" を含めます。}}
app.kubernetes.io/instance: {{ .Release.Name }}
{{ - 終わり}}

次に、デプロイメントの名前とタグを置き換えます。

 # テンプレート/デプロイメント.yaml
apiバージョン: apps/ v1
種類: デプロイメント
メタデータ:
名前: {{ template "my-ghost.fullname" . }}
ラベル:
{{ include "my-ghost.labels" . | インデント 4 }}
仕様:
セレクタ:
一致ラベル:
{{ include "my-ghost.selectorLabels" . | インデント 6 }}
レプリカ: {{ .Values.replicaCount }}
テンプレート:
メタデータ:
ラベル:
{{ include "my-ghost.selectorLabels" . | インデント 8 }}
仕様:
# その他の仕様...

デプロイメントにラベルを追加し、labelSelectorを命名テンプレートmy-ghost.selectorLabelsに置き換えます。同様に、サービスにも対応する変更を加えます。

 apiバージョン: v1
種類: サービス
メタデータ:
名前: {{ template "my-ghost.fullname" . }}
ラベル:
{{ include "my-ghost.labels" . | インデント 4 }}
仕様:
セレクタ:
{{ include "my-ghost.selectorLabels" . | インデント 4 }}
タイプ: {{ .Values.service.type }}
# その他の仕様...

ここで、Helm テンプレート レンダリングを使用して結果が正しいかどうかを確認できます。

  helm テンプレート--debug my-ghost
install.go:178: [デバッグ] 元のチャートのバージョン: ""
install.go:195: [デバッグ] チャートパス: /Users/ych/devs/workspace/yidianzhishi/course/k8strain3/content/helm/manifests/ my-ghost

---
# ソース: my-ghost/templates/service.yaml
apiバージョン: v1
種類: サービス
メタデータ:
名前: リリース名-私のゴースト
ラベル:
helm.sh/chart: my-ghost-0 .1. 0
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
app.kubernetes.io/バージョン: "1.16.0"
app.kubernetes.io/ 管理者: Helm
仕様:
セレクタ:
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
タイプ: NodePort
ポート:
- プロトコル: TCP
ターゲットポート: 2368
ポート: 80
---
# ソース: my-ghost/templates/deployment.yaml
apiバージョン: apps/ v1
種類: デプロイメント
メタデータ:
名前: リリース名-私のゴースト
ラベル:
helm.sh/chart: my-ghost-0 .1. 0
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
app.kubernetes.io/バージョン: "1.16.0"
app.kubernetes.io/ 管理者: Helm
仕様:
セレクタ:
一致ラベル:
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
レプリカ: 1
テンプレート:
メタデータ:
ラベル:
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
仕様:
コンテナ:
-名前: ゴーストアプリ
画像: ゴースト
ポート:
-コンテナポート: 2368
環境:
-名前: NODE_ENV
価値: 生産
-名前: URL
値: http : //ghost.k8s.local

バージョン互換性

Kubernetes は非常に高速にイテレーションされるため、Chart パッケージを開発する際には、Kubernetes の異なるバージョン、特に Ingress リソースのバージョンとの互換性を考慮することが不可欠です。Kubernetes バージョン 1.19 では、Ingress リソース用の新しい API である networking.k8s.io/v1 が導入されました。この API の使用方法は以前の networking.k8s.io/v1beta1 ベータ版とほぼ同様ですが、以前の extensions/v1beta1 バージョンとは、特にリソースオブジェクトのプロパティにおいて大きく異なります。したがって、異なるバージョン間での互換性を確保するには、テンプレート内で Ingress オブジェクトを適切に処理する必要があります。

新しいリソース オブジェクト形式を以下に示します。

 apiバージョン: networking.k8s.io/ v1
種類: イングレス
メタデータ:
名前: 最小進入
注釈:
nginx.ingress.kubernetes.io/ 書き換え-target : /
仕様:
イングレスクラス名: nginx
ルール:
- http :
パス:
-パス: / testpath
パスタイプ: プレフィックス
バックエンド:
サービス:
名前: テスト
ポート:
番号: 80

リソース オブジェクト形式の古いバージョンは次のとおりです。

 apiバージョン: extensions/ v1beta1
種類: イングレス
メタデータ:
名前: 最小侵入
注釈:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ 書き換え-target : /
仕様:
ルール:
- http :
パス:
-パス: / testpath
バックエンド:
サービス名: テスト
サービスポート: 80

それでは、GhostにIngressテンプレートを追加してみましょう。templates/ingress.yamlという名前の新しいテンプレートファイルを作成し、まずIngressテンプレートのv1バージョンを追加します。

 apiバージョン: networking.k8s.io/ v1
種類: イングレス
メタデータ:
名前: ゴースト
仕様:
イングレスクラス名: nginx
ルール:
-ホスト: ghost.k8s.local
http :
パス:
-パス:​​ /
パスタイプ: プレフィックス
バックエンド:
サービス:
名前: ゴースト
ポート:
番号: 80

次に、同様に、テンプレート パラメータを使用して名前とサービス名を置き換えます。

 api バージョン: networking.k8s.io/v1  
種類: イングレス
メタデータ
名前: {{ template "my-ghost.fullname" . }}
ラベル:
{{ include "my-ghost.labels" . | インデント4 }}
仕様:
イングレスクラス名: nginx
ルール
- ホスト: {{ .Values ​​.url }}
http :
パス:
- パス/
パスタイプ: プレフィックス
バックエンド:
サービス
名前: {{ template "my-ghost.fullname" . }}
ポート:
番号: {{ .Values ​​.service .port }}

次に、他のバージョン形式との互換性について説明します。これには Capabilities オブジェクトを使用する必要があります。Chart パッケージの `_helpers.tpl` ファイルに、クラスターのバージョンまたは API を識別するための命名テンプレートをいくつか追加します。

 {{ /* KubeVersion をオーバーライドできるようにします。 */ }}
{{ - 「my-ghost.kubeVersion」 を定義します- }}
{{ - デフォルトの.Capabilities.KubeVersion。 バージョンの値。 kubeVersionOverride - }}
{{ - 終わり -
{{ /* Ingress API バージョンを取得 */ }}
{{ - "my-ghost.ingress.apiVersion" を定義- }}
{{ - if and ( .Capabilities.APIVersions. Has "networking.k8s.io/v1" ) (semverCompare ">= 1.19-0" (include "my-ghost.kubeVersion" . ) ) - }}
{{ - "networking.k8s.io/v1" を印刷- }}
{{ - else if .Capabilities.APIVersions. has "networking.k8s.io/v1beta1 - }}
{{ - "networking.k8s.io/v1beta1" を印刷- }}
{{ - それ以外 - }}
{{ - "extensions/v1beta1" を印刷- }}
{{ - 終わり - }}
{{ - 終わり - }}
{{ /* Ingress の安定性をチェック */ }}
{{ - "my-ghost.ingress.isStable" を定義- }}
{{ - eq (include "my-ghost.ingress.apiVersion" . ) "networking.k8s.io/v1" - }}
{{ - 終わり - }}
{{ /* Ingress が pathType をサポートしているかどうか確認 */ }}
{{ /* pathType は Kubernetes 1.18 で networking.k8s.io/v1beta1 に追加されました */ }}
{{ - "my-ghost.ingress.supportsPathType" を定義- }}
{{ - または(eq (include "my-ghost.ingress.isStable" . ) "true" ) (および(eq (include "my-ghost.ingress.apiVersion" . ) "networking.k8s.io/v1beta1" ) (semverCompare ">= 1.18-0" (include "my-ghost.kubeVersion" . ) ) ) - }}
{{ - 終わり - }}

上記では、`.Capabilities.APIVersions.Has` を使用して、使用すべき APIVersion を決定しました。バージョンが `networking.k8s.io/v1` の場合、`isStable` として定義されます。さらに、バージョンに基づいて `pathType` 属性のサポートが必要かどうかを判断しました。次に、Ingress オブジェクトテンプレートで、上記で定義した命名テンプレートを使用して、使用する属性を以下のように決定します。

 {{ - .Values.ingress. が有効になっている場合}}
{{ - $apiIsStable := eq (include "my-ghost.ingress.isStable" . ) "true" - }}
{{ - $ingressSupportsPathType := eq (include "my-ghost.ingress.supportsPathType" . ) "true" - }}
apiバージョン: {{ include "my-ghost.ingress.apiVersion" . }}
種類: イングレス
メタデータ:
名前: {{ template "my-ghost.fullname" . }}
注釈:
nginx.ingress.kubernetes.io/ ssl -redirect : "false"
{{ - if かつ.Values.ingress. ingressClass ( $apiIsStable ではない) }}
kubernetes.io/ingress.class: {{ .Values.ingress. ingressClass }}
{{ - 終わり}}
ラベル:
{{ - "my-ghost.labels" をインクルードします| nindent 4 }}
仕様:
{{ - if および.Values.ingress. ingressClass $apiIsStable }}
イングレスクラス名: {{ .Values.ingress. ingressClass }}
{{ - 終わり}}
ルール:
{{ -でない場合( .Values. url) }}
-ホスト: {{ .Values. url }}
http :
{{ - それ以外}}
- http :
{{ - 終わり}}
パス:
-パス:​​ /
{{ - $ingressSupportsPathType の場合}}
パスタイプ: プレフィックス
{{ - 終わり}}
バックエンド:
{{ - $apiIsStable の場合}}
サービス:
名前: {{ template "my-ghost.fullname" . }}
ポート:
番号: {{ .Values.service.port }}
{{ - それ以外}}
サービス名: {{ template "my-ghost.fullname" . }}
サービスポート: {{.Values.service.port}}
{{ - 終わり}}
{{ - 終わり}}

一部のシナリオではIngressを使用してサービスを公開する必要がないため、まず`ingress.enabled`プロパティを使用してレンダリングが必要かどうかを制御します。次に、現在のクラスターがAPIの安定バージョンを使用しているかどうかを示す`$apiIsStable`変数を定義します。この変数に基づいて、異なるプロパティをレンダリングする必要があります。例えば、`ingressClass`の場合、APIの安定バージョンであれば`spec.ingressClassName`を使用して指定します。それ以外の場合は、`kubernetes.io/ingress.class`アノテーションを使用して指定します。最後に、次のデフォルトのIngress構成データを`values.yaml`ファイルに追加します。

入口:
有効: true
イングレスクラス: nginx

ここで、Helm Chart テンプレートを再度レンダリングして、リソース インベントリ データを検証します。

  helm テンプレート--debug my-ghost
install.go:178: [デバッグ] 元のチャートのバージョン: ""
install.go:195: [デバッグ] チャートパス: /Users/ych/devs/workspace/yidianzhishi/course/k8strain3/content/helm/manifests/ my-ghost

---
# ソース: my-ghost/templates/service.yaml
apiバージョン: v1
種類: サービス
メタデータ:
名前: リリース名-私のゴースト
ラベル:
helm.sh/chart: my-ghost-0 .1. 0
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
app.kubernetes.io/バージョン: "1.16.0"
app.kubernetes.io/ 管理者: Helm
仕様:
セレクタ:
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
タイプ: NodePort
ポート:
- プロトコル: TCP
ターゲットポート: 2368
ポート: 80
---
# ソース: my-ghost/templates/deployment.yaml
apiバージョン: apps/ v1
種類: デプロイメント
メタデータ:
名前: リリース名-私のゴースト
ラベル:
helm.sh/chart: my-ghost-0 .1. 0
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
app.kubernetes.io/バージョン: "1.16.0"
app.kubernetes.io/ 管理者: Helm
仕様:
セレクタ:
一致ラベル:
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
レプリカ: 1
テンプレート:
メタデータ:
ラベル:
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
仕様:
コンテナ:
-名前: ゴーストアプリ
画像: ゴースト
ポート:
-コンテナポート: 2368
環境:
-名前: NODE_ENV
価値: 生産
-名前: URL
値: http : //ghost.k8s.local
---
# ソース: my-ghost/templates/ingress.yaml
apiバージョン: networking.k8s.io/ v1
種類: イングレス
メタデータ:
名前: リリース名-私のゴースト
注釈:
nginx.ingress.kubernetes.io/ ssl -redirect : "false"
ラベル:
helm.sh/chart: my-ghost-0 .1. 0
app.kubernetes.io/名前: my-ghost
app.kubernetes.io/instance: リリース名
app.kubernetes.io/バージョン: "1.16.0"
app.kubernetes.io/ 管理者: Helm
仕様:
イングレスクラス名: nginx
ルール:
-ホスト: ghost.k8s.local
http :
パス:
-パス:​​ /
パスタイプ: プレフィックス
バックエンド:
サービス:
名前: リリース名-私のゴースト
ポート:
番号: 80

上記のリソースリストを見ると、期待通りの結果が得られていることがわかります。インストールして結果をテストしてみましょう。

  helm upgrade --install my-ghost ./ my-ghost -n default
リリース「my-ghost」は存在しません。今すぐインストールします
名前: my-ghost
最終デプロイ日時: 2022年3月17日(木) 13:11:15
名前空間: デフォルト
ステータス: 展開済み
改訂: 1
テストスイート: なし
helm ls -n デフォルト
名前名前空間リビジョン更新ステータスチャートアプリバージョン
my-ghost デフォルト1 2022-03-17 13:11:15. 79828 + 0800 CST デプロイ済みmy-ghost-0 .1. 0 1.16. 0
kubectl get pods -n デフォルト
名前準備完了ステータス再起動年齢
my-ghost-7cf7fb6484-75hkk 1/1 実行中0 3分9秒
kubectl get svc -n デフォルト
名前タイプクラスターIP 外部IP ポート年齢
kubernetes ClusterIP 10.96.0. 1 <なし> 443/ TCP 142d
my-ghost ノードポート10.108.125. 187 <なし> 80:32433/ TCP 3分20秒
kubectl get ingress -n デフォルト
名前クラスホストアドレスポート年齢
my-ghost nginx ghost.k8s. ローカル192.168.31. 31 80 3分32秒

その後、Ghost は正常にデプロイされ、ドメイン http://ghost.k8s.local 経由でアクセスできるようになります。

おばけ

粘り強さ

上記で使用したGhostイメージはデフォルトでSQLiteデータベースを使用するため、データの永続化が不可欠です。もちろん、ユーザーがこれを選択できるようにする必要があります。templates/deployment.yamlファイルを編集し、関連するボリューム設定を追加します。

 # その他の仕様...
仕様:
ボリューム:
-名前: ゴーストデータ
{{ - .Values.persistence. が有効になっている場合}}
永続ボリュームクレーム:
クレーム名: {{ .Values.persistence. existingClaim | デフォルト( "my-ghost.fullname"を含む . ) }}
{{ - それ以外}}
空ディレクトリ: {}
{{ 終わり}}
コンテナ:
-名前: ゴーストアプリ
画像: {{ .Values. image }}
ボリュームマウント:
-名前: ゴーストデータ
マウントパス: /var/lib/ghost/ コンテンツ
# その他の仕様...

ここでは、`persistence.enabled` を使用して、永続データを有効にする必要があるかどうかを判断します。有効になっている場合は、ユーザーが既存のPVCオブジェクトを提供しているかどうかを確認する必要があります。提供されていない場合は、適切なPVCオブジェクトを自分で作成する必要があります。永続性が不要な場合は、`emptyDir:{}` を使用できます。以下の内容を含む `templates/pvc.yaml` テンプレートを追加します。

 {{ - .Values.persistence . enabled の場合 .Values.persistence. existingClaim ではない) }}
種類: PersistentVolumeClaim
apiバージョン: v1
メタデータ:
名前: {{ template "my-ghost.fullname" . }}
ラベル:
{{ - "my-ghost.labels" をインクルードします| nindent 4 }}
仕様:
{{ - if .Values.persistence.storageClass }}
ストレージクラス名: {{ .Values.persistence. storageClass | quote }}
{{ - 終わり}}
アクセスモード:
- {{ .Values.persistence. accessMode | 引用}}
リソース:
リクエスト:
ストレージ: {{ .Values.persistence. size | quote }}
{{ - 終わり - }}

アクセスモード、ストレージ容量、StorageClass、既存のPVCはすべてValuesで指定できるため、柔軟性が向上します。対応するvalues.yamlファイルにデフォルトの設定を指定できます。

 ## PVCを使用してデータの永続性を有効にするかどうか
持続性:
有効: true
## storageClass を使用するかどうか。使用しない場合は、構成を追加します。
# ストレージクラス: "xxx"
##
## 既存の PVC オブジェクトを使用する場合は、それを以下の existingClaim 変数に渡すだけです。
# 既存の請求: あなたの請求
accessMode: ReadWriteOnce # アクセスモード
サイズ: 1Gi # ストレージ容量

カスタムメイド

上記の主な要件に加えて、いくつかの追加のカスタマイズ要件があります。例えば、ユーザーは更新戦略を設定したい場合があります。更新戦略は静的ではないため、これは以前とは異なり、新しい関数 toYaml を使用する必要があります。

 {{ - if .Values. updateStrategy }}
戦略: {{ toYaml .Values. updateStrategy | nindent 4 }}
{{ - 終わり}}

つまり、`updateStrategy` の値を 4 つのスペースを残したまま YAML 形式に変換します。次に、`nodeSelector`、tolerance、affinity を追加するかどうかなどの設定を追加します。ここでは、`toYaml` 関数を使用してスペースを制御します(以下を参照)。

 {{ - if .Values. nodeSelector }}
nodeSelector: {{ - toYaml .Values. ノードセレクター| ニンデント 8 }}
{{ - 終わり - }}
{{ - .Values. アフィニティ付き}}
アフィニティ: {{ - toYaml . | nindent 8 }}
{{ - 終わり}}
{{ - .Values . tolerations 付き}}
許容範囲: {{ - toYaml . | nindent 8 }}
{{ - 終わり}}

次のステップは、もちろんイメージの設定です。プライベートリポジトリの場合は、imagePullSecretsも指定する必要があります。

 {{ - if .Values.image.pullSecrets }}
画像プルシークレット:
{{ - 範囲.Values.image. pullSecrets }}
-名前: ` `.` `
{{ - 終わり}}
{{ - 終わり}}
コンテナ:
-名前: ゴースト
画像: {{ printf "%s:%s" .Values.image. name .Values.image. tag }}
画像プルポリシー: {{ .Values.image. pullPolicy | quote }}
ポート:
-コンテナポート: 2368

対応する値を以下に示します。

画像:
名前: ゴースト
タグ: 最新
プルポリシー: IfNotPresent
## プライベートリポジトリの場合は、imagePullSecretsを指定する必要があります
# プルシークレット:
# - レジストリキーシークレット名

次はリソースの宣言です。ここではリソースのデフォルト値を定義し、toYaml関数を使ってスペースを制御します。

リソース:
{{ toYaml .Values. resources | インデント 10 }}

最後に、ヘルスチェックセクションがあります。これまでは `livenessProbe` を実装していませんでしたが、チャートテンプレートを開発する際には可能な限り包括的なものにする必要があります。ここでは、liveness、readability、startup の 3 つのプローブを追加します。プローブを追加するかどうかは、`livenessProbe.enabled`、`readinessProbe.enabled`、`startupProbe.enabled` の値に基づいて決定します。各プローブのパラメータもこれらの値を使用して設定されます。

 {{ - .Values.startupProbe. が有効になっている場合}}
スタートアッププローブ:
httpGet:
パス: /
ポート: 2368
初期遅延秒数: {{ .Values.startupProbe. initialDelaySeconds }}
periodSeconds: {{ .Values.startupProbe. periodSeconds }}
タイムアウト秒数: {{ .Values.startupProbe. timeoutSeconds }}
失敗しきい値: {{ .Values.startupProbe. failureThreshold }}
成功しきい値: {{ .Values.startupProbe. successThreshold }}
{{ - 終わり}}
{{ - .Values.livenessProbe. が有効になっている場合}}
ライブネスプローブ:
httpGet:
パス: /
ポート: 2368
InitialDelaySeconds: {{ .Values.livenessProbe. 初期遅延秒}}
periodSeconds: {{ .Values.livenessProbe. 期間秒}}
タイムアウト秒数: {{ .Values.livenessProbe. timeoutSeconds }}
失敗しきい値: {{ .Values.livenessProbe. failureThreshold }}
successThreshold: {{ .Values.livenessProbe. 成功のしきい値}}
{{ - 終わり}}
{{ - .Values.readinessProbe. が有効になっている場合}}
準備プローブ:
httpGet:
パス: /
ポート: 2368
初期遅延秒数: {{ .Values.readinessProbe. initialDelaySeconds }}
periodSeconds: {{ .Values.readinessProbe. periodSeconds }}
タイムアウト秒数: {{ .Values.readinessProbe. timeoutSeconds }}
失敗しきい値: {{ .Values.readinessProbe. failureThreshold }}
成功しきい値: {{ .Values.readinessProbe. successThreshold }}
{{ - 終わり}}

デフォルトの values.yaml ファイルは次のようになります。

レプリカ数: 1
画像:
名前: ゴースト
タグ: 最新
プルポリシー: IfNotPresent
node_env: プロダクション
URL: ghost.k8s.local
サービス:
タイプ: ClusterIP
ポート: 80
入口:
有効: true
イングレスクラス: nginx
## PVCを使用してデータの永続性を有効にするかどうか
持続性:
有効: true
## storageClass を使用するかどうか。使用しない場合は、構成を追加します。
# ストレージクラス: "xxx"
##
## 既存の PVC オブジェクトを使用する場合は、それを以下の existingClaim 変数に渡すだけです。
# 既存の請求: あなたの請求
accessMode: ReadWriteOnce # アクセスモード
サイズ: 1Gi # ストレージ容量
ノードセレクター: {}
親和性: {}
許容範囲: {}
リソース: {}
スタートアッププローブ:
有効: false
ライブネスプローブ:
有効: false
準備プローブ:
有効: false

それではリリースを更新しましょう:

  helm upgrade --install my-ghost ./ my-ghost -n default
リリース「my-ghost」がアップグレードされました。Helming をお楽しみに
名前: my-ghost
最終デプロイ日時: 2022年3月17日(木) 16:03:02
名前空間: デフォルト
ステータス: 展開済み
改訂: 2
テストスイート: なし
helm ls -n デフォルト
名前名前空間リビジョン更新ステータスチャートアプリバージョン
my-ghost デフォルト2 2022-03-17 16:05:07. 123349 + 0800 CST デプロイ済みmy-ghost-0 .1. 0 1.16. 0
kubectl get pods -n デフォルト
名前準備完了ステータス再起動年齢
my-ghost-6dbc455fc7-cmm4p 1/1 ランニング0 2 分42秒
kubectl get pvc -n デフォルト
名前ステータスボリューム容量アクセスモードストレージクラス 年齢
my-ghost バウンドpvc-2f0b7d5a-04d4-4331-848b-af21edce673e 1Gi RWO nfs-client 4分59秒
kubectl get ingress -n デフォルト
名前クラスホストアドレスポート年齢
my-ghost nginx ghost.k8s. ローカル192.168.31. 31 80 3時間24分

このシンプルなHelm Chartsパッケージの開発は、これでほぼ完了しました。もちろん、将来的には新たな要件が発生する可能性があり、継続的な改善と最適化が必要になります。

共有チャート

Helm Charts パッケージが完成しました。他の人にも使ってもらいたい場合は、共有する必要があります。共有は Chart リポジトリを通じて行うことができます。Helm Charts はリモートリポジトリでもローカル環境/リポジトリでも使用できます。リモートリポジトリは、Bitnami Charts のようなパブリックリポジトリでも、Google Cloud Storage や GitHub のようなホストリポジトリでも構いません。デモのため、Charts パッケージのホストには GitHub を使用します。

GitHub Pages を使って Charts リポジトリを作成できます。GitHub では、静的 Web ページを 2 つの方法で提供できます。

  • docs/ ディレクトリの内容を提供するようにプロジェクトを構成します。
  • 特定のブランチを提供するようにプロジェクトを構成します。

ここでは2番目の方法を使用します。まず、GitHubにコードリポジトリ(https://github.com/cnych/helm101)を作成し、上記で作成したmy-ghostパッケージをリポジトリのchartsディレクトリにコミットし、チャートパッケージをパッケージ化します。

  helm パッケージcharts/ my-ghost
チャートを正常にパッケージ化し、次の場所に保存しました: /Users/ych/devs/workspace/yidianzhishi/course/k8strain3/content/helm/manifests/helm101/ my-ghost-0 .1.0.tgz

パッケージ化された圧縮ファイルを別のディレクトリ repo/stable に配置します。リポジトリ構造は次のようになります。

  

ライセンス
README.md
チャート
マイゴースト
チャートロック
チャート.yaml
チャート
テンプレート
_helpers.tpl
デプロイメント.yaml
イングレス.yaml
pvc.yaml
サービス.yaml
テスト
.yaml
└─── レポ
└─── 安定
my-ghost-0 .1.0 てつ

インデックス ファイルを生成するには、次のコマンドを実行します。

  helm リポジトリインデックスrepo/ stable --url https://raw.githubusercontent.com/cnych/helm101/main/repo/ stable

上記のコマンドを実行すると、以下に示すように、repo/stable ディレクトリに index.yaml ファイルが生成されます。

 apiバージョン: v1
エントリー:
私の幽霊:
- apiバージョン: v2
アプリバージョン: 1.16.0
作成日時: "2022-03-17T17:40:21.093654+08:00"
説明: Kubernetes 用のHelmチャート
ダイジェスト: f6d6308d6a6cd6357ab2b952650250c2df7b2727ce84c19150531fd72732626b
名前: my-ghost
タイプ: アプリケーション
URL:
- https://raw.githubusercontent.com/cnych/helm101/main/repo/stable/my-ghost-0 .1.0.tgz
バージョン: 0.1.0
生成日時: "2022-03-17T17:40:21.090371+08:00"

`index.yaml` ファイルは、リポジトリから Chart パッケージを取得するための鍵となります。その後、コードを GitHub にプッシュします。

  git ステータス
ブランチメイン
ブランチ'origin/main' 最新です
追跡されていないファイル:
( コミットする内容を含めるには、 「git add <file>...」を使用します)
チャート/
リポジトリ/
コミットには何も追加されていませんが、追跡されていないファイルが存在します 追跡するには「git add」を使用してください
git commit -m "チャートとindex.yamlを追加"
[ main aae1059 ] チャートとインデックスの.yamlを追加
11 ファイルが変更され、 431 個の追加( + )
作成モード100644 チャート/ my-ghost /. helmignore
作成モード100644 チャート/ my-ghost /Chart. lock
作成モード100644 チャート/ my-ghost / Chart.yaml
作成モード100644 チャート/ my-ghost /templates/ _helpers.tpl
作成モード100644 チャート/ my-ghost /templates/ deployment.yaml
作成モード100644 charts / my-ghost /templates/ ingress.yaml
作成モード100644 チャート/ my-ghost /templates/ pvc.yaml
作成モード100644 charts / my-ghost /templates/ service.yaml
作成モード100644 charts / my-ghost / values.yaml
モード100644リポジトリ/stable/ インデックス.yamlを作成
モード100644リポジトリ/stable/ my-ghost-0 .1.0.tgzを作成
git プッシュorigin main
オブジェクトの列挙: 18、完了。
オブジェクトのカウント100% (18 / 18) 、完了。
オブジェクトの書き込み: 100% (18 / 18)8.71 KiB | 2.18 MiB /s、完了。
合計 18 (デルタ0)再利用 0 (デルタ0)
github .com:cnych/helm101.git
9c389a6.. aae1059 メイン - > メイン

次に、このリポジトリ用のGitHub Pagesを設定します。まず、ローカルにgh-pagesという名前の新しいブランチを作成します。

  git チェックアウト-b gh-pages

ルート ディレクトリに `repo/stable/index.yaml` ファイルのみを残し、他のファイルは無視して、リモート リポジトリにプッシュします。

  git プッシュorigin gh-pages
オブジェクトの列挙: 2、完了。
オブジェクトのカウント100% (2/2 、完了。
オブジェクトの書き込み: 100% (2 / 2)301 バイト| 301.00 KiB /s、完了。
合計 2 (デルタ0)再利用 0 (デルタ0)
リモート:
リモート: GitHub で'gh-pages' プル リクエストを作成するには、次の URL にアクセスします。
リモート: https://github.com/cnych/helm101/pull/new/gh-pages
リモート:
github .com:cnych/helm101.git
* [ 新しいブランチ] gh-pages - > gh-pages

GitHub Pages ページで gh-pages ブランチを選択するだけです。

ページ

これで、https://cnych.github.io/helm101/ から Chart パッケージを入手できるようになりました。

以下のコマンドを使用して repo リポジトリを追加します。

  helm リポジトリに helm101 を追加しますhttps://cnych.github.io/helm101/
「helm101」リポジトリに追加されました

また、`helm search` を使用してリポジトリ内の Chart パッケージを検索することもできます。これには通常、上記の `my-ghost` パッケージが含まれます。

  helm 検索リポジトリ helm101
名前チャートバージョンアプリバージョン説明
helm101/ my-ghost 0.1. 0 1.16. 0 Kubernetes用のHelm チャート

これで、チャート パッケージを通常どおりに使用できるようになります (インストールなど)。

  helm インストールmy-ghost helm101/