130
107

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

kubectlチートシート

Last updated at Posted at 2016-05-01

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)
130
107
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
130
107

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?