k8s 集群运维篇–kubectl 常用命令 - 腾讯云开发者社区 - 腾讯云

本文由 简悦 SimpRead 转码, 原文地址 cloud.tencent.com

k8s 集群运维篇–kubectl 常用命令。

当然最基础的我就一笔带过:

查看帮助:

1
[root@master1 ~]# kubectl --help

查看版本:(至今,yum 安装的版本竟然是 1.5.2,,这两天准备升级到 1.8x)

1
2
[[email protected] ~]# kubectl --version
Kubernetes v1.5.2

get

get 命令用于获取集群的一个或一些 resource 信息。 使用–help 查看详细信息。

Ps:kubectl 的帮助信息、示例相当详细,而且简单易懂。建议大家习惯使用帮助信息。kubectl 可以列出集群所有 resource 的详细。resource 包括集群节点、运行的 pod,ReplicationController,service 等。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[[email protected] ~]# kubectl get po        //查看所有的pods
NAME        READY     STATUS    RESTARTS   AGE
pod-redis   1/1       Running   0          24s
[[email protected] ~]# kubectl get nodes     //查看所有的nodes
NAME      STATUS    AGE
node1     Ready     2d
node2     Ready     2d
[[email protected] ~]# kubectl get pods -o wide      //查看所有的pods更详细些
NAME        READY     STATUS    RESTARTS   AGE       IP         NODE
pod-redis   1/1       Running   0          1m        10.0.8.2   node1
[[email protected] ~]# kubectl get nodes -o wide
NAME      STATUS    AGE       EXTERNAL-IP
node1     Ready     2d        <none>
node2     Ready     2d        <none>
[[email protected] ~]# kubectl get po --all-namespaces       //查看所有的namespace
NAMESPACE     NAME                        READY     STATUS             RESTARTS   AGE
default       pod-redis                   1/1       Running            0          6m

3 种方式查看一个 pod 的详细信息和参数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[[email protected] ~]# kubectl get po pod-redis -o yaml      //以yaml文件形式显示一个pod的详细信息
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: 2018-03-02T08:02:42Z
  labels:
    name: redis
  name: pod-redis
  namespace: default
  resourceVersion: "112273"
  selfLink: /api/v1/namespaces/default/pods/pod-redis
  uid: 15b3d4e9-1df0-11e8-9d2d-000c2926e9ae
spec:
  containers:
  - image: docker.io/redis
    imagePullPolicy: Always
    name: pod-redis
    ports:
    - containerPort: 6379
      hostPort: 6379
      protocol: TCP
    resources: {}
    terminationMessagePath: /dev/termination-log
  dnsPolicy: ClusterFirst
  nodeName: node1
  nodeSelector:
    zone: node1
  restartPolicy: Always
  securityContext: {}
  terminationGracePeriodSeconds: 30
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2018-03-02T08:02:44Z
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: 2018-03-02T08:02:55Z
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: 2018-03-02T08:02:42Z
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: docker://bd7ebb1017042a5f7cfb20daf96d8517a238bcefc3b850591ba2ed8ef8ffea2b
    image: docker.io/redis
    imageID: docker-pullable://docker.io/[email protected]:e55dff3a21a0e7ba25e91925ed0d926d959dac09f9099fd1bcc919263305f1e4
    lastState: {}
    name: pod-redis
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2018-03-02T08:02:54Z
  hostIP: 192.168.161.163
  phase: Running
  podIP: 10.0.8.2
  startTime: 2018-03-02T08:02:44Z

以 jison 格式输出 pod 的详细信息。

1
kubectl get po <podname> -o json

3. describe

describe 类似于 get,同样用于获取 resource 的相关信息。不同的是,get 获得的是更详细的 resource 个性的详细信息,describe 获得的是 resource 集群相关的信息。describe 命令同 get 类似,但是 describe 不支持 - o 选项,对于同一类型 resource,describe 输出的信息格式,内容域相同。

注:如果发现是查询某个 resource 的信息,使用 get 命令能够获取更加详尽的信息。但是如果想要查询某个 resource 的状态,如某个 pod 并不是在 running 状态,这时需要获取更详尽的状态信息时,就应该使用 describe 命令。

