作業メモ。
Kubernetes完全ガイド impress top gearシリーズを読みながら手元で確認した時のメモ。
環境
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.3", GitCommit:"2bba0127d85d5a46ab4b778548be28623b32d0b0", GitTreeState:"clean", BuildDate:"2018-05-28T20:03:09Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"11+", GitVersion:"v1.11.5-eks-6bad6d", GitCommit:"6bad6d9c768dc0864dab48a11653aa53b5a47043", GitTreeState:"clean", BuildDate:"2018-12-06T23:13:14Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Kubernetes 環境としては EKS を利用。
概要
環境変数を利用することでコンテナに任意の情報を与えることが出来る。
例えば DB への接続先 URL,ユーザー名やパスワード情報など。
- 静的設定
- Pod の情報
- コンテナの情報
- Secret リソースの機密情報
- ConfigMap リソースの設定値
1. 静的設定
Define an environment variable for a container
上記にあるように env もしくは envFrom フィールドでマニュフェストファイルに定義できる。
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/node-hello:1.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"
やってみる。
# Pod 作成
$kubectl apply -f https://k8s.io/examples/pods/inject/envars.yaml
pod "envar-demo" created
# describe すると設定がわかる
$kubectl describe pod envar-demo
・・・
Environment:
DEMO_GREETING: Hello from the environment
DEMO_FAREWELL: Such a sweet sorrow
# exec を使って env コマンドを実行すると設定されていることが確認出来る
$ kubectl exec -it envar-demo -- env|grep DEMO
DEMO_GREETING=Hello from the environment
DEMO_FAREWELL=Such a sweet sorrow
マニュフェストファイルで環境変数を利用する場合の注意点
Using environment variables inside of your config
上記のようにマニュフェストファイルに環境変数を定義し、マニュフェストファイルで参照(command や args など)する場合には注意が必要。
通常であれば ${GREETING} という形式で参照できるがマニュフェストファイル内での読み込む場合には $(GREETING) というように「{}」ではなく、「()」を利用する。
apiVersion: v1
kind: Pod
metadata:
name: print-greeting
spec:
containers:
- name: env-print-demo
image: bash
env:
- name: GREETING
value: "Warm greetings to"
- name: HONORIFIC
value: "The Most Honorable"
- name: NAME
value: "Kubernetes"
command: ["echo"]
args: ["$(GREETING) $(HONORIFIC) $(NAME)"]
# Pod 作成
$kubectl apply -f envvars2.yaml
pod "print-greeting" created
# マニュフェストファイルに定義した環境変数が args で読み込めている
$kubectl logs print-greeting
Warm greetings to The Most Honorable Kubernetes
2. Pod の情報、3. コンテナの情報
Expose Pod Information to Containers Through Environment Variables
Pod の情報(どのノードで起動しているか、自分の IP アドレスなど)について fieldRef を使って参照可能。
参照可能な値については kubectl get pods -o yaml
などで確認出来る。
コンテナの情報(CPU リソース設定など)は resourceFieldRef を使って参照可能。
参照可能な値については kubectl get pods -o yaml
などで確認出来る。
同じような方法で取得が可能なので今回は Pod の情報取得を試す。
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
sleep 10;
done;
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
restartPolicy: Never
# Pod 作成
$ kubectl apply -f dapi-envars-pod.yaml
pod "dapi-envars-fieldref" created
# Pod の情報が確認できる。while tru; doしているので継続的に表示される
$kubectl logs dapi-envars-fieldref
ip-172-31-23-75.ap-northeast-1.compute.internal
dapi-envars-fieldref
default
172.31.24.230
default
ip-172-31-23-75.ap-northeast-1.compute.internal
dapi-envars-fieldref
default
172.31.24.230
default
# exec しても環境変数が設定されている事が分かる
$kubectl exec -it dapi-envars-fieldref -- env |grep MY
MY_POD_NAMESPACE=default
MY_POD_IP=172.31.24.230
MY_POD_SERVICE_ACCOUNT=default
MY_NODE_NAME=ip-172-31-23-75.ap-northeast-1.compute.internal
MY_POD_NAME=dapi-envars-fieldref
4. Secret リソースの機密情報
Distribute Credentials Securely Using Secrets
ユーザー名・パスワードなどの機密情報を設定する場合には Secret を利用する。
なお、Secret は Base64 エンコードされているだけで暗号化されていない。
その為、Git リポジトリにマニュフェストファイルを配置するような場合、kubesecを使って暗号化するなど対応が必要。
以下より試す。
Base64 エンコード化する
Convert your secret data to a base-64 representation
Secret を使うためにはまずは設定したい値を Base64 エンコード化する。
$echo -n 'my-app' | base64
bXktYXBw
$ echo -n '39528$vdg7Jb' | base64
Mzk1MjgkdmRnN0pi
それぞれの値をメモしておく。
Secret 作成
以下のうようなマニュフェストファイルを作成する。
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
作成。
$kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-pod.yaml
secret "test-secret" created
# Secret の存在及び 2つのデータがあることを確認
$ kubectl get secret test-secret
NAME TYPE DATA AGE
test-secret Opaque 2 35s
# describe するとより詳細をな情報が確認出来る
$kubectl describe secret test-secret
Name: test-secret
Namespace: default
Labels: <none>
Annotations:
Type: Opaque
Data
====
password: 12 bytes
username: 6 bytes
Secret を環境変数経由で Pod からアクセスする
環境変数で Secret から値を参照する場合、 secretKeyRef を設定する。
なお、環境変数で参照した際には Base64 デコードされて設定されている。
apiVersion: v1
kind: Pod
metadata:
name: secret-envars-test-pod
spec:
containers:
- name: envars-test-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: test-secret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: test-secret
key: password
$ kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-envars-pod.yaml
pod "secret-envars-test-pod" created
# Secret の内容が Base64 デコードされて環境変数に設定されている。
$ kubectl exec -it secret-envars-test-pod -- env |grep SECRET
SECRET_USERNAME=my-app
SECRET_PASSWORD=39528$vdg7Jb
なお、Secret は環境変数だけでなく、 Volume を通して値を取得する事もできる。
Create a Pod that has access to the secret data through a Volume
volumes で Secret 名を定義し、対象の Volume をマウントする。
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# name must match the volume name below
- name: secret-volume
mountPath: /etc/secret-volume
# The secret data is exposed to Containers in the Pod through a Volume.
volumes:
- name: secret-volume
secret:
secretName: test-secret
試す。
$kubectl create -f https://k8s.io/docs/tasks/inject-data-application/secret-pod.yaml
pod "secret-test-pod" created
# マウントした /etc/secret-volume 配下に2つのファイルが存在する
$kubectl exec -it secret-test-pod -- ls /etc/secret-volume
password username
# 環境変数と同様に Base64 デコードされて設定されている
$kubectl exec -it secret-test-pod -- cat /etc/secret-volume/username
my-app%
$kubectl exec -it secret-test-pod -- cat /etc/secret-volume/password
39528$vdg7Jb%
5. ConfigMap リソースの設定値
Configure a Pod to Use a ConfigMap
機密性がないような情報の場合、ConfigMap を使って Key=Value 形式で値を予め保存し、環境変数で参照する事が出来る。
また、Secret と同じように ConfigMap においても Volume をマウントして値を参照する事もできる(基本的に方法は同じ)
ConfigMap を予め作成し、値を環境変数から参照する。
ConfigMap を作成する
ディレクトリを指定する、ファイルを指定する、 literal valuesから作成するなどいくつかの方法がある。
今回はマニュフェストファイル2つ作成して環境変数に設定し、参照する。
Define container environment variables with data from multiple ConfigMaps
apiVersion: v1
kind: ConfigMap
metadata:
name: special-config
namespace: default
data:
special.how: very
apiVersion: v1
kind: ConfigMap
metadata:
name: env-config
namespace: default
data:
log_level: INFO
# 作成
$kubectl apply -f configmap1.yaml
configmap "special-config" created
$kubectl apply -f configmap2.yaml
configmap "env-config" created
# 2つの ConfigMap が存在し、データはそれぞれ一つ(Key=value のペアが一つという意味)
$ kubectl get configmap
NAME DATA AGE
env-config 1 53s
special-config 1 1m
# Secret と違い、describe すると Value が確認出来る
$kubectl describe configmap env-config
Name: env-config
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","data":{"log_level":"INFO"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"env-config","namespace":"default"}}
Data
====
log_level:
----
INFO
Events: <none>
Pod から環境変数経由で参照する
configMapKeyRef を指定して環境変数で参照可能。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: SPECIAL_LEVEL_KEY
valueFrom:
configMapKeyRef:
name: special-config
key: special.how
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: env-config
key: log_level
restartPolicy: Never
# Pod 作成
$kubectl apply -f configmap-pod.yaml
pod "dapi-test-pod" created
# configmap1 の内容が参照可能
$ kubectl logs dapi-test-pod |grep SPECIAL
SPECIAL_LEVEL_KEY=very
# configmap2 の内容が参照可能
$kubectl logs dapi-test-pod |grep LOG
LOG_LEVEL=INFO
なお、envFrom フィールドを使うと指定し ConfigMap のすべての環境変数を参照するようにすることも出来る。
apiVersion: v1
kind: Pod
metadata:
name: dapi-test-pod
spec:
containers:
- name: test-container
image: k8s.gcr.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- configMapRef:
name: special-config
restartPolicy: Never
上記を使う場合、マニュフェストファイルを見ただけではどのような内容が設定されているか分からない。