Downward API で Pod の情報を読む
v1.37 時点(2026年10月25日 確認)
目次
この記事では Pod やコンテナの情報をコンテナの中で動くプログラムに渡す、Downward API の仕組みを図で説明します。Pod の名前や IP アドレス、コンテナに割り当てた CPU とメモリの値を、環境変数とファイルの 2 つの方法で渡せること、方法によって渡せる情報が違うことがわかります。その土台として、コンテナで動かすコマンドと引数を決める command と args、環境変数を決める env の書き方も説明します。後半では kind のクラスタで、Pod 自身の名前やリソースの値をコンテナの中から読む手順を示します。
ConfigMap の値を、環境変数とボリュームの 2 つの方法でコンテナに渡した第17回の内容を前提にしています。まだの方は先にこちらをどうぞ。
環境変数とボリュームで渡す ConfigMap の違い設定のデータをコンテナイメージから切り離して Pod に渡す ConfigMap の仕組みを図で説明します。環境変数とボリュームの 2 つの渡し方と、ConfigMap を書き換えたときにボリュームのファイルは後から更新され、環境変数は自動では更新されない理由を押さえ、kind のクラスタで確かめる手順を紹介します。以下の図は Pod downward-demo の情報を、Downward API で Pod の中のコンテナ main に渡している様子を表しています。後半の「手元で試す」で作る構成です。
Pod の名前や Namespace、ラベル、Pod を動かすノードの名前、Pod の IP アドレスは Pod のフィールドです。CPU とメモリの requests と limits は、コンテナごとに書くフィールドです。公式ドキュメントによると、Pod のフィールドは fieldRef、コンテナのフィールドは resourceFieldRef で選びます。選んだ値は環境変数としても、downwardAPI という種類のボリュームのファイルとしても渡せます。どちらの方法でも、Pod のフィールドとコンテナのフィールドの両方を渡せます。ただし、どちらの方法でも渡せるフィールドと、片方の方法でしか渡せないフィールドがあります。どのフィールドをどちらの方法で渡せるかは、あとの「使えるフィールド」の表で確かめてください。図の矢印はどちらの方法で渡すかを表しています。図ではボリュームとコンテナを結ぶ線を省いています。
参考:Downward API | Kubernetes、Expose Pod Information to Containers Through Environment Variables | Kubernetes、Expose Pod Information to Containers Through Files | Kubernetes
Downward API とは
Downward API は Pod とコンテナのフィールドの値を、動いているコンテナに渡す仕組み です。公式ドキュメントによると、渡し方は環境変数と、特別な種類のボリューム(downwardAPI ボリューム)に置かれるファイルの 2 つです。この 2 つの渡し方をまとめて、Downward API と呼びます。フィールドは第5回で見た、マニフェストの metadata、spec、status の下に並ぶ項目のことです。
名前に API と付いていますが、コンテナの中のプログラムが kube-apiserver(第4回)に問い合わせるわけではありません。公式ドキュメントは、Downward API を使うと、コンテナは Kubernetes のクライアントや API サーバーを使わずに、自分自身やクラスタについての情報を使える、と説明しています。
Downward API で渡せるのは、Kubernetes の API のフィールドのうちの一部だけです。どのフィールドを渡せるかは、あとの「使えるフィールド」で表にまとめます。
なぜ Downward API が必要なのか
公式ドキュメントによると、コンテナが Kubernetes に強く結び付きすぎずに、自分自身についての情報を持てると便利なことがあります。挙げられている例は次のようなものです。すでにあるアプリケーションが、決まった名前の環境変数に、自分を見分けるための一意の値(識別子)が入っていると想定して作られているとします。アプリケーションを別のプログラムで包んで(ラップして)値を用意する方法もありますが、手間がかかって間違いも起きやすく、結び付きを弱く保つという目的にも反します。それよりも、Pod の名前を識別子として使い、決まった名前の環境変数に Pod の名前を入れるほうがよい、と書かれています。
ほかにも一般的な例として、同じアプリケーションの Pod がいくつも動いているとき、ログの各行にどの Pod が書いたかを入れたい場面が考えられます。Pod の名前を環境変数で受け取れば、アプリケーションは Kubernetes のことを知らなくても、その値をログに書けます。
第11回と第12回で見たとおり、ReplicaSet や Deployment が作る Pod の名前は、ReplicaSet の名前の後ろに文字列が付いたものになります。Pod の名前はマニフェストを書く時点では決まっていないので、env に値を直接書くことはできません。Pod を動かすノードは、Pod を作ったあとで kube-scheduler が決めます(第4回)。Pod の IP アドレス(第8回)は status.podIP という status のフィールドで、第5回で見たとおり、status はマニフェストに書くものではありません。こうした、Pod を作ってから決まる値をコンテナに渡すために、Downward API が使えると考えられます。
参考:ReplicaSet | Kubernetes、Kubernetes Scheduler | Kubernetes、Downward API | Kubernetes
なお、Pod の名前は Downward API を使わなくてもコンテナから読めます。公式ドキュメントによると、コンテナのホスト名は、そのコンテナが動いている Pod の名前で、hostname コマンドなどで読めます。ただし、公式ドキュメントがホスト名として挙げているのは Pod の名前だけです。Pod の名前と Namespace は、Downward API を使えば環境変数として使える、と説明されています。Namespace やノードの名前、IP アドレス、CPU とメモリの値なども、この回では Downward API で渡します。
Downward API の仕組み
値をコンテナに入れるのが誰かについて、Downward API の公式ドキュメントにまとまった説明はありません。limits を書いていない場合の説明(あとの「コンテナのリソースの値を渡す」)では、値を渡す(expose)主体を kubelet としています。そのため、環境変数を入れるのも、ボリュームのファイルを書くのも、Pod が動くノードの kubelet(第4回)だと考えられます。第17回の ConfigMap でも、コンテナを起動するときにデータを使うのは kubelet でした。
Downward API の環境変数は、コンテナの env に書きます。また、環境変数の値はコンテナで動かすコマンドの引数にも使えます。そこで、Downward API に入る前に、コンテナで動かすコマンドと引数、環境変数の書き方を順に見ます。
コンテナで動かすコマンドと引数
第8回で見たとおり、コンテナイメージはアプリケーションを動かすのに必要なもの一式を入れたパッケージです。第9回で見たとおり、イメージにはコンテナを起動したときに動かす既定のコマンドも決められています。
イメージの既定のコマンドはイメージを作るときに書きます。Docker の公式ドキュメントによると、Dockerfile はイメージを組み立てるためのコマンドを並べたテキストのファイルです。既定のコマンドは Dockerfile の ENTRYPOINT と CMD という 2 つの命令で書きます。
たとえば、ENTRYPOINT ["echo"] と CMD ["hello"] を書いた架空のイメージがあるとします。このあと引用する Docker の公式ドキュメントの表に当てはめると、このイメージからコンテナを起動したときには echo hello が動くはずです。echo が動かすプログラムで、hello がその引数です。Docker の公式ドキュメントの 2 つの命令の説明を、次の表にまとめます。
| 命令 | 説明 |
|---|---|
ENTRYPOINT | コンテナを、実行ファイル(executable)として動くように設定できる |
CMD | 実行するコンテナに既定値を与える。ENTRYPOINT のコマンドの既定の引数を決めるか、コンテナでその場限りのコマンドを動かす方法として使うべき(should)もの |
参考:Dockerfile reference | Docker Docs、Dockerfile reference | Docker Docs、Dockerfile reference | Docker Docs
どちらの命令も ENTRYPOINT ["executable", "param1", "param2"] のように、実行するプログラムと引数をリストで書けます(exec 形式)。exec 形式はシェルを通さず、リストの 1 つ目のプログラムを直接動かす書き方です。Docker の公式ドキュメントによると、exec 形式ではシェル(コマンドを解釈して動かすプログラム)が自動では使われません。あとで見る Kubernetes の command も、シェルを通さずに実行されます。
Docker の公式ドキュメントの表によると、2 つの命令を両方とも exec 形式で、ENTRYPOINT ["exec_entry", "p1_entry"] と CMD ["exec_cmd", "p1_cmd"] のように書くと、exec_entry p1_entry exec_cmd p1_cmd が動きます。CMD の値が ENTRYPOINT の後ろに引数として付きます。同じ表によると、ENTRYPOINT が無く、CMD ["exec_cmd", "p1_cmd"] だけを書いたイメージでは、exec_cmd p1_cmd が動きます。ENTRYPOINT が無く、CMD を exec 形式で書いたイメージでは、CMD の 1 つ目が動かすプログラムになります。そのようなイメージで Kubernetes の args だけを書いた場合は、このあとの表の 2 行目に当てはめると、args の 1 つ目が動かすプログラムになると考えられます。
参考:Dockerfile reference | Docker Docs、Dockerfile reference | Docker Docs
Kubernetes ではこの既定のコマンドを Pod のマニフェストで変えられます。公式ドキュメントによると、Pod を作るとき、コンテナごとに、command でコマンドを、args でそのコマンドの引数を決められます。マニフェストで決めたコマンドと引数は、イメージが決めている既定のコマンドと引数を上書きします。公式ドキュメントは、一部のコンテナランタイム(第4回)では、command が ENTRYPOINT に、args が CMD にあたる、と注記しています。
参考:Define a Command and Arguments for a Container | Kubernetes
公式ドキュメントと API リファレンスで説明されている組み合わせを、次の表にまとめます。
| マニフェストの書き方 | 動くもの |
|---|---|
command も args も書かない | イメージの ENTRYPOINT と CMD |
args だけを書く | イメージの ENTRYPOINT に、args を引数として付けたもの(イメージの CMD は使われない) |
command と args を両方書く | command に、args を引数として付けたもの |
参考:Define a Command and Arguments for a Container | Kubernetes、Pod | Kubernetes API Reference
1 行目と 2 行目は API リファレンスの説明によるものです。command を書かなければイメージの ENTRYPOINT が、args を書かなければイメージの CMD が使われる、と書かれています。2 行目はタスクのページの「args だけを書くと、既定のコマンドが新しい引数で動く」という説明とも合います。command だけを書いた場合に、イメージの CMD がどう扱われるかを示した例は、公式ドキュメントのタスクのページにはないので、この回では扱いません。
参考:Pod | Kubernetes API Reference、Define a Command and Arguments for a Container | Kubernetes
以下の図はイメージの ENTRYPOINT と CMD、マニフェストの command と args から、コンテナで動くコマンドが決まる関係を、表の 3 つの書き方ごとに表しています。
マニフェストに書いたものが、イメージの既定より優先されます。3 段目のように command と args を両方書けば、イメージの既定のコマンドと引数はどちらも使われません。
参考:Define a Command and Arguments for a Container | Kubernetes
command と args について、API リファレンスと公式ドキュメントに書かれた決まりは次のとおりです。
commandはシェルを通さずに実行される- パイプでつないだ複数のコマンドやシェルスクリプトは、
/bin/shに-cで渡して動かす $(変数の名前)の形はコンテナの環境変数の値に置き換わる(あとで説明します)- Pod を作ったあとでは変えられない
参考:Pod | Kubernetes API Reference、Define a Command and Arguments for a Container | Kubernetes
公式ドキュメントのシェルで動かす例は、次のとおりです。
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]参考:Define a Command and Arguments for a Container | Kubernetes
command で動かすプログラムは /bin/sh(シェル)です。args の 1 つ目の -c と 2 つ目の文字列が、シェルへの引数になります。第9回と第16回では、command: ['sh', '-c', '...'] のように、シェルと -c、動かす文字列をすべて command に並べていました。公式ドキュメントの Pod Lifecycle のページの busybox:1.28 を使う例も、この書き方です。シェルとその引数を command と args に分けても、すべて command に並べても、一般に -c の後ろの文字列をシェルが実行する点は同じです。「手元で試す」では公式ドキュメントの Downward API の例と同じく、command に sh と -c を、args にシェルで動かす文字列を書きます。
参考:Pod Lifecycle | Kubernetes、Expose Pod Information to Containers Through Environment Variables | Kubernetes
環境変数を書く
公式ドキュメントによると、Pod を作るときに、env か envFrom でコンテナの環境変数を決められます。envFrom は第17回で見たとおり、ConfigMap か Secret のキーと値の組を、まとめて環境変数にするものです。env は、名前を付けた環境変数ごとに値を決めるものです。以下は公式ドキュメントの例の env の部分です。
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"参考:Define Environment Variables for a Container | Kubernetes
name が環境変数の名前、value が値です。値をここに直接書かず、ほかの場所から持ってくるときは、value の代わりに valueFrom を書きます。API リファレンスによると、value が空でなければ valueFrom は使えません。valueFrom の下に書けるものを、v1.37 時点の API リファレンスに沿って次の表にまとめます。
| フィールド | 値の出どころ |
|---|---|
configMapKeyRef | ConfigMap のキーの値(第17回) |
secretKeyRef | Secret のキーの値。Secret は機密のデータを入れるオブジェクト(第18回) |
fieldRef | Pod のフィールドの値(Downward API) |
resourceFieldRef | コンテナの CPU やメモリなどの requests と limits の値(Downward API) |
fileKeyRef | ファイルに書いたキーの値。機能ゲート EnvFiles が有効であることが必要(v1.35 から既定で有効) |
参考:Pod | Kubernetes API Reference、Pod | Kubernetes API Reference
fileKeyRef は、init コンテナ(第10回)などが書いたファイルから、環境変数の値を読む機能です。v1.37 時点ではベータで、v1.35 から既定で有効です。機能ゲートは第17回で見たとおり、Kubernetes の機能ごとに有効か無効かを切り替える設定です。この回では使いません。
参考:Define Environment Variable Values Using An Init Container | Kubernetes、Feature Gates | Kubernetes
第17回で見たとおり、env や envFrom で決めた環境変数は、イメージに書かれた同じ名前の環境変数より優先されます。公式ドキュメントによると、コンテナにはこのほか、Service の情報も環境変数として渡されます。Service は第21回で扱います。今は自分で書いていない環境変数もコンテナに入っていることがある、と知っておけば十分です。
参考:Define Environment Variables for a Container | Kubernetes、Container Environment | Kubernetes、Container Environment | Kubernetes
環境変数を、引数やほかの環境変数の中で使う
env で決めた環境変数は、$(変数の名前) の形で、command と args の中で使えます。公式ドキュメントの例は次のとおりです。
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]参考:Define a Command and Arguments for a Container | Kubernetes
公式ドキュメントによると、環境変数は丸括弧を付けた "$(VAR)" の形で書く必要があります。この形でないと、command や args の中で値に置き換わりません。また、引数は環境変数を決めるどの方法(any of the techniques)を使っても作れる、と書かれています。例として挙がっているのは ConfigMap と Secret ですが、Downward API で作った環境変数も、この「どの方法」に含まれると読めます。API リファレンスによると、command はシェルを通さずに実行され、$(VAR) は Kubernetes がコンテナの環境変数で置き換えます。そのため、sh -c でシェルを動かす場合も、シェルには置き換えたあとの文字列が渡ると考えられます。置き換えられなければ、書いたまま残ります(第17回)。
参考:Define a Command and Arguments for a Container | Kubernetes、Pod | Kubernetes API Reference
$(変数の名前) は、env の value の中でも使えます。Downward API で作った環境変数を、ほかの環境変数の値に組み込むときにも役立つと考えられます。ただし、command と args の場合とは決まりが少し違います。公式ドキュメントの例を次に示します。SERVICE_IP などは名前に SERVICE と付いていますが、Service とは関係なく、値を直接書いただけの環境変数です。
env:
- name: SERVICE_PORT
value: "80"
- name: SERVICE_IP
value: "172.17.0.1"
- name: UNCHANGED_REFERENCE
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: PROTOCOL
value: "https"
- name: SERVICE_ADDRESS
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: ESCAPED_REFERENCE
value: "$$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"公式ドキュメントでは、UNCHANGED_REFERENCE、SERVICE_ADDRESS、ESCAPED_REFERENCE の 3 つの環境変数の値は次のようになっています。
公式ドキュメントの説明を、次の表にまとめます。
| 環境変数 | 値がこうなる理由 |
|---|---|
SERVICE_ADDRESS | 参照した 3 つの環境変数が、どれもリストの前のほうで決まっているので、すべて置き換わる |
UNCHANGED_REFERENCE | PROTOCOL はリストの後ろで決まっているので、まだ決まっていないものとして扱われる。$(PROTOCOL) はただの文字列として残る |
ESCAPED_REFERENCE | $$(PROTOCOL) のように $ を 2 つ重ねると置き換えられず、$(PROTOCOL) という文字列になる |
env の value の中で参照できるのは、リストでそれより前に決めた環境変数だけです。API リファレンスも、value の中の $(変数の名前) は、そのコンテナで前に決めた環境変数と、Service の環境変数(上で触れた、Kubernetes が入れる環境変数)で置き換える、と説明しています。公式ドキュメントによると、置き換えられなかった参照があっても、一般にコンテナの起動は止められません。参照し合うときは、互いに参照する形(循環参照)も避けるよう書かれています。
参考:Define Dependent Environment Variables | Kubernetes、Pod | Kubernetes API Reference、Define Environment Variables for a Container | Kubernetes
Pod のフィールドを環境変数で渡す(fieldRef)
ここから Downward API に入ります。以下は公式ドキュメントの例の env の部分です。Pod のフィールドを 5 つ、環境変数にしています。
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName参考:Expose Pod Information to Containers Through Environment Variables | Kubernetes
fieldRef の fieldPath に、渡したい Pod のフィールドを、spec.nodeName のように . でつないで書きます。API リファレンスによると、fieldRef にはもう 1 つ apiVersion を書けます。fieldPath をどのバージョンの形で書いたかを表すもので、既定は "v1" です。公式ドキュメントは、この例のフィールドは Pod のフィールドで、Pod の中のコンテナのフィールドではない、と注記しています。
参考:Pod | Kubernetes API Reference、Expose Pod Information to Containers Through Environment Variables | Kubernetes
公式ドキュメントでは、この例のコンテナが 5 つの環境変数の値を書き出したログは、次のとおりです。上から順に、ノードの名前、Pod の名前、Namespace、Pod の IP アドレス、ServiceAccount の名前です。
参考:Expose Pod Information to Containers Through Environment Variables | Kubernetes
minikube は、例を動かしたクラスタのノードの名前です。minikube は kind と同じく、手元で Kubernetes のクラスタを動かすツールです。ServiceAccount は Pod の中のプログラムが API を使うときの身元で、第38回で扱います。
コンテナのリソースの値を渡す(resourceFieldRef)
コンテナの CPU とメモリの値を渡す前に、requests と limits を短く確かめておきます。公式ドキュメントによると、Pod を書くとき、コンテナが必要とする資源(リソース)の量を、任意で書けます。requests は、kube-scheduler が Pod を置くノードを決めるのに使います。limits を書くと、kubelet は、動いているコンテナがその量を超えて資源を使わないようにします。詳しくは第29回で扱います。
CPU とメモリの量の書き方を、公式ドキュメントに沿って次の表にまとめます。
| 資源 | 単位と書き方 |
|---|---|
| CPU | 1 は、物理的な CPU のコア 1 つか、仮想的なコア 1 つにあたる。0.1 と 100m は同じ量で、m は 1000 分の 1(ミリ CPU) |
| メモリ | バイトで数える。Mi、Gi などの 2 のべき乗の単位や、M、G などの単位を付けて書ける |
参考:Resource Management for Pods and Containers | Kubernetes、Resource Management for Pods and Containers | Kubernetes
以下は公式ドキュメントの例です。コンテナ test-container の CPU とメモリの requests と limits を、4 つの環境変数にしています。
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory参考:Expose Pod Information to Containers Through Environment Variables | Kubernetes
resourceFieldRef に書くフィールドを、API リファレンスと公式ドキュメントに沿って次の表にまとめます。
| フィールド | 内容 | 既定値 |
|---|---|---|
resource | 選ぶ資源(requests.cpu、limits.memory など)。必須 | なし |
containerName | 資源の値を読むコンテナの名前。ボリュームでは必須、環境変数では書かなくてもよい | なし |
divisor | 値を表す単位。1 なら CPU はコア、メモリはバイトで表す | "1" |
参考:Pod | Kubernetes API Reference、Expose Pod Information to Containers Through Files | Kubernetes
環境変数で containerName を書かなかったときにどのコンテナの値になるかは、API リファレンスには書かれていません。環境変数を決めたコンテナ自身の値になると考えられます。「手元で試す」では containerName を環境変数では書かず、ボリュームでは書きます。
公式ドキュメントでは、この例のコンテナが 4 つの環境変数の値を書き出したログは、次のとおりです。上から順に、CPU の requests、CPU の limits、メモリの requests、メモリの limits です。
参考:Expose Pod Information to Containers Through Environment Variables | Kubernetes
メモリの 2 つは、divisor が既定の 1 なので、32Mi と 64Mi をバイトで表した値です。CPU の 2 つは、125m(0.125 コア)と 250m(0.25 コア)のどちらも 1 になっています。コアを単位にして、小数ではなく整数に切り上げて表していると読めます。丸め方そのものは公式ドキュメントには書かれていません。公式ドキュメントのボリュームの例では、CPU の divisor を 1m にしています。こうすると、ミリ CPU を単位にした値(125m なら 125)になるはずです。
参考:Expose Pod Information to Containers Through Environment Variables | Kubernetes、Expose Pod Information to Containers Through Files | Kubernetes
コンテナに CPU やメモリの limits を書いていない場合も、Downward API で limits を読めます。公式ドキュメントによると、そのときは kubelet が、ノードの割り当て可能な量(node allocatable)をもとに、CPU とメモリの割り当て可能な最大の値を渡します。node allocatable は一般に、ノードの資源のうち、Pod に割り当てられる量のことです。
使えるフィールド
Downward API で使える Pod のフィールドは、渡し方によって違います。表に出てくるデュアルスタックは一般に、IPv4 と IPv6 の両方のアドレスを持つ構成のことです。v1.37 時点の公式ドキュメントの一覧を、次の表にまとめます。
| フィールド | 内容 | 環境変数 | ボリューム |
|---|---|---|---|
metadata.name | Pod の名前 | 使える | 使える |
metadata.namespace | Pod の Namespace(第37回) | 使える | 使える |
metadata.uid | Pod の一意の ID | 使える | 使える |
metadata.labels['<KEY>'] | キーが <KEY> のラベルの値 | 使える | 使える |
metadata.annotations['<KEY>'] | キーが <KEY> のアノテーション(第42回)の値 | 使える | 使える |
metadata.labels | Pod のすべてのラベル。1 行に 1 つ | 使えない | 使える |
metadata.annotations | Pod のすべてのアノテーション。1 行に 1 つ | 使えない | 使える |
spec.serviceAccountName | Pod の ServiceAccount の名前 | 使える | 使えない |
spec.nodeName | Pod が動いているノードの名前 | 使える | 使えない |
status.hostIP | Pod を割り当てたノードの主な IP アドレス | 使える | 使えない |
status.hostIPs | status.hostIP のデュアルスタック版。1 つ目は status.hostIP と同じ | 使える | 使えない |
status.podIP | Pod の主な IP アドレス(ふつうは IPv4 のアドレス) | 使える | 使えない |
status.podIPs | status.podIP のデュアルスタック版。1 つ目は status.podIP と同じ | 使える | 使えない |
表のとおり、ノードの名前や IP アドレスは環境変数でしか、すべてのラベルとアノテーションはボリュームでしか渡せません。名前と Namespace、<KEY> を指定したラベルとアノテーションは、どちらの方法でも渡せます。
Pod の IP アドレスは第20回で扱います。status.hostIPs を Pod と Downward API で使えるようにする機能(機能ゲート PodHostIPs)は v1.30 で Stable になりました。今は常に使える機能で、切り替えの設定(機能ゲート)は無くなっています。
コンテナのフィールドとして resourceFieldRef で選べる資源は、v1.37 時点の公式ドキュメントでは次の 4 種類で、それぞれ limits と requests があります。
- CPU(
limits.cpu、requests.cpu) - メモリ(
limits.memory、requests.memory) - hugepages(
limits.hugepages-*、requests.hugepages-*) - 一時的なストレージ(
limits.ephemeral-storage、requests.ephemeral-storage)
hugepages は一般に、メモリを大きな単位で割り当てる仕組みのことです。hugepages を Downward API で使えるようにする機能(機能ゲート DownwardAPIHugePages)は v1.27 で Stable になりました。こちらも今は常に使える機能で、切り替えの設定は無くなっています。
なお、この回の「手元で試す」は API リファレンスと概念のページの両方に載っているフィールドだけを使うので、次の食い違いの影響は受けません。API リファレンスのフィールドの説明に挙がっている値は、この一覧より少なくなっています。環境変数の fieldRef の説明には metadata.uid と status.hostIPs が無く、環境変数の resourceFieldRef の説明には CPU、メモリ、一時的なストレージだけが、ボリュームの resourceFieldRef の説明には CPU とメモリだけが挙がっています。この回は概念のページの一覧に沿います。
参考:Pod | Kubernetes API Reference、Pod | Kubernetes API Reference、Downward API | Kubernetes
ファイルで渡す(downwardAPI ボリューム)
第10回と第17回で見たとおり、ボリュームは Pod の中のコンテナから使えるディレクトリで、コンテナの中の決まったパスにマウントして使います。公式ドキュメントによると、downwardAPI ボリュームは、Downward API のデータをアプリケーションに渡すボリュームです。ボリュームの中では渡したデータを、プレーンテキスト(文字だけの形式)の読み取り専用のファイルとして読めます。
以下は公式ドキュメントの例の Pod です。ラベルとアノテーションを、downwardAPI ボリュームのファイルにしています。
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox:1.27.2
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations参考:Expose Pod Information to Containers Through Files | Kubernetes
volumes の downwardAPI の items に、作るファイルを 1 つずつ書きます。公式ドキュメントによると、1 つ目の項目は、Pod の metadata.labels の値を labels という名前のファイルに入れる、という意味です。2 つ目はアノテーションを annotations というファイルに入れる、という意味です。ボリュームはコンテナの /etc/podinfo にマウントしているので、ファイルはコンテナからは /etc/podinfo/labels と /etc/podinfo/annotations として見えます。
参考:Expose Pod Information to Containers Through Files | Kubernetes
公式ドキュメントでは、labels のファイルの中身は次のとおりです。
参考:Expose Pod Information to Containers Through Files | Kubernetes
公式ドキュメントによると、すべてのラベルを渡すと、ラベルのキー="エスケープした値" の形で、1 行に 1 つずつ書かれます。エスケープは一般に、特別な意味を持つ記号を、ただの文字として扱われる形に書き換えることです。アノテーションも同じ形です。
コンテナのフィールドもボリュームで渡せます。公式ドキュメントの別の例では items に次のような項目を並べています。
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
divisor: 1m参考:Expose Pod Information to Containers Through Files | Kubernetes
公式ドキュメントによると、この項目は、コンテナ client-container の limits.cpu の値を、1m で決めた形式で、cpu_limit という名前のファイルに書く、という意味です。ボリュームではどのコンテナの値かを containerName で必ず書きます。
参考:Expose Pod Information to Containers Through Files | Kubernetes、Pod | Kubernetes API Reference
downwardAPI ボリュームに書けるフィールドを、API リファレンスに沿って次の表にまとめます。
| フィールド | 内容 |
|---|---|
items[*].path | 作るファイルの、ボリュームの中での相対パス。必須。絶対パスや .. を含むパスは書けない |
items[*].fieldRef | ファイルに書く Pod のフィールド |
items[*].resourceFieldRef | ファイルに書くコンテナの資源の値 |
items[*].mode | そのファイルの権限。書かなければ defaultMode が使われる |
defaultMode | 作るファイルの権限の既定値。既定は 0644 |
参考:Pod | Kubernetes API Reference、Pod | Kubernetes API Reference
公式ドキュメントの例では、ls -laR /etc/podinfo で表示したボリュームのディレクトリの中身は次のようになっています。
参考:Expose Pod Information to Containers Through Files | Kubernetes
公式ドキュメントによると、labels と annotations のファイルの実体は、一時的なサブディレクトリ(例では ..2982_06_02_21_47_53.299460680)の中にあります。..data はその一時的なサブディレクトリを指すシンボリックリンクです。シンボリックリンクは一般に、別の場所にあるファイルやディレクトリを指す、ファイルの別名のようなものです。labels と annotations も ..data の中のファイルを指すシンボリックリンクです。
参考:Expose Pod Information to Containers Through Files | Kubernetes
値が変わったときの反映
Pod のフィールドの値が、Pod が動いているあいだに変わることもあります。値が変わったときの、v1.37 時点の公式ドキュメントの説明を次の表にまとめます。
| 場面 | 公式ドキュメントの説明 |
|---|---|
| ボリュームのファイルを更新するとき | 新しい一時ディレクトリに書き、..data のシンボリックリンクの付け替えを一度に(atomically)行う |
subPath でマウントしたとき | フィールドの値が変わっても、更新が届かない |
| コンテナの CPU とメモリを、動かしたまま変えたとき | ボリュームのファイルは更新される。環境変数は、コンテナが再起動するまで更新されない |
参考:Expose Pod Information to Containers Through Files | Kubernetes、Volumes | Kubernetes、Downward API | Kubernetes
公式ドキュメントによると、シンボリックリンクを使うことで、メタデータを動的に、一度に(atomic)更新できます。付け替えには Linux の rename という、名前の付け替えを一度に行う仕組みを使います。読む側に、古いファイルと新しいファイルが混ざった途中の状態が見えないようにする仕組みだと考えられます。subPath(第17回)でマウントした場合に更新が届かないのは、ConfigMap と同じです。
参考:Expose Pod Information to Containers Through Files | Kubernetes、Volumes | Kubernetes
表の最後の行は動いているコンテナの CPU とメモリを、Pod を作り直さずに変える機能(機能ゲート InPlacePodVerticalScaling)についての説明です。公式ドキュメントによると、この機能は v1.27 で登場し、v1.35 から Stable で、無効にはできません(機能ゲートに値を設定しても無視されます)。
ラベルやアノテーションを書き換えたときについては、ファイルで渡すタスクのページが、ラベルとアノテーションをファイルにする例の中で、シンボリックリンクを使うことでメタデータを動的に一度に更新できる、と説明しています。subPath でマウントしたときだけ更新が届かないことと合わせると、subPath を使わなければ、ラベルやアノテーションを書き換えたとき、ボリュームのファイルは新しい値に更新されると読めます。環境変数については第17回の ConfigMap や、表の CPU とメモリの場合と同じく、コンテナを起動したときの値のままだと考えられます。動いているあいだの更新はこの回の手順では試しません。
参考:Expose Pod Information to Containers Through Files | Kubernetes、Volumes | Kubernetes
手元で試す
ここまでの内容を手元の kind のクラスタで試す手順を示します。Downward API で Pod とコンテナのフィールドを渡す Pod を作り、コンテナのログで、args の中の $(変数の名前) が置き換わったことを確かめます。続けて、コンテナの中で環境変数を表示し、ボリュームのファイルを読みます。コマンドは macOS や Linux のシェル(bash や zsh)で実行する前提で書いています。Windows では WSL(Windows の中で Linux を動かす仕組み)などを使ってください。試す環境は次のとおりです。
| 項目 | 内容 |
|---|---|
| kind | v0.33.0 |
| Kubernetes | v1.37.0(kind v0.33.0 の既定のノードイメージ) |
| ノード構成 | シングルノード(クラスタ名 kind):コントロールプレーン 1 |
| 必要なもの | Docker、kubectl(v1.36〜v1.38)、テキストエディタ、端末(ターミナル)2 つ |
参考:Release v0.33.0 · kubernetes-sigs/kind、Version Skew Policy | Kubernetes
kind でクラスタを作る手順は、以下の記事で解説しています。この回では第16回・第17回と同じく、シングルノードのクラスタを使います。この回で見る値の渡し方は、ノードが 1 つでも確かめられるからです。
kind で検証用のクラスタを作るDocker のコンテナをノードにして、手元のマシンに Kubernetes のクラスタを作るツール kind の仕組みを図で説明します。kind create cluster で何が起きるかを押さえ、シングルノードとマルチノードのクラスタを作って、ノードの正体が Docker のコンテナであることを確かめる手順を紹介します。シングルノードのクラスタを用意する
まず、前の回のクラスタが残っていないかを確かめます。
$ kind get clusters
kind が表示されたら、作り直さずにそのまま使えるので、クラスタを作る次のコマンドは飛ばします。表示されなければ、クラスタを作ってから、もう一度一覧します。前の回の multi-node が表示されても、この回では使いません。手元のマシンの資源(メモリなど)に余裕がなければ、kind delete cluster --name multi-node で消してから進めてください。
$ kind create cluster
$ kind get clusters
kind get clusters に kind が表示されれば、クラスタができています。第3回で決めたとおり、ここからのコマンドには --context kind-kind を付けて、操作するクラスタをはっきりさせます。
続けて、ノードを一覧します。
$ kubectl get nodes --context kind-kind
ノードが 1 つ表示され、STATUS 列が Ready になっていれば準備ができています。Ready になっていなければ、少し待ってからもう一度実行します。NAME 列のノードの名前はあとで環境変数の値と見比べるので、覚えておいてください。
Downward API を使う Pod を作る
以下はこの回で使う Pod のマニフェストです。公式ドキュメントの環境変数の例と、ボリュームの 2 つの例を 1 つの Pod にまとめました。違いは次のとおりです。
- イメージは第9回・第16回と同じ
busybox:1.28にした argsは、環境変数を$(変数の名前)で使って 1 行書き出し、そのあと 1 時間待つだけにした- CPU の requests を
divisorの違う 2 つの環境変数で渡し、値を見比べられるようにした - 名前、ラベル、ボリュームに入れる項目を、この回に合わせて変えた
downward-demo.yaml という名前で、コマンドを実行するディレクトリに保存します。
apiVersion: v1
kind: Pod
metadata:
name: downward-demo
labels:
app: downward-demo
tier: demo
annotations:
build: two
builder: john-doe
spec:
containers:
- name: main
image: busybox:1.28
command: ["sh", "-c"]
args:
- echo "Hello from $(MY_POD_NAME) in $(MY_POD_NAMESPACE) on $(MY_NODE_NAME)";
sleep 3600
resources:
requests:
cpu: "125m"
memory: "32Mi"
limits:
cpu: "250m"
memory: "64Mi"
env:
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
resource: requests.cpu
- name: MY_CPU_REQUEST_MILLI
valueFrom:
resourceFieldRef:
resource: requests.cpu
divisor: 1m
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
- path: "cpu_limit"
resourceFieldRef:
containerName: main
resource: limits.cpu
divisor: 1m
- path: "mem_request"
resourceFieldRef:
containerName: main
resource: requests.memory
divisor: 1Mi参考:Expose Pod Information to Containers Through Environment Variables | Kubernetes、Expose Pod Information to Containers Through Files | Kubernetes、Pod | Kubernetes API Reference
マニフェストで渡す値を、次の表にまとめます。
| 渡し方 | 名前 | 中身 |
|---|---|---|
| 環境変数 | MY_POD_NAME、MY_POD_NAMESPACE | Pod の名前と Namespace |
| 環境変数 | MY_NODE_NAME、MY_POD_IP | Pod が動いているノードの名前と、Pod の IP アドレス |
| 環境変数 | MY_CPU_REQUEST、MY_CPU_REQUEST_MILLI | CPU の requests。divisor は既定の 1 と、1m |
| 環境変数 | MY_MEM_LIMIT | メモリの limits。divisor は既定の 1 |
| ファイル | /etc/podinfo/labels、/etc/podinfo/annotations | Pod のすべてのラベルと、すべてのアノテーション |
| ファイル | /etc/podinfo/cpu_limit | CPU の limits。divisor は 1m |
| ファイル | /etc/podinfo/mem_request | メモリの requests。divisor は 1Mi |
args の文字列は公式ドキュメントの例と同じく、YAML で複数行に分けて書いています。一般に、YAML ではこのような複数行の文字列は、改行が空白に変わって 1 行につながります。そのため、シェルには echo "Hello from $(MY_POD_NAME) in $(MY_POD_NAMESPACE) on $(MY_NODE_NAME)"; sleep 3600 という 1 行が渡ると考えられます。ただし、$(MY_POD_NAME) などはシェルに渡る前に、Kubernetes が環境変数の値に置き換えます。そのため、シェルには $(MY_POD_NAME) ではなく downward-demo という文字が入った文字列が渡ると考えられます。API リファレンスによると、環境変数が決まっていなくて置き換えられなければ、$(MY_POD_NAME) は書いたまま残ります。シェルの書き方の $MY_POD_NAME でも、シェルが環境変数を読むので同じ値を表示できると考えられます。この回では Kubernetes の置き換えを確かめるために、$(…) の形を使います。sleep 3600 は 1 時間待つコマンドで、そのあいだコンテナは動き続けるので、コンテナの中でコマンドを動かして確かめられます。
参考:Pod | Kubernetes API Reference、Define a Command and Arguments for a Container | Kubernetes
ここからは端末を 2 つ使います。第11回・第13回〜第17回と同じく、1 つ目の端末で変化を追い続け、2 つ目の端末でマニフェストを渡したり、値を確かめたりします。この回で 1 つ目の端末が追うのは Pod です。2 つ目の端末を開いたら、cd でマニフェストを保存したディレクトリに移動しておきます。
1 つ目の端末で、Pod を監視します。-l app=downward-demo で、この回の Pod だけを選びます。この監視は片付けの前まで止めずに続けます。
$ kubectl get pods --watch -l app=downward-demo --context kind-kind
Pod がまだ無いので、何も表示されないか、見つからないことを知らせる 1 行が出たあと、止まったように見えると考えられます。
2 つ目の端末で、マニフェストを渡します。
$ kubectl apply -f downward-demo.yaml --context kind-kind
pod/downward-demo が作られたことを知らせる 1 行が出るはずです。1 つ目の端末には downward-demo の行が書き足されていき、STATUS 列は Pending、ContainerCreating を経て Running になるはずです。クラスタを作ったばかりなら、busybox:1.28 のイメージの取得に時間がかかるので、ContainerCreating のまましばらく止まって見えることがあります(第9回)。
引数の中で置き換わった値をログで見る
1 つ目の端末で Running になったのを確かめたら、2 つ目の端末で、コンテナのログを表示します。
$ kubectl logs downward-demo --context kind-kind
Hello from downward-demo in default on に、ノードの名前が続く 1 行が表示されるはずです。ノードの名前は、さきほど kubectl get nodes で表示された名前と同じになるはずです。第8回で見たとおり、kind の Quick Start の例では、クラスタ名 kind のノードのコンテナは kind-control-plane という名前なので、ノードの名前も同じような名前になると考えられます。Namespace はマニフェストで指定していないので、公式ドキュメントの例と同じく default になるはずです。
args に書いた $(MY_POD_NAME) などが Downward API で渡した値に置き換わっています。マニフェストを書いたときには、Pod を動かすノードの名前は決まっていませんでした。ノードが決まってから、その名前がコンテナに渡されたと読めます。
参考:Define a Command and Arguments for a Container | Kubernetes、Expose Pod Information to Containers Through Environment Variables | Kubernetes
Pod の名前と IP アドレスを環境変数で読む
2 つ目の端末で、コンテナの中で printenv を動かし、Pod のフィールドから作った 4 つの環境変数を表示します。第10回で見たとおり、kubectl exec はコンテナの中でコマンドを動かすコマンドで、-- の後ろがコンテナの中で動かすコマンドです。printenv は一般に、環境変数を表示するコマンドで、名前を並べると、その環境変数の値だけを 1 行ずつ表示します。公式ドキュメントの例のコンテナも printenv に名前を並べて値を書き出しています。
$ kubectl exec downward-demo --context kind-kind -- printenv MY_POD_NAME MY_POD_NAMESPACE MY_NODE_NAME MY_POD_IP
参考:kubectl exec | Kubernetes、Expose Pod Information to Containers Through Environment Variables | Kubernetes
4 行が表示され、上から downward-demo、default、ノードの名前、Pod の IP アドレスになるはずです。「Pod のフィールドを環境変数で渡す」で引用した公式ドキュメントのログと、並びの考え方は同じです。例のログには ServiceAccount の名前を含む 5 行がありますが、この回では 4 つの環境変数だけを表示するので 4 行です。値も、名前、ノードの名前、IP アドレスが手元のものになります。
Pod の IP アドレスを、Pod の側からも確かめます。第8回と同じく -o wide を付けて Pod を表示します。
$ kubectl get pod downward-demo -o wide --context kind-kind
IP 列の値が、MY_POD_IP の値と同じになるはずです。NODE 列の値も、MY_NODE_NAME の値と同じになるはずです。
コンテナのリソースの値を環境変数で読む
続けて、コンテナの資源から作った 3 つの環境変数を表示します。
$ kubectl exec downward-demo --context kind-kind -- printenv MY_CPU_REQUEST MY_CPU_REQUEST_MILLI MY_MEM_LIMIT
上から次の 3 つの値になると考えられます。
| 環境変数 | 考えられる値 | 根拠 |
|---|---|---|
MY_CPU_REQUEST | 1 | 公式ドキュメントの例で、divisor を書かない 125m の requests が 1 と表示されている |
MY_CPU_REQUEST_MILLI | 125 | divisor を 1m にしたので、ミリ CPU を単位にした値になるはず |
MY_MEM_LIMIT | 67108864 | 公式ドキュメントの例で、divisor を書かない 64Mi の limits が 67108864 と表示されている |
参考:Expose Pod Information to Containers Through Environment Variables | Kubernetes、Expose Pod Information to Containers Through Files | Kubernetes
MY_CPU_REQUEST の値は公式ドキュメントの例から読み取ったもので、丸め方は公式ドキュメントに書かれていません。1 以外の値が表示されても、手順の失敗ではありません。同じ CPU の requests でも、divisor によって表す単位が変わります。CPU の値を 1 コアより細かく読みたいときは、divisor を 1m にするとよいと考えられます。
ラベルとリソースの値をファイルで読む
2 つ目の端末で、コンテナの中のボリュームのファイルを 1 つずつ表示します。cat は一般に、ファイルの中身を表示するコマンドです。
$ kubectl exec downward-demo --context kind-kind -- cat /etc/podinfo/labels
$ kubectl exec downward-demo --context kind-kind -- cat /etc/podinfo/annotations
$ kubectl exec downward-demo --context kind-kind -- cat /etc/podinfo/cpu_limit
$ kubectl exec downward-demo --context kind-kind -- cat /etc/podinfo/mem_request
参考:Expose Pod Information to Containers Through Files | Kubernetes
各ファイルの中身として考えられるものを、次の表にまとめます。
| ファイル | 考えられる中身 |
|---|---|
labels | app="downward-demo" と tier="demo" の 2 行 |
annotations | build="two" と builder="john-doe" の行。このほか、kubectl apply が付ける kubectl.kubernetes.io/last-applied-configuration などの行も並ぶと考えられる |
cpu_limit | 250(250m を、1m を単位にした値) |
mem_request | 32(32Mi を、1Mi を単位にした値) |
labels と annotations の形は、公式ドキュメントの例の出力(キー、=、" で囲んだ値)と同じになるはずです。例とは、キーと値が違います。annotations に last-applied-configuration が並ぶと考えられるのは、第7回で見たとおり、kubectl apply で作ったオブジェクトには kubectl がこのアノテーションを付けるからです。公式ドキュメントの例の出力にはこの行がありません。第5回で見たとおり、このアノテーションの中身はマニフェストを JSON の形にした文字列なので、とても長い 1 行になると考えられます。cpu_limit と mem_request の値は、公式ドキュメントには例の出力が無いので、divisor の説明から考えた値です。
ファイルの末尾に改行があるかどうかは、公式ドキュメントには書かれていません。改行が無い場合は、値のすぐ後ろに、次のプロンプト(コマンドの入力を待つ表示)が続いて表示されると考えられます。
最後に、ボリュームのディレクトリの中身を表示します。
$ kubectl exec downward-demo --context kind-kind -- ls -la /etc/podinfo
「ファイルで渡す(downwardAPI ボリューム)」で引用した公式ドキュメントの例と同じく、.. で始まる日時のような名前のディレクトリと、それを指す ..data が表示されるはずです。labels、annotations、cpu_limit、mem_request の 4 つは、..data の中のファイルを指すシンボリックリンク(-> で指す先が書かれた行)として表示されるはずです。例では labels と annotations の 2 つでしたが、この回では 4 つになります。ディレクトリの名前や日時は、例とは違う手元の値になります。例の後半(/etc/..2982_06_02_21_47_53.299460680: で始まる、サブディレクトリの中の一覧)は、公式ドキュメントがサブディレクトリの中までたどる ls -laR を使ったときの表示なので、この回の ls -la では出ないと考えられます。
参考:Expose Pod Information to Containers Through Files | Kubernetes
片付け
1 つ目の端末で Ctrl+C を押して、Pod の監視を止めます。
2 つ目の端末で、作った Pod を、マニフェストを指定して削除します。
$ kubectl delete -f downward-demo.yaml --context kind-kind
pod "downward-demo" deleted のような 1 行が出るまで、しばらくかかることがあります。少し待ってから、残っていないかを確かめます。
$ kubectl get pods -l app=downward-demo --context kind-kind
Pod が Terminating で表示されていたら、少し待ってからもう一度実行します。第8回と同じく、見つからないことを知らせる 1 行が出れば、削除できています。
最後に、クラスタを削除し、消えたことを確かめます。
$ kind delete cluster
$ kind get clusters
kind delete cluster は存在しないクラスタを指定してもエラーを返しません。kind get clusters に kind が表示されなくなったことを確かめます。kubeconfig に kind-kind のコンテキストが残っていたら、第3回の片付けと同じく kubectl config delete-context kind-kind で消します。
注意点
コマンドと引数、環境変数、Downward API でつまずきやすい点と、後から変えられない設定を、次の表にまとめます。
| 項目 | 内容 |
|---|---|
command と args は後から変えられない | Pod を作ったあとでは変えられない。env も Pod を作ったあとで書き換えられない |
command はシェルを通さない | パイプや複数のコマンドを使うときは、/bin/sh に -c で渡す |
$(VAR) は丸括弧を付ける | command と args の中で置き換えるには、"$(VAR)" の形で書く |
value の中の参照は順番が大事 | 参照できるのは、リストでそれより前に決めた環境変数だけ。$$(VAR) は置き換えられない |
| 渡し方で使えるフィールドが違う | ノードの名前や IP アドレスは環境変数だけ、すべてのラベルとアノテーションはボリュームだけ |
ボリュームでは containerName が必須 | resourceFieldRef の containerName は、ボリュームでは必須、環境変数では省ける |
CPU の値は divisor で単位が変わる | 既定の 1 ではコアを単位にする。公式ドキュメントの例では 125m が 1 と表示される |
| limits を書かないときの値 | kubelet が、node allocatable をもとに、CPU とメモリの割り当て可能な最大の値を渡す |
subPath でマウントすると更新されない | subPath でマウントした downwardAPI ボリュームには、値が変わっても更新が届かない |
参考:Define a Command and Arguments for a Container | Kubernetes、Pod | Kubernetes API Reference、Define Dependent Environment Variables | Kubernetes、Downward API | Kubernetes、Volumes | Kubernetes
表の 1 行目の「書き換えられない」は、API リファレンスの「Cannot be updated」の訳で、動いている Pod の command、args、env のフィールドを API で書き換えられない、という意味です。値を変えたいときは、Pod を作り直します。Deployment の Pod なら、第12回で見たとおり、ひな形の command や env を変えると、新しい Pod に入れ替わります。
関連記事
この回で MY_POD_IP として読んだ、Pod の IP アドレスと、Pod どうしが通信する仕組みについては、以下の記事で解説しています。
この回で resourceFieldRef で読んだ、CPU とメモリの requests と limits については、以下の記事で解説しています。
この回で downwardAPI ボリュームのファイルで読んだ、ラベルとアノテーションの違いについては、以下の記事で解説しています。