首页 > 技术文章 > 5.Kubernetes集群管理工具kubectl

55zjc 2022-03-06 22:57 原文

一、概述

kubectl是Kubernetes集群的命令行工具,通过kubectl能够对集群本身进行管理,并能够在集群上进行容器化应用的安装和部署

二、命令格式

命令格式如下

kubectl [command] [type] [name] [flags]

参数

  • command:指定要对资源执行的操作,例如create、get、describe、delete
  • type:指定资源类型,资源类型是大小写敏感的,开发者能够以单数 、复数 和 缩略的形式

例如:

kubectl get pod pod1
kubectl get pods pod1
kubectl get po pod1

  • name:指定资源的名称,名称也是大小写敏感的,如果省略名称,则会显示所有的资源,例如
kubectl get pods
  • flags:指定可选的参数,例如,可用 -s 或者 -server参数指定Kubernetes API server的地址和端口

三、常见命令

kubectl help 获取更多信息

通过 help命令,能够获取帮助信息

# 获取kubectl的命令
kubectl --help

# 获取某个命令的介绍和使用
kubectl get --help

基础命令

常见的基础命令

命令 介绍
create 通过文件名或标准输入创建资源
expose 将一个资源公开为一个新的Service
run 在集群中运行一个特定的镜像
set 在对象上设置特定的功能
get 显示一个或多个资源
explain 文档参考资料
edit 使用默认的编辑器编辑一个资源
delete 通过文件名,标准输入,资源名称或标签来删除资源

部署命令

命令 介绍
rollout 管理资源的发布
rolling-update 对给定的复制控制器滚动更新
scale 扩容或缩容Pod数量,Deployment、ReplicaSet、RC或Job
autoscale 创建一个自动选择扩容或缩容并设置Pod数量

集群管理命令

命令 介绍
certificate 修改证书资源
cluster-info 显示集群信息
top 显示资源(CPU/M)
cordon 标记节点不可调度
uncordon 标记节点可被调度
drain 驱逐节点上的应用,准备下线维护
taint 修改节点taint标记
   

故障和调试命令

命令 介绍
describe 显示特定资源或资源组的详细信息
logs 在一个Pod中打印一个容器日志,如果Pod只有一个容器,容器名称是可选的
attach 附加到一个运行的容器
exec 执行命令到容器
port-forward 转发一个或多个
proxy 运行一个proxy到Kubernetes API Server
cp 拷贝文件或目录到容器中
auth 检查授权

其它命令

命令 介绍
apply 通过文件名或标准输入对资源应用配置
patch 使用补丁修改、更新资源的字段
replace 通过文件名或标准输入替换一个资源
convert 不同的API版本之间转换配置文件
label 更新资源上的标签
annotate 更新资源上的注释
completion 用于实现kubectl工具自动补全
api-versions 打印受支持的API版本
config 修改kubeconfig文件(用于访问API,比如配置认证信息)
help 所有命令帮助
plugin 运行一个命令行插件
version 打印客户端和服务版本信息

目前使用的命令

# 创建一个nginx镜像
kubectl create deployment nginx --image=nginx

# 对外暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort

# 查看资源
kubectl get pod, svc

# 对资源应用进行配置
kubectl apply -f

四、helm3

helm 是基于 kubernetes 的包管理器。它之于 kubernetes 就如 yum 之于 centos,pip 之于 python,npm 之于 javascript

Helm 有两个重要得概念:chart 和 release

chart :是创建一个应用的信息集合,包括各种 kubernetes 对象得配置模板、参数定义、依赖关系、文档说明等,可以将 chart 想象成 yum 中的软件安装包

release :是 chart 的运行实例,代表了一个正在运行的应用。当 chart 被安装到 kubernetes 集群,就会生成一个 release,chart 能够多次安装到同一个集群,但是只会有一个 release

1、下载

wget https://get.helm.sh/helm-v3.2.0-linux-amd64.tar.gz

 

2、解压

