Downward API で Pod の情報を読む

v1.37 時点(2026年10月25日 確認)

Kubernetes 基本仕様第19回 / 全45回 ・ 第3部 設定と機密情報
目次

この記事では Pod やコンテナの情報をコンテナの中で動くプログラムに渡す、Downward API の仕組みを図で説明します。Pod の名前や IP アドレス、コンテナに割り当てた CPU とメモリの値を、環境変数とファイルの 2 つの方法で渡せること、方法によって渡せる情報が違うことがわかります。その土台として、コンテナで動かすコマンドと引数を決める command と args、環境変数を決める env の書き方も説明します。後半では kind のクラスタで、Pod 自身の名前やリソースの値をコンテナの中から読む手順を示します。

ConfigMap の値を、環境変数とボリュームの 2 つの方法でコンテナに渡した第17回の内容を前提にしています。まだの方は先にこちらをどうぞ。

基本仕様 ・ 第17回 環境変数とボリュームで渡す ConfigMap の違い設定のデータをコンテナイメージから切り離して Pod に渡す ConfigMap の仕組みを図で説明します。環境変数とボリュームの 2 つの渡し方と、ConfigMap を書き換えたときにボリュームのファイルは後から更新され、環境変数は自動では更新されない理由を押さえ、kind のクラスタで確かめる手順を紹介します。

以下の図は Pod downward-demo の情報を、Downward API で Pod の中のコンテナ main に渡している様子を表しています。後半の「手元で試す」で作る構成です。

Pod とコンテナのフィールドを、環境変数とファイルで受け取るコンテナ

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 の下に並ぶ項目のことです。

参考:Downward API | Kubernetes

名前に API と付いていますが、コンテナの中のプログラムが kube-apiserver(第4回)に問い合わせるわけではありません。公式ドキュメントは、Downward API を使うと、コンテナは Kubernetes のクライアントや API サーバーを使わずに、自分自身やクラスタについての情報を使える、と説明しています。

参考:Downward API | Kubernetes

Downward API で渡せるのは、Kubernetes の API のフィールドのうちの一部だけです。どのフィールドを渡せるかは、あとの「使えるフィールド」で表にまとめます。

参考:Downward API | Kubernetes

なぜ Downward API が必要なのか

公式ドキュメントによると、コンテナが Kubernetes に強く結び付きすぎずに、自分自身についての情報を持てると便利なことがあります。挙げられている例は次のようなものです。すでにあるアプリケーションが、決まった名前の環境変数に、自分を見分けるための一意の値(識別子)が入っていると想定して作られているとします。アプリケーションを別のプログラムで包んで(ラップして)値を用意する方法もありますが、手間がかかって間違いも起きやすく、結び付きを弱く保つという目的にも反します。それよりも、Pod の名前を識別子として使い、決まった名前の環境変数に Pod の名前を入れるほうがよい、と書かれています。

参考:Downward API | Kubernetes

ほかにも一般的な例として、同じアプリケーションの 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 で渡します。

参考:Container Environment | Kubernetes

Downward API の仕組み

値をコンテナに入れるのが誰かについて、Downward API の公式ドキュメントにまとまった説明はありません。limits を書いていない場合の説明(あとの「コンテナのリソースの値を渡す」)では、値を渡す(expose)主体を kubelet としています。そのため、環境変数を入れるのも、ボリュームのファイルを書くのも、Pod が動くノードの kubelet(第4回)だと考えられます。第17回の ConfigMap でも、コンテナを起動するときにデータを使うのは kubelet でした。

参考:Downward API | Kubernetes、ConfigMaps | Kubernetes

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 つの書き方ごとに表しています。

マニフェストの command と args、イメージの ENTRYPOINT と CMD の関係

マニフェストに書いたものが、イメージの既定より優先されます。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

公式ドキュメントのシェルで動かす例は、次のとおりです。

yaml
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 の部分です。

yaml
    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 リファレンスに沿って次の表にまとめます。

フィールド値の出どころ
configMapKeyRefConfigMap のキーの値(第17回)
secretKeyRefSecret のキーの値。Secret は機密のデータを入れるオブジェクト(第18回)
fieldRefPod のフィールドの値(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 の中で使えます。公式ドキュメントの例は次のとおりです。

yaml
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 とは関係なく、値を直接書いただけの環境変数です。

yaml
      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)"

参考:Define Dependent Environment Variables | Kubernetes

公式ドキュメントでは、UNCHANGED_REFERENCE、SERVICE_ADDRESS、ESCAPED_REFERENCE の 3 つの環境変数の値は次のようになっています。

UNCHANGED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
SERVICE_ADDRESS=https://172.17.0.1:80
ESCAPED_REFERENCE=$(PROTOCOL)://172.17.0.1:80

参考:Define Dependent Environment Variables | Kubernetes

公式ドキュメントの説明を、次の表にまとめます。

環境変数値がこうなる理由
SERVICE_ADDRESS参照した 3 つの環境変数が、どれもリストの前のほうで決まっているので、すべて置き換わる
UNCHANGED_REFERENCEPROTOCOL はリストの後ろで決まっているので、まだ決まっていないものとして扱われる。$(PROTOCOL) はただの文字列として残る
ESCAPED_REFERENCE$$(PROTOCOL) のように $ を 2 つ重ねると置き換えられず、$(PROTOCOL) という文字列になる

参考:Define Dependent Environment Variables | Kubernetes

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 つ、環境変数にしています。

yaml
      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 の名前です。

minikube
dapi-envars-fieldref
default
172.17.0.4
default

参考: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回で扱います。

参考:Resource Management for Pods and Containers | Kubernetes

CPU とメモリの量の書き方を、公式ドキュメントに沿って次の表にまとめます。

資源単位と書き方
CPU1 は、物理的な 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 つの環境変数にしています。

yaml
      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 です。

1
1
33554432
67108864

参考: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 | Kubernetes

使えるフィールド

Downward API で使える Pod のフィールドは、渡し方によって違います。表に出てくるデュアルスタックは一般に、IPv4 と IPv6 の両方のアドレスを持つ構成のことです。v1.37 時点の公式ドキュメントの一覧を、次の表にまとめます。

フィールド内容環境変数ボリューム
metadata.namePod の名前使える使える
metadata.namespacePod の Namespace(第37回)使える使える
metadata.uidPod の一意の ID使える使える
metadata.labels['<KEY>']キーが <KEY> のラベルの値使える使える
metadata.annotations['<KEY>']キーが <KEY> のアノテーション(第42回)の値使える使える
metadata.labelsPod のすべてのラベル。1 行に 1 つ使えない使える
metadata.annotationsPod のすべてのアノテーション。1 行に 1 つ使えない使える
spec.serviceAccountNamePod の ServiceAccount の名前使える使えない
spec.nodeNamePod が動いているノードの名前使える使えない
status.hostIPPod を割り当てたノードの主な IP アドレス使える使えない
status.hostIPsstatus.hostIP のデュアルスタック版。1 つ目は status.hostIP と同じ使える使えない
status.podIPPod の主な IP アドレス(ふつうは IPv4 のアドレス)使える使えない
status.podIPsstatus.podIP のデュアルスタック版。1 つ目は status.podIP と同じ使える使えない

参考:Downward API | Kubernetes

表のとおり、ノードの名前や IP アドレスは環境変数でしか、すべてのラベルとアノテーションはボリュームでしか渡せません。名前と Namespace、<KEY> を指定したラベルとアノテーションは、どちらの方法でも渡せます。

Pod の IP アドレスは第20回で扱います。status.hostIPs を Pod と Downward API で使えるようにする機能(機能ゲート PodHostIPs)は v1.30 で Stable になりました。今は常に使える機能で、切り替えの設定(機能ゲート)は無くなっています。

参考:Feature Gates (removed) | Kubernetes

コンテナのフィールドとして 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)

参考:Downward API | Kubernetes

hugepages は一般に、メモリを大きな単位で割り当てる仕組みのことです。hugepages を Downward API で使えるようにする機能(機能ゲート DownwardAPIHugePages)は v1.27 で Stable になりました。こちらも今は常に使える機能で、切り替えの設定は無くなっています。

参考:Feature Gates (removed) | Kubernetes

なお、この回の「手元で試す」は 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 のデータをアプリケーションに渡すボリュームです。ボリュームの中では渡したデータを、プレーンテキスト(文字だけの形式)の読み取り専用のファイルとして読めます。

参考:Volumes | Kubernetes

以下は公式ドキュメントの例の Pod です。ラベルとアノテーションを、downwardAPI ボリュームのファイルにしています。

yaml
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 のファイルの中身は次のとおりです。

cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"

参考:Expose Pod Information to Containers Through Files | Kubernetes

公式ドキュメントによると、すべてのラベルを渡すと、ラベルのキー="エスケープした値" の形で、1 行に 1 つずつ書かれます。エスケープは一般に、特別な意味を持つ記号を、ただの文字として扱われる形に書き換えることです。アノテーションも同じ形です。

参考:Downward API | Kubernetes

コンテナのフィールドもボリュームで渡せます。公式ドキュメントの別の例では items に次のような項目を並べています。

yaml
          - 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 で表示したボリュームのディレクトリの中身は次のようになっています。

drwxr-xr-x  ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx  ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx  ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx  ... Feb 6 21:47 labels -> ..data/labels

