kubernetes资源组织、管理介绍

如果已经在kubenetes中部署了应用,并通过service的形式将它暴露出去。接下来呢?kubenetes提供了大量工具帮助用户管理应用的部署、弹性伸缩、升级等。

组织资源配置文件

很多应用要求同时创建多个资源,比如deployment与service等。管理多个相关资源的一种简单的方法是将它们简单的组织在一个文件中(在YAML格式的文件中通过 --- 分隔),如下例:

# https://github.com/kubernetes/website/blob/master/content/en/docs/concepts/cluster-administration/nginx-app.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-svc
  labels:
    app: nginx
spec:
  type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

创建方式与单个资源相同,只需运行一次创建命令即可:

$ kubectl create -f https://k8s.io/docs/concepts/cluster-administration/nginx-app.yaml
service "my-nginx-svc" created
deployment "my-nginx" created

资源会依在配置文件中出现的顺序依次创建,因此,最好首先指定需要创建的service,因为这将确保调度程序能够将与服务相关联的pod展开,因为它们是由控制器创建的,比如deployment。

kubectl create命令支持多个-f选项,如:

$ kubectl create -f https://k8s.io/docs/concepts/cluster-administration/nginx/nginx-svc.yaml -f https://k8s.io/docs/concepts/cluster-administration/nginx/nginx-deployment.yaml

也可指定目录:

$ kubectl create -f https://k8s.io/docs/concepts/cluster-administration/nginx/

kubectl命令会读取目录下所有后缀为.yaml, .yml, or .json的文件。

鼓励实践将相同微服务或者是同层应用的所有配置文件集中放置在一个文件中,或者是将紧密相关的文件放入到同一个目录之下。如果同层应用是通过DNS彼此绑定,那么就可以简单将堆栈中的所以组件一起部署。

*** 还是应该将资源的定义分隔成单独的文件,然后再将相关的文件通过目录的形式组织在一起,避免单个文件内容过大过于复杂。

kubectl批量操作

资源创建并非kubectl命令能实现的唯一批量操作。它也可以从资源配置文件中提取出资源名称实现其它操作,特别是删除指创建的资源:

$ kubectl delete -f https://k8s.io/docs/concepts/cluster-administration/nginx-app.yaml
deployment "my-nginx" deleted
service "my-nginx-svc" deleted

因为只有两个资源,所以直接使用命令行,通过resource/name也很容易实现:

$ kubectl delete deployments/my-nginx services/my-nginx-svc

对于更大的资源数量,可以很容易的通过为命令行指定标签查询选择器过虑出需要操作的资源,如使用-l --selector等选项:

$ kubectl delete deployment,services -l app=nginx
deployment "my-nginx" deleted
service "my-nginx-svc" deleted

因为这种方式是通过标签选择器过虑出符合条件的资源,所以要求严格规范标签的使用,否则容易发生误操作。

kubectl命令执行时需要资源名称,与命令执行后输出的资源名称语法相同,因此很容易利用管道、$()、xargs等技术将之个命令组合在一起,例如:

$ kubectl get $(kubectl create -f docs/concepts/cluster-administration/nginx/ -o name | grep service)
NAME           CLUSTER-IP   EXTERNAL-IP   PORT(S)      AGE
my-nginx-svc   10.0.0.208        80/TCP       0s

上述命令,首先执行kubectl create创建docs/concepts/cluster-administration/nginx/目录下指定的资源,因为指定了-o name选项,输出结果的格式被设定为“resource/name”格式,再通过管理将输出传递给grep命令,将其中的service资源检出,结果作为kubectl get的参数。

也可以通过多层目录组织资源,运行命令时指定--recursive、-R与--filename、-f选项,则命令遍历整个目录,实现对所有资源的批处理。假设存在着如下目录:

project/k8s/development
├── configmap
│   └── my-configmap.yaml
├── deployment
│   └── my-deployment.yaml
└── pvc
    └── my-pvc.yaml

当执行如一命令时会报错,原因是默认情况下只处理目录的第一次,不会深入处理目录下的子目录:

$ kubectl create -f project/k8s/development
error: you must provide one or more resources by argument or filename (.json|.yaml|.yml|stdin)