tar -zxvf helm-v3.2.0-linux-amd64.tar.gz

 

3、拷贝

cp linux-amd64/helm /usr/local/bin

 

4、验证

[root@master ~]# helm version
version.BuildInfo{Version:"v3.2.0", GitCommit:"e11b7ce3b12db2941e90399e874513fbd24bcb71", GitTreeState:"clean", GoVersion:"go1.13.10"}

 

5、添加 chart 源

helm repo add  stable https://kubernetes-charts.storage.googleapis.com
helm repo add  aliyuncs https://apphub.aliyuncs.com

 

6、查询当前集群有哪些 chart 库

[root@master1 ~]# helm repo list
NAME        URL                                             
stable      https://kubernetes-charts.storage.googleapis.com
aliyuncs    https://apphub.aliyuncs.com 

 

7、查询某个库 有哪些安装程序

[root@master1 ~]# helm search repo aliyuncs | head -5
NAME                                CHART VERSION             APP VERSION                     DESCRIPTION                                       
aliyuncs/admin-mongo                       0.1.0                 1                         MongoDB管理工具(web gui)                          
aliyuncs/aerospike                        0.3.2              v4.5.0.5                      A Helm chart for Aerospike in Kubernetes          
aliyuncs/airflow                          4.3.3               1.10.9                       Apache Airflow is a platform to programmaticall...
aliyuncs/ambassador                        5.3.0               0.86.1                        A Helm chart for Datawire Ambassador 

 

8、查找安装程序

helm search repo nginx

 

9、安装一个程序

helm install nginx aliyuncs/nginx

 

10、查询 svc

[root@master1 ~]# kubectl get svc -n default
NAME            TYPE             CLUSTER-IP          EXTERNAL-IP         PORT(S)                  AGE
kubernetes       ClusterIP            10.96.0.1           <none>          443/TCP                   116m
nginx        LoadBalancer            10.99.247.71         <pending>        80:30300/TCP,443:32617/TCP         45s

 

11、访问 集群

[root@master1 ~]# curl http://10.99.247.71
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
.......
<p><em>Thank you for using nginx.</em></p>
</body>
</html>

 

12、查看安装的应用

[root@master1 ~]# helm list
NAME        NAMESPACE       REVISION                       UPDATED                 STATUS      CHART        APP VERSION
nginx       default          1           2020-12-15 11:48:13.181211885 +0800 CST    deployed    nginx-5.1.5          1.16.1 

 

13、删除一个应用

helm uninstall nginx

五、k8s安装kubernetes dashboard

1.修改后的recommended.yaml

# Copyright 2017 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.

apiVersion: v1
kind: Namespace
metadata:
  name: kubernetes-dashboard

---

apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard

---

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  type: NodePort
  ports:
    - port: 443
      targetPort: 8443
      nodePort: 31443
  selector:
    k8s-app: kubernetes-dashboard

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-certs
  namespace: kubernetes-dashboard
type: Opaque

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-csrf
  namespace: kubernetes-dashboard
type: Opaque
data:
  csrf: ""

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-key-holder
  namespace: kubernetes-dashboard
type: Opaque

---

kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-settings
  namespace: kubernetes-dashboard

---

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
rules:
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
    verbs: ["get", "update", "delete"]
    # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
  - apiGroups: [""]
    resources: ["configmaps"]
    resourceNames: ["kubernetes-dashboard-settings"]
    verbs: ["get", "update"]
    # Allow Dashboard to get metrics.
  - apiGroups: [""]
    resources: ["services"]
    resourceNames: ["heapster", "dashboard-metrics-scraper"]
    verbs: ["proxy"]
  - apiGroups: [""]
    resources: ["services/proxy"]
    resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
    verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
rules:
  # Allow Metrics Scraper to get metrics from the Metrics server
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods", "nodes"]
    verbs: ["get", "list", "watch"]