/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r--  ... Feb  6 21:47 annotations
-rw-r--r--  ... Feb  6 21:47 labels

参考: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 で、無効にはできません(機能ゲートに値を設定しても無視されます)。

参考:Downward API | Kubernetes、Feature Gates | Kubernetes

ラベルやアノテーションを書き換えたときについては、ファイルで渡すタスクのページが、ラベルとアノテーションをファイルにする例の中で、シンボリックリンクを使うことでメタデータを動的に一度に更新できる、と説明しています。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 を動かす仕組み)などを使ってください。試す環境は次のとおりです。

項目内容
kindv0.33.0
Kubernetesv1.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 つでも確かめられるからです。

基本仕様 ・ 第2回 kind で検証用のクラスタを作るDocker のコンテナをノードにして、手元のマシンに Kubernetes のクラスタを作るツール kind の仕組みを図で説明します。kind create cluster で何が起きるかを押さえ、シングルノードとマルチノードのクラスタを作って、ノードの正体が Docker のコンテナであることを確かめる手順を紹介します。

シングルノードのクラスタを用意する

まず、前の回のクラスタが残っていないかを確かめます。

console
$ kind get clusters

kind が表示されたら、作り直さずにそのまま使えるので、クラスタを作る次のコマンドは飛ばします。表示されなければ、クラスタを作ってから、もう一度一覧します。前の回の multi-node が表示されても、この回では使いません。手元のマシンの資源(メモリなど)に余裕がなければ、kind delete cluster --name multi-node で消してから進めてください。

console
$ kind create cluster
$ kind get clusters

kind get clusters に kind が表示されれば、クラスタができています。第3回で決めたとおり、ここからのコマンドには --context kind-kind を付けて、操作するクラスタをはっきりさせます。

参考:Quick Start | kind

続けて、ノードを一覧します。

console
$ kubectl get nodes --context kind-kind

ノードが 1 つ表示され、STATUS 列が Ready になっていれば準備ができています。Ready になっていなければ、少し待ってからもう一度実行します。NAME 列のノードの名前はあとで環境変数の値と見比べるので、覚えておいてください。

参考:kubectl get | Kubernetes、Node Status | Kubernetes

Downward API を使う Pod を作る

以下はこの回で使う Pod のマニフェストです。公式ドキュメントの環境変数の例と、ボリュームの 2 つの例を 1 つの Pod にまとめました。違いは次のとおりです。

  • イメージは第9回・第16回と同じ busybox:1.28 にした
  • args は、環境変数を $(変数の名前) で使って 1 行書き出し、そのあと 1 時間待つだけにした
  • CPU の requests を divisor の違う 2 つの環境変数で渡し、値を見比べられるようにした
  • 名前、ラベル、ボリュームに入れる項目を、この回に合わせて変えた

downward-demo.yaml という名前で、コマンドを実行するディレクトリに保存します。

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_NAMESPACEPod の名前と Namespace
環境変数MY_NODE_NAME、MY_POD_IPPod が動いているノードの名前と、Pod の IP アドレス
環境変数MY_CPU_REQUEST、MY_CPU_REQUEST_MILLICPU の requests。divisor は既定の 1 と、1m
環境変数MY_MEM_LIMITメモリの limits。divisor は既定の 1
ファイル/etc/podinfo/labels、/etc/podinfo/annotationsPod のすべてのラベルと、すべてのアノテーション
ファイル/etc/podinfo/cpu_limitCPU の 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 だけを選びます。この監視は片付けの前まで止めずに続けます。

console
$ kubectl get pods --watch -l app=downward-demo --context kind-kind

参考:kubectl get | Kubernetes

Pod がまだ無いので、何も表示されないか、見つからないことを知らせる 1 行が出たあと、止まったように見えると考えられます。

2 つ目の端末で、マニフェストを渡します。

console
$ 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回)。

参考:Pod Lifecycle | Kubernetes

引数の中で置き換わった値をログで見る

1 つ目の端末で Running になったのを確かめたら、2 つ目の端末で、コンテナのログを表示します。

console
$ kubectl logs downward-demo --context kind-kind

参考:kubectl logs | Kubernetes

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 に名前を並べて値を書き出しています。

console
$ 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 を表示します。

console
$ kubectl get pod downward-demo -o wide --context kind-kind

参考:kubectl get | Kubernetes

IP 列の値が、MY_POD_IP の値と同じになるはずです。NODE 列の値も、MY_NODE_NAME の値と同じになるはずです。

コンテナのリソースの値を環境変数で読む

続けて、コンテナの資源から作った 3 つの環境変数を表示します。

console
$ kubectl exec downward-demo --context kind-kind -- printenv MY_CPU_REQUEST MY_CPU_REQUEST_MILLI MY_MEM_LIMIT

