有什么方法可以在 kubectl 命令中自动完成多个对象?

Any way to autocomplete multiple objects in a kubectl command?

k8s kubectl autocomplete 很棒,直到你想要 运行 一条命令处理多项内容。

比如我要删除2个pods,我可以运行:

k delete pod foo-12345 bar-67890

但我只能使用 foo 自动完成。 bar 怎么样?

最好的情况是部分解决方法。经过几次测试,我可以说你的目标可以实现,但它有一些缺点。可能有第三方解决方案,但我不知道。

bash-完成

需要

'bash-completion' 包才能使 kubectl shell 完成按预期工作。您可以使用 apt-get install bash-completionmo 安装它。可以在 Kubernetes 文档 Optional kubectl configurations.

中找到更多信息

调试

Bash-completion 有自己的语法和函数。出于调试目的,您可以 运行 export BASH_COMP_DEBUG_FILE=$HOME/compdebug.txt。它将创建 compdebug 文本文件并将 kubectl shell 完成函数的所有调试输出发送给它。下面的示例输出:

__kubectl_parse_get: get completion by kubectl get  -o template --template="{{ range .items  }}{{ .metadata.name }} {{ end }}" "first-deployment-85b75bf4f9-mn8zh"
__kubectl_handle_word: c is 0 words[c] is kubectl
__kubectl_handle_command: c is 0 words[c] is kubectl
__kubectl_handle_command: looking for _kubectl_root_command
__kubectl_handle_word: c is 1 words[c] is get
__kubectl_handle_command: c is 1 words[c] is get
__kubectl_handle_command: looking for _kubectl_get
__kubectl_handle_word: c is 2 words[c] is pod
__kubectl_handle_noun: c is 2 words[c] is pod
__kubectl_handle_reply
__kubectl_parse_get: get completion by kubectl get  -o template --template="{{ range .items  }}{{ .metadata.name }} {{ end }}" "pod"

工作原理

kubectl 不会完成多个对象,因为它是自动完成功能 运行 的子请求 kubectl get argN 获取对象列表,而 argN 是现有命令行的先前参数。当你第一次使用它时,它接受来自 kubectl command pod->argN 和 运行 kubectl get pod 的参数。第二次它从 kubectl command pod podname1->argN 获取参数,因此子请求看起来像 kubectl get podname1 而不是 kubectl get pod,这会导致错误和空输出而不是对象列表。

测试场景

要实现此脚本,您可以使用命令 kubectl completion bash > k8scompletion.sh

最好创建第二个完成脚本,您可以回滚到默认设置 - kubectl completion bash > k8scompletion-copy.sh

$ vi k8scompletion.sh

在函数 __kubectl_get_resource() 中,我将 __kubectl_parse_get "${nouns[${#nouns[@]} -1]}" 编辑为 __kubectl_parse_get "${nouns[0]}"

__kubectl_get_resource()
{
    if [[ ${#nouns[@]} -eq 0 ]]; then
      local kubectl_out
      if kubectl_out=$(__kubectl_debug_out "kubectl api-resources $(__kubectl_override_flags) -o name --cached --request-timeout=5s --verbs=get"); then
          COMPREPLY=( $( compgen -W "${kubectl_out[*]}" -- "$cur" ) )
          return 0
      fi
      return 1
    fi
    __kubectl_parse_get "${nouns[0]}"
}

脚本调整概览

调整后的脚本可以让你完成kubernetes资源和来自这个资源的所有对象。以下解决方法足以演示和解决问题中提到的问题,但会导致一些副作用,因此请注意您获得的结果。

旁注

Shell完成脚本因kubectl版本而异,因此很难创建通用补丁。

测试输出

$ kubectl delete <TAB>
apiservices.apiregistration.k8s.io                            nodes.metrics.k8s.io
backendconfigs.cloud.google.com                               persistentvolumeclaims
certificatesigningrequests.certificates.k8s.io                persistentvolumes
clusterrolebindings.rbac.authorization.k8s.io                 poddisruptionbudgets.policy
clusterroles.rbac.authorization.k8s.io                        pods
componentstatuses                                             podsecuritypolicies.policy
configmaps                                                    pods.metrics.k8s.io
controllerrevisions.apps                                      podtemplates
cronjobs.batch                                                priorityclasses.scheduling.k8s.io
csidrivers.storage.k8s.io                                     replicasets.apps
... and few others

$ kubectl delete pod<TAB>
poddisruptionbudgets.policy  pods                         podsecuritypolicies.policy   pods.metrics.k8s.io          podtemplates

$ kubectl delete pod <TAB><TAB>
httpd-deploy-1-6c4b998b99-jk876  httpd-deploy-6867dfd79c-tr648    nginx2                           nginx-deploy-2-94985d7bd-bdb4d
httpd-deploy-2-64dc95c468-s7vt2  nginx                            nginx-deploy-1-5494687955-sm5lh  nginx-deploy-85df977897-44lcn

$ kubectl get pod nginx<TAB>
nginx                            nginx2                           nginx-deploy-1-5494687955-sm5lh  nginx-deploy-2-94985d7bd-bdb4d   nginx-deploy-85df977897-44lcn

$ kubectl get pod nginx-deploy-<TAB>
nginx-deploy-1-5494687955-sm5lh  nginx-deploy-2-94985d7bd-bdb4d   nginx-deploy-85df977897-44lcn

$ kubectl get pod nginx-deploy-1<TAB>
###It autocomplete below after clicking on tab to nginx-deploy-1-5494687955-sm5lh

$ kubectl get pod nginx-deploy-1-5494687955-sm5lh <TAB>
httpd-deploy-1-6c4b998b99-jk876  httpd-deploy-6867dfd79c-tr648    nginx2                           nginx-deploy-2-94985d7bd-bdb4d
httpd-deploy-2-64dc95c468-s7vt2  nginx                            nginx-deploy-1-5494687955-sm5lh  nginx-deploy-85df977897-44lcn

$ kubectl delete pod nginx-deploy-1-5494687955-sm5lh nginx<TAB>
nginx                            nginx2                           nginx-deploy-1-5494687955-29vqs  nginx-deploy-2-94985d7bd-bdb4d   nginx-deploy-85df977897-44lcn
$ kubectl delete pod nginx-deploy-1-5494687955-sm5lh nginx2 <TAB>
httpd-deploy-1-6c4b998b99-jk876  httpd-deploy-6867dfd79c-tr648    nginx2                           nginx-deploy-2-94985d7bd-bdb4d
httpd-deploy-2-64dc95c468-s7vt2  nginx                            nginx-deploy-1-5494687955-29vqs  nginx-deploy-85df977897-44lcn
$ kubectl delete pod nginx-deploy-1-5494687955-sm5lh nginx2

回滚更改

要应用这个特定的完成脚本,您必须使用 source 命令 - source k8scompletion.shsource k8scompletion-copy.sh.