指定--recursive 或者 -R,则会遍历目录及其下的所有子目录:

$ kubectl create -f project/k8s/development --recursive
configmap "my-config" created
deployment "my-deployment" created
persistentvolumeclaim "my-pvc" created

高效使用标签

在现实的使用场景中,一个资源往往需要加入多个标签,以便从不同的维度上将资源划归到不同的集合中。例如gustbook中前端:

     labels:
        app: guestbook
        tier: frontend

两个标签分别标识资源的app各类与所属的层级。

Redis中的master:

     labels:
        app: guestbook
        tier: backend
        role: master

Redis中的slave:

     labels:
        app: guestbook
        tier: backend
        role: slave

用“role”标签区分master与slave角色。

通过指定标签从不同的维度组织资源:

$ kubectl create -f examples/guestbook/all-in-one/guestbook-all-in-one.yaml
$ kubectl get pods -Lapp -Ltier -Lrole
NAME                           READY     STATUS    RESTARTS   AGE       APP         TIER       ROLE
guestbook-fe-4nlpb             1/1       Running   0          1m        guestbook   frontend   
guestbook-fe-ght6d             1/1       Running   0          1m        guestbook   frontend   
guestbook-fe-jpy62             1/1       Running   0          1m        guestbook   frontend   
guestbook-redis-master-5pg3b   1/1       Running   0          1m        guestbook   backend    master
guestbook-redis-slave-2q2yf    1/1       Running   0          1m        guestbook   backend    slave
guestbook-redis-slave-qgazl    1/1       Running   0          1m        guestbook   backend    slave
my-nginx-divi2                 1/1       Running   0          29m       nginx            
my-nginx-o0ef1                 1/1       Running   0          29m       nginx            
$ kubectl get pods -lapp=guestbook,role=slave
NAME                          READY     STATUS    RESTARTS   AGE
guestbook-redis-slave-2q2yf   1/1       Running   0          3m
guestbook-redis-slave-qgazl   1/1       Running   0          3m

金丝雀部署

标签的一个使用场景是区分同一个组件的不同发布版本或者配置版本,常见的实践是用标签实现金丝雀部署。例如,使用“track”标签标识同一组件的不同版本。对于主力、稳定版本,“track”标签的值为“stable”。

     name: frontend
     replicas: 3
     ...
     labels:
        app: guestbook
        tier: frontend
        track: stable
     ...
     image: gb-frontend:v3

对于新发布版本,“track”标签的值为“canary”。

     name: frontend-canary
     replicas: 1
     ...
     labels:
        app: guestbook
        tier: frontend
        track: canary
     ...
     image: gb-frontend:v4

这样,同一个组件的两种版本同时存在,使用的image不同,不同版本的实例通过“track”标签的值加以区分。前端服务的选择器通过指定两种版本的共有标签从面包含组件的不同版本,如下:

  selector:
     app: guestbook
     tier: frontend

可以调整稳定版与测试版副本的数据,从而决定两者所处理的流量比例。经过一定时间的测试后,如果没有问题。则可以将所有“track”为“stable”的实例升级成最新版本,并将“track”为“canary”的实例删除,从而完成版本升级。如果出现问题,只需将“canary”版本的实例删除即可。

更新标签

用kubectl label命令对已经存在的Pod或者其它资源重新打标签,如下:

$ kubectl label pods -l app=nginx tier=fe
pod "my-nginx-2035384211-j5fhi" labeled
pod "my-nginx-2035384211-u2c7e" labeled
pod "my-nginx-2035384211-u3t6x" labeled

以上命令中-l app=nginx表示过滤条件,检出系统中所有app为nginx的组件,后边的tier=fe表示对检出的资源重新打上标签。确认结果:

$ kubectl get pods -l app=nginx -L tier
NAME                        READY     STATUS    RESTARTS   AGE       TIER
my-nginx-2035384211-j5fhi   1/1       Running   0          23m       fe
my-nginx-2035384211-u2c7e   1/1       Running   0          23m       fe
my-nginx-2035384211-u3t6x   1/1       Running   0          23m       fe

以上命令输出所有符合“app=nginx”条件的Pod,-L tier指示在输出结果中添加额外的列显示tier标签内容。

更新注解

注解属于注释性、非标识性的元数据,对已存在的资源追加注解的方式如下:

$ kubectl annotate pods my-nginx-v4-9gw19 description='my frontend running nginx'
$ kubectl get pods my-nginx-v4-9gw19 -o yaml
apiversion: v1
kind: pod
metadata:
  annotations:
    description: my frontend running nginx
...

应用伸缩

通过kubectl scale调整实例个数,将nginx实例的副本数据从3减少到1:

$ kubectl scale deployment/my-nginx --replicas=1
deployment "my-nginx" scaled

目前只有一个nginx的Pod实例:

$ kubectl get pods -l app=nginx
NAME                        READY     STATUS    RESTARTS   AGE
my-nginx-2035384211-j5fhi   1/1       Running   0          30m

kubenetes支持设置副本数量的最小值与最大值,系统根据实例的负载情况,在最大值与最小值之间动态动态调整副本数量实现自动伸缩。

$ kubectl autoscale deployment/my-nginx --min=1 --max=3
deployment "my-nginx" autoscaled

就地更新资源

有时候,对于已经创建的资源,需要进行精确的、无破坏性的更新。解释:前文中所涉及的更新方法,属于kubectl管理对象三种方法中的“祈使对象配置”,在有些情况下,这种更新方式会产生破坏性。

推荐的管理配置文件的方式是与版本控制系统集成,与GIT,然后通过kubectl apply将GIT中的配置文件应用到集群中,从而实现配置文件与集群中实时配置的版本控制。kubectl apply命令本质上是计算配置文件与系统中实时对象配置的差值,再通过补丁的形式将这种差值应用到系统中,而不是从整体上替换掉系统中的配置,这样不会丢失那么独立于配置的属性从而避免破坏性更新。

$ kubectl apply -f docs/concepts/cluster-administration/nginx/nginx-deployment.yaml
deployment "my-nginx" configured

注意,kubectl apply管理资源的方法称为“声明对象配置”,其在系统中的实时对象,在其注解中会保存一份历史配置。当对这个对象更新时,系统参考配置文件、实时对象注解、实时对象在系统中的实际配置三个方面的计算,最后决定如何更新对象。

前文涉及到的资源通过kubectl create -f形式创建,这种方法称为“祈使对象配置”,系统中的实时对象没有包含历史配置的注解,需要通过一定的方法将资源的管理从“祈使对象配置”迁移到“声明对象配置”,推荐方法:

$ kubectl edit deployment/my-nginx

或者:

$ kubectl get deployment my-nginx -o yaml > /tmp/nginx.yaml
$ vi /tmp/nginx.yaml
# do some edit, and then save the file
$ kubectl apply -f /tmp/nginx.yaml
deployment "my-nginx" configured
$ rm /tmp/nginx.yaml

破坏性更新

系统中实时对象的某些属性独立于配置文件变化,破坏性更新的本质是忽略掉这些属性的变更,首先将实时对象的配置从系统中删然后再将新的配置文件应用到系统中,如下:

$ kubectl replace -f docs/concepts/cluster-administration/nginx/nginx-deployment.yaml --force
deployment "my-nginx" deleted
deployment "my-nginx" replaced

更新应用时不中断服务

例如首先执行如下命令:

$ kubectl run my-nginx --image=nginx:1.7.9 --replicas=3
deployment "my-nginx" created

kubectl run命令属于kubectl管理对象三种方式中的“祈使命令”方式。以上命令会创建一个deploment类型的Pod,副本数据为3,实例镜像为nginx:1.7.9。如果打算将nginx版本从1.7.9升级到1.9.1,执行如下命令:

$ kubectl edit deployment/my-nginx

在编辑器中将.spec.template.spec.containers[0].image的值由nginx:1.7.9改成nginx:1.1.1即可。kubenetes系统检测到配置变化后会逐升级副本,始终有可用的实例从而保证服务不中断。

参考文档:https://kubernetes.io/docs/concepts/cluster-administration/manage-deployment/

你可能感兴趣的:(kubernetes)