上から次の 3 つの値になると考えられます。

環境変数考えられる値根拠
MY_CPU_REQUEST1公式ドキュメントの例で、divisor を書かない 125m の requests が 1 と表示されている
MY_CPU_REQUEST_MILLI125divisor を 1m にしたので、ミリ CPU を単位にした値になるはず
MY_MEM_LIMIT67108864公式ドキュメントの例で、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 は一般に、ファイルの中身を表示するコマンドです。

console
$ 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

各ファイルの中身として考えられるものを、次の表にまとめます。

ファイル考えられる中身
labelsapp="downward-demo" と tier="demo" の 2 行
annotationsbuild="two" と builder="john-doe" の行。このほか、kubectl apply が付ける kubectl.kubernetes.io/last-applied-configuration などの行も並ぶと考えられる
cpu_limit250(250m を、1m を単位にした値)
mem_request32(32Mi を、1Mi を単位にした値)

labels と annotations の形は、公式ドキュメントの例の出力(キー、=、" で囲んだ値)と同じになるはずです。例とは、キーと値が違います。annotations に last-applied-configuration が並ぶと考えられるのは、第7回で見たとおり、kubectl apply で作ったオブジェクトには kubectl がこのアノテーションを付けるからです。公式ドキュメントの例の出力にはこの行がありません。第5回で見たとおり、このアノテーションの中身はマニフェストを JSON の形にした文字列なので、とても長い 1 行になると考えられます。cpu_limit と mem_request の値は、公式ドキュメントには例の出力が無いので、divisor の説明から考えた値です。

ファイルの末尾に改行があるかどうかは、公式ドキュメントには書かれていません。改行が無い場合は、値のすぐ後ろに、次のプロンプト(コマンドの入力を待つ表示)が続いて表示されると考えられます。

最後に、ボリュームのディレクトリの中身を表示します。

console
$ 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 を、マニフェストを指定して削除します。

console
$ kubectl delete -f downward-demo.yaml --context kind-kind

参考:kubectl delete | Kubernetes

pod "downward-demo" deleted のような 1 行が出るまで、しばらくかかることがあります。少し待ってから、残っていないかを確かめます。

console
$ kubectl get pods -l app=downward-demo --context kind-kind

Pod が Terminating で表示されていたら、少し待ってからもう一度実行します。第8回と同じく、見つからないことを知らせる 1 行が出れば、削除できています。

最後に、クラスタを削除し、消えたことを確かめます。

console
$ kind delete cluster
$ kind get clusters

kind delete cluster は存在しないクラスタを指定してもエラーを返しません。kind get clusters に kind が表示されなくなったことを確かめます。kubeconfig に kind-kind のコンテキストが残っていたら、第3回の片付けと同じく kubectl config delete-context kind-kind で消します。

参考:Quick Start | kind、kubectl config | Kubernetes

注意点

コマンドと引数、環境変数、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 に入れ替わります。

参考:Pod | Kubernetes API Reference、Deployments | Kubernetes

関連記事

この回で MY_POD_IP として読んだ、Pod の IP アドレスと、Pod どうしが通信する仕組みについては、以下の記事で解説しています。

基本仕様 ・ 第20回 Pod 同士が通信する仕組みPod 同士が通信する仕組みを、Kubernetes のネットワークモデルから図で説明します。Pod ごとに付く IP アドレス、NAT を使わない Pod どうしの通信、ネットワークプラグイン(CNI プラグイン)の役割、Pod の IP アドレスの範囲を押さえ、kind のマルチノードのクラスタで、別のノードの Pod に IP アドレスで直接届くことを確かめる手順を紹介します。

この回で resourceFieldRef で読んだ、CPU とメモリの requests と limits については、以下の記事で解説しています。

基本仕様 ・ 第29回 requests と limits の仕組みコンテナが使う CPU とメモリの量を書く requests と limits の仕組みを図で説明します。requests で Pod を置くノードが選ばれること、limits を超えようとした CPU とメモリに起きること、QoS クラスの決まり方を押さえ、kind のクラスタで OOMKilled を観察する手順を紹介します。

この回で downwardAPI ボリュームのファイルで読んだ、ラベルとアノテーションの違いについては、以下の記事で解説しています。

基本仕様 ・ 第42回 ラベルとアノテーションの違いリソースに付けるキーと値の組であるラベルとアノテーションの違いを図で説明します。選ぶためのラベルと選ぶためではないアノテーションの区別、書き方の決まり、推奨のラベル、複数の次元で分ける設計を押さえ、kind のクラスタでラベルで絞り込んでまとめて操作する手順を紹介します。

Kubernetes 基本仕様の目次へ