---

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      containers:
        - name: kubernetes-dashboard
          image: kubernetesui/dashboard:v2.1.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8443
              protocol: TCP
          args:
            - --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            # Uncomment the following line to manually specify Kubernetes API server Host
            # If not specified, Dashboard will attempt to auto discover the API server and connect
            # to it. Uncomment only if the default does not work.
            # - --apiserver-host=http://my-address:port
          volumeMounts:
            - name: kubernetes-dashboard-certs
              mountPath: /certs
              # Create on-disk volume to store exec logs
            - mountPath: /tmp
              name: tmp-volume
          livenessProbe:
            httpGet:
              scheme: HTTPS
              path: /
              port: 8443
            initialDelaySeconds: 30
            timeoutSeconds: 30
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsUser: 1001
            runAsGroup: 2001
      volumes:
        - name: kubernetes-dashboard-certs
          secret:
            secretName: kubernetes-dashboard-certs
        - name: tmp-volume
          emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      nodeSelector:
        "kubernetes.io/os": linux
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule

---

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 8000
      targetPort: 8000
  selector:
    k8s-app: dashboard-metrics-scraper

---

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: dashboard-metrics-scraper
  template:
    metadata:
      labels:
        k8s-app: dashboard-metrics-scraper
      annotations:
        seccomp.security.alpha.kubernetes.io/pod: 'runtime/default'
    spec:
      containers:
        - name: dashboard-metrics-scraper
          image: kubernetesui/metrics-scraper:v1.0.6
          ports:
            - containerPort: 8000
              protocol: TCP
          livenessProbe:
            httpGet:
              scheme: HTTP
              path: /
              port: 8000
            initialDelaySeconds: 30
            timeoutSeconds: 30
          volumeMounts:
          - mountPath: /tmp
            name: tmp-volume
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsUser: 1001
            runAsGroup: 2001
      serviceAccountName: kubernetes-dashboard
      nodeSelector:
        "kubernetes.io/os": linux
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      volumes:
        - name: tmp-volume
          emptyDir: {}

为了避免网络问题,其中第32行定义的Service需要进行修改,配置为NodePort,以便我们直接通过地址+端口进行访问,否则该service会被分配ClusterIP无法直接访问

其中nodePort:31443配置的31443端口,可以根据自己机器的环境选择一个未被占用的端口,然后我们将修改的文件上传到k8s集群的任何一个节点机器,执行以下命令即可:

kubectl apply -f recommended.yaml

执行完成后,我们查看pods:

# kubectl apply -f recommended.yaml

执行完成后,我们查看pods:

[root@k8s ~]# kubectl get pods --all-namespaces
NAMESPACE              NAME                                         READY   STATUS    RESTARTS   AGE
kube-system            coredns-7f89b7bc75-5c6zv                     1/1     Running   0          2d9h
kube-system            coredns-7f89b7bc75-lbnxs                     1/1     Running   0          2d9h
kube-system            etcd-k8s.master001                           1/1     Running   0          2d9h
kube-system            kube-apiserver-k8s.master001                 1/1     Running   0          2d9h
kube-system            kube-controller-manager-k8s.master001        1/1     Running   0          2d9h
kube-system            kube-flannel-ds-amd64-84ql2                  1/1     Running   0          2d7h
kube-system            kube-flannel-ds-amd64-qhbzl                  1/1     Running   0          2d8h
kube-system            kube-proxy-5856c                             1/1     Running   0          2d9h
kube-system            kube-proxy-dd9q4                             1/1     Running   0          2d7h
kube-system            kube-scheduler-k8s.master001                 1/1     Running   0          2d9h
kubernetes-dashboard   dashboard-metrics-scraper-79c5968bdc-qpwl7   1/1     Running   0          2d5h
kubernetes-dashboard   kubernetes-dashboard-7448ffc97b-nv459        1/1     Running   1          2d5h

其中namespace为kubernetes-dashboard的两个pods为k8s dashboard。

如果查看了当前pods,发现其状态不是Running状态,可以通过以下命令查看pod启动时发生了什么问题:

[root@k8s ~]# kubectl describe pods -n kubernetes-dashboard kubernetes-dashboard-7448ffc97b-nv459 

如果是镜像获取失败,可以从阿里云等国内镜像仓库下载之后,再执行kubectl apply -f recommended.yaml。

2.配置权限
2.1.访问dashboard
此时我们通过访问集群的任何节点的ip+31443端口来访问k8s dashboard(本文访问https://172.16.197.160:31443),可以看到如下页面:

因为k8s dashboard使用https进行访问,我们没有相关证书,因此Chrome或者Safari浏览器是禁止访问的,我们可以使用FireFox进行访问。

可以看到k8s提供两种登录机制,本文采用Token访问机制进行登录。

首先查看k8s集群的secret:

[root@k8s ~]# kubectl -n kubernetes-dashboard get secret
NAME                               TYPE                                  DATA   AGE
default-token-hm8n8                kubernetes.io/service-account-token   3      17h
kubernetes-dashboard-certs         Opaque                                0      17h
kubernetes-dashboard-csrf          Opaque                                1      17h
kubernetes-dashboard-key-holder    Opaque                                2      17h
kubernetes-dashboard-token-r7fpl   kubernetes.io/service-account-token   3      17h

然后查看token:

[root@k8s ~]# kubectl describe secrets -n kubernetes-dashboard kubernetes-dashboard-token-r7fpl
Name:         kubernetes-dashboard-token-r7fpl
Namespace:    kubernetes-dashboard
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: kubernetes-dashboard
              kubernetes.io/service-account.uid: 1dbf2168-d42e-4557-b3ab-265888818975

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1066 bytes
namespace:  20 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IjRhdzJQVS1fNExza2dYNXhBRDAxTTRRajAzUFV2SlFtTUZiUElqSjJERmsifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi1yN2ZwbCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjFkYmYyMTY4LWQ0MmUtNDU1Ny1iM2FiLTI2NTg4ODgxODk3NSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.RSBZKHTpUPVDU6F2nsTid2eMclyODDmW6CrW5m7eJrcPgVOYh98zOYDd6OJyt7HG3n9ZyVzSXWFlMcQF25q3auXcQlPwjTeRpGoNNV2OhCrpNBaBmcOdq3LvSwj_l2ty3JRxvFPUQdTtDVLOvb431O-O_xZlnPHTR_bNK4SpY2BZh_UkPXqhh1boAmA0ORzbodFpAMfOx8Mk-_6QkOyhS0FAXfGE57kLSAYG2r9AqxMmQzLX7_IzvrR5FLVrivFrNYgYR9WB7EoD8QSeuYFnJZan9EwW2yTlWrDSLkSSd_tXfE23BqHd1naZt57IybdEj3nVl__xpGTvXHv7RDVV7A

复制最后的token字符串到登录界面,点击登录,可以看到dashboard首页:

此时我们看不到任何数据,点击右上角的小铃铛,发现异常信息:
serviceaccounts is forbidden: User “system:serviceaccount:kubernetes-dashboard:kubernetes-dashboard” cannot list resource “serviceaccounts” in API group “” in the namespace “default”,说明为权限不足,下面我们配置权限。

2.2.配置权限
k8s采用的是基于角色的访问控制策略,Role-Based Access Control, 即”RBAC”,使用”rbac.authorization.k8s.io” API Group实现授权决策,涉及到ServiceAccount,Role,ClusterRole,RoleBinding,ClusterRoleBinding,Secret等概念,后面的文章中我们会详细讲到。

首先解决本文的问题,执行以下命令:

[root@k8s ~]# kubectl create clusterrolebinding serviceaccount-cluster-admin --clusterrole=cluster-admin --user=system:serviceaccount:kubernetes-dashboard:kubernetes-dashboard
clusterrolebinding.rbac.authorization.k8s.io/serviceaccount-cluster-admin created

然后我们再看刚才访问的界面,已经刷新出数据:

此时,我们已经可以正常访问k8s dashboard。

推荐阅读