(O+P)ut

アウトプット



(O+P)ut

Output Log

【Kubernetes】Deploymentを例にOwnerReferencesを理解する

はじめに

Kubernetesではkubectl create deployment nginx-dep --image nginxとデプロイメントを作成すると自動的にReplicaSetやPodが作成され、同デプロイメントを削除すれば自動的にReplicaSetやPodも削除されます

これはOwnerReferencesによってオブジェクトの親子関係が管理されていることでガーベッジコレクションが行われる仕組みでもあります。本記事ではこのOwnerReferencesに伴うガーベッジコレクションの例をデプロイメントで説明します。

コマンド実行環境
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"15",...

事前準備

以下のデプロイメントを作成すると

$ kubectl create deployment nginx-dep --image nginx
deployment.apps/nginx-dep created

デプロイメント、レプリカセット、ポッドが作成されます。

$ kubectl get deploy,rs,pod
NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.extensions/nginx-dep   1/1     1            1           21s

NAME                                         DESIRED   CURRENT   READY   AGE
replicaset.extensions/nginx-dep-76c88d5587   1         1         1       21s

NAME                             READY   STATUS    RESTARTS   AGE
pod/nginx-dep-76c88d5587-k4g2j   1/1     Running   0          21s

ownerReferenceを確認する

YAMLファイルでは「ownerReference」で管理されるのでそれぞれで確認するとReplicaSetとPodにのみ存在します。

$ kubectl get deploy nginx-dep -o yaml | grep ownerReferences

$ kubectl get rs nginx-dep-76c88d5587 -o yaml | grep ownerReferences
  ownerReferences:

$ kubectl get pod nginx-dep-76c88d5587-k4g2j  -o yaml | grep ownerReferences
  ownerReferences:

そしてそれぞれを確認するとReplicaSetではDeploymentがowner、PodではReplicaSetがownerとして管理されています。

ownerReferences:
...
kind: Deployment
name: nginx-dep
...

ownerReferences:
...
kind: ReplicaSet
name: nginx-dep-76c88d5587
...

OwnerReferenceで指定されているオブジェクトが削除された場合は同オブジェクトも削除される動きを取るため、デプロイメントを削除すれば連鎖的にレプリカセットとポッドが削除されるというわけです。

終わりに

Kubernetes初学者の方が素朴に抱く「なぜDeploymentを消せば関連するPodが全て消えるのか」という問いは「OwneReferenceで紐づいているから」というのが回答になります。

ただし、削除する際に--cascade=falseと指定すればそのオブジェクトがOwnerとして記載されているオブジェクトの削除が行われないようにすることも可能です。こちらも併せて覚えておくとどこかで役立つと思います。

【Linux】cutコマンドで2文字以上の区切り文字を使いたい

格言

cutコマンドを使う人が欲しいのは区切り文字で挟まれた値である

環境情報
# cut --version
cut (GNU coreutils) 8.26

結論

awkを用いて実現させます

例えば<>が区切り文字であったとすると以下のように指定した文字列を取得できます。

$ # echo "123<>abc<>def<>456" | awk 'BEGIN{FS="<>"}{print $2}'
abc

以下、補足です。

補足

以下記事と同じ構成です。

一行の中で区切り文字で表現されているテキストから
特定の値を取り出すコマンドとしてcutコマンドがあります。

ただし区切り文字を文字ではなく文字列で指定すると以下エラーとなります。

# echo "123<>abc<>def<>456" | cut -d"<>" -f2
cut: the delimiter must be a single character
Try 'cut --help' for more information.

以上、ご参考ください。

【Kubernetes】特定Podを停止させずにレプリカセットから切り離す手順

はじめに

Kubernetesではkubectl create deployment nginx-dep --image nginxとデプロイメントを作成すると自動的にReplicaSetも作成され、不具合が発生した場合もPodをdeleteすれば自動的に新たなPodが復旧します。

ただ、PD対応等で特定のPodを一時的に退避してデプロイメントで管理するPodから外して新たなPodを作成したい場合があります。本記事ではそのような際に利用できるPodのラベル変更手順によるPodの切り離しを説明します。

コマンド実行環境
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"15",...

想定するシナリオ

以下のPod(Labels:app=nginx-dep)が

$ kubectl get pod
NAME                         READY   STATUS    RESTARTS   AGE
nginx-dep-76c88d5587-7fjp7   1/1     Running   0          26m
nginx-dep-76c88d5587-7k6gs   1/1     Running   0          10m

