BioErrorLog Tech Blog

試行錯誤の記録

kubectlをコマンド補完できるようにする

kubectlでコマンド補完できるようにする方法を整理します。

はじめに

最近Kubernetesに入門している中で、kubectlのコマンド補完ができなくて不便に感じてました。

コマンド補完可に設定できるようなので、やり方を整理します。

※ 作業環境: M2 Mac / zsh

kubectlをコマンド補完できるようにする

やり方はOSとshellの種類で異なります。

本記事では、macOSにおけるzshの場合を見ていきます。

他のケースについても公式ドキュメントに記載があるので、そちらを確認ください。

kubectl completion | Kubernetes

やり方

~/.zshrcに下記の処理を追加します。

source <(kubectl completion zsh)

kubectl completion zshというコマンドによって、kubectlのコマンド補完を設定するためのコードが出力されます。 それをsourceで実行する、という処理です。

ちなみにkubectl completion zsh自体の出力はこんな感じ:

$ kubectl completion zsh
#compdef kubectl
compdef _kubectl kubectl

# Copyright 2016 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#compdef kubectl
compdef _kubectl kubectl

# zsh completion for kubectl                              -*- shell-script -*-

__kubectl_debug()
{
    local file="$BASH_COMP_DEBUG_FILE"
    if [[ -n ${file} ]]; then
        echo "$*" >> "${file}"
    fi
}

_kubectl()
{
    local shellCompDirectiveError=1
    local shellCompDirectiveNoSpace=2
    local shellCompDirectiveNoFileComp=4
    local shellCompDirectiveFilterFileExt=8
    local shellCompDirectiveFilterDirs=16
    local shellCompDirectiveKeepOrder=32

    local lastParam lastChar flagPrefix requestComp out directive comp lastComp noSpace keepOrder
    local -a completions

    __kubectl_debug "\n========= starting completion logic =========="
    __kubectl_debug "CURRENT: ${CURRENT}, words[*]: ${words[*]}"

    # The user could have moved the cursor backwards on the command-line.
    # We need to trigger completion from the $CURRENT location, so we need
    # to truncate the command-line ($words) up to the $CURRENT location.
    # (We cannot use $CURSOR as its value does not work when a command is an alias.)
    words=("${=words[1,CURRENT]}")
    __kubectl_debug "Truncated words[*]: ${words[*]},"

    lastParam=${words[-1]}
    lastChar=${lastParam[-1]}
    __kubectl_debug "lastParam: ${lastParam}, lastChar: ${lastChar}"

    # For zsh, when completing a flag with an = (e.g., kubectl -n=<TAB>)
    # completions must be prefixed with the flag
    setopt local_options BASH_REMATCH
    if [[ "${lastParam}" =~ '-.*=' ]]; then
        # We are dealing with a flag with an =
        flagPrefix="-P ${BASH_REMATCH}"
    fi

    # Prepare the command to obtain completions
    requestComp="${words[1]} __complete ${words[2,-1]}"
    if [ "${lastChar}" = "" ]; then
        # If the last parameter is complete (there is a space following it)
        # We add an extra empty parameter so we can indicate this to the go completion code.
        __kubectl_debug "Adding extra empty parameter"
        requestComp="${requestComp} \"\""
    fi


## 長いので以下略 ##

エラー対処: command not found: compdef

先述のようにしてsource <(kubectl completion zsh)が実行されると、私の場合下記のエラーが出ました:

/dev/fd/11:2: command not found: compdef
/dev/fd/11:18: command not found: compdef

このようなエラーが出た場合は、以下の処理を~/.zshrcの冒頭に書き込むことで解消します。

autoload -Uz compinit
compinit

compinitを実行することによって、zshの補完機能を有効化させています。

補足: コマンドaliasを使ってる場合

少し調べてみると、kubectlにaliasを設定している場合は追加で手を打つ必要がある、という記事が多く見当たります。

ただしこれは、zshの場合は当てはまりません。 kubectlにaliasを設定している場合でも、zshなら問題なく動作するはずです。

ただbashの場合は、下記を追加で設定する必要があります。

complete -o default -F __start_kubectl k


詳しくはドキュメントをご覧ください。

おわりに

以上、kubectlをコマンド補完できるようにするための手順を簡単にまとめました。

同じくkubernetesに入門中のどなたかの参考になれば幸いです。

[関連記事]

www.bioerrorlog.work

参考

kubectl completion | Kubernetes

Install and Set Up kubectl on macOS | Kubernetes

kubectlチートシート | Kubernetes

zsh/Completion/compinit at master · zsh-users/zsh · GitHub