节点角色

master

组件列表:

  • API Server: crud 操作, http rest,整个集群的对外接口,集群的“营业厅”

  • Controller Manager: 所有资源对象的自动化控制中心, 资源对象的 “大总管”

  • Scheduler:负责资源( Pod 调度)的进程,公交公司的“调度室”

  • ETCD: 资源对象数据都保存在 ETCD 中

node

也叫 Minion,集群中的工作负载节点,如果 Node01 挂了,工作负载会被 Master 自动转移到其他的 Node 节点。 每一个 Node 上都运行下面组件:

  • Kubelet: 负责 Pod 对应的容器的创建,启动停止,Master 协作

  • Proxy: 实现 kubernetes service 的通信与负载均衡机制

  • Docker Engine(dockerd): 负责本机的容器创建于管理

kubelet 会向 Master 注册自己,注册成功后定期向 Master 回传情况:操作系统,docker版本,cpu、ram 等使用情况

资源对象

pod

基本概念

Pod 是 Kubernetes 最重要的基本概念,每一个 Pod 都有一个特殊的被称为 “根容器“ 的 Pause 容器( Infra容器)gcr.io/google_containers/pause-amd64:3.1。除了 Pause 容器以外 Pod 中还包含一个或多个业务容器。 pause容器的PID是1。而在kubernetes中容器的PID=1的进程即为容器本身的业务进程。

为什么需要 Pod?

  • 可以简化一组容器作为一个单元的检测

  • Pod 内的多个容器共享 Pause 的 IP,共享 Pause 容器挂载的 Volumn

Pod 分类: - 普通 Pod:通过 集群调度的 Pod - 静态 Pod:work Node 上指定启动的,数据不存在 ETCD 中

Pod 与 Controller Pod 不会自愈。如果 Pod 运行的 Node 故障,或者是调度器本身故障,这个 Pod 就会被删除。同样的,如果 Pod 所在 Node 缺少资源或者 Pod 处于维护状态,Pod 也会被驱逐。Kubernetes 使用更高级的称为 Controller 的抽象层,来管理 Pod 实例。虽然可以直接使用Pod,但是在Kubernetes中通常是使用 Controller 来管理 Pod 的。 Controller 可以创建和管理多个 Pod,提供副本管理、滚动升级和集群级别的自愈能力。例如,如果一个 Node 故障,Controller 就能自动将该节点上的 Pod 调度到其他健康的 Node 上。包含一个或者多个 Pod 的 Controller 示例:Deployment、StatefulSet、DaemonSet 通常, Controller 会用你提供的 Pod Template 来创建相应的 Pod。

pod-yaml:

apiVersion: v1
kind: Pod # 表示这是一个 Pod 的资源类型
metadata:
  name: busybox # Pod 的名称,在 metadata 里面还可以定义资源对象的标签
  labels: test
spec:
  containers:
  - name: busybox
    image: reg.test.k8s/library/busybox:1.24
    command: ["/bin/sh", "-c", "env | grep -i APP"]
    command: ["sleep", "10000000"]
    env:
    - name: K
      values: 'V'
  restartPolicy: Never
  • Endpoint: Pod-IP:containerPort, 代表此 Pod 里的一个服务进程对外的通信地址

  • Volumn

  • EVENT

  • resource requests&limit

Label

相当于打上一个标签,在使用 label-selector 查询和筛选拥有某些 Label 的资源对象, kubernetes 使用这种方式来实现类似于 类似于 SQL 的 where 条件, 例如 release=dev -> select * from pod where release = 'dev'. 目前有两种 label selector 表达式:

  • 基于等式

name = redis-slave
env != production
  • 基于集合

name in (redis-master, redis-slave)
env not in (production)

也可以通过多个 Label selector 表达式实现复杂的条件选择, 多个表达式之间使用"," 进行分割, 几个条件之间是逻辑 and 关系

download-api

  • 通过 env

  • 通过 volumn

  • print

pod 的生命周期与重启策略

Pod 状态

  • Pending: API Server 已经创建该 Pod, 但是在 Pod 内还有一个或者多个容器的镜像没有创建(包含正在下载镜像的过程)

  • Running: Pod 内所有容器均已创建,并且只有有一个容器处于运行状态、正在启动状态或者重启状态

  • Succeeded: Pod 内所有容器均成功执行后推出,且不会重启

  • Failed: Pod内所有的容器均已退出,至少有一个容器退出为失败状态

  • Unknown: 由于某周原因无法获取该 Pod 的状态, 可能由于网络通信?

