kubectl run関連
新しいpodで対話的シェルを起動
kubectl run <DEPLOYMENT NAME/POD NAME PREFIX> --image=<IMAGE>:<TAG> <CMD>
Alpine LinuxのEdgeでshを起動するなら以下のようにする
$ kubectl run mypod --tty -i --image=alpine:edge sh
C-d等で抜けたあともコンテナは起動し続ける。run mypod
の結果、mypod
というdeploymentと、mypod-ランダムな文字列
というpodが作られている。
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
mypod 1 1 1 1 29m
nslkup 1 1 1 0 1m
$ kubectl get po
kubectl run --overridesでNET_ADMINをつける
$ kubectl run -it --restart=Never --image=gcr.io/google-containers/ubuntu-slim:0.14 netadm-test --overrides '
{
"spec": {
"hostNetwork": true,
"containers":[
{
"args": ["/bin/bash"],
"stdin": true,
"tty": true,
"name": "netadm-test",
"image": "gcr.io/google-containers/ubuntu-slim:0.14",
"securityContext": {
"capabilities": {
"add": ["NET_ADMIN"]
}
}
}
]
}
}' -- /bin/bash
iptables-save
kubectl run --overridesでpodのホスト名、サブドメイン等を指定する
$ kubectl run -it --image alpine:3.4 alpine --overrides '{"spec":{"template":{"spec":{"hostname":"foo","subdomain":"bar"}}}}' -- sh
/ # nslookup foo.bar.default.svc.cluster.local
nslookup: can't resolve '(null)': Name does not resolve
Name: foo.bar.default.svc.cluster.local
Address 1: 172.17.0.23 foo.bar.default.svc.cluster.local
/ # hostname
foo
/ # hostname -f
foo.bar.default.svc.cluster.local
kubectl run --overridesでenvFromを指定する
Ref: https://github.com/kubernetes/kubernetes/issues/48361#issuecomment-342810925
kubectl run ubuntu --overrides='
{
"spec": {
"containers": [
{
"name": "app",
"image": "ubuntu",
"envFrom": [
{
"configMapRef": {
"name": "config-env"
}
},
{
"secretRef": {
"name": "secret-env"
}
}
]
}
]
}
}
' --image=ubuntu --restart=Never --dry-run -o yaml -- bash -c "sleep 3 && env"
AWS: kubectl runでIAMロールを割り当てる
※kube2iamやkiamがクラスタにインストールされている前提
pod=iamtest-$(date +%s)
role=k8s-managed-service-role
kubectl run -it --restart=Never --namespace kube-system \
--image=kubeaws/awscli:0.9.0 $pod \
--overrides '{"metadata":{"annotations":{"iam.amazonaws.com/role":"'$role'"}}}' -- bash
iamtest
```
起動したシェル上で`aws ec2 describe-instances --region ap-northeast-1`などを実行して、IAMロールが想定どおり割り当てられているかを確認できる。
# kubectl exec関連
## 実行中のpodで任意のコマンドを実行
```
# kubectl exec <POD NAME> <CMD>
kubectl exec mypod-1315135266-ceh0x echo hello world
```
応用すると、任意のpodでシェルを起動して、環境変数、ネットワーク、ファイル等を確認しながらデバッグできる。
```
# kubectl exec -it デバッグしたいpod名 sh
```
# pod一般
## podの削除
```
kubectl delete po(d) <POD NAME>
```
POD NAMEはget poなどで確認できる。
```
$ kubectl get po
NAME READY STATUS RESTARTS AGE
mypod-1315135266-ceh0x 1/1 Running 1 20m
mysql-omsvn 1/1 Running 0 28m
$ kubectl delete po mypod-1315135266-ceh0x
pod "mypod-1315135266-ceh0x" deleted
```
## 実行中のpod一覧を得る
```
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
mypod-1315135266-ceh0x 1/1 Running 1 5m
```
## 特定DaemonSetやDeploymentのPodをすべて再起動
一気に再起動していいのであれば、以下のようにpodを削除してしまえばOK。削除したPodはDaemonSetやDeploymentによって再起動されるから。
```
$ kubectl delete pod $(k get po | grep fluentd | cut -d ' ' -f 1)
```
sleepを入れる場合は以下のようにする。
```
for pod in $(k get po | grep fluentd | cut -d ' ' -f 1); do
k delete pod $pod
sleep 3
done
```
# クラスタ全体
## 全ネームスペースのPod一覧
default以外のnamespaceも使っている場合は、`--all-namespaces`で全ネームスペース横断
```
$ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default mypod-1315135266-ceh0x 1/1 Running 1 12m
default mysql-omsvn 1/1 Running 0 19m
```
`-o wide`でそのpodがいるNodeも出る
```
$ kubectl get pods --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE NODE
default mypod-1315135266-ceh0x 1/1 Running 1 13m default
default mysql-omsvn 1/1 Running 0 21m default
```
## 全ネームスペースのsvc一覧
`--all-namespaces`をつけると、k8sクラスタ自体の機能を構成するサービスも見える。以下だと`kube-dns`
```
$ kubectl get --all-namespaces svc
NAMESPACE NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes 10.1.30.1 <none> 443/TCP 26m
default mysql 10.1.30.223 <none> 3306/TCP 24m
kube-system kube-dns 10.1.30.3 <none> 53/UDP,53/TCP 26m
```
## 複数種類のk8sオブジェクトの一覧をまとめて得る
```
# svc → service
# rc → replication controller
$ kubectl get svc,pod,rc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.1.30.1 <none> 443/TCP 19m
mysql 10.1.30.223 <none> 3306/TCP 17m
NAME READY STATUS RESTARTS AGE
mypod-1315135266-ceh0x 1/1 Running 1 10m
mysql-omsvn 1/1 Running 0 17m
NAME DESIRED CURRENT AGE
mysql 1 1 17m
```
# jsonpath
## kubectl get po --output jsonでpodのspec, status, metadataデータを見る
これで得られるデータのうち、[Kubernetes - Using the Downward API to Convey Pod Properties](http://kubernetes.io/docs/user-guide/downward-api/)で言及されているものが`fieldRef`等でコンテナの環境変数に渡せる。
```
$ kubectl get po --output json alpine-1094096498-lsxx1
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "alpine-1094096498-lsxx1",
"generateName": "alpine-1094096498-",
"namespace": "default",
"selfLink": "/api/v1/namespaces/default/pods/alpine-1094096498-lsxx1",
"uid": "12a67f48-590f-11e6-8946-a25f995cc626",
"resourceVersion": "2407713",
"creationTimestamp": "2016-08-03T00:13:15Z",
"labels": {
"pod-template-hash": "1094096498",
"run": "alpine"
},
"annotations": {
"kubernetes.io/created-by": "{\"kind\":\"SerializedReference\",\"apiVersion\":\"v1\",\"reference\":{\"kind\":\"ReplicaSet\",\"namespace\":\"default\",\"name\":\"alpine-1094096498\",\"uid\":\"12a53eaf-590f-11e6-8946-a25f995cc626\",\"apiVersion\":\"extensions\",\"resourceVersion\":\"2407685\"}}\n"
}
},
"spec": {
"volumes": [
{
"name": "default-token-w3x3w",
"secret": {
"secretName": "default-token-w3x3w"
}
}
],
"containers": [
{
"name": "alpine",
"image": "alpine:3.4",
"args": [
"sh"
],
"resources": {},
"volumeMounts": [
{
"name": "default-token-w3x3w",
"readOnly": true,
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
}
],
"terminationMessagePath": "/dev/termination-log",
"imagePullPolicy": "IfNotPresent",
"stdin": true,
"tty": true
}
],
"restartPolicy": "Always",
"terminationGracePeriodSeconds": 30,
"dnsPolicy": "ClusterFirst",
"serviceAccountName": "default",
"serviceAccount": "default",
"nodeName": "minikubevm",
"securityContext": {},
"hostname": "foo",
"subdomain": "bar"
},
"status": {
"phase": "Running",
"conditions": [
{
"type": "Initialized",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2016-08-03T00:13:15Z"
},
{
"type": "Ready",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2016-08-03T00:13:16Z"
},
{
"type": "PodScheduled",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2016-08-03T00:13:15Z"
}
],
"hostIP": "10.0.2.15",
"podIP": "172.17.0.23",
"startTime": "2016-08-03T00:13:15Z",
"containerStatuses": [
{
"name": "alpine",
"state": {
"running": {
"startedAt": "2016-08-03T00:13:15Z"
}
},
"lastState": {},
"ready": true,
"restartCount": 0,
"image": "alpine:3.4",
"imageID": "docker://sha256:4e38e38c8ce0b8d9041a9c4fefe786631d1416225e13b0bfe8cfa2321aec4bba",
"containerID": "docker://f5fcc93e52a87533581b3a8daa7fdb5c9f8d0ea0c26c7f3ee8ad0ad91ceb7845"
}
]
}
}
```
# リソース関連
## Namespaceにリソース制限を設定する
Admission ControlのResource Quotaを設定する
```
$ cat quota.yml
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota
spec:
hard:
memory: 1Gi
cpu: 20
pods: 10
services: 5
replicationcontrollers: 20
resourcequotas: 1
$ kubectl crerate --namespace=development quota.yml
```
## Namespace内のPodにリソース制限を設定する
Admission ControlのLimitsを設定する
```
$ cat limits.yml
apiVersion: v1
kind: LimitRange
metadata:
name: limits
namespace: default
spec:
limits:
- type: Container
defaultRequests:
cpu: 250m
$ kubectl create --namespae=development limits.yml
```
参考: [CoreOS Fest 2016: Kubernetes Access Control with dex // Speaker Deck](https://speakerdeck.com/ericchiang/coreos-fest-2016-kubernetes-access-control-with-dex)
### -o jsonpath=...で「.(ドット)」を含むキーを参照する
例えば以下のようなsecretのdb.confキーの値を抽出したい。
```yaml
data:
db.conf: base64encodedcontent..
```
以下のように普通に.をキーに含めると何もとれないが、
```
kubectl get secrets mysecret -o "jsonpath={.data['db.conf']}"
```
以下のようにバックスラッシュでエスケープすればとれる。
```
kubectl get secrets mysecret -o "jsonpath={.data['db\.conf']}"
```
参考: https://github.com/kubernetes/kubernetes/issues/23386#issuecomment-305348170
# DaemonSet関連
## kubectl edit/applyを使わずにDaemonSetのローリングアップデート
コンテナイメージの変更だけであれば、edit/applyを使わずとも、set imageでできる。
```
kubectl set image ds/<daemonset-name> <container-name>=<container-new-image>
kubectl rollout status ds/<daemonset-name>
```
参考: [Perform a Rolling Update on a DaemonSet | Kubernetes](https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#updating-only-the-container-image)
# Ingress関連
## Ingress Load Balancerのホスト名
```
k get ing -o jsonpath={.items[0].status.loadBalancer.ingress[0].hostname}
```
出力例:
```
ab94c9d72bac811e79231068c4de2c62-myaccountid.ap-northeast-1.elb.amazonaws.com
```
# 応用編
## 障害が起きたノードを隔離して、テスト用podだけをスケジュールさせる
障害が起きたノードを「ip-10-0-5-178.ap-northeast-1.compute.internal」として、
```
# 応急処置として、該当ノードに今後podがスケジュールされないようにする
# 既に何かpodが動いているなら、kubectl drainでも可。kubectl drainはkubectl cordon + 稼働中podの退避。
kubectl cordon ip-10-0-5-178.ap-northeast-1.compute.internal
# 状況調査のため、該当ノードにテスト用podだけスケジュールできるようにする準備
# dedicated=adminというtaintをつけて、taintに対抗するtolerationがあるpodだけスケジュールできるようにする。
# テスト用pod以外はtolerationがついていないとすると、テスト用podにtolerationをつければ結果的にやりたいことが実現できる。
kubectl taint node ip-10-0-5-178.ap-northeast-1.compute.internal dedicated=admin:NoSchedule
# taintしたので、cordonを解除してそもそもpodがスケジュール可能な状態に戻す
# 繰り返しになるが、スケジュール可能になっても前述の操作でtaintされているので、他のpodはこのノードにはスケジュールされない
kubectl uncordon ip-10-0-5-178.ap-northeast-1.compute.internal
# kubectl runの--overridesで
# (1)taintに対抗するtolerationをつける。これでスケジュール先ノードの選択肢として、障害が発生したノード「も」含まれるようになる
# (2)nodeSelectorを追加して、障害が発生したノード「にだけ」スケジュールされるようにする
kubectl run pod1 -i --tty --overrides='{ "apiVersion": "extensions/v1beta1", "spec": { "template": { "metadata": { "annotations": { "scheduler.alpha.kubernetes.io/tolerations": "[{\"key\":\"dedicated\", \"value\":\"admin\"}]" } }, "spec": { "nodeSelector": { "kubernetes.io/hostname": "ip-10-0-5-178.ap-northeast-1.compute.internal" } } } } }' --image alpine --command -- /bin/sh
# あとはshの中でよしなに調査を行う
```
## kubednsが動いているかをテストする
```
$ kubectl run mypod8 --restart=Never --image=alpine:edge -- sh -c 'nslookup kubernetes.default.svc.cluster.local localhost'
job "mypod8" created
$ kubectl get po -a
NAME READY STATUS RESTARTS AGE
mypod8-3u9qi 0/1 Completed 0 1m
$ kubectl logs mypod8-3u9qi
```
## 全deploymentを消す
```
$ for DEPLOYMENT in $(kubectl get deployments -o json | jq -r '.items[].metadata.name'); do kubectl delete deployment $DEPLOYMENT; done
```
# あわせて読みたい
- [Playing with kubectl output](https://gist.github.com/so0k/42313dbb3b547a0f51a547bb968696ba)