DevOpsk8s系列文章--《kubernetes权威指南》学习笔记

k8s系列文章6: 资源对象介绍

2021-03-18  本文已影响0人  特斯拉的交流电很直

  前面的文章已经介绍了用kubeadm搭建一套简单的k8s集群,并在上面运行了一个简单的服务示例。下面介绍一下k8s中比较重要的资源对象:

1. Master

  Master是k8s的控制节点,在每个k8s中,都必须有一个Master负责整个集群的管理和控制,基本上k8s所有的控制命令都发给它。如果Master节点宕机,整个集群都将不能使用。Master节点是k8s的“大脑”。Master节点上运行着以下关键进程:

2. Node

  除了Master节点,k8s集群中的其他机器,无论是虚拟机还是物理机,都是Node节点。每个Node都会被Master分配一些工作负载。Node上运行着以下关键进程:

kubectl get nodes
获取Nodes.png

  然后,通过以下命令查看某个Node的详细信息:

kubectl describe node host-10-5-3-206
Node详细信息

  上述命令展示Node的基本关键信息,如下:

3. pod

pod是k8s最基础重要的基本概念,每个pod都有一个特殊的被称为“跟容器”pause容器。pause容器对应的镜像属于k8s平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的业务容器。 pod的组成示意图

  k8s设计pod的原因如下:

spec:
    containers:
    - name: db
      image: mysql
      resources: 
          requests:  #一般情况下
              memory: "64Mi"
              cpu: "250m"
          limits:      #最大值
              memory: "128Mi" 
              cpu: "500m"

4. Labels

  Lables是k8s系统中另一个核心的概念,一个Label是一个key=value形式的键值对,其中key和value由用户自己指定。Label相当于我们熟悉的标签,通过Label Selector进行选择。Label Selector可以理解成是SQL语句中的where语句。目前有两种Label Selector表达式,分别是分别是:

5. Replication Controller

  RC是k8s系统中的核心概念之一,简单来说,它其实定义了一个期望的场景,即声明某种Pod的副本的数量在任意时刻都符合某个预期值,所以RC定义包括如下几个部分。

apiVersion: v1
kind: ReplocationController
metadata: frontend
spec:
    replicas: 1
    selector: 
        tier: frontend
template:
    metadata:
        labels:
            app: app-demo
            tier: frontend
    spec:
        container:
         - name: tomcat-demo
           image: tomcat
           imagePullPolicy: IfNotPresent
           env:
            - name: GET_HOSTS_FROM
              value: dns
           ports:
           - containerPort: 80

  在定义了一个RC并将其提交到k8s集群中后,Master上的Controller Manager组件就得到通知,定期巡检系统中当前存活的目标Pod,并确保Pod示例的数量刚好等于此RC的期望值,如果有过多的Pod副本的存在运行,系统就会停掉一些Pod,否则系统会自动创建一些Pod。可以说,通过RC,k8s实现了用户应用集群的高可用性,并且大大减少了系统管理员在传统IT环境中需要完成的许多手工运维工作。在运行时,可以通过修改RC的副本数量,来实现Pod的动态缩放(Scaling),这可以通过执行kubectl scale命令来一键完成。

kubectl scale rc redis-slave --replicas=3

  需要注意的是,删除RC并不会影戏那个通过该RC已经创建好的Pod。为了删除所有Pod,可以设置replicas的值为0,然后更新该RC。同时,kubectl提供了stop和delete命令来一次性删除RC和RC控制的全部Pod。RC支持滚动升级。Replication Controller由于与k8s中的Replication Controller同名,k8s在1.2之后,升级为另一个新的概念,Replica Set。官方解释是“新一代的RC”,当前的唯一区别是,Replica Sets支持基于Label selector(Set-based selector),而RC只支持基于等式的Label Selector(equality-based selector),这使得Replica Set的功能更强。下面等价于之前RC例子的Replica Set的定义(省去来Pod模版部分的内容):

apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
    name: frontend
spec:
    selector:
        matchlabels:
            tier: frontend
        matchExpressions:
          - {key: tier, operator: in, values: [frontend]}
    template:
    .....

  当前,我们很少使用Replica Set,它主要被Deployment这个更高级的资源对象所使用,从而形成一整套Pod创建建设、删除、更新的编排机制。Replica Set和Deplotment这两个重要的资源对象逐渐替代了之前的RC,是k8s 1.3里Pod自动弹缩这个告警功能实现的基础。
