LoginSignup
130
109

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で言及されているものが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

-o jsonpath=...で「.(ドット)」を含むキーを参照する

例えば以下のようなsecretのdb.confキーの値を抽出したい。

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

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

あわせて読みたい

130
109
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
109