1
[root@master1 ~]# kubectl describe po rc-nginx-3-l8v2r

4. create

不多讲了,前面已经说了很多次了。 直接使用 create 则可以基于 rc-nginx-3.yaml 文件创建出 ReplicationController(rc),rc 会创建两个副本:

1
[root@master1 ~]# kubectl create -f rc-nginx.yaml

5. replace

replace 命令用于对已有资源进行更新、替换。如前面 create 中创建的 nginx,当我们需要更新 resource 的一些属性的时候,如果修改副本数量,增加、修改 label,更改 image 版本,修改端口等。都可以直接修改原 yaml 文件,然后执行 replace 命令。

注:名字不能被更更新。另外,如果是更新 label,原有标签的 pod 将会与更新 label 后的 rc 断开联系,有新 label 的 rc 将会创建指定副本数的新的 pod,但是默认并不会删除原来的 pod。所以此时如果使用 get po 将会发现 pod 数翻倍,进一步 check 会发现原来的 pod 已经不会被新 rc 控制,此处只介绍命令不详谈此问题,好奇者可自行实验。

1
[root@master1 ~]# kubectl replace -f rc-nginx.yaml

6. patch

如果一个容器已经在运行,这时需要对一些容器属性进行修改,又不想删除容器,或不方便通过 replace 的方式进行更新。kubernetes 还提供了一种在容器运行时,直接对容器进行修改的方式,就是 patch 命令。

如前面创建 pod 的 label 是 app=nginx-2,如果在运行过程中,需要把其 label 改为 app=nginx-3,这 patch 命令如下:

1
kubectl patch pod rc-nginx-2-kpiqt -p '{"metadata":{"labels":{"app":"nginx-3"}}}'

7. edit

edit 提供了另一种更新 resource 源的操作,通过 edit 能够灵活的在一个 common 的 resource 基础上,发展出更过的 significant resource。例如,使用 edit 直接更新前面创建的 pod 的命令为:

1
[root@master1 ~]# kubectl edit po rc-nginx-btv4j

上面命令的效果等效于:

1
2
3
4
kubectl get po rc-nginx-btv4j -o yaml >> /tmp/nginx-tmp.yaml   
vim /tmp/nginx-tmp.yaml   
/*do some changes here */   
kubectl replace -f /tmp/nginx-tmp.yaml

8. Delete

根据 resource 名或 label 删除 resource。

1
2
3
kubectl delete -f rc-nginx.yaml   
kubectl delete po rc-nginx-btv4j   
kubectl delete po -lapp=nginx-2

9. apply

apply 命令提供了比 patch,edit 等更严格的更新 resource 的方式。通过 apply,用户可以将 resource 的 configuration 使用 source control 的方式维护在版本库中。每次有更新时,将配置文件 push 到 server,然后使用 kubectl apply 将更新应用到 resource。kubernetes 会在引用更新前将当前配置文件中的配置同已经应用的配置做比较,并只更新更改的部分,而不会主动更改任何用户未指定的部分。

apply 命令的使用方式同 replace 相同,不同的是,apply 不会删除原有 resource,然后创建新的。apply 直接在原有 resource 的基础上进行更新。同时 kubectl apply 还会 resource 中添加一条注释,标记当前的 apply。类似于 git 操作。

10. logs

logs 命令用于显示 pod 运行中,容器内程序输出到标准输出的内容。跟 docker 的 logs 命令类似。如果要获得 tail -f 的方式,也可以使用 - f 选项。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[[email protected]-1 tmp]# kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
mysql-478535978-1dnm2        1/1       Running   0          1h
sonarqube-3574384362-m7mdq   1/1       Running   0          1h
[[email protected]-1 tmp]# kubectl logs mysql-478535978-1dnm2
Initializing database
...
2017-06-29T09:04:37.081939Z 0 [Note] Event Scheduler: Loaded 0 events
2017-06-29T09:04:37.082097Z 0 [Note] mysqld: ready for connections.
Version: '5.7.16'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

11. rolling-update

rolling-update 是一个非常重要的命令,对于已经部署并且正在运行的业务,rolling-update 提供了不中断业务的更新方式。rolling-update 每次起一个新的 pod,等新 pod 完全起来后删除一个旧的 pod,然后再起一个新的 pod 替换旧的 pod,直到替换掉所有的 pod。

