Kubernetes の小技 2016

この記事は、「[Kubernetes Advent Calendar 2016](http://qiita.com/advent-calendar/2016/kubernetes)」11日目の記事です。9日目の「[k8sが導入するService Brokerの仕組みとは](https://jaco.udcp.info/k8s-cf-service-broker/)」で紹介されている service-catalog には非常に注目しており、とても楽しく読むことができました :blush:

ここでは、これまで Kubernetes を使ってきて貯まった小技を共有します。

1. [kubectl のサブコマンドやオプションを補完する](#tips-kubectl-completion)
1. [kubectl の context や namespace を環境変数によって指定する](#tips-kubectl-environment-variables)
1. [指定しているコンテキストやネームスペースをプロンプトに表示する (zsh)](#tips-kubectl-zsh)
1. [クラスタで有効な API バージョンを取得する](#tips-api-versions)
1. [クラスタで有効なリソースタイプを取得する](#tips-resource-types)

## <span id="tips-kubectl-completion">kubectl のサブコマンドやオプションを補完する</span>

```zsh:.zshrc
source <(kubectl completion zsh)
```

kubectl のサブコマンドやオプションが補完されるようになります。`kubectl get` などオプションに作成されているリソース名をとる場合でも補完されるようになっているので、積極的に使いたいです。bash と zsh に対応しています。

- [Kubernetes \- kubectl completion](http://kubernetes.io/docs/user-guide/kubectl/kubectl_completion/)

## <span id="tips-kubectl-environment-variables">kubectl の context や namespace を環境変数によって指定する</span>

```zsh:kubectl.zsh
function kubectl() {
    command kubectl \
        --context="$KUBECTL_CONTEXT" \
        --namespace="$KUBECTL_NAMESPACE" \
        --user="$KUBECTL_USER" \
        --server="$KUBECTL_SERVER" \
        "$@"
}
```

kubectl のアクセス先のサーバやネームスペース、ユーザ、それらの組み合わせであるコンテキストは kubeconfig ファイルを使い指定しますが、一時的に設定を切り替えたいときには kubectl に用意されている `--context`, `--namespace` などのオプションを使うことができます。ただこれらのオプションは都度指定する必要があるため手間です。
上記の関数を使うことで、それぞれのオプションを環境変数によって指定することができるようになります。環境変数であれば設定されている間有効になるため、都度オプションで指定するような手間がありません。

- [Proposal: make \`kubectl\` respect KUBECTL\_\{CONTEXT,NAMESPACE\} environment variables · Issue \#27308 · kubernetes/kubernetes](https://github.com/kubernetes/kubernetes/issues/27308#issuecomment-227335781)

## <span id="tips-kubectl-zsh">current context と namespace をプロンプトに表示する (zsh)</span>

![image](https://qiita-image-store.s3.amazonaws.com/0/3780/d512eb2a-c394-4702-b72e-bda7065c379b.png)

- https://github.com/superbrothers/zsh-kubectl-prompt

複数の Kubernetes クラスタを操作していると、現在どのコンテキストやネームスペースが指定されているのか分からなくなり混乱することがあります。
上記のスクリプトを使うことで現在のコンテキストやクラスタ/ネームスペースなどをプロンプトに常に表示しておくことができます。詳しい使い方は README.md を参照してください。

## <span id="tips-api-versions">クラスタで有効な API バージョンを取得する</span>

```
$ kubectl api-versions
```

接続先のクラスタで有効な API バージョンを取得するには上記のコマンドを使います。
kube-apiserver を `--runtime-config=api/all=true` で起動させ、上記コマンドを実行することで、そのバージョンのクラスタで利用できる全ての API バージョンを知ることができ、kube-apiserver の `--runtime-config` を設定するのにも役立ちますし、最近は ThirdPartyResources が活発に利用され始めているため、それによって追加された API バージョンを調べることにも使えます。

- [Kubernetes \- kubectl api\-versions](http://kubernetes.io/docs/user-guide/kubectl/kubectl_api-versions/)

## <span id="tips-resource-types">クラスタで有効なリソースタイプを取得する</span>

*ETA 18/2/20: kubectl proxy を使わないように変更しました。*

```shell-session
$ kubectl api-versions | sed -e 's|^|apis/|g' | sed -e 's|apis/v1|api/v1|g' | xargs -P3 -I{} bash -c "kubectl get --raw {} | jq -r 'select(.resources !=null).resources[].name'" | grep -v '/' | sort | uniq
apiservices
bindings
certificatesigningrequests
clusterrolebindings
clusterroles
componentstatuses
configmaps
controllerrevisions
cronjobs
customresourcedefinitions
...
```

API バージョンを取得するの応用で、クラスタで有効なリソースタイプを取得するには、上記のワンライナーが使えます。ABAC, RBAC など認可の設定をするときに便利です。またサブリソースも取得したいときは下記のワンライナーを使ってください。

```console
$ kubectl api-versions | sed -e 's|^|apis/|g' | sed -e 's|apis/v1|api/v1|g' | xargs -P3 -I{} bash -c "kubectl get --raw {} | jq -r 'select(.resources !=null).resources[].name'" | sort | uniq
apiservices
apiservices/status
bindings
certificatesigningrequests
certificatesigningrequests/approval
certificatesigningrequests/status
clusterrolebindings
clusterroles
componentstatuses
configmaps
controllerrevisions
cronjobs
...
```

これらのワンライナーは jq コマンドを利用しています。必要に応じてインストールしてください。

- https://stedolan.github.io/jq/

## まとめ

Kubernetes クラスタを使う側とクラスタを設定する側それぞれで便利な小技を紹介しました。来年はもうちょっとしっかりしたエントリでアドベントカレンダに臨むようにします :sweat_smile: