Skip to content

基础概念

Kubernetes 基本概念

Kubernetes 由多种对象组成,每种对象都有自己的作用,其中最常用的有 pod,deployment,service,secret,namespace,statefulset,daemonset,cronjob 等等

Pod

Pod 是 kuber 中最基本的概念, 是 Kubernetes 调度管理的基本单位,是一组紧密相关联的容器集合。它内部包含一个或多个紧密相关的用户业务容器,同时还包含一个 pause 容器。 Pod 的设计理念是支持多个容器在一个 pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。

Pod 的特征:

  • 包含多个共享 IPC 、 Network 和 UTC namespace 的容器,可直接通过 Localhost 通信
  • Pod 内的所有容器都可以访问共享的 Volume ,可以访问共享数据
  • 无容错性:直接创建的 Pod 一旦被调度后就跟 Node 绑定,及时 Node 挂掉也不会被重新调度,而是被自动删除,因此推荐使用 Deployment 、 Daemonset 等控制器来容错
  • 优雅终止:Pod 删除的时候先给其内的进程发送 SIGTERM ,等待一段时间后才发送 SIGKILL 来强制停止还在运行的进程
  • 特权容器:通过 SecurityContext 配置具有改变系统配置的权限的容器,该特性在网络插件中大量应用

通常很少会直接在 k8s 中创建单个 Pod 。因为 Pod 的生命周期是短暂的,用后即焚的实体。当 Pod 被创建后(不论是由你直接创建还是被其他 Controller ),都会被 Kuberentes 调度到集群的 Node 上。直到 Pod 的进程终止、被删掉、因为缺少资源而被驱逐、或者 Node 故障之前这个 Pod 都会一直保持在那个 Node 上。

Namespace

Namespace 是对一组资源和对象的抽象集合,比如可以用来将系统内部对象划分为不同的项目组或用户组。 Namespace 常用来隔离不同的用户,比如 Kubernetes 自带的服务一般运行在名为 kube-system 的 Namespace 下。
常见的 Pod 、 Service 、 Deployment 等都是属于某一个 Namespace 的,而 Node 、 Persistent Volume 等资源则不属于任何 Namespace 。

apiVersion: v1
kind: Namespace
metadata:
  name: new-namespace

Replication Controller

Replication Controller(RC)是 pod 副本管理器。在定义时需提供三个部分,一个是 pod 期待的副本数,一个是筛选 pod 的 label selector ,另一个是用于创建 pod 副本的模板( template )。RC 可以在运行时修改 pod 数量。删除 RC 不会影响 RC 创建好的 Pod 。
此外还有 ReplicaSet ,它是 RC 的更新版本,增加了支持集合的 Selector 。

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80

Deployment

Deployment 是 RC 的升级,使用了 ReplicaSet 来实现目的。它增加了 Pod 部署进度的查询功能。比 RC 要更加方便使用。 Deployment 为 Pod 和 ReplicSet 提供了一个声明式定义方法,用来替代 RC 来方便地管理应用。
Deployment 的典型应用场景包括:

  • 创建 Pod 和 ReplicaSet
  • 滚动升级和回滚应用
  • 扩容和缩容
  • 暂停和继续业务部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
        ports:
        - containerPort: 80

Service

Service 是提供给客户的一个微服务,它由多个 pod 构建的集群, selector 以及 RC 组建而成。前端应用通过 service 提供的访问地址访问它的 pod , service 与 pod 之间由 selector 进行无缝对接,而 RC 用于保证 service 的质量与能力。它是分布式集群架构的核心,它有唯一的指定名,一个虚拟 ip ,能够提供某种远程服务,由一组能够提供该能力的容器们映射。常基于socket 来通信。
借助 Service ,应用可以方便地实现服务发现与负载均衡,并实现应用的零宕机升级。

Service 有四种类型:

  • ClusterIP:默认类型,自动分配一个仅集群内部可以访问的虚拟 IP
  • NodePort:在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过该端口来访问服务
  • LoadBalancer:在 NodePort 的基础上,借助云提供商创建一个外部的负载均衡器,并将请求转发到 NodePort 上
  • ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名

用户也可以将已有的服务以 Service 的形式加入到集群中来,只需要在创建 Service 的时候不指定 Label Selector ,而是在 Service 创建好后手动为其添加 Endpoint 。
Service 的 ClusterIP 是在建立后自动添加的,所以无法事先知晓该 IP ,若要与改 service 进行通讯则需要设计某种发现机制。例如,使用环境变量来获取 IP 。

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

Secret

Secret 是一个包含少量敏感数据的对象,例如密码,令牌或密钥。否则,这些信息可能会被放入 Pod 的 spec 中或者镜像中。
将敏感信息放入 Secret 对象可以更好地控制它的使用方式,并降低暴露的风险。 用户可以手动创建 Secret ,同时系统也会创建一些 Secret 。
要使用 Secret ,pod 需要引用该 Secret 。 Secret 可以通过两种方式与 pod 一起使用:作为挂载在该 pod 中的某些容器的 volume ,或者在为 pod 拉取镜像时由 kubelet 使用。

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

Statefulset

StatefulSet 是用于管理有状态应用程序的工作负载 API 对象。它管理一组 Pod 的部署和扩展,并提供有关这些 Pod 的排序和唯一性的保证。
与 Deployment 类似的是,StatefulSet 管理基于相同容器规范的 Pod 。与 Deployment 不同的是,StatefulSet 为其每个 Pod 维护一个粘性标识( sticky identity )。这些 pod 是根据相同的规范创建的,但不可互换,因为每个 pod 都有一个持久的标识符( persistent identifier ),它在任何重新安排时都会保留。
使用 StatefulSet 的应用通常需要以下的一个或多个条件:

  • 稳定且唯一的网络标识
  • 稳定且持久的储存
  • 有序且优雅的部署和扩展
  • 有序且自动化的滚动更新
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # 这里需要匹配service的 .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # 这里需要匹配service的 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

Daemonset

Daemonset 保证在每个 Node 行都运行一个 Pod 副本,常用来部署一些集群的日志、监控或者其他系统管理应用。随着 Node 添加到群集中,会将 Pod 添加到 Node 中。随着 Node 从群集中删除,这些 Pod 将被垃圾回收。删除 DaemonSet 将清除它创建的 Pod。
与 Deploymet 一样,DaemonSet 也支持滚动更新和回滚。
典型的应用场景包括:

  • 日志收集:比如 fluentd、l ogstash等
  • 系统监控:比如 Prometheus Node Exporter、 collectd等
  • 系统程序:比如 kube-proxy、 kube-dns、 ceph等
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: k8s.gcr.io/fluentd-elasticsearch:1.20
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

CronJob

CronJob 用于创建一些基于时间计划的任务。它按照给定的时间表周期性的运行某些任务,时间表的编写遵顼 corn 表达式格式。
如何使用 CornJob 自动运行任务可以查看官方文档的 例子

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

参考:
kubernetes官方文档
kubernetes中文文档