[toc]

# 1. 概念

这里记录下K8s的几个核心概念。

# 1.1. pod

PodKubernetes 创建或部署的最小/最简单的基本单位,一个Pod代表集群上正在运行的一个进程。

一个Pod由一个或多个容器组成,Pod中容器共享网络、存储和计算资源,在同一台Docker主机上运行。

为什么要使用pod,为什么不能直接使用容器呢?使用pod,相当于一个逻辑主机,还记得创建一个vm,在vm上运行几个进程么,其实道理是一样的,pod的存在主要是让几个紧密连接的几个容器之间共享资源,例如ip地址,共享存储等信息。如果直接调度容器的话,那么几个容器可能运行在不同的主机上,这样就增加了系统的复杂性。

# 1.2. Pod 控制器

# 1.2.1. Deployment

无状态应用部署。Deployment 的作用是管理和控制PodReplicaset, 管控它们运行在用户期望的状态中。

# 1.2.2. Replicaset

确保预期的Pod副本数量。Replicaset 的作用就是管理和控制Pod,管控他们好好干活。 但是,Replicaset 受控于Deployment

可以理解成 Deployment 就是总包工头,主要负责监督底下的工人Pod干活,确保每时每刻有用户要求数量的Pod在工作。如果一旦发现某个工人Pod不行了,就赶紧新拉一个Pod过来替换它。而 ReplicaSet 就是总包工头手下的小包工头。

从K8S使用者角度来看,用户会直接操作 Deployment 部署服务,而当 Deployment 被部署的时候,K8S 会自动生成要求的 ReplicaSetPod。用户只需要关心 Deployment 而不操心 ReplicaSet

资源对象Replication ControllerReplicaSet 的前身,官方推荐用 Deployment 取代 Replication Controller 来部署服务

# 1.2.3. Daemonset

确保所有节点运行同一类Pod,保证每个节点上都有一个此类Pod运行,通常用于实现系统级后台任务。

# 1.2.4. Statefulset

有状态应用部署

# 1.2.5. Job

一次性任务。根据用户的设置,Job管理的Pod把任务成功完成就自动退出了

# 1.2.6. Cronjob

周期性计划性任务

# 1.3. Label

标签,是K8S特色的管理方式,便于分类管理资源对象。

Label可以附加到各种资源对象上,例如NodePodServiceRC等,用于关联对象、查询和筛选。

一个Label是一个 key-value 的键值对,其中 keyvalue 由用户自己指定。

一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象中,也可以在对象创建后动态添加或者删除。可以通过给指定的资源对象捆绑一个或多个不同的Label,来实现多维度的资源分组管理功能。

# 1.4. Label选择器(Label selector )

给某个资源对象定义一个Label, 就相当于给它打了一个标签,随后可以通过标签选择器(Label selector) 查询和筛选拥有某些Label的资源对象。

标签选择器目前有两种:基于等值关系(等于、不等于)和基于集合关系(属于、不属于、存在)。

# 1.5. Service

在K8S的集群里,虽然每个Pod会被分配一个单独的IP地址,但由于Pod是有生命周期的(它们可以被创建,而且销毁之后不会再启动),随时可能会因为业务的变更,导致这个IP地址也会随着 Pod 的销毁而消失,Service就是用来解决这个问题的核心概念。

K8S中的 Service 并不是我们常说的“服务”的含义,而更像是网关层,可以看作一组提供相同服务的Pod的对外访问接口、流量均衡器,Service 作用于哪些Pod,是通过标签选择器来定义的。

在K8S集群中,Service 可以看作一组提供相同服务的 Pod 的对外访问接口。客户端需要访问的服务就是 Service 对象。每个Service都有一个固定的虚拟IP (这个IP也被称为Cluster IP) ,自动并且动态地绑定后端的Pod, 所有的网络请求直接访问 Service 的虚拟IP,Service会自动向后端做转发。

Service除了提供稳定的对外访问方式之外,还能起到负载均衡(Load Balance) 的功能,自动把请求流量分布到后端所有的服务上,service可以做到对客户透明地进行水平扩展(scale)。

