一、对象模型总览



k8s可以看做是面向对象的,每类服务可看做是k8s的一个对象。这些对象由用户定义yaml,k8s的api负责创建。所有对象包含spec(规范)+status两类基本信息。

例如:k8s创建pod的api为: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#pod-v1-core

kubectl 也会将yaml转成json发送到master节点。



k8s中常用的对象有pod、deployment、service、statefulSet等,每个对象至少包含3个metadata:namespace、name、uid。


kubernetesrancher 如何指定pod的节点 kubernetes pod yaml_java



二、k8s中常见的object kind



  • pod
  • 基本调度单元,特定关系的一组容器集合,最小的部署集合。
  • 非持久性实体,调度失败、自愈等情况会被终止,重建,不建议手动创建Pod,而是通过controller创建pod,如deployment。
  • Service
  • pod 重启之后ip会改变,多个相同服务的pod需要有discovery+loadbalance 。这一点与“微服务”中的概念一致。通过label selector 可轻松实现逻辑分组。
  • service 的声明周期内,ip不会改变。可通过nodeport 暴露到外部。
  • 有的service不需要ip、有的service 不需要负载均衡。
  • Controllers
  • Replicaset (rs)副本数,用于loadbalance和冗余。(老版本是ReplicationController- rc,算是功能升级,官方推荐使用rs 代替rc)。现阶段非特殊情况如升级pod的操作,也不推荐单独使用,
  • Deployment

使用并管理rs ,算是更高一层的概念,这是现在比较常用的部署app的方式。deployment为pod和rs提供声明式更新(而非命令式)。支持滚动更新(rollingUpdate),支持回滚操作。



kubernetesrancher 如何指定pod的节点 kubernetes pod yaml_数据库_02


statefulSet(k8s 1.9 GA)

我们自己开发的应用一般都是stateless的,像是redis、zk、kafka、mysql这类的中间件通常需要使用statefulSet。通常适用于稳定的持久存储、稳定的网络标识、有序部署有序扩展、有序收缩、有序滚动升级的场景。

pod的存储一般都是volumes外挂到persistent介质。并且伸缩或删除不会删除关联的存储。需要headless service负责pod的网络身份。

<font color=red size=1> "注意:statefulSet 对应的service为headless servie,和普通的service的区别在于,普通的有cluster ip,通过只有service 有dns,通过iptables进行负载。headless service无cluster ip,endpoints是所有pod的dns地址。就意味着statefulset 创建pod的时候为pod生成了dns信息。如3 节点的mysql,会生成mysql-0 ... mysql-2三个pod(pod名称生产规则为pod+递增序号),并且会生成域: $(podname).(headless server name),完整FQDN为: $(podname).(headless server name).namespace.svc.cluster.local" </font>

看一个完整的statefulSet + headless service 的示例。



apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.11
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
      nodeSelector:
        node: kube-node3
      volumes:
        - name: www
          hostPath:
            path: /mydir



  • DeamonSet
    每个node都有一个pod副本运行。常用在后台常驻程序如ceph,日志收集,心跳检查,Prometheus exporter等。
  • ConfigMap
    向pod 提供非敏感的配置信息,支持键值对,单个属性,配置文件。
    使用方式:环境变量,容器命令行参数,数据卷挂载。
    定义示例:



apiVersion:V1
kind:ConfigMap
metadata:
    name:hello-config
    namespace:public-config
data:
    title:hello everybody
    sex:girl

引用示例:

apiVersion:V1
kind:deployment
metadata:
    name:hello-dem
spec:
    containers:
    - name:goodboy
        image:hub/images
        command:["/bin/bash","-c","echo ${envTitle} ${envSex}"]
        env:
            - name:envTitle
              valueFrom:
                configMapKeyRef:
                    name:hello-config
                    key:title
            - name:envSex
        valueFrom:
            configMapKeyRef:
                name:hello-config
                key:sex



  • Secret
    对应于ConfigMap,用于敏感信息配置,如token,密码,秘钥等。
  • Endpoints
    service 和 pod 之间的关系会创建endpoint对象,默认与service 同名。kube-proxy将会监听service 和 endpoint的变化,从而更新iptables的规则。
  • PodDisruptionBudget(pdb,主动驱逐保护)
  • 没有pdb。当进行节点维护时,如果某个服务的多个pod在该节点上,则节点的停机可能会造成服务中断或者服务降级。举个例子,某服务有5个pod,最低3个pod能保证服务质量,否则会造成响应慢等影响,此时该服务的4个pod在node01上,如果对node01进行停机维护,此时只有1个pod能正常对外服务,在node01的4个pod迁移过程中,就会影响该服务正常响应;
  • pdb能保证应用在节点维护时不低于一定数量的pod运行,从而保持服务质量;
  • 等等其他的如 ingress





三、 k8s中有常见的metadata



  • name && UID (uid是在k8s的整个声明周期中均唯一,不会产生相同的uid,可对等为mysql的auto increment key)
    来看一个api访问对象的路径:/api/{version}/namespaces/{namespace}/{object-kind}/{name} ,k8s通过层层限定来寻找唯一标识的name。
  • namespace
    对一组资源和对象的抽象集合,从逻辑上划分k8s实现分层管理,并实现一定层度上的资源和权限隔离。
    内置三个namespace:default,kube-system(存放api-server、dns插件等),kube-public(供所有用户包含未经过身份验证的用户使用,实现资源集群内共享)
    Node和persistentVolume(简称PV,通过PVC和pod绑定)不属于任何namespace。
  • label
    标识性的数据,有严格的命名规范,k8s可通过标签组合管理对象,达到松耦合。在spec中通过selectors进行匹配。
  • annotation(理解为java注释吧)
    非标识性的元数据附加到对象上。通常会有时间戳,版本号,用户信息等辅助信息。




四、k8s spec中常见的参数

  • selectors(标签和标签选择器)
    对应label对应的key-value 进行对象的选择



K8S的ip模型



k8s的ip:

  • node Ip :node节点的ip,为物理ip.
  • pod Ip:pod的ip,即docker 容器的ip,为虚拟ip。
  • cluster Ip:service 的ip,为虚拟ip。提供一个集群内部的虚拟IP以供Pod访问。


六、k8s的volume

k8s的volume和docker有所不同,v是独立于容器的,与pod声明周期相同,即pod删除空间也被删除。有多重类型

  • emptydir
    空目录,pod中的容器会共享此目录
    如下所示,busybox的文件写入,在nginx容器中能够读出来。



[root@master ~]# cat test.yaml 
apiVersion: v1
kind: Service
metadata:
  name: serivce-mynginx
  namespace: default
spec:
  type: NodePort
  selector:
    app: mynginx
  ports:
  - name: nginx
    port: 80
    targetPort: 80
    nodePort: 30080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy
  namespace: default
spec:
  replicas: 1
  selector: 
    matchLabels:
      app: mynginx
  template:
    metadata:
      labels:
        app: mynginx
    spec:
      containers:
      - name: mynginx
        image: lizhaoqwe/nginx:v1
        volumeMounts:
        - mountPath: /usr/share/nginx/html/
          name: share
        ports:
        - name: nginx
          containerPort: 80
      - name: busybox
        image: busybox
        command:
        - "/bin/sh"
        - "-c"
        - "sleep 4444"
        volumeMounts:
        - mountPath: /data/
          name: share
      volumes:
      - name: share
        emptyDir: {}