综上:

6. Deployment

  Deployment是k8s在1.2版本中引入的概念,用于更好地解决Pod的编排问题。从各种角度来看,Deployment和RC的相似度超过90%。Deployment相对于RC的一个最大升级就是我们可以随时知道Pod“部署”的进度。实际上由于一个Pod的创建、调度、绑定节点及在目标Node上启动对应的容器这一完整过程需要一定的时间,所以 我们期待系统启动N个Pod副本的目标状态,实际上是一个连续变化的“部署过程”导致的最终状态。

7. Horizontal Pod Autoscaler

  有的场景下,需要频繁的触发水平扩容和缩容。1.1版本发布了Horizontal Pod Autoscale(HPA),HPA有以下两种方式作为Pod负载的度量指标。

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
    name: php-apache
    namespace: default
spec: 
    maxReplicas: 10
    minReplicas:1
    scaleTargetRef:
        kind: Deplotment
    name: php-apache
    targetCPUUtilizationPercentage: 90

  和上面等价的命令行行为:

kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10

8. StatefulSet

  k8s系统中,Pod的管理对象RC、Deployment、DeamonSet和Job都面向无状态的服务。但是有时候是很多的服务是有状态的,特别是一些有着以下特点的集群:

9. Service

9.1 概述

  Service服务是k8s的核心资源对象之一,k8s里的每个Service其实就是我们经常提起的微服务架构中的一个微服务,之前讲解Pod、RC等资源对象其实都是为讲解k8s Service做铺垫的。K8s的Service定义了一个服务的访问入口地址,前端的应用(Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,Service和其后端Pod副本集群之间则是通过Label Selector来实现无缝对接的。RC的作用实际上是保证Service的服务能力和服务数量始终符合预期标准。K8s的服务之间通过TCP/IP进行通信。k8s发明了一种很巧妙的服务发现和负载均衡机制。Service不是公用一个负载均衡的IP地址,每个Service都被分配了一个全局唯一的的虚拟IP地址,这个虚拟IP被称为Cluster IP地址。服务调用就变成了最基础的TCP网络通信问题。下面是一个tomcat-service的yaml文件:

apiVersion: v1
kind: Service
metadata:
    name: tomcat-service
spec:
    ports: 
    -port: 8000
    selector:
        tier: frontend

  运行下面的内容进行创建:

kubectl create -f tomcat-server.yaml

  运行下面的命令分查看端口和Cluster IP:

kubectl get endpoints
kubectl get svc tomcat-service -o yaml

  在很多服务中,都存在多端口问题,通常一个端口提供业务服务,另一个端口提供管理功能。k8s支持多个Endpoint,但是要求每一个Endpoint都定义一个名称来区分。下面的 例子是Tomcat多端口service的定义示例:

apVersion: v1
kind: Service
metadata: 
    name: tomcat-service
spec:
    ports:
    - port: 8080
    name: service-port
    - port: 8005
    name: shutdown-port
    selector:
        tier: frontend

9.2 k8s的服务发现机制

 &emps;任何分布式系统都会涉及“服务发现”这个基础问题,大部分分布式系统都通过提供特定的API接口来实现服务发现功能,但是这样会导致平台的侵入性比较强,也增加了开发、测试的难度。k8s则采用了直观朴素的思路去解决这个棘手的问题。
  首先,每个k8s中的Service都有唯一的Cluster IP及唯一的名称,而名称是由开发者自己定义的,部署时也没有必要改变,所以完全可以固定到配置中,接下来的问题就是如何通过Service的名称找到对应的Cluster IP。
  k8s通过Add-on增值包引入了DNS系统,将服务名作为域名,这样程序就可以直接使用服务名来建立通信了。后续将会介绍如何部署DNS系统。

9.3 外部系统访问Service的问题

  k8s中有三种IP,弄清他们的区别对于 理解k8s很有必要。

10. Job

  批处理任务通常并行启动多个计算机进程去处理一批工作项,在处理完成后,整个批处理任务结束。从1.2开始,k8s支持批处理类型的应用,可以通过Job这种资源对象定义并启动一个批处理任务的Job。Job控制一组Pod容器,可以将Job看作是一个特殊的Pod副本控制器,同时Job控制Pod副本和RC等控制器的工作机制有以下的区别:

11. Volume

  Volume是Pod中能够被多个容器访问的共享目录。k8s的Volume概念、用途和目的和Docker的Volume比较类似,但是两者不能等价。首先,k8s的volume被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下;其次,k8s的Volume和Pod的生命周期相同,但是与容器的生命周期不相关,当容器终止或者重启时,Volume中的数据并不会丢失,最后,k8s支持多种类型的Volume。使用Volume,必须要现在Pod声明一个Volume,然后在容器中引用该Volume并挂载(Mount)到容器里的某个目录上。定义一个Volume如下:

# Pod的部分内容
template: 
    metadata:
        labels:
            app: app-demo
            tier: frontend
spec:
    volumes:
        - name: detavol
        emptydir: {}
    containers:
    - name: tomcat-demo
    image: tomcat
    volumeMounts:
      - mountPath: /mydata-data
        name: datavol
    imagePullpolicy: IfNotPresent

  除了可以让Pod里的多个容器共享文件、让容器的数据可以写到宿主机的磁盘上或者写文件到网络存储中,k8s的Volume还扩展了一种非常有使用价值的功能,就是容器配置文件的集中化定义与 管理,这是通过ConfigMap这种新的资源对象来实现的。k8s实现了丰富的Volume类型的,如下:

volumes:
    -name: "Persistent-storage"
    hostPath:
        path: "/data"

12. Persistent Volume

  网络存储是相对独立于计算资源而存在的一种实体资源。比如在使用虚拟机的情况下,我们通常会定义一个网络存储,然后从中划出一个“网盘”并挂载到虚拟机上。Persistent Volume(PV)和与之相关联的Persistent Volume chaim(PVC)也起到了类似的作用。PV可以理解成是k8s集群中的某个网络存储对应的一块存储,它与Volume类似,但是有以下区别:
  1.PV只能是网络存储,不属于任何Node,但是可以被任何Node访问
  2.PV并不是被定义 在Pod上的,而是独立于Pod之外定义的
  下面给出一个NFS类型的PV的yaml定义问价,声明需要 5G的空间:

apiVersion: v1
kind: PersistentVolume
metadata:
    name: pv0003
spec:
    capacity:
        storage: 5Gi
    accessModes:
    nfs:
        path: /somepath
        server: 172.17.0.2
  如果某个Pod想要申请某种类型的PV,则首先需要定义一个Persistent VolumeClaim对象:
```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata: 
    name: myclaim
spec:
    accessModes:
      - ReadWriteOnce
    resources:
      requests:
        stoorage: 8Gi

  然后在Pod的Volume定义中引用上述PVC即可

volume:
    - name: mypod
       persistent:VolumeVlaim: 
         claimName: myclaim

  最后说下PV的状态。PV是有状态的对象,它的状态有以下集中
  1.Available:空闲状态
  2.Bound:已经绑定到某个PVC上
  3.Released:对应的PVC已经被删除,但是资源还没有被集群回收
  4.Failed:PV自动回收失败

13. Namespace

  Namespace是k8s系统中另一个非常重要的概念,Namespace在很多情况下用于实现用户的资源隔离。Namespace通过将集群内部的资源对象“分配”到不同的Namespace中,形成逻辑上分组的不同项目、小组或用户组,便于不同的分组在共享整个集群资源的同时还能被分别管理。Namespace的定义很简单:

apiVersion: v1
kind: Namespace
metadata:
    name: development

  一旦创建了Namespace,在创建资源的时候,就可以指定资源对象属于哪个Namespace

apiVersion: v1
kind: Pod
metadata:
    name: busybox
    namespace: development
spec:
     containers:
        - image: busybox
         command:
          - sleep
          - "3600"

14. ConfigMap

  为了解决Docker容器运行时修改配置文件的问题,k8s提供了如下巧妙的实现:
  首先,把所有的配置项当作是key-value字符串。value可以来自某个文本文件。配置参数可以作为Map表中的一个项,整个Map的数据可以被持久化存储在etcd数据库中,然后提供API以方便k8s相关组件或者客户应用CRUD操作这些数据,上述专门用来保存配置参数的Map就是K8s的ConfigMap对象。然后k8s提供一种内建机制,将存储在etcd中的ConfigMap通过Volume映射的方式变成目标Pod内的配置文件,不管目标Pod被调度到哪个服务器上,都会自动映射。

以上是k8s中资源的一个概述,后续将会继续根据资源,逐渐进行深入研究。你 ,学废了吗?

上一篇下一篇

猜你喜欢

热点阅读