rolling-update 需要确保新的版本有不同的 name,Version 和 label,否则会报错 。

1
kubectl rolling-update rc-nginx-2 -f rc-nginx.yaml

如果在升级过程中,发现有问题还可以中途停止 update,并回滚到前面版本

1
kubectl rolling-update rc-nginx-2 —rollback

rolling-update 还有很多其他选项提供丰富的功能,如—update-period 指定间隔周期,使用时可以使用 - h 查看 help 信息。

12. scale

scale 用于程序在负载加重或缩小时副本进行扩容或缩小,如前面创建的 nginx 有两个副本,可以轻松的使用 scale 命令对副本数进行扩展或缩小。

扩展副本数到 4:

1
kubectl scale rc rc-nginx-3 —replicas=4

重新缩减副本数到 2:

1
kubectl scale rc rc-nginx-3 —replicas=2

13. autoscale

scale 虽然能够很方便的对副本数进行扩展或缩小,但是仍然需要人工介入,不能实时自动的根据系统负载对副本数进行扩、缩。autoscale 命令提供了自动根据 pod 负载对其副本进行扩缩的功能。

autoscale 命令会给一个 rc 指定一个副本数的范围,在实际运行中根据 pod 中运行的程序的负载自动在指定的范围内对 pod 进行扩容或缩容。如前面创建的 nginx,可以用如下命令指定副本范围在 1~4

1
kubectl autoscale rc rc-nginx-3 --min=1 --max=4

14. cordon, drain, uncordon

这三个命令是正式 release 的 1.2 新加入的命令,三个命令一起介绍,是因为三个命令配合使用可以实现节点的维护。

在 1.2 之前,因为没有相应的命令支持,如果要维护一个节点,只能 stop 该节点上的 kubelet 将该节点退出集群,是集群不在将新的 pod 调度到该节点上。如果该节点上本生就没有 pod 在运行,则不会对业务有任何影响。如果该节点上有 pod 正在运行,kubelet 停止后,master 会发现该节点不可达,而将该节点标记为 notReady 状态,不会将新的节点调度到该节点上。同时,会在其他节点上创建新的 pod 替换该节点上的 pod。

这种方式虽然能够保证集群的健壮性,但是任然有些暴力,如果业务只有一个副本,而且该副本正好运行在被维护节点上的话,可能仍然会造成业务的短暂中断。

1.2 中新加入的这 3 个命令可以保证维护节点时,平滑的将被维护节点上的业务迁移到其他节点上,保证业务不受影响。如下图所示是一个整个的节点维护的流程(为了方便 demo 增加了一些查看节点信息的操作):

1)首先查看当前集群所有节点状态,可以看到共四个节点都处于 ready 状态;

2)查看当前 nginx 两个副本分别运行在 d-node1 和 k-node2 两个节点上;

3)使用 cordon 命令将 d-node1 标记为不可调度;

4)再使用 kubectl get nodes 查看节点状态,发现 d-node1 虽然还处于 Ready 状态,但是同时还被禁能了调度,这意味着新的 pod 将不会被调度到 d-node1 上。

5)再查看 nginx 状态,没有任何变化,两个副本仍运行在 d-node1 和 k-node2 上;

6)执行 drain 命令,将运行在 d-node1 上运行的 pod 平滑的赶到其他节点上;

7)再查看 nginx 的状态发现,d-node1 上的副本已经被迁移到 k-node1 上;这时候就可以对 d-node1 进行一些节点维护的操作,如升级内核,升级 Docker 等;

8)节点维护完后,使用 uncordon 命令解锁 d-node1,使其重新变得可调度;

9)检查节点状态,发现 d-node1 重新变回 Ready 状态。

https://ask.qcloudimg.com/http-save/yehe-1011658/wd1e5qbxvu.gif

15. attach

类似于 docker attach 的功能,用于取得实时的类似于 kubectl logs 的信息