以下のレプリカセットで管理されている状況で

$ kubectl describe rs nginx-dep-76c88d5587
Name:           nginx-dep-76c88d5587
Namespace:      default
Selector:       app=nginx-dep,pod-template-hash=76c88d5587
Labels:         app=nginx-dep

nginx-dep-76c88d5587-7fjp7のPodを立ち上げたままレプリカセットから切り離すことで、デプロイメントとしてのPod数は維持したままでnginx-dep-76c88d5587-7fjp7の内部調査を行いたい。

Podのラベルを変更することでSelectorの対象から外す

レプリカセットの中身を見れば分かる通り以下の条件でPod数を監視しています。

Selector:       app=nginx-dep,pod-template-hash=76c88d5587

切り離したいPodは以下のように同ラベルが付与されているので

$ kubectl describe pod nginx-dep-76c88d5587-7fjp7
...
Labels:         app=nginx-dep
                pod-template-hash=76c88d5587

以下コマンドでエディタを開きPodのラベルを変更(nginx-dep→nginx-depX)すれば

$ kubectl edit pod nginx-dep-76c88d5587-7fjp7
pod/nginx-dep-76c88d5587-7fjp7 edited
$ kubectl describe pod nginx-dep-76c88d5587-7fjp7
...
Labels:       app=nginx-depX

新たなPodがreplica数を維持するために起動してきます。

$ kubectl get pod
NAME                         READY   STATUS              RESTARTS   AGE
nginx-dep-76c88d5587-7fjp7   1/1     Running             0          27m
nginx-dep-76c88d5587-7k6gs   1/1     Running             0          11m
nginx-dep-76c88d5587-hpnxg   0/1     ContainerCreating   0          6s

そしてデプロイメントを削除しても

$ kubectl delete deploy nginx-dep
deployment.extensions "nginx-dep" deleted

ラベルを変更したPodはデプロイメントの管理外となり起動したままになります。

$ kubectl get pod
NAME                         READY   STATUS        RESTARTS   AGE
nginx-dep-76c88d5587-7fjp7   1/1     Running       0          28m
nginx-dep-76c88d5587-7k6gs   0/1     Terminating   0          12m
nginx-dep-76c88d5587-hpnxg   0/1     Terminating   0          37s

終わりに

不具合が発生しているPodはkubectl delete podやデプロイメント自体で落とし上げを行いがちですが、Podを落とさずにラベル名のみを付け替えることで該当のPodを起動したまま同様の操作ができるので覚えておくと役立つと思います。

【Unicode順】数字英字カタカナひらがな漢字の順にsortする

やりたいこと

UNIX環境にて以下のような文字列のファイルを

$ cat testmoji.txt
Apple
りんご
イチゴ
15
メロン
葡萄
いちじく
Banana

Unicode順(数字→英字→片仮名→平仮名→漢字)に並べ替える。

環境情報
$ sort --version
sort (GNU coreutils) 8.26
$ echo $LANG
ja_JP.UTF-8

やり方

sortコマンドにLANG=ja_JP.Unicodeを付与する。

$ cat testmoji.txt | LANG=ja_JP.Unicode sort
15
Apple
Banana
いちじく
りんご
イチゴ
メロン
葡萄

以下、補足です。

補足

日本語が入っているファイルに対してsortを行う際は文字コードに気を遣う必要があります。

例えば以下のようなUTF-8 Unicode形式のファイルを

$ file testmoji.txt
testmoji.txt: UTF-8 Unicode text

そのままsortで並び替えすると以下のようになります。

$ cat testmoji.txt | sort
15
Apple
Banana
イチゴ
いちじく
メロン
りんご
葡萄

上記結果は、あいうえお順という観点では正しいものの状況によっては表題のような順序で並べ替えて欲しい時があります。

そのような場合は「jp_JP.Unicode」とコマンド単位でLANG情報を変更することで取得したい結果を得ることができます。
以上、ご参考になれば幸いです。

【Kubernetes】kubectlではなくcurlコマンドで直接APIサーバと通信する

はじめに

Kubernetesではkubectlコマンドを利用してマスターノードのAPIサーバと通信を行いますが、今回はkubectlコマンドではなくcurlコマンドで直接deploymentの削除であるkubectl delete deploymentに相当するリクエストを行ってみます。

コマンド実行環境
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"15",...

事前準備

以下コマンドでnginx-depという名称のデプロイメントを作成します。

$ kubectl create deployment nginx-dep --image=nginx

