3.1、基本操作

(1)kubectl语法

kubectl命令语法如下:

# kubectl [command] [TYPE] [NAME] [flags]

命令语法解析:

l command:子命令。

l TYPE:资源类型。

l NAME:资源名称。

l flags:命令参数。

kubectl命令选项如下:

l --alsologtostderr[=false]:同时输出日志到标准错误控制台和文件。

l --api-version="":和服务端交互使用的API版本。

l --certificate-authority="":用以进行认证授权的.cert文件路径。

l --client-certificate="":TLS使用的客户端证书路径。

l --client-key="":TLS使用的客户端密钥路径。

l --cluster="":指定使用的kubeconfig配置文件中的集群名。

l --context="":指定使用的kubeconfig配置文件中的环境名。

l --insecure-skip-tls-verify[=false]:如果为true,将不会检查服务器凭证的有效性,这会导致HTTPS链接变得不安全。

l --kubeconfig="":命令行请求使用的配置文件路径。

l --log-backtrace-at=:0:当日志长度超过定义的行数时,忽略堆栈信息。

l --log-dir="":如果不为空,将日志文件写入此目录。

l --log-flush-frequency=5s:刷新日志的最大时间间隔。

l --logtostderr[=true]:输出日志到标准错误控制台,不输出到文件。

l --match-server-version[=false]:要求服务端和客户端版本匹配。

l --namespace="":如果不为空,命令将使用此namespace。

l --password="":APIServer进行简单认证使用的密码。

l -s,--server="":Kubernetes API Server的地址和端口号。

l --stderrthreshold=2:高于此级别的日志将被输出到错误控制台。

l --token="":认证到APIServer使用的令牌。

l --user="":指定使用的kubeconfig配置文件中的用户名。

l --username="":APIServer进行简单认证使用的用户名。

l --v=0:指定输出日志的级别。

l --vmodule=:指定输出日志的模块。

常用命令如下:

l kubectl annotate:更新资源的注解。

l kubectl api-versions:以“组/版本”的格式输出服务端支持的API版本。

l kubectl apply:通过文件名或控制台输入,对资源进行配置。

l kubectl attach:连接到一个正在运行的容器。

l kubectl autoscale:对replication controller进行自动伸缩。

l kubectl cluster-info:输出集群信息。

l kubectl config:修改kubeconfig配置文件。

l kubectl create:通过文件名或控制台输入,创建资源。

l kubectl delete:通过文件名、控制台输入、资源名或者label selector删除资源。

l kubectl describe:输出指定的一个或多个资源的详细信息。

l kubectl edit:编辑服务端的资源。

l kubectl exec:在容器内部执行命令。

l kubectl expose:输入rc、svc或Pod,并将其暴露为新的kubernetes service。

l kubectl get:输出一个或多个资源。

l kubectl label:更新资源的label。

l kubectl logs:输出Pod中一个容器的日志。

l kubectl namespace:(已停用)设置或查看当前使用的namespace。

l kubectl patch:通过控制台输入更新资源中的字段。

l kubectl port-forward:将本地端口转发到Pod。

l kubectl proxy:为Kubernetes API Server启动代理服务器。

l kubectl replace:通过文件名或控制台输入替换资源。

l kubectl rolling-update:对指定的replication controller执行滚动升级。

l kubectl run:在集群中使用指定镜像启动容器。

l kubectl scale:为replication controller设置新的副本数。

l kubectl version:输出服务端和客户端的版本信息。

(2)创建资源对象kubectl create

使用kubectl create(创建按)命令可进行资源的创建。

根据Yaml配置文件一次性创建service和rc:

# kubectl create -f my-service.yaml -f my-rc.yaml

根据<directory>目录下所有.yaml、.yml、.json文件的定义进行创建操作:

# kubectl create -f <directory>

(3)查看资源对象kubectl get

查看所有Pod列表:

# kubectl get(查看)pods