而实现 service 这一功能的关键, 就是kube-proxykube-proxy运行在每个节点上,监听API Server中服务对象的变化,可通过以下三种流量调度模式: userspace (废弃)、iptables (濒临废弃)、ipvs (推荐,性能最好)来实现网络的转发。

Service是K8S服务的核心,屏蔽了服务细节,统一对外暴露服务接口, 真正做到了“微服务”。比如我们的一个服务A,部署了3个副本,也就是3个Pod;对于用户来说,只需要关注一个 Service 的入口就可以,而不需要操心究竞应该请求哪一个Pod

优势非常明显,一方面外部用户不需要感知因为Pod上服务的意外崩溃、 K8S 重新拉起 Pod 而造成的IP变更,外部用户也不需要感知因升级、变更服务带来的Pod替换而造成的IP变化。

# 1.6. Ingress

Service主要负责K8S 集群内部的网络拓扑,那么集群外部怎么访问集群内部呢?这个时候就需要Ingress了。

Ingress是整个K8S集群的接入层,负责集群内外通讯。Ingress是 K8S 集群里工作在OSI网络参考模型下,第7层的应用,对外暴露的接口,典型的访问方式是http/https

Service只能进行第四层的流量调度,表现形式是ip+portIngress则可以调度不同业务域、不同URL访问路径的业务流量。比如:客户端请求http://www.qq.com: port ---> Ingress ---> Service ---> Pod

# 1.7. Name

由于K8S内部,使用“资源”来定义每一种逻辑概念(功能),所以每种“资源”,都应该有自己的“名称”。

“资源”有api版本(apiversion) 、类别(kind)、元数据(metadata) 、定义清单(spec)、状态(status) 等配置信息。

“名称”通常定义在“资源”的“元数据”信息里。在同一个 namespace 空间中必须是唯一的。

# 1.8. Namespace

随着项目增多、人员增加、集群规模的扩大,需要一种能够逻辑上隔离K8S内各种“资源"的方法,这就是Namespace

Namespace是为了把一个K8S集群划分为若千个资源不可共享的虚拟集群组而诞生的。不同 Namespace 内的“资源”名称可以相同,相同 Namespace 内的同种“资源”, “名称”不能相同。

合理的使用K8S的 Namespace,可以使得集群管理员能够更好的对交付到K8S里的服务进行分类管理和浏览。K8S里默认存在的 Namespace 有: defaultkube-systemkube-public 等。

# 2. yaml示例

Deployment 配置如下,有 labelsportsreplicas 等。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment.nginx.the.test.com
spec:
  minReadySeconds: 0
  replicas: 1
  strategy:
    type: RollingUpdate
  selector:
    matchLabels:
      k8s-app: deployment.nginx.the.test.com
  template:
    metadata:
      labels:
        k8s-app: deployment.nginx.the.test.com
    spec:
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      nodeSelector: {}
      dnsPolicy: ClusterFirst
      containers:
        - name: nginx
          image: the/image:123-1
          ports:
            - name: container
              containerPort: 80
              protocol: TCP
          volumeMounts:
            - name: corefile
              mountPath: /data/corefile
              readOnly: false
            - name: logs
              mountPath: /data/logs
              readOnly: false
      volumes:
        - name: corefile
          hostPath:
            path: /data/corefile
        - name: logs
          hostPath:
            path: /data/logs
      imagePullSecrets:
        - name: nes-fe-secret

Service 配置如下,有 ports 等。

apiVersion: v1
kind: Service
metadata:
  name: service-nginx-some-test-com
  labels: {}
  annotations: {}
spec:
  type: NodePort
  selector:
    k8s-app: deployment.nginx.the.test.com
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: container
      nodePort: 0

Ingress 配置如下,有 hostshttp 等。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-the.test.com-0
  annotations:
    kubernetes.io/ingress.class: xxxcloud
    kubernetes.io/ingress.existLbId: xxx
spec:
  tls:
    - hosts:
        - the.test.com
      secretName: the.test.com.cert
  rules:
    - host: the.test.com
      http:
        paths:
          - path: /
            backend:
              serviceName: service-nginx-some-test-com
              servicePort: 80

# 3. 参考