1
2
3
4
5
6
[[email protected]-1 tmp]# kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
mysql-478535978-1dnm2        1/1       Running   0          1h
sonarqube-3574384362-m7mdq   1/1       Running   0          1h
[[email protected]-1 tmp]# kubectl attach sonarqube-3574384362-m7mdq
If you don't see a command prompt, try pressing enter.

16. exec

exec 命令同样类似于 docker 的 exec 命令,为在一个已经运行的容器中执行一条 shell 命令,如果一个 pod 容器中,有多个容器,需要使用 - c 选项指定容器。

1
2
3
4
5
6
[[email protected]-1 tmp]# kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
mysql-478535978-1dnm2        1/1       Running   0          1h
sonarqube-3574384362-m7mdq   1/1       Running   0          1h
[[email protected]-1 tmp]# kubectl exec mysql-478535978-1dnm2 hostname       //查看这个容器的hostname
mysql-478535978-1dnm2

17. port-forward

转发一个本地端口到容器端口,博主一般都是使用 yaml 的方式编排容器,所以基本不使用此命令。

18. proxy

博主只尝试过使用 nginx 作为 kubernetes 多 master HA 方式的代理,没有使用过此命令为 kubernetes api server 运行过 proxy

19. run

类似于 docker 的 run 命令,直接运行一个 image。

20. label

为 kubernetes 集群的 resource 打标签,如前面实例中提到的为 rc 打标签对 rc 分组。还可以对 nodes 打标签,这样在编排容器时,可以为容器指定 nodeSelector 将容器调度到指定 lable 的机器上,如如果集群中有 IO 密集型,计算密集型的机器分组,可以将不同的机器打上不同标签,然后将不同特征的容器调度到不同分组上。

在 1.2 之前的版本中,使用 kubectl get nodes 则可以列出所有节点的信息,包括节点标签,1.2 版本中不再列出节点的标签信息,如果需要查看节点被打了哪些标签,需要使用 describe 查看节点的信息。

21. cp

kubectl cp 用于 pod 和外部的文件交换,比如如下示例了如何在进行内外文件交换。

在 pod 中创建一个文件 message.log

1
2
3
4
5
6
7
8
[[email protected] tmp]# kubectl exec -it mysql-478535978-1dnm2 sh
# pwd
/
# cd /tmp
# echo "this is a message from `hostname`" >message.log
# cat message.log
this is a message from mysql-478535978-1dnm2
# exit

拷贝出来并确认

