• 0、k8s的安装以及基础pod方式搭建


    0、准备的主机

    Kubernetes技术已经成为了原生云技术的事实标准,它是目前基础软件领域最为热门的分布式调度和管理平台。于是,Kubernetes也几乎成了时下开发工程师和运维工程师必备的技能之一。

    Master01 192.168.1.20
    Node01 192.168.1.21
    Node02 192.168.1.22
    Node03 192.168.1.23

    ssh-keygen两两交换

    1、主机名

    $ vim /etc/hosts
    192.168.1.20 master01 master01.wuyanzu.com   
    192.168.1.21 node01 node01.wuyanzu.com
    192.168.1.22 node02 node02.wuyanzu.com
    192.168.1.23 node03 node03.wuyanzu.com
    

    节点的 hostname 必须使用标准的 DNS 命名,另外千万不用什么默认的 localhost 的 hostname,会导致各种错误出现的。在 Kubernetes 项目里,机器的名字以及一切存储在 Etcd 中的 API 对象,都必须使用标准的 DNS 命名(RFC 1123)。

    $ scp /etc/hosts 192.168.1.21:/etc/
    $ scp /etc/hosts 192.168.1.22:/etc/
    $ scp /etc/hosts 192.168.1.23:/etc/
    

    2、禁用防火墙与SELINUX

    $ systemctl stop firewalld.service 
    $ systemctl stop iptables.service
    $ systemctl disable firewalld.service
    $ systemctl disable iptables.service
    
    $ setenforce 0
    $ cat /etc/selinux/config
    SELINUX=disabled
    
    # 使用sed
    $ sed -i 's@^(SELINUX=).*@1disabled@' /etc/sysconfig/selinux
    

    3、同步服务器时间

    $ yum install chrony -y && systemctl enable chronyd &&systemctl start chronyd 
    # 同步时间
    $ chronyc sources
    $ date
    

    不过,建议用户配置使用本地的的时间服务器,在节点数量众多时尤其如此。存在可用的本地时间服务器时,修改节点的/etc/crhony.conf配置文件,并将时间服务器指向相应的主机即可,配置格式如下:
    server CHRONY-SERVER-NAME-OR-IP iburst

    4、禁用Swap设备

    部署集群时,kubeadm默认会预先检查当前主机是否禁用了Swap设备,并在未禁用时强制终止部署过程。因此,在主机内存资源充裕的条件下,需要禁用所有的Swap设备,否则,就需要在后文的kubeadm init及kubeadm join命令执行时额外使用相关的选项忽略检查错误。

    $ free -m
                  total        used        free      shared  buff/cache   available
    Mem:            954         147         440           9         366         653
    Swap:          2047           9        2038
    #临时
    $ swapoff -a
    $ free -m
                  total        used        free      shared  buff/cache   available
    Mem:            954         150         433          12         370         646
    Swap:             0           0           0
    
    
    
    关闭Swap设备,需要分两步完成。首先是关闭当前已启用的所有Swap设备:
    $ swapoff -a
    

    修改/etc/fstab文件,注释掉 SWAP 的自动挂载。swappiness 参数调整,修改/etc/sysctl.d/k8s.conf添加下面一行:

    $ vim /etc/sysctl.d/k8s.conf
    vm.swappiness=0
    $ sysctl -p /etc/sysctl.d/k8s.conf
    

    5、启用ipvs内核模块

    由于开启内核 ipv4 转发需要加载 br_netfilter 模块,所以加载下该模块:

    $ modprobe br_netfilter
    $ vim /etc/sysctl.d/k8s.conf
    vm.swappiness=0
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    net.ipv4.ip_forward = 1
    $ sysctl -p /etc/sysctl.d/k8s.conf
    
    $ scp /etc/sysctl.d/k8s.conf node01:/etc/sysctl.d/
    $ scp /etc/sysctl.d/k8s.conf node02:/etc/sysctl.d/
    $ scp /etc/sysctl.d/k8s.conf node03:/etc/sysctl.d/
    

    bridge-nf

    bridge-nf 使得 netfilter 可以对 Linux 网桥上的 IPv4/ARP/IPv6 包过滤。
    比如,设置net.bridge.bridge-nf-call-iptables=1后,二层的网桥在转发包时也会被 iptables的 FORWARD 规则所过滤。常用的选项包括:
    
    net.bridge.bridge-nf-call-arptables:是否在 arptables 的 FORWARD 中过滤网桥的 ARP 包
    net.bridge.bridge-nf-call-ip6tables:是否在 ip6tables 链中过滤 IPv6 包
    net.bridge.bridge-nf-call-iptables:是否在 iptables 链中过滤 IPv4 包
    net.bridge.bridge-nf-filter-vlan-tagged:是否在 iptables/arptables 中过滤打了 vlan 标签的包。
    

    安装 ipvs

    $ cat > /etc/sysconfig/modules/ipvs.modules <<EOF
    #!/bin/bash
    modprobe -- ip_vs
    modprobe -- ip_vs_rr
    modprobe -- ip_vs_wrr
    modprobe -- ip_vs_sh
    modprobe -- nf_conntrack_ipv4
    EOF
    $ chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep -e ip_vs -e nf_conntrack_ipv4
    

    上面脚本创建了的/etc/sysconfig/modules/ipvs.modules文件,保证在节点重启后能自动加载所需模块。使用lsmod | grep -e ip_vs -e nf_conntrack_ipv4命令查看是否已经正确加载所需的内核模块。

    接下来还需要确保各个节点上已经安装了 ipset 软件包:

    $ yum install ipset -y
    

    为了便于查看 ipvs 的代理规则,最好安装一下管理工具 ipvsadm:

    $ yum install ipvsadm -y
    

    6、安装docker

    [docker-ce]
    name=docker
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/
    
    
    $ yum install docker-ce -y  --nogpgcheck
    $ systemctl start docker
    $ systemctl enable docker.service
    

    配置镜像加速器

    $ mkdir -p /etc/docker
    $ vim /etc/docker/daemon.json
    {
      "exec-opts": ["native.cgroupdriver=systemd"],
      "log-driver": "json-file",
      "log-opts": {
        "max-size": "100m"
      },
      "storage-driver": "overlay2",
      "registry-mirrors" : [
        "https://sw9esv3f.mirror.aliyuncs.com"
      ]
    }
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    $ scp /etc/docker/daemon.json node01:/etc/docker/
    $ scp /etc/docker/daemon.json node02:/etc/docker/
    $ scp /etc/docker/daemon.json node03:/etc/docker/
    

    cgroup 驱动

    由于默认情况下 kubelet 使用的 cgroupdriver 是 systemd,所以需要保持 docker 和kubelet 的 cgroupdriver 一致,我们这里修改 docker 的 cgroupdriver=systemd。如果不修改 docker 则需要修改 kubelet 的启动配置,需要保证两者一致。

    docker命令补全

    sudo yum install -y bash-completion
    #登出一下再进来即可
    

    7、安装k8s

    1-7是所有主机都要执行的

    [kubernetes]
    name=kubernetes
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/kubernetes/yum/repos/kubernetes-el7-x86_64/
    
    --disableexcludes 禁掉除了kubernetes之外的别的仓库
    $ yum install kubelet kubeadm kubectl -y --nogpgcheck --disableexcludes=kubernetes
    
    # 查看版本
    $ kubeadm version
    #设置为开机启动
    $ systemctl enable --now kubelet
    

    8、初始化集群

    master 节点配置 kubeadm 初始化文件,可以通过如下命令导出默认的初始化配置:

    8.1、通过配置文件加载配置

    $ kubeadm config print init-defaults > kubeadm.yaml
    

    然后根据我们自己的需求修改配置,比如修改 imageRepository 的值,kube-proxy 的模式为 ipvs,另外需要注意的是我们这里是准备安装 flannel 网络插件的,需要将 networking.podSubnet 设置为10.244.0.0/16

    apiVersion: kubeadm.k8s.io/v1beta2
    bootstrapTokens:
    - groups:
      - system:bootstrappers:kubeadm:default-node-token
      token: abcdef.0123456789abcdef
      ttl: 24h0m0s
      usages:
      - signing
      - authentication
    kind: InitConfiguration
    localAPIEndpoint:
      advertiseAddress: 192.168.1.20 # apiserver 节点内网IP
      bindPort: 6443
    nodeRegistration:
      criSocket: /var/run/dockershim.sock
      name: master1
      taints:
      - effect: NoSchedule
        key: node-role.kubernetes.io/master
    ---
    apiServer:
      timeoutForControlPlane: 4m0s
    apiVersion: kubeadm.k8s.io/v1beta2
    certificatesDir: /etc/kubernetes/pki
    clusterName: kubernetes
    controllerManager: {}
    dns:
      type: CoreDNS
    etcd:
      local:
        dataDir: /var/lib/etcd
    imageRepository: registry.aliyuncs.com/google_containers
    # registry.aliyuncs.com/k8sxio   # 修改成阿里云镜像源
    kind: ClusterConfiguration
    kubernetesVersion: 1.21.1
    networking:
      dnsDomain: cluster.local
      podSubnet: 10.244.0.0/16  # Pod 网段,flannel插件需要使用这个网段
      serviceSubnet: 10.96.0.0/12
    scheduler: {}
    ---
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    kind: KubeProxyConfiguration
    mode: ipvs  # kube-proxy 模式
    

    godoc 文档:完整的资源对象对应的属性

    https://godoc.org/k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta2。

    $ kubeadm init --config kubeadm.yaml
    

    kubectl是kube-apiserver的命令行客户端程序,实现了除系统部署之外的几乎全部的管理操作,是kubernetes管理员使用最多的命令之一。kubectl需经由API server认证及授权后方能执行相应的管理操作,kubeadm部署的集群为其生成了一个具有管理员权限的认证配置文件/etc/kubernetes/admin.conf,它可由kubectl通过默认的“$HOME/.kube/config”的路径进行加载。当然,用户也可在kubectl命令上使用--kubeconfig选项指定一个别的位置。

    下面复制认证为Kubernetes系统管理员的配置文件至目标用户(例如当前用户root)的家目录下:

    $ mkdir -p $HOME/.kube
    $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    $ sudo chown $(id -u):$(id -g) $HOME/.kube/config
    

    8.2、命令行初始化方式

    $ kubeadm init --kubernetes-version=v1.21.1 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --image-repository  registry.aliyuncs.com/google_containers  --ignore-preflight-errors=Swap
    

    命令中的各选项简单说明如下:

    • --kubernetes-version选项的版本号用于指定要部署的Kubenretes程序版本,它需要与当前的kubeadm支持的版本保持一致;
    • --pod-network-cidr选项用于指定分Pod分配使用的网络地址,它通常应该与要部署使用的网络插件(例如flannel、calico等)的默认设定保持一致,10.244.0.0/16是flannel默认使用的网络;
    • --service-cidr用于指定为Service分配使用的网络地址,它由kubernetes管理,默认即为10.96.0.0/12;
    • 最后一个选项“--ignore-preflight-errors=Swap”仅应该在未禁用Swap设备的状态下使用。

    注意初始化的时候coredns在阿里云的有点不一致,所以需要手动去拉一下,然后去打下标签在初始化

    $ docker pull registry.aliyuncs.com/google_containers/coredns:1.8.0
    $ docker tag registry.aliyuncs.com/google_containers/coredns:1.8.0  registry.aliyuncs.com/google_containers/coredns/coredns:v1.8.0
    $ docker rmi registry.aliyuncs.com/google_containers/coredns:1.8.0
    

    在各个node节点中也是需要手动拉改的

    如果没有得到全是OK的结果

    # 是/etc/kubernetes/manifests下的kube-controller-manager.yaml和kube-scheduler.yaml设置的默认端口是0导致
    $ kubectl get cs
    NAME                 STATUS      MESSAGE                                                                                     ERROR
    scheduler            Unhealthy   Get http://127.0.0.1:10251/healthz: dial tcp 127.0.0.1:10251: connect: connection refused
    controller-manager   Unhealthy   Get http://127.0.0.1:10252/healthz: dial tcp 127.0.0.1:10252: connect: connection refused
    etcd-0               Healthy     {"health":"true"}
    
    # kube-scheduler.yaml配置修改:注释掉19行
    $ vim /etc/kubernetes/manifests/kube-scheduler.yaml
    ...
    16     - --bind-address=127.0.0.1
    17     - --kubeconfig=/etc/kubernetes/scheduler.conf
    18     - --leader-elect=true
    19   #  - --port=0
    ...
    # kube-controller-manager.yaml文件修改:注释掉27行
    $ vim /etc/kubernetes/manifests/kube-controller-manager.yaml
    ...
     22     - --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
     23     - --controllers=*,bootstrapsigner,tokencleaner
     24     - --kubeconfig=/etc/kubernetes/controller-manager.conf
     25     - --leader-elect=true
     26     - --node-cidr-mask-size=24
     27  #  - --port=0
    ...
    
    $ kubectl get cs
    NAME                 STATUS    MESSAGE             ERROR
    scheduler            Healthy   ok                  
    controller-manager   Healthy   ok                  
    etcd-0               Healthy   {"health":"true"}   
    

    kubeadm init 命令执行流程图

    9、添加节点

    安装 kubeadm、kubelet、kubectl(可选)

    # 将 master 节点上面的 ~/.kube/config 文件拷贝到 node 节点对应的文件中,这样每个node也可以查看面板
    $ scp ~/.kube/config node01:~/.kube/
    $ scp ~/.kube/config node02:~/.kube/
    $ scp ~/.kube/config node03:~/.kube/
    
    # 查看token
    $ kubeadm token list
    # 查看--discovery-token-ca-cert-hash
    $ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
    
    # 或者2者
    $ kubeadm token create --print-join-command
    kubeadm join 192.168.1.20:6443 --token bhq4ro.jieonxs43q0iimal --discovery-token-ca-cert-hash sha256:37ea892c7874b116e24b63ab1403dbe9573e9414beb2d07e2547cad6000fa6f3 
    

    join执行流程图

    10、网络插件

    Kubernetes系统上Pod网络的实现依赖于第三方插件进行,这类插件有近数十种之多,较为著名的有flannel、calico、canal和kube-router等,简单易用的实现是为CoreOS提供的flannel项目。下面的命令用于在线部署flannel至Kubernetes系统之上:

    $ wget -e "https_proxy=http://192.168.1.6:7890" https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    
    # 因为有节点是多网卡,所以需要在资源清单文件中指定内网网卡
    # 搜索到名为 kube-flannel-ds 的 DaemonSet,在kube-flannel容器下面
    $ vim kube-flannel.yml
    ......
    containers:
    - name: kube-flannel
      image: quay.io/coreos/flannel:v0.13.0
      command:
      - /opt/bin/flanneld
      args:
      - --ip-masq
      - --kube-subnet-mgr
      - --iface=eth0  # 如果是多网卡的话,指定内网网卡的名称
    ......
    
    # 安装 flannel 网络插件
    $ kubectl apply -f kube-flannel.yml  
    
    # 全部显示ready表示成功建立flannel隧道
    $ kubectl get nodes
    NAME     STATUS   ROLES                  AGE   VERSION
    node     Ready    control-plane,master   30m   v1.21.1
    node01   Ready    <none>                 26m   v1.21.1
    node02   Ready    <none>                 19m   v1.21.1
    node03   Ready    <none>                 19m   v1.21.1
    
    # 查看主节点的配置信息
    $ kubectl config view
    apiVersion: v1
    clusters:
    - cluster:
        certificate-authority-data: DATA+OMITTED
        server: https://192.168.1.20:6443
      name: kubernetes
    contexts:
    - context:
        cluster: kubernetes
        user: kubernetes-admin
      name: kubernetes-admin@kubernetes
    current-context: kubernetes-admin@kubernetes
    kind: Config
    preferences: {}
    users:
    - name: kubernetes-admin
      user:
        client-certificate-data: REDACTED
        client-key-data: REDACTED
    

    11、Dashboard(简单使用)

    $ wget -e "https_proxy=http://192.168.1.6:7890" https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
    $ vim  recommended.yaml 
    # 修改Service为NodePort类型
    ......
    kind: Service
    apiVersion: v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kubernetes-dashboard
    spec:
      ports:
        - port: 443
          targetPort: 8443
      selector:
        k8s-app: kubernetes-dashboard
      type: NodePort  # 加上type=NodePort变成NodePort类型的服务,向外暴露端口
    ......
    $ kubectl apply -f recommended.yaml 
    $ kubectl get pods -n kubernetes-dashboard 
    NAME                                         READY   STATUS    RESTARTS   AGE
    dashboard-metrics-scraper-856586f554-sjcrw   1/1     Running   0          82s
    kubernetes-dashboard-78c79f97b4-j6sd6        1/1     Running   0          82s
    
    $ kubectl get svc -n kubernetes-dashboard 
    NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
    dashboard-metrics-scraper   ClusterIP   10.97.149.154   <none>        8000/TCP        102s
    kubernetes-dashboard        NodePort    10.99.166.71    <none>        443:32660/TCP   102s
    

    在 YAML 文件中可以看到新版本 Dashboard 集成了一个 metrics-scraper 的组件,可以通过 Kubernetes 的 Metrics API 收集一些基础资源的监控信息,并在 web 页面上展示,所以要想在页面上展示监控信息就需要提供 Metrics API,比如安装 Metrics Server。

    使用火狐测试192.168.1.20:32660(任何一个节点IP)

    然后创建一个具有全局所有权限的用户来登录Dashboard:(admin.yaml)

    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: admin
      annotations:
        rbac.authorization.kubernetes.io/autoupdate: "true"
    roleRef:
      kind: ClusterRole
      name: cluster-admin
      apiGroup: rbac.authorization.k8s.io
    subjects:
    - kind: ServiceAccount
      name: admin
      namespace: kubernetes-dashboard
    
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: admin
      namespace: kubernetes-dashboard
    
    $ kubectl apply -f admin.yaml
    $ kubectl get secret -n kubernetes-dashboard
    NAME                               TYPE                                  DATA   AGE
    admin-token-tm8hk                  kubernetes.io/service-account-token   3      32s
    default-token-5zq2k                kubernetes.io/service-account-token   3      8m15s
    kubernetes-dashboard-certs         Opaque                                0      8m15s
    kubernetes-dashboard-csrf          Opaque                                1      8m15s
    kubernetes-dashboard-key-holder    Opaque                                2      8m15s
    kubernetes-dashboard-token-qq9zn   kubernetes.io/service-account-token   3      8m15s
    
    $ kubectl  describe secret admin-token-wj5hg -n kubernetes-dashboard
    ...
    token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IklsTGNCZ1oxREpHLUZ2M0xTMHg4UFo5Ym14QUdrZkd2S2VwcHNrM1FPc00ifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi13ajVoZyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImZkNWVkNTY4LTAwMzctNDJiMy1iMDQ3LTU3NDhmZTM4M2NjNSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbiJ9.Lks1svXuk1xwD7xosvgwuApft3zjTUapG6rPacbIrSNkHRL2BfWw6r79-0XtfCCBrTcsggBICJ4gDwBhrh6Iz5veKF2l4dKQcNLODttjm6Bt-1gJlmYxx-9mrige4tpXEjm7YAeXE8cqnDM_wG9Zrar2JRm3S-FvQAI9jf79q_4H-WuMvCQ0iuQJ80yk2Y-Y6dsTO8E39LujJ6XSiBdEID9vmcNzMBwl3hiJ_StSdqSeYvph-x9F2DDxYsOM9p6OF6wfq87u_wBzqZGH6RzernahXqC9Ror_iUO77_RH-rCApU-RJbPHF94oT_F0EPckCJDi6N9pHLNqpQFxYxU_EQ
    ...
    
    # 直接一条命令取出来,base64解码后的值
    $ kubectl get secrets admin-token-tm8hk -o jsonpath={.data.token} -n kubernetes-dashboard
    

    12、清理

    如果你的集群安装过程中遇到了其他问题,我们可以使用下面的命令来进行重置:

    $ kubeadm reset
    $ ifconfig cni0 down && ip link delete cni0
    $ ifconfig flannel.1 down && ip link delete flannel.1
    $ rm -rf /var/lib/cni/
    

    13、k8s 命令自动补全

    yum install -y bash-completion &&
    source /usr/share/bash-completion/bash_completion &&
    source <(kubectl completion bash) &&
    echo "source <(kubectl completion bash)" >> ~/.bashrc 
    

    14、IDE与服务器交互的2种方式

    1、sftp连接

    见pycharm

    2、Bash on MacOS

    在 Mac 下面,就稍微复杂一点点了,因为 Mac 上的 Bash 默认版本是3.2,已经过时了,kubectl 的自动补全脚本至少需要 Bash 4.1 版本。

    所以要在 Mac 上使用 kubectl 自动补全功能,你就需要安装新版本的 Bash,更新 Bash 是很容易的,可以查看这篇文章:Upgrading Bash on macOS,这里我们就不详细说明了。

    在继续向下之前,请确保你的 Bash 版本在 4.1 以上。和 Linux 中一样,Bash 的补全脚本依赖 bash-completion 项目,所以我们也必须要安装它。

    我们可以使用 Homebrew 工具来安装:

    $ brew install bash-completion@2
    

    @2代表 bash-completion v2 版本,kubectl 命令补全脚本需要 v2 版本,而 v2 版本至少需要 Bash 4.1 版本,所以这就是不能在低于4.1的 Bash 下面使用 kubectl 的补全脚本的原因。

    brew 安装命令完成会输出一段提示信息,其中包含将下面内容添加到~/.bash_profile文件中的说明:

    export BASH_COMPLETION_COMPAT_DIR=/usr/local/etc/bash_completion.d
    [[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
    

    这样就完成了 bash-completion 的安装,但是建议将上面这一行信息添加到~/.bashrc当中,这样可以在子 shell 中也可以使用 bash-completion。

    重新加载 shell 后,可以使用以下命令测试是否正确安装了 bash-completion:

    $ type _init_completion
    

    如果输出一个 shell 函数,证明安装成功了。然后就需要进行一些配置来让我们在所有的 shell 会话中都可以获取 kubectl 补全脚本。

    一种方法是将下面的内容添加到~/.bashrc文件中:

    source <(kubectl completion bash)
    

    另外一种方法是添加 kubectl 补全脚本到/usr/local/etc/bash_completion.d目录下面:

    $ kubectl completion bash >/usr/local/etc/bash_completion.d/kubectl
    

    使用 Homebrew 安装 bash-completion 时上面的方法才会生效。

    如果你还是使用 Homebrew 安装的 kubectl 的话,上面的步骤都可以省略,因为补全脚本已经被自动放置到/usr/local/etc/bash_completion.d目录中去了,这种情况,kubectl 命令补全应该在安装完 bash-completion 后就可以正常使用了。

    最后,重新加载 shell 后,kubectl 自动提示应该就可以正常工作了。

  • 相关阅读:
    CF 118E Bertown roads 桥
    hdu 3917 Road constructions 最大权闭合子图
    hdu 4714 Tree2cycle 树形经典问题
    POJ 2516 Minimum Cost 最小费用流
    POJ 3921 Destroying the bus stations 沿着最短路迭代加深搜索
    POJ 3422 Kaka's Matrix Travels K取方格数
    BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增
    hdu 4010 Query on The Trees LCT
    poj 2455 Secret Milking Machine 二分+最大流 sap
    定制标记---简单标记处理器
  • 原文地址:https://www.cnblogs.com/wuyanzu123/p/14823739.html
Copyright © 2020-2023  润新知