このデプロイメントに対して以下コマンドを行えば本デプロイメントを作成できるyamlファイルが作成できるので

$ kubectl get deployment nginx-dep -o yaml --export > nginx-dep.yaml

以下コマンドで削除が可能になります。

$ kubectl delete -f nginx-dep.yaml
deployment.extensions "nginx-dep" delete

起動も同様です。

kubectl deleteで行われていることを確認

kubectlコマンドではオプションとして--v=数値を付与することでコマンドの詳細が確認できます。
例えば数値を6にすると以下のようにkubectl deleteの

$ sudo kubectl delete -f nginx-dep.yaml --v=6
I0627     4109 loader.go:359] Config loaded from file:  /home/xx/.kube/config
I0627     4109 round_trippers.go:438] DELETE https://10.0.0.1:6443/apis/extensions/v1beta1/namespaces/default/deployments/nginx-dep 200 OK in 14 milliseconds
deployment.extensions "nginx-dep" deleted
I0627     4109 round_trippers.go:438] GET https://10.0.0.1:6443/apis/extensions/v1beta1/namespaces/default/deployments?fieldSelector=metadata.name%3Dnginx-dep 200 OK in 11 milliseconds

ここで10.0.0.1はmasterノードのIPアドレスです。

これを見れば分かるようにDeleteコマンドの詳細は以下の通信です。今回はこれをcurlで行います。

DELETE https://10.0.0.1:6443/apis/extensions/v1beta1/namespaces/default/deployments/nginx-dep

kube-proxyを起動

APIサーバとの通信はAPIサーバとの認証をクリアする必要があるので直接上記のURLを叩くと以下のエラーとなります。

$ curl -X DELETE https://10.0.0.1:6443/apis/extensions/v1beta1/namespaces/default/deployments/nginx-dep
curl: (60) SSL certificate problem: unable to get local issuer certificate

よって今回は認証を突破するためにkube-proxyを立ち上げ、kube-proxy経由でAPIサーバと通信することにします。

以下コマンドでバッググラウンドでプロキシサーバが起動するので

$ kubectl proxy --port=8080 &
[1] 13625
$ Starting to serve on 127.0.0.1:8080
bg
-bash: bg: job 1 already in background

先ほどの

https://10.0.0.1:6443

http://localhost:8080

に置き換えてcurlコマンドを打てば認証をクリアできまs。

curlコマンドでDeploymentをDeleteする

デプロイメントが起動している状態で以下のcurlコマンドを押下すれば

$ sudo curl -X DELETE http://localhost:8080/apis/apps/v1/namespaces/default/deployments/nginx-dep

標準出力に以下が返ってきます。成功しています。

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Success",
  "details": {
    "name": "nginx-dep",
    "group": "apps",
    "kind": "deployments",
    "uid": "086bc1a3-cd68-4fb5-99bf-2f16090388d3"
  }
}

正しくデプロイメントを終了させることができました。尚、APIバージョンはbetaではなくstableを利用しています。
>|\
$ kubectl get deployment
No resources found.
|

終わりに

KubernetesのAPIサーバを直接curlコマンドで叩いてみました。
kubectlを利用せずにAPIサーバと通信する状況はないとは思いつつも、POST&DELETEでオブジェクトを制御している様を掴むためにも一度は実践してみることおススメします。

【Kubernetes入門】ConfigMapでPodの環境変数を設定する

はじめに

Kubernetesではデータベースの接続先やアプリケーションのパラメータをConfigMapとしてPodとは別に管理することができます。
今回はコンテナ内の環境変数をConfigMapオブジェクトから設定する流れについて分かりやすく解説しました。

コマンド実行環境
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"15",...

ConfigMapを作成する

以下がConfigMapのマニフェストの例です。

$ cat nginx-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-cm
data:
  TESTCM: hoge
  SAMPLECM: sample

data配下にKey:Value方式で値を設定できます。

今回は「TESTCM」というキーに対して「hoge」という設定値を指定したものと「SAMPLECM」というキーに対して「sample」という設定値を指定しました。

同ファイルはPodやDeploymentと同様に以下のように適用できます。

$ kubectl apply -f nginx-cm.yaml
configmap/nginx-cm created

以下コマンドで作成したコンフィグマップが確認できます。

$ kubectl get configmap
NAME       DATA   AGE
nginx-cm   2      8s
$ kubectl describe configmap nginx-cm
Name:         nginx-cm
Namespace:    default
...
続きを読む

他の記事を読む