查看rc和service列表:

# kubectl get rc,service

(4)描述资源对象kubectl describe

显示Node的详细信息:

# kubectl describe nodes <node-name>

显示Pod的详细信息:

# kubectl describe pods/<pod-name>

显示由RC管理的Pod的信息:

# kubectl describe pods <rc-name>

(5)删除资源对象kubectl delete

基于Pod.yaml定义的名称删除Pod:

# kubectl delete -f pod.yaml-

删除所有包含某个label的Pod和service:

# kubectl delete pods,services -l name=<label-name>

删除所有Pod:

# kubectl delete pods --all

(6)容器操作

执行Pod的data命令,默认是用Pod中的第一个容器执行:

# kubectl exec <pod-name> data

指定Pod中某个容器执行data命令:

# kubectl exec <pod-name> -c <container-name> data

通过bash获得Pod中某个容器的TTY,相当于登录容器:

# kubectl exec -it <pod-name> -c <container-name> bash

(7)Pod的扩容与缩容

执行扩容缩容Pod的操作:

# kubectl scale rc redis --replicas=3

需要确认的是,在rc配置文件中定义的replicas数量,当执行上述命令的结果大于replicas的数量时,则执行的命令相当于扩容操作,反之则为缩容。可以理解为填写的数量即需要的Pod数量。

注意:当需要进行永久性扩容时,不要忘记修改rc配置文件中的replicas数量。

(8)Pod的滚动升级

执行滚动升级操作:

# kubectl rolling-update redis -f redis-rc.update.yaml

注意:当执行rolling-update命令前需要准备好新的rc配置文件以及ConfigMap配置文件。rc配置文件中需要指定升级后需要使用的镜像名称,或者可以使用kubeclt rolling-update redis --image=redis-2.0命令直接指定镜像名称来直接升级。

3.2、运行容器

(1)运行Nginx应用

运行Nginx应用。

[root@master ~]# kubectl run nginx --image=10.18.4.10/library/nginx:latest

kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.

deployment.apps/nginx created

(2)查看Pods

验证Pods是否正常运行。

[root@master ~]# kubectl get pods

NAME                    READY   STATUS    RESTARTS   AGE

nginx-ccb467dc5-92tbn       1/1       Running    0            93s

……

(3)开放端口

使用expose将service的80端口开放出去。

[root@master ~]# kubectl expose deploy/nginx --port 80

service/nginx exposed

(4)测试Nginx应用

[root@master ~]# kubectl get svc

NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE

kubernetes       ClusterIP     10.96.0.1         <none>        443/TCP   3h18m

nginx           ClusterIP     10.100.220.6      <none>        80/TCP    9s

[root@master ~]#  curl 10.100.220.6:80

……

<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>

使用curl工具可以成功获取到Nginx网页信息,说明80端口已开放成功。

3.3、Kubernetes运维

(1)Node的隔离与恢复

在硬件升级、硬件维护等情况下,需要将某些Node隔离。使用kubectl cordon <node_name>命令可禁止Pod调度到该节点上,在其上运行的Pod并不会自动停止,管理员需要手动停止在该Node上运行的Pod。

[root@master ~]# kubectl cordon node

查看Node的状态,可以观察到在node的状态中增加了一项SchedulingDisabled,对于后续创建的Pod,系统将不会再向该Node进行调度。

[root@master ~]# kubectl get nodes

通过kubectl uncordon命令可完成对Node的恢复。

[root@master ~]# kubectl uncordon node

[root@master ~]# kubectl get nodes

可以看到Node节点已恢复调度,允许Pod调度到该节点上。

通过kubectl drain <node>命令可实现对node节点的驱逐,该命令会删除该节点上的所有Pod(DaemonSet除外),在其他Node上重新启动它们。

(2)Pod动态扩容和缩放