重启策略

重启策略应用于 Pod 内的所有容器,并且仅在 Pod 所处的 Node 上由 Kubelet 进行判断和执行重启操作。 当容器一场退出或者健康检查失败,kubelet 根据 RestartPolicy 的设置操作:

  • Always: 当容器失效时( default )

  • Onfailure: 当容器终止运行且 exit code != 0 时

  • Never: 不用解释了...

健康检查

  • LivenessProbe: 用于判断容器是否存活( running ), 如果不探针监测到容器不健康,kubelet 将 kill 这个容器,根据容器的重启策略做对应的处理

  • ReadinessProbe: 用于判断容器的服务是否可用 ( Ready ), 达到 Ready 状态的 Pod 才可以接受请求。 对于被 Service 管理的 Pod,Service 与 Pod Endpoint 的关联关系也会基于 Pod 是否 Ready,进行设置, 如果 ready 为 false service将其从后端的 Endpoint 列表隔离

三种实现方式
  • ExecAction

  • TCPSocketAction

  • HTTPGetAction

Replica Sets

基本概念

定义了一个期望的场景,声明这个场景下 需要什么样的 Pod 和 Pod 副本数量应该是多少。

创建完毕的 RS 提交到 Kubernetes 集群后, Master 上的 Controller Manager 组件就会定期检查系统中当前的存活的目标 Pod, 并确保 Pod 实例的数量刚好等于 RS 的期望值。

  • Pod 期待的副本数

  • 筛选目标的 Label Selector

  • Pod 副本数低于预期的时候,用于创建 Pod 的模版

大多数情况下,我们也不会创建 ReplicaSets, 它主要被 Deployment 所使用

Deployment

基本概念

Deployment 内部使用 ReplicaSet 实现目的,在 RC 基础上升级了对当前 Pod 部署的进度。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: app-demo
        tier: frontend
    spec:
      containers:
      - name: tomcat-demo
        image: tomcat
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

[root@k8s-master01 pod]# kubectl get deploy -o wide
NAME    READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
nginx   2/2     2            2           25h   nginx        nginx    run=lb-example
#  READY: 2/2 表示 current/desired; UP-TO-DATE: 2 用于指示在滚动升级过程中,有多少个 Pod 副本已经升级成功

Deployment 的使用场景:

  • 创建一个 Deployment 对象来生成对应的 RS ,完成 Pod 副本的创建

  • 检查 Deployment 的状态来看部署是否完成

  • 更新 Deployment 创建新的 Pod (升级) ........

StatefulSet

基本概念

StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括

  • 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现

  • 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现

  • 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现

  • 有序收缩,有序删除(即从N-1到0)

# svc
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
 # sts
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: gcr.io/google_containers/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
      annotations:
        volume.alpha.kubernetes.io/storage-class: anything
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi

DaemonSet

基本概念

DaemonSet保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:

  • 日志收集,比如fluentd,logstash等

  • 系统监控,比如Prometheus Node Exporter,collectd,

  • 系统程序,比如kube-proxy, kube-dns, glusterd, ceph等

Service

Kubernetes Pod 是有生命周期的,它们可以被创建,也可以被销毁,然而一旦被销毁生命就永远结束。 通过 ReplicationController 能够动态地创建和销毁 Pod。 每个 Pod 都会获取它自己的 IP 地址,即使这些 IP 地址不总是稳定可依赖的。

这会导致一个问题:在 Kubernetes 集群中,如果一组 Pod(称为 backend)为其它 Pod (称为 frontend)提供服务,那么那些 frontend 该如何发现,并连接到这组 Pod 中的哪些 backend 呢?关于 ServiceKubernetes Service 定义了这样一种抽象:一个 Pod 的逻辑分组, 这一组 Pod 能够被 Service 访问到,通常是通过 Label Selector(查看下面了解,为什么可能需要没有 selector 的 Service)实现的。举 对非 Kubernetes 集群中的应用,Kubernetes 提供了基于 VIP 的网桥的方式访问 Service,再由 Service 重定向到 backend Pod。

  • 有 selector 的 service

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  • 没有 selector 的service

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 1.2.3.4
    ports:
      - port: 9376