1
2
3
4
[[email protected]-1 tmp]# kubectl cp mysql-478535978-1dnm2:/tmp/message.log message.log
tar: Removing leading `/' from member names
[[email protected]-1 tmp]# cat message.log
this is a message from mysql-478535978-1dnm2

更改 message.log 并拷贝回 pod

1
2
3
4
5
[[email protected]-1 tmp]# echo "information added in `hostname`" >>message.log 
[[email protected]-1 tmp]# cat message.log 
this is a message from mysql-478535978-1dnm2
information added in ku8-1
[[email protected]-1 tmp]# kubectl cp message.log mysql-478535978-1dnm2:/tmp/message.log

确认更改后的信息

1
2
3
[[email protected]-1 tmp]# kubectl exec mysql-478535978-1dnm2 cat /tmp/message.log
this is a message from mysql-478535978-1dnm2
information added in ku8-1

22. kubectl cluster-info

使用 cluster-info 和 cluster-info dump 也能取出一些信息,尤其是你需要看整体的全部信息的时候一条命令一条命令的执行不如 kubectl cluster-info dump 来的快一些

1
2
3
4
[[email protected]1 tmp]# kubectl cluster-info
Kubernetes master is running at http://localhost:8080

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

21. 实际操作:

集群构成

一主三从的 Kubernetes 集群

https://ask.qcloudimg.com/http-save/yehe-1011658/wd1e5qbxvu.gif

1
2
3
4
5
[[email protected]-1 tmp]# kubectl get nodes
NAME             STATUS    AGE
192.168.32.132   Ready     12m
192.168.32.133   Ready     11m
192.168.32.134   Ready     11m

yaml 文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[[email protected] tmp]# cat nginx/nginx.yaml 
---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        name: nginx
    spec:
      containers:
      - name: nginx
        image: 192.168.32.131:5000/nginx:1.12-alpine
        ports:
        - containerPort: 80
          protocol: TCP
---
kind: Service
apiVersion: v1
metadata:
  name: nginx
  labels:
    name: nginx
spec:
  type: NodePort
  ports:
  - protocol: TCP
    nodePort: 31001
    targetPort: 80
    port: 80
  selector:
    name: nginx

kubectl create

创建 pod/deployment/service
1
2
3
[[email protected] tmp]# kubectl create -f nginx/
deployment "nginx" created
service "nginx" created

确认 创建 pod/deployment/service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
[[email protected] tmp]# kubectl get service
NAME         CLUSTER-IP        EXTERNAL-IP   PORT(S)        AGE
kubernetes   172.200.0.1       <none>        443/TCP        1d
nginx        172.200.229.212   <nodes>       80:31001/TCP   58s
[[email protected] tmp]# kubectl get pod
NAME                     READY     STATUS    RESTARTS   AGE
nginx-2476590065-1vtsp   1/1       Running   0          1m
[[email protected] tmp]# kubectl get deploy
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     1         1         1            1           1m

kubectl edit

edit 这条命令用于编辑服务器上的资源,具体是什么意思,可以通过如下使用方式来确认。

编辑对象确认

使用 - o 参数指定输出格式为 yaml 的 nginx 的 service 的设定情况确认,取得现场情况,这也是我们不知道其 yaml 文件而只有环境时候能做的事情。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[[email protected] tmp]# kubectl get service |grep nginx
nginx        172.200.229.212   <nodes>       80:31001/TCP   2m
[[email protected] tmp]# kubectl get service nginx -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: 2017-06-30T04:50:44Z
  labels:
    name: nginx
  name: nginx
  namespace: default
  resourceVersion: "77068"
  selfLink: /api/v1/namespaces/default/services/nginx
  uid: ad45612a-5d4f-11e7-91ef-000c2933b773
spec:
  clusterIP: 172.200.229.212
  ports:
  - nodePort: 31001
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    name: nginx
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

使用 edit 命令对 nginx 的 service 设定进行编辑,得到如下信息

可以看到当前端口为 31001,在此编辑中,我们把它修改为 31002

1
2
[[email protected] tmp]# kubectl edit service nginx
service "nginx" edited

编辑之后确认结果发现,此服务端口已经改变

1
2
3
4
[[email protected] tmp]# kubectl get service
NAME         CLUSTER-IP        EXTERNAL-IP   PORT(S)        AGE
kubernetes   172.200.0.1       <none>        443/TCP        1d
nginx        172.200.229.212   <nodes>       80:31002/TCP   8m

确认后发现能够立连通

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[[email protected] tmp]# curl http://192.168.32.132:31002/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

而之前的端口已经不通

1
2
[[email protected] tmp]# curl http://192.168.32.132:31001/
curl: (7) Failed connect to 192.168.32.132:31001; Connection refused

kubectl replace

了解到 edit 用来做什么之后,我们会立即知道 replace 就是替换,我们使用上个例子中的 service 的 port,重新把它改回 31001

1
2
3
4
[[email protected] tmp]# kubectl get service
NAME         CLUSTER-IP        EXTERNAL-IP   PORT(S)        AGE
kubernetes   172.200.0.1       <none>        443/TCP        1d
nginx        172.200.229.212   <nodes>       80:31002/TCP   17m

取得当前的 nginx 的 service 的设定文件,然后修改 port 信息

1
2
3
4
5
6
7
8
[[email protected] tmp]# kubectl get service nginx -o yaml >nginx_forreplace.yaml
[[email protected] tmp]# cp -p nginx_forreplace.yaml nginx_forreplace.yaml.org
[[email protected] tmp]# vi nginx_forreplace.yaml
[[email protected] tmp]# diff nginx_forreplace.yaml nginx_forreplace.yaml.org
15c15
<   - nodePort: 31001
---
>   - nodePort: 31002

执行 replace 命令

提示被替换了
1
2
[[email protected] tmp]# kubectl replace -f nginx_forreplace.yaml
service "nginx" replaced

确认之后发现 port 确实重新变成了 31001

1
2
3
4
[[email protected] tmp]# kubectl get service
NAME         CLUSTER-IP        EXTERNAL-IP   PORT(S)        AGE
kubernetes   172.200.0.1       <none>        443/TCP        1d
nginx        172.200.229.212   <nodes>       80:31001/TCP   20m

kubectl patch

当部分修改一些设定的时候 patch 非常有用,尤其是在 1.2 之前的版本,port 改来改去好无聊,这次换个 image

当前 port 中使用的 nginx 是 alpine 的 1.12 版本

1
2
3
[[email protected]-1 tmp]# kubectl exec nginx-2476590065-1vtsp  -it sh
/ # nginx -v
nginx version: nginx/1.12.0

执行 patch 进行替换

1
2
[[email protected]-1 tmp]# kubectl patch pod nginx-2476590065-1vtsp -p '{"spec":{"containers":[{"name":"nginx","image":"192.168.32.131:5000/nginx:1.13-alpine"}]}}'
"nginx-2476590065-1vtsp" patched

确认当前 pod 中的镜像已经 patch 成了 1.13

1
2
3
[[email protected]-1 tmp]# kubectl exec nginx-2476590065-1vtsp  -it sh
/ # nginx -v
nginx version: nginx/1.13.1

kubectl scale

scale 命令用于横向扩展,是 kubernetes 或者 swarm 这类容器编辑平台的重要功能之一,让我们来看看是如何使用的

事前设定 nginx 的 replica 为一,而经过确认此 pod 在 192.168.32.132 上运行

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[[email protected] tmp]# kubectl delete -f nginx/
deployment "nginx" deleted
service "nginx" deleted
[[email protected] tmp]# kubectl create -f nginx/
deployment "nginx" created
service "nginx" created
[[email protected] tmp]# 
[[email protected] tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-74tpk   1/1       Running   0          17s       172.200.26.2   192.168.32.132
[[email protected] tmp]# kubectl get deployments -o wide
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     1         1         1            1           27s

执行 scale 命令

使用 scale 命令进行横向扩展,将原本为 1 的副本,提高到 3。

1
2
[[email protected] tmp]# kubectl scale --current-replicas=1 --replicas=3 deployment/nginx
deployment "nginx" scaled

通过确认发现已经进行了横向扩展,除了 192.168.132.132,另外 133 和 134 两台机器也各有一个 pod 运行了起来,这正是 scale 命令的结果。

1
2
3
4
5
6
7
8
[[email protected]-1 tmp]# kubectl get deployment
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     3         3         3            3           2m
[[email protected]-1 tmp]# kubectl get pod -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-74tpk   1/1       Running   0          2m        172.200.26.2   192.168.32.132
nginx-2476590065-cm5d9   1/1       Running   0          16s       172.200.44.2   192.168.32.133
nginx-2476590065-hmn9j   1/1       Running   0          16s       172.200.59.2   192.168.32.134

kube autoscale ★★★★

autoscale 命令用于自动扩展确认,跟 scale 不同的是前者还是需要手动执行,而 autoscale 则会根据负载进行调解。而这条命令则可以对 Deployment/ReplicaSet/RC 进行设定,通过最小值和最大值的指定进行设定,这里只是给出执行的结果,不再进行实际的验证。

1
2
[[email protected] tmp]# kubectl autoscale deployment nginx --min=2 --max=5
deployment "nginx" autoscaled

当然使用还会有一些限制,比如当前 3 个,设定最小值为 2 的话会出现什么样的情况?

1
2
3
4
5
6
7
[[email protected] tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-74tpk   1/1       Running   0          5m        172.200.26.2   192.168.32.132
nginx-2476590065-cm5d9   1/1       Running   0          2m        172.200.44.2   192.168.32.133
nginx-2476590065-hmn9j   1/1       Running   0          2m        172.200.59.2   192.168.32.134
[[email protected] tmp]# kubectl autoscale deployment nginx --min=2 --max=2
Error from server (AlreadyExists): horizontalpodautoscalers.autoscaling "nginx" already exists

kubectl cordon 与 uncordon ★★★

在实际维护的时候会出现某个 node 坏掉,或者做一些处理,暂时不能让生成的 pod 在此 node 上运行,需要通知 kubernetes 让其不要创建过来,这条命令就是 cordon,uncordon 则是取消这个要求。例子如下:

创建了一个 nginx 的 pod,跑在 192.168.32.133 上。

1
2
3
4
5
6
7
[[email protected] tmp]# kubectl create -f nginx/
deployment "nginx" created
service "nginx" created
[[email protected] tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-dnsmw   1/1       Running   0          6s        172.200.44.2   
192.168.32.133

执行 scale 命令 ★★★

横向扩展到 3 个副本,发现利用 roundrobin 策略每个 node 上运行起来了一个 pod,134 这台机器也有一个。

1
2
3
4
5
6
7
8
9
[[email protected]-1 tmp]# kubectl scale --replicas=3 deployment/nginx
deployment "nginx" scaled
[[email protected]-1 tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-550sm   1/1       Running   0          5s        172.200.26.2   192.168.32.132
nginx-2476590065-bt3bc   1/1       Running   0          5s        172.200.59.2   192.168.32.134
nginx-2476590065-dnsmw   1/1       Running   0          17s       172.200.44.2   192.168.32.133
[[email protected]-1 tmp]# kubectl get pods -o wide |grep 192.168.32.134
nginx-2476590065-bt3bc   1/1       Running   0          12s       172.200.59.2   192.168.32.134

执行 cordon 命令

设定 134,使得 134 不可使用,使用 get node 确认,其状态显示 SchedulingDisabled。

1
2
3
4
5
6
7
[[email protected]-1 tmp]# kubectl cordon 192.168.32.134
node "192.168.32.134" cordoned
[[email protected]-1 tmp]# kubectl get nodes -o wide
NAME             STATUS                     AGE       EXTERNAL-IP
192.168.32.132   Ready                      1d        <none>
192.168.32.133   Ready                      1d        <none>
192.168.32.134   Ready,SchedulingDisabled   1d        <none>

执行 scale 命令

再次执行横向扩展命令,看是否会有 pod 漂到 134 这台机器上,结果发现只有之前的一个 pod,再没有新的 pod 漂过去。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[[email protected]-1 tmp]# kubectl scale --replicas=6 deployment/nginx
deployment "nginx" scaled
[[email protected]-1 tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-550sm   1/1       Running   0          32s       172.200.26.2   192.168.32.132
nginx-2476590065-7vxvx   1/1       Running   0          3s        172.200.44.3   192.168.32.133
nginx-2476590065-bt3bc   1/1       Running   0          32s       172.200.59.2   192.168.32.134
nginx-2476590065-dnsmw   1/1       Running   0          44s       172.200.44.2   192.168.32.133
nginx-2476590065-fclhj   1/1       Running   0          3s        172.200.44.4   192.168.32.133
nginx-2476590065-fl9fn   1/1       Running   0          3s        172.200.26.3   192.168.32.132
[[email protected]-1 tmp]# kubectl get pods -o wide |grep 192.168.32.134
nginx-2476590065-bt3bc   1/1       Running   0          37s       172.200.59.2   192.168.32.134

执行 uncordon 命令

使用 uncordon 命令解除对 134 机器的限制,通过 get node 确认状态也已经正常。

1
2
3
4
5
6
7
8
[[email protected]-1 tmp]# kubectl uncordon 192.168.32.134
node "192.168.32.134" uncordoned
[[email protected]-1 tmp]# 
[[email protected]-1 tmp]# kubectl get nodes -o wide
NAME             STATUS    AGE       EXTERNAL-IP
192.168.32.132   Ready     1d        <none>
192.168.32.133   Ready     1d        <none>
192.168.32.134   Ready     1d        <none>

执行 scale 命令

再次执行 scale 命令,发现有新的 pod 可以创建到 134node 上了。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
[[email protected]-1 tmp]# kubectl scale --replicas=10 deployment/nginx
deployment "nginx" scaled
[[email protected]-1 tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-550sm   1/1       Running   0          1m        172.200.26.2   192.168.32.132
nginx-2476590065-7vn6z   1/1       Running   0          3s        172.200.44.4   192.168.32.133
nginx-2476590065-7vxvx   1/1       Running   0          35s       172.200.44.3   192.168.32.133
nginx-2476590065-bt3bc   1/1       Running   0          1m        172.200.59.2   192.168.32.134
nginx-2476590065-dnsmw   1/1       Running   0          1m        172.200.44.2   192.168.32.133
nginx-2476590065-fl9fn   1/1       Running   0          35s       172.200.26.3   192.168.32.132
nginx-2476590065-pdx91   1/1       Running   0          3s        172.200.59.3   192.168.32.134
nginx-2476590065-swvwf   1/1       Running   0          3s        172.200.26.5   192.168.32.132
nginx-2476590065-vdq2k   1/1       Running   0          3s        172.200.26.4   192.168.32.132
nginx-2476590065-wdv52   1/1       Running   0          3s        172.200.59.4   192.168.32.134

kubectl drain ★★★★★

drain 命令用于对某个 node 进行设定,是为了设定此 node 为维护做准备。英文的 drain 有排干水的意思,下水道的水之后排干后才能进行维护。那我们来看一下 kubectl” 排水” 的时候都作了什么

将 nginx 的副本设定为 4,确认发现 134 上启动了两个 pod。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
[[email protected]-1 tmp]# kubectl create -f nginx/
deployment "nginx" created
service "nginx" created
[[email protected]-1 tmp]# kubectl get pod -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-d6h8f   1/1       Running   0          8s        172.200.59.2   192.168.32.134
[[email protected]-1 tmp]# 
[[email protected]-1 tmp]# kubectl get nodes -o wide
NAME             STATUS    AGE       EXTERNAL-IP
192.168.32.132   Ready     1d        <none>
192.168.32.133   Ready     1d        <none>
192.168.32.134   Ready     1d        <none>
[[email protected]-1 tmp]# 
[[email protected]-1 tmp]# kubectl scale --replicas=4 deployment/nginx
deployment "nginx" scaled
[[email protected]-1 tmp]# 
[[email protected]-1 tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-9lfzh   1/1       Running   0          12s       172.200.59.3   192.168.32.134
nginx-2476590065-d6h8f   1/1       Running   0          1m        172.200.59.2   192.168.32.134
nginx-2476590065-v8xvf   1/1       Running   0          43s       172.200.26.2   192.168.32.132
nginx-2476590065-z94cq   1/1       Running   0          12s       172.200.44.2   192.168.32.133

执行 drain 命令

执行 drain 命令,发现这条命令做了两件事情:

  1. 设定此 node 不可以使用(cordon)
  2. evict 了其上的两个 pod
1
2
3
4
5
[[email protected] tmp]# kubectl drain 192.168.32.134
node "192.168.32.134" cordoned
pod "nginx-2476590065-d6h8f" evicted
pod "nginx-2476590065-9lfzh" evicted
node "192.168.32.134" drained

结果确认

evict 的意思有驱逐和回收的意思,让我们来看一下 evcit 这个动作的结果到底是什么。 结果是 134 上面已经不再有 pod,而在 132 和 133 上新生成了两个 pod,用以替代在 134 上被退场的 pod,而这个替代的动作应该是 replicas 的机制保证的。所以 drain 的结果就是退场 pod 和设定 node 不可用(排水),这样的状态则可以进行维护了,执行完后重新 uncordon 即可。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[[email protected]-1 tmp]# kubectl get pods -o wide
NAME                     READY     STATUS    RESTARTS   AGE       IP             NODE
nginx-2476590065-1ld9j   1/1       Running   0          13s       172.200.44.3   192.168.32.133
nginx-2476590065-ss48z   1/1       Running   0          13s       172.200.26.3   192.168.32.132
nginx-2476590065-v8xvf   1/1       Running   0          1m        172.200.26.2   192.168.32.132
nginx-2476590065-z94cq   1/1       Running   0          55s       172.200.44.2   192.168.32.133
[[email protected]-1 tmp]# 
[[email protected]-1 tmp]# kubectl get nodes -o wide
NAME             STATUS                     AGE       EXTERNAL-IP
192.168.32.132   Ready                      1d        <none>
192.168.32.133   Ready                      1d        <none>
192.168.32.134   Ready,SchedulingDisabled   1d        <none>