ConfigMap
PropertySource
の使用
Kubernetes は、キーと値のペア、または埋め込み application.properties
または application.yaml
ファイルの形式でアプリケーションに渡すパラメーターを外部化する、ConfigMap
(英語) という名前のリソースを提供します。Spring Cloud Kubernetes 構成 [GitHub] (英語) プロジェクトは、アプリケーションの起動時に Kubernetes ConfigMap
インスタンスを使用できるようにし、監視されている ConfigMap
インスタンスで変更が検出されたときに Bean または Spring コンテキストのホットリロードをトリガーします。
以下の内容は主に ConfigMaps を使用した例を参照して説明されますが、シークレットについても同様です。つまり、すべての機能が両方でサポートされています。
デフォルトの動作では、次のいずれかの metadata.name
を持つ Kubernetes ConfigMap
に基づいて Fabric8ConfigMapPropertySource
(または KubernetesClientConfigMapPropertySource
) を作成します。
spring.cloud.kubernetes.config.name
の値Spring アプリケーションの価値 (
spring.application.name
プロパティで定義されているとおり)文字列リテラル
"application"
ただし、複数の ConfigMap
インスタンスを使用できる、より高度な構成が可能です。spring.cloud.kubernetes.config.sources
リストはこれを可能にします。例: 次の ConfigMap
インスタンスを定義できます。
spring:
application:
name: cloud-k8s-app
cloud:
kubernetes:
config:
name: default-name
namespace: default-namespace
sources:
# Spring Cloud Kubernetes looks up a ConfigMap named c1 in namespace default-namespace
- name: c1
# Spring Cloud Kubernetes looks up a ConfigMap named default-name in whatever namespace n2
- namespace: n2
# Spring Cloud Kubernetes looks up a ConfigMap named c3 in namespace n3
- namespace: n3
name: c3
前述の例では、spring.cloud.kubernetes.config.namespace
が設定されていない場合、アプリケーションが実行する名前空間で c1
という名前の ConfigMap
が検索されます。アプリケーションの名前空間がどのように解決されるかをより深く理解するには、名前空間の解決を参照してください。
一致する ConfigMap
が見つかった場合は、次のように処理されます。
個々の構成プロパティを適用します。
spring.application.name
の値によって名前が付けられたプロパティの内容をyaml
(またはproperties
) として適用します (存在しない場合は、application.yaml/properties
)上記の名前と各アクティブなプロファイルの内容をプロパティファイルとして適用します。
例を見てみると、さらにわかりやすいはずです。spring.application.name=my-app
であり、k8s
という単一のアクティブなプロファイルがあると仮定します。以下のような構成の場合:
kind: ConfigMap
apiVersion: v1
metadata:
name: my-app
data:
my-app.yaml: |-
...
my-app-k8s.yaml: |-
..
my-app-dev.yaml: |-
..
not-my-app.yaml: |-
..
someProp: someValue
最終的にロードするものは次のとおりです。
my-app.yaml
をファイルとして扱うmy-app-k8s.yaml
をファイルとして扱うdev
はアクティブなプロファイルではないため、my-app-dev.yaml
は無視されましたnot-my-app.yaml
はspring.application.name
と一致しないため無視されますsomeProp: someValue
プレーンプロパティ
プロパティを読み込む順序は次のとおりです。
最初に
my-app.yaml
からすべてのプロパティをロードしますその後、すべてプロファイルベースのソースから:
my-app-k8s.yaml
その後、すべてのプレーンプロパティ
someProp: someValue
これは、プロファイルベースのソースが非プロファイルベースのソースより優先されることを意味します (バニラ Spring アプリと同様)。また、プレーンプロパティは、プロファイルベースのソースと非プロファイルベースのソースの両方よりも優先されます。以下に例を示します。
kind: ConfigMap
apiVersion: v1
metadata:
name: my-app
data:
my-app-k8s.yaml: |-
key1=valueA
key2=valueB
my-app.yaml: |-
key1=valueC
key2=valueA
key1: valueD
このような ConfigMap を処理すると、プロパティには key1=valueD
、key2=valueB
が表示されます。
前述のフローの 1 つの例外は、ファイルが YAML またはプロパティファイルであることを示す単一のキーが ConfigMap
に含まれる場合です。その場合、キーの名前は application.yaml
または application.properties
である必要はなく (何でも構いません)、プロパティの値は正しく処理されます。この機能により、次のようなものを使用して ConfigMap
が作成されたユースケースが容易になります。
kubectl create configmap game-config --from-file=/path/to/app-config.yaml
次のプロパティを使用してスレッドプール構成を読み取る demo
という名前の Spring Boot アプリケーションがあるとします。
pool.size.core
pool.size.maximum
これは、次のように yaml
形式で設定マップに外部化できます。
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
pool.size.core: 1
pool.size.max: 16
個々のプロパティはほとんどの場合に問題なく機能します。ただし、場合によっては、組み込み yaml
の方が便利です。この場合、次のように、application.yaml
という名前の単一プロパティを使用して yaml
を埋め込みます。
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yaml: |-
pool:
size:
core: 1
max:16
次の例も機能します。
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
custom-name.yaml: |-
pool:
size:
core: 1
max:16
ラベルに基づいて検索が行われるように定義することもできます。例:
spring:
application:
name: labeled-configmap-with-prefix
cloud:
kubernetes:
config:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
letter: a
これにより、名前空間 spring-k8s
内でラベル {letter : a}
を持つすべての構成マップが検索されます。ここで注意すべき重要な点は、名前で構成マップを読み取る場合とは異なり、複数の構成マップが読み取られる可能性があるということです。通常どおり、同じ機能がシークレットに対してサポートされています。
ConfigMap
の読み取り時にマージされるアクティブなプロファイルに応じて、Spring Boot アプリケーションを異なる構成にすることもできます。次のように、application.properties
または application.yaml
プロパティを使用し、それぞれ独自のドキュメント (---
シーケンスで示される) でプロファイル固有の値を指定することにより、異なるプロファイルに異なるプロパティ値を提供できます。
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yml: |-
greeting:
message: Say Hello to the World
farewell:
message: Say Goodbye
---
spring:
profiles: development
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
---
spring:
profiles: production
greeting:
message: Say Hello to the Ops
前述のケースでは、development
プロファイルを使用して Spring アプリケーションにロードされる構成は次のとおりです。
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
ただし、production
プロファイルがアクティブな場合、構成は次のようになります。
greeting:
message: Say Hello to the Ops
farewell:
message: Say Goodbye
両方のプロファイルがアクティブな場合、ConfigMap
内で最後に表示されるプロパティによって、それより前の値が上書きされます。
もう 1 つのオプションは、プロファイルごとに異なる構成マップを作成することです。spring boot は、アクティブなプロファイルに基づいてそれを自動的に取得します。
kind: ConfigMap
apiVersion: v1
metadata:
name: demo
data:
application.yml: |-
greeting:
message: Say Hello to the World
farewell:
message: Say Goodbye
kind: ConfigMap
apiVersion: v1
metadata:
name: demo-development
data:
application.yml: |-
spring:
profiles: development
greeting:
message: Say Hello to the Developers
farewell:
message: Say Goodbye to the Developers
kind: ConfigMap
apiVersion: v1
metadata:
name: demo-production
data:
application.yml: |-
spring:
profiles: production
greeting:
message: Say Hello to the Ops
farewell:
message: Say Goodbye
どの profile
を有効にする必要があるかを Spring Boot に伝えるには、Spring Boot ドキュメントを参照してください。Kubernetes にデプロイするときに特定のプロファイルをアクティブにするオプションの 1 つは、コンテナー仕様で PodSpec で定義できる環境変数を使用して Spring Boot アプリケーションを起動することです。デプロイリソースファイルは次のようになります。
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-name
labels:
app: deployment-name
spec:
replicas: 1
selector:
matchLabels:
app: deployment-name
template:
metadata:
labels:
app: deployment-name
spec:
containers:
- name: container-name
image: your-image
env:
- name: SPRING_PROFILES_ACTIVE
value: "development"
同じプロパティ名を持つ複数の構成マップが存在する状況が発生する可能性があります。例:
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-one
data:
application.yml: |-
greeting:
message: Say Hello from one
および
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-two
data:
application.yml: |-
greeting:
message: Say Hello from two
これらを bootstrap.yaml|properties
に配置する順序によっては、予期しない結果が発生する可能性があります (最後の構成マップが優先されます)。例:
spring:
application:
name: cloud-k8s-app
cloud:
kubernetes:
config:
namespace: default-namespace
sources:
- name: config-map-two
- name: config-map-one
プロパティ greetings.message
は Say Hello from one
になります。
useNameAsPrefix
を指定することで、このデフォルト構成を変更する方法があります。例:
spring:
application:
name: with-prefix
cloud:
kubernetes:
config:
useNameAsPrefix: true
namespace: default-namespace
sources:
- name: config-map-one
useNameAsPrefix: false
- name: config-map-two
このような構成では、次の 2 つのプロパティが生成されます。
greetings.message
はSay Hello from one
に等しい。config-map-two.greetings.message
とSay Hello from two
は等しい
spring.cloud.kubernetes.config.useNameAsPrefix
の優先順位は spring.cloud.kubernetes.config.sources.useNameAsPrefix
よりも低いことに注意してください。これにより、すべてのソースに対して "default" 戦略を設定できると同時に、いくつかのソースのみをオーバーライドすることができます。
構成マップ名の使用がオプションでない場合は、explicitPrefix
という別の戦略を指定できます。これは選択する明示的なプレフィックスであるため、sources
レベルにのみ提供できます。同時に、useNameAsPrefix
よりも高い優先順位を持ちます。次のエントリを含む 3 番目の構成マップがあるとします。
kind: ConfigMap
apiVersion: v1
metadata:
name: config-map-three
data:
application.yml: |-
greeting:
message: Say Hello from three
以下のような構成です。
spring:
application:
name: with-prefix
cloud:
kubernetes:
config:
useNameAsPrefix: true
namespace: default-namespace
sources:
- name: config-map-one
useNameAsPrefix: false
- name: config-map-two
explicitPrefix: two
- name: config-map-three
その結果、次の 3 つのプロパティが生成されます。
greetings.message
はSay Hello from one
に等しい。two.greetings.message
はSay Hello from two
に等しい。config-map-three.greetings.message
はSay Hello from three
に等しい。
configmap のプレフィックスを設定するのと同じ方法で、シークレットに対しても行うことができます。名前に基づくシークレットとラベルに基づくシークレットの両方。例:
spring:
application:
name: prefix-based-secrets
cloud:
kubernetes:
secrets:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
letter: a
useNameAsPrefix: false
- labels:
letter: b
explicitPrefix: two
- labels:
letter: c
- labels:
letter: d
useNameAsPrefix: true
- name: my-secret
プロパティソースを生成する場合、構成マップの場合と同じ処理ルールが適用されます。唯一の違いは、ラベルでシークレットを検索すると、複数のソースが見つかる可能性があることです。このような場合、プレフィックス ( useNameAsPrefix
で指定した場合) は、それらの特定のラベルで見つかったすべてのシークレットの名前になります。
もう 1 つ留意すべき点は、シークレットごとではなくソースごとに prefix
をサポートしていることです。これを説明する最も簡単な方法は、次の例です。
spring:
application:
name: prefix-based-secrets
cloud:
kubernetes:
secrets:
enableApi: true
useNameAsPrefix: true
namespace: spring-k8s
sources:
- labels:
color: blue
useNameAsPrefix: true
このようなラベルに一致するクエリの結果として、secret-a
と secret-b
という 2 つのシークレットが提供されるとします。これらのシークレットは両方とも、color=sea-blue
および color=ocean-blue
という同じプロパティ名を持ちます。どの color
がプロパティソースの一部になるかは未定義ですが、そのプレフィックスは secret-a.secret-b
(自然にソートされた連結、シークレットの名前) になります。
より詳細な結果が必要な場合は、ラベルを追加してシークレットを一意に識別することもできます。
デフォルトでは、sources
構成で指定された構成マップを読み取るほかに、Spring は「プロファイル対応」ソースからすべてのプロパティを読み取ろうとします。これを説明する最も簡単な方法は、例を使用することです。アプリケーションで "dev" というプロファイルが有効になっており、次のような構成があるとします。
spring:
application:
name: spring-k8s
cloud:
kubernetes:
config:
namespace: default-namespace
sources:
- name: config-map-one
config-map-one
の読み取りに加えて、Spring は config-map-one-dev
の読み取りも試行します。この特定の順序で各アクティブなプロファイルは、プロファイル対応構成マップを生成します。
アプリケーションがそのような構成マップの影響を受けることはありませんが、必要に応じて無効にすることができます。
spring:
application:
name: spring-k8s
cloud:
kubernetes:
config:
includeProfileSpecificSources: false
namespace: default-namespace
sources:
- name: config-map-one
includeProfileSpecificSources: false
以前と同様に、このプロパティを指定できるレベルは 2 つあります。つまり、すべての構成マップに対して、または個別の構成マップに対してです。後者の方が優先されます。
セキュリティ構成セクションを確認する必要があります。pod 内から構成マップにアクセスするには、正しい Kubernetes サービスアカウント、ロール、ロールバインディングが必要です。 |
ConfigMap
インスタンスを使用するもう 1 つのオプションは、Spring Cloud Kubernetes アプリケーションを実行し、Spring Cloud Kubernetes にファイルシステムからインスタンスを読み取らせることで、ConfigMap
インスタンスを Pod にマウントすることです。
この機能は非推奨であり、将来のリリースでは削除される予定です (代わりに spring.config.import を使用してください)。この動作は、spring.cloud.kubernetes.config.paths プロパティによって制御されます。前述のメカニズムに加えて、またはその代わりにこれを使用できます。ディレクトリは再帰的に解析されないため、spring.cloud.kubernetes.config.paths は各プロパティファイルへのフルパスのリストを期待します。例: |
spring:
cloud:
kubernetes:
config:
paths:
- /tmp/application.properties
- /var/application.yaml
spring.cloud.kubernetes.config.paths または spring.cloud.kubernetes.secrets.path を使用する場合、自動リロード機能は動作しません。/actuator/refresh エンドポイントに対して POST リクエストを行うか、アプリケーションを再起動 / 再デプロイする必要があります。 |
場合によっては、アプリケーションが Kubernetes API を使用して ConfigMaps
の一部をロードできないことがあります。このような場合にアプリケーションが起動プロセスに失敗するようにしたい場合は、アプリケーションの起動が例外で失敗するように spring.cloud.kubernetes.config.fail-fast=true
を設定できます。
失敗した場合に、アプリケーションで ConfigMap
プロパティソースのロードを再試行するようにすることもできます。まず、spring.cloud.kubernetes.config.fail-fast=true
を設定する必要があります。次に、spring-retry
と spring-boot-starter-aop
をクラスパスに追加する必要があります。spring.cloud.kubernetes.config.retry.*
プロパティを設定することで、最大試行回数、初期間隔、乗数、最大間隔などのバックオフオプションなどの再試行プロパティを構成できます。
何らかの理由ですでにクラスパス上に spring-retry および spring-boot-starter-aop があり、フェイルファストを有効にしたいが、再試行は有効にしたくない場合。spring.cloud.kubernetes.config.retry.enabled=false を設定することで、ConfigMap PropertySources の再試行を無効にできます。 |
名前 | タイプ | デフォルト | 説明 |
---|---|---|---|
|
|
| ConfigMaps |
|
|
| 検索する |
|
| クライアント名前空間 | ルックアップ先の Kubernetes 名前空間を設定します |
|
|
|
|
|
|
| API を介した |
|
|
|
|
|
|
| 構成の再試行を有効または無効にします。 |
|
|
| ミリ秒単位の初期再試行間隔。 |
|
|
| 最大試行回数。 |
|
|
| バックオフの最大間隔。 |
|
|
| 次の区間の乗数。 |