在实际生产系统中,经常会遇到某个服务需要扩容的场景,也可能会遇到由于资源紧张或者工作负载降低而需要减少服务实例数量的场景。此时可以利用kubectl scale deployment命令来完成这些任务。

以Nginx Deployment为例,已定义的最初副本数量为1。

[root@master ~]# kubectl run nginx --image=10.18.4.10/library/nginx:latest

kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.

deployment.apps/nginx created

[root@master ~]# kubectl get pods

NAME                    READY   STATUS    RESTARTS   AGE

nginx-ccb467dc5-jlr4c   1/1     Running   0          40s

通过执行下面的命令将Nginx Deployment控制的Pod副本数量从初始的1更新为5。

[root@master ~]# kubectl scale deployment nginx --replicas=5

deployment.extensions/nginx scaled

执行kubectl get pods命令来验证Pod的副本数量增加到5。

[root@master ~]# kubectl get pods

NAME                    READY   STATUS    RESTARTS   AGE

nginx-ccb467dc5-2f6n2   1/1     Running   0          34s

......

将--replicas设置为比当前Pod副本数量更小的数字,系统将会“杀掉”一些运行中的Pod,即可实现应用集群缩容。

[root@master ~]# kubectl scale deployment nginx --replicas=2

deployment.extensions/nginx scaled

[root@master ~]# kubectl get pods

NAME                    READY   STATUS    RESTARTS   AGE

nginx-ccb467dc5-bl4jp   1/1     Running   0          2m50s

nginx-ccb467dc5-jlr4c   1/1     Running   0          5m21s

(3)将Pod调度到指定的Node

Kubernetes的Scheduler服务(kube-scheduler进程)负责实现Pod的调度,整个调度过程通过执行一系列复杂的算法最终为每个Pod计算出一个最佳的目标节点,这一过程是自动完成的,用户无法知道Pod最终会被调度到哪个节点上。有时可能需要将Pod调度到一个指定的Node上。此时,可以通过Node的标签(Label)和Pod的nodeSelector属性相匹配,来达到上述目的。

Label(标签)作为用户可灵活定义的对象属性,在已创建的对象上,仍然可以随时通过kubectl label命令对其进行增加、修改、删除等操作。使用kubectl label给node打标签的用法如下:

# kubectl label nodes <node-name> <label-key>=<label-value>

下面的示例,为node打上一个project=gcxt的标签。

[root@master ~]# kubectl label nodes node project=gcxt

node/node labeled

如果想删除Label,只需要在命令行最后指定Label的key名,并加一个减号即可。

[root@master ~]# kubectl label node node project-

node/node labeled

在Pod中加入nodeSelector定义,示例如下。

[root@master ~]# cat nginx.yaml

apiVersion: v1

kind: ReplicationController

metadata:

  name: memcached-gcxt

  labels:

    name: memcached-gcxt

spec:

  replicas: 1

  selector:

    name: memcached-gcxt

  template:

    metadata:

      labels:

        name: memcached-gcxt

    spec:

      containers:

      - name: memcached-gcxt

        image: memcached

        command:

        - memcached

        - -m 64

        ports:

        - containerPort: 11211

      nodeSelector:

        project: gcxt

运行kubectl create -f命令创建Pod,scheduler就会将该Pod调度到拥有project=gcxt标签的Node上去。

[root@master ~]# kubectl create -f nginx.yaml

replicationcontroller/memcached-gcxt created

查看Pod。

[root@master ~]# kubectl get pods -owide

NAME                   READY   STATUS    RESTARTS   AGE   IP          NODE   NOMINATED NODE   READINESS GATES

memcached-gcxt-hdt5x   1/1     Running   0          14s   10.24.9.2   node   <none>           <none>

可以看到,Pod已成功调度到指定的Node节点。

这种基于Label标签的调度方式灵活性很高,比如,可以把一组Node分别贴上“开发环境”、“测试环境”、“生产环境”这3组标签中的一种,此时一个Kubernetes集群就承载了3个环境,这将大大提高开发效率。

注意:如果指定了PodnodeSelector条件,且集群中不存在包含相应标签的Node时,即使还有其他可供调度的Node,这个Pod也最终会调度失败。

(4)应用滚动升级

当集群中的某个服务需要升级时,需要停止目前与该服务相关的所有Pod,然后重新拉取镜像并启动。如果集群规模比较大,这个工作就变成了一个挑战。如果采取先全部停止,然后逐步升级的方式,会导致较长时间的服务不可用。Kubernetes提供了rolling-update(滚动升级)功能来解决上述问题。

滚动升级通过执行kubectl rolling-update命令一键完成,该命令创建了一个新的Deployment,然后自动控制旧的Deployment中的Pod副本数量逐渐减少到0,同时新的Deployment中的Pod副本数量从0逐步增加到目标值,最终实现了Pod的升级。

注意:系统要求新的Deployment需要与旧的Deployment在相同的命名空间(Namespace)内,即不能把别人的资产偷偷转移到自家名下。

下面的示例在第一次部署时使用httpd:2.2.31,然后使用滚动升级更新到httpd:2.2.32。

定义httpd.yaml文件。

[root@master ~]# cat httpd.yaml

apiVersion: apps/v1beta1

kind: Deployment

metadata:

  name: httpd

spec:

  replicas: 3

  template:

    metadata:

      labels:

        run: httpd

    spec:

      containers:

        - name: httpd

          image: 10.18.4.10/library/httpd:2.2.31

          ports:

            - containerPort: 80

启动Deployment。

[root@master ~]# kubectl create -f httpd.yaml

deployment.apps/httpd created

[root@master ~]# kubectl get pods

NAME                     READY   STATUS    RESTARTS   AGE

httpd-5ddb558f47-46tf5   1/1     Running   0          49s

httpd-5ddb558f47-5dg96   1/1     Running   0          49s

httpd-5ddb558f47-672sk   1/1     Running   0          49s

查看Deployment。

[root@master ~]# kubectl get deployments httpd -o wide

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR

httpd    3/3      3           3        93s    httpd     httpd:2.2.31  run=httpd

可以看到,IMAGES为httpd:2.2.31。

把配置文件中的httpd:2.2.31改为httpd:2.2.32,再次启动。

[root@master ~]# cat httpd.yaml

apiVersion: apps/v1beta1

kind: Deployment

metadata:

  name: httpd

spec:

  replicas: 3

  template:

    metadata:

      labels:

        run: httpd

    spec:

      containers:

        - name: httpd

          image: 10.18.4.10/library/httpd:2.2.32    //将2.2.31更改为2.2.32

          ports:

            - containerPort: 80

[root@master ~]# kubectl apply -f httpd.yaml

deployment.apps/httpd configured

再次查看Deployment。

[root@master ~]# kubectl get deployments httpd -o wide

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR

httpd    3/3      3       3            7m53s   httpd   httpd:2.2.32  run=httpd

查看Deployment的详细信息。

[root@master ~]# kubectl describe deployment httpd

…...

Events:

  Type    Reason             Age   From                   Message

  ----    ------             ----  ----                   -------

  Normal  ScalingReplicaSet  22m   deployment-controller  Scaled up replica set httpd-5ddb558f47 to 3

  Normal  ScalingReplicaSet  15m   deployment-controller  Scaled up replica set httpd-8bdffc6d8 to 1

  Normal  ScalingReplicaSet  14m   deployment-controller  Scaled down replica set httpd-5ddb558f47 to 2

  Normal  ScalingReplicaSet  14m   deployment-controller  Scaled up replica set httpd-8bdffc6d8 to 2

  Normal  ScalingReplicaSet  14m   deployment-controller  Scaled down replica set httpd-5ddb558f47 to 1

  Normal  ScalingReplicaSet  14m   deployment-controller  Scaled up replica set httpd-8bdffc6d8 to 3

  Normal  ScalingReplicaSet  13m   deployment-controller  Scaled down replica set httpd-5ddb558f47 to 0

上面的日志信息就描述了滚动升级的过程:

① 启动一个新版Pod。

② 把旧版Pod数量降为2。

③ 再启动一个新版,数量变为2。

④ 把旧版Pod数量降为1。

⑤ 再启动一个新版,数量变为3。

⑥ 把旧版Pod数量降为0。

这就是滚动的意思,始终保持副本数量为3,控制新旧Pod的交替,实现了无缝升级。

kubectl apply每次更新应用时,kubernetes都会记录下当前的配置,保存为一个revision,这样就可以回滚到某个特定的版本。

创建3个配置文件,内容中唯一不同的就是镜像的版本号。

httpd.v1.yaml:

[root@master ~]# cat httpd.v1.yaml

apiVersion: apps/v1beta1

kind: Deployment

metadata:

  name: httpd

spec:

  revisionHistoryLimit: 10  # 指定保留最近的几个revision

  replicas: 3

  template:

    metadata:

      labels:

        run: httpd

    spec:

      containers:

        - name: httpd

          image: 10.18.4.10/library/httpd:2.2.16

          ports:

            - containerPort: 80

httpd.v2.yaml:

[root@master ~]# cat httpd.v2.yaml

apiVersion: apps/v1beta1

kind: Deployment

metadata:

  name: httpd

spec:

  revisionHistoryLimit: 10  # 指定保留最近的几个revision

  replicas: 3

  template:

    metadata:

      labels:

        run: httpd

    spec:

      containers:

        - name: httpd

          image: 10.18.4.10/library/httpd:2.2.17

          ports:

            - containerPort: 80

httpd.v3.yaml:

[root@master ~]# cat httpd.v3.yaml

apiVersion: apps/v1beta1

kind: Deployment

metadata:

  name: httpd

spec:

  revisionHistoryLimit: 10  # 指定保留最近的几个revision

  replicas: 3

  template:

    metadata:

      labels:

        run: httpd

    spec:

      containers:

        - name: httpd

          image: 10.18.4.10/library/httpd:2.2.18

          ports:

            - containerPort: 80

部署Deployment。

[root@master ~]# kubectl apply -f httpd.v1.yaml --record

deployment.apps/httpd configured

[root@master ~]# kubectl apply -f httpd.v2.yaml --record

deployment.apps/httpd configured

[root@master ~]# kubectl apply -f httpd.v3.yaml --record

deployment.apps/httpd configured

--record的作用是将当前命令记录到revision中,可以知道每个revision对应的是哪个配置文件。

查看Deployment。

[root@master ~]# kubectl get deployments -o wide

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR

httpd    3/3        1           3      31m      httpd   10.18.4.10/library/httpd:2.2.18 run=httpd

查看revision历史记录。

[root@master ~]# kubectl rollout history deployment httpd

deployment.extensions/httpd

REVISION  CHANGE-CAUSE

1         <none>

2         <none>

3         kubectl apply --filename=httpd.v1.yaml --record=true

4         kubectl apply --filename=httpd.v2.yaml --record=true

5         kubectl apply --filename=httpd.v3.yaml --record=true

CHANGE-CAUSE即-record的结果。

执行如下操作,回滚到指定版本revision 1。

[root@master ~]# kubectl rollout undo deployment httpd --to-revision=1

deployment.extensions/httpd rolled back

[root@master ~]# kubectl get deployments -o wide

NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR

httpd    3/3       3            3      35m     httpd    10.18.4.10/library/httpd:2.2.31 run=httpd

再次查看Deployment可以看到httpd版本已经回退了。

查看revision历史记录,可以看到revision记录也发生了变化。

[root@master ~]# kubectl rollout history deployment httpd

deployment.extensions/httpd