K8S控制器介绍与使用

K8S逻辑架构图

img

Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;

  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;

  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;

  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;

  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);

  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
    除了核心组件,还有一些推荐的Add-ons:

  • kube-dns负责为整个集群提供DNS服务

  • Ingress Controller为服务提供外网入口

  • Heapster提供资源监控

  • Dashboard提供GUI

  • Federation提供跨可用区的集群

  • Fluentd-elasticsearch提供集群日志采集、存储与查询

CNI( 容器网络接口,提供网络资源)

CNI是Container Network Interface的是一个标准的,通用的接口。 CNI用于连接容器管理系统和网络插件。CNI的工作是从容器管理系统处获取运行时信息,包括network namespace的路径,容器ID以及network interface name,再从容器网络的配置文件中加载网络配置信息,再将这些信息传递给对应的插件,由插件进行具体的网络配置工作,并将配置的结果再返回到容器管理系统中。

CNI插件是可执行文件,由被kubelet调用。启动kubelet --network-plugin=cni,–cni-conf-dir 指定networkconfig配置,默认路径是:/etc/cni/net.d,并且,–cni-bin-dir 指定plugin可执行文件路径,默认路径是:/opt/cni/bin;

CNI plugin 只需要通过 CNI 库实现两类方法, 一类事创建容器时调用, 一类是删除容器时调用.

img

CNI的接口中包括以下几个方法:

type CNI interface {
    AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
    DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error

    AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)
    DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
} 
该接口只有四个方法,添加网络、删除网络、添加网络列表、删除网络列表。

img

Overlay 模式

Overlay指的是一种传统网络架构上叠加的虚拟化技术,底层有(NVGRE和VXLAN等技术),在的典型特征是容器独立于主机的 IP 段,这个 IP 段进行跨主机网络通信时是通过在主机之间创建隧道的方式,将整个容器网段的包全都封装成底层的物理网络中主机之间的包。该方式的好处在于它不依赖于底层网络;

扩展资料:http://www.h3c.com/cn/d_201501/852551_30008_0.htm

路由模式

中主机和容器也分属不同的网段,它与 Overlay 模式的主要区别在于它的跨主机通信是通过路由打通,无需在不同主机之间做一个隧道封包。但路由打通就需要部分依赖于底层网络,比如说要求底层网络有二层可达的一个能力;

Underlay

模式中容器和宿主机位于同一层网络,两者拥有相同的地位。容器之间网络的打通主要依靠于底层网络。因此该模式是强依赖于底层能力的。

k8s网络之Flannel网络 k8s网络之Calico网络 https://www.cnblogs.com/goldsunshine/p/10740928.html

原文链接:https://blog.csdn.net/valada/article/details/104786619

参考地址:https://blog.csdn.net/zhonglinzhang/article/details/82697524

https://zhuanlan.zhihu.com/p/33390023

https://blog.csdn.net/valada/article/details/104786619

CRI (容器运行时接口,提供计算资源)

容器运行时接口(Container Runtime Interface),用于解除K8S和容器的耦合性;

CRI中定义了容器镜像的服务的接口

  • RuntimeService:容器和Sandbox运行时管理
  • ImageService:提供了从镜像仓库拉取、查看、和移除镜像的RPC。
cri-o:同时兼容OCI和CRI的容器运行时
cri-containerd:基于Containerd的Kubernetes CNI实现
rkt:由于CoreOS主推的用来跟docker抗衡的容器运行时
frakti:基于hypervisor的CRI
docker:kuberentes最初就开始支持的容器运行时,目前还没完全从kubelet中解耦,docker公司同时推广了OCI标准
clear-containers:由Intel推出的同时兼容OCI和CRI的容器运行时
kata-containers:符合OCI规范同时兼容CRI

在Kubernetes1.9中的CRI接口在api.proto中定义

// Runtime service defines the public APIs for remote container runtimes
service RuntimeService {
    // Version returns the runtime name, runtime version, and runtime API version.
    rpc Version(VersionRequest) returns (VersionResponse) {}

    // RunPodSandbox creates and starts a pod-level sandbox. Runtimes must ensure
    // the sandbox is in the ready state on success.
    rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}
    // StopPodSandbox stops any running process that is part of the sandbox and
    // reclaims network resources (e.g., IP addresses) allocated to the sandbox.
    // If there are any running containers in the sandbox, they must be forcibly
    // terminated.
    // This call is idempotent, and must not return an error if all relevant
    // resources have already been reclaimed. kubelet will call StopPodSandbox
    // at least once before calling RemovePodSandbox. It will also attempt to
    // reclaim resources eagerly, as soon as a sandbox is not needed. Hence,
    // multiple StopPodSandbox calls are expected.
    rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}
    // RemovePodSandbox removes the sandbox. If there are any running containers
    // in the sandbox, they must be forcibly terminated and removed.
    // This call is idempotent, and must not return an error if the sandbox has
    // already been removed.
    rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}
    // PodSandboxStatus returns the status of the PodSandbox. If the PodSandbox is not
    // present, returns an error.
    rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}
    // ListPodSandbox returns a list of PodSandboxes.
    rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}

    // CreateContainer creates a new container in specified PodSandbox
    rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}
    // StartContainer starts the container.
    rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}
    // StopContainer stops a running container with a grace period (i.e., timeout).
    // This call is idempotent, and must not return an error if the container has
    // already been stopped.
    // TODO: what must the runtime do after the grace period is reached?
    rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}
    // RemoveContainer removes the container. If the container is running, the
    // container must be forcibly removed.
    // This call is idempotent, and must not return an error if the container has
    // already been removed.
    rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}
    // ListContainers lists all containers by filters.
    rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}
    // ContainerStatus returns status of the container. If the container is not
    // present, returns an error.
    rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}
    // UpdateContainerResources updates ContainerConfig of the container.
    rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}

    // ExecSync runs a command in a container synchronously.
    rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}
    // Exec prepares a streaming endpoint to execute a command in the container.
    rpc Exec(ExecRequest) returns (ExecResponse) {}
    // Attach prepares a streaming endpoint to attach to a running container.
    rpc Attach(AttachRequest) returns (AttachResponse) {}
    // PortForward prepares a streaming endpoint to forward ports from a PodSandbox.
    rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}

    // ContainerStats returns stats of the container. If the container does not
    // exist, the call returns an error.
    rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {}
    // ListContainerStats returns stats of all running containers.
    rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {}

    // UpdateRuntimeConfig updates the runtime configuration based on the given request.
    rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {}

    // Status returns the status of the runtime.
    rpc Status(StatusRequest) returns (StatusResponse) {}
}

// ImageService defines the public APIs for managing images.
service ImageService {
    // ListImages lists existing images.
    rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}
    // ImageStatus returns the status of the image. If the image is not
    // present, returns a response with ImageStatusResponse.Image set to
    // nil.
    rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}
    // PullImage pulls an image with authentication config.
    rpc PullImage(PullImageRequest) returns (PullImageResponse) {}
    // RemoveImage removes the image.
    // This call is idempotent, and must not return an error if the image has
    // already been removed.
    rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}
    // ImageFSInfo returns information of the filesystem that is used to store images.
    rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {}

CSI:容器存储接口,提供存储资源 CSI 代表容器存储接口,CSI 试图建立一个行业标准接口的规范,借助 CSI 容器编排系统(CO)可以将任意存储系统暴露给自己的容器工作负载。

csi 卷类型是一种 in-tree(即跟其它存储插件在同一个代码路径下,随 Kubernetes 的代码同时编译的) 的 CSI 卷插件,用于 Pod 与在同一节点上运行的外部 CSI 卷驱动程序交互。部署 CSI 兼容卷驱动后,用户可以使用 csi 作为卷类型来挂载驱动提供的存储。

CSI 持久化卷支持是在 Kubernetes v1.9 中引入的,作为一个 alpha 特性,必须由集群管理员明确启用。换句话说,集群管理员需要在 apiserver、controller-manager 和 kubelet 组件的 “–feature-gates =” 标志中加上 “CSIPersistentVolume = true”。

CSI 持久化卷具有以下字段可供用户指定:

  • driver:一个字符串值,指定要使用的卷驱动程序的名称。必须少于 63 个字符,并以一个字符开头。驱动程序名称可以包含 “.”、“-”、“_” 或数字。

  • volumeHandle:一个字符串值,唯一标识从 CSI 卷插件的 CreateVolume 调用返回的卷名。随后在卷驱动程序的所有后续调用中使用卷句柄来引用该卷。

  • readOnly:一个可选的布尔值,指示卷是否被发布为只读。默认是 false。

对象管理与配置格式

K8S以对象的形式描述各种资源,多数对象都可以在 yaml 文件中作为一种 API 类型来配置

类别名称
资源对象Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition
存储对象Volume、PersistentVolume、Secret、ConfigMap
策略对象SecurityContext、ResourceQuota、LimitRange
身份对象ServiceAccount、Role、ClusterRole

每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec 和 对象 status

  • spec 必须提供,它描述了对象的 期望状态—— 希望对象所具有的特征。
  • status 描述了对象的 实际状态,它是由 Kubernetes 系统提供和更新。

在任何时刻,Kubernetes 控制平面一直处于活跃状态,管理着对象的实际状态以与我们所期望的状态相匹配

必需字段

在想要创建的 Kubernetes 对象对应的 .yaml 文件中,需要配置如下的字段:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本

  • kind - 想要创建的对象的类型

  • metadata - 帮助识别对象唯一性的数据,包括一个 name 字符串、UID 和可选的 namespace

示例

apiVersion: apps/v1beta1 #指定k8sapi版本
kind: Deployment 指定控制器
metadata:  #标识一下唯一性
  name: nginx-deployment
spec: #开始描述对象的期望数量
  replicas: 3 #期望的副本数量
  minReadySeconds: 0 #指定新的pod就绪多久后才认为这个pod正常运行了
  template: # 指定一下模板(PodTemplateSpec),k8s根据指定的模板创建pod
    metadata: #指定模板唯一标识
      labels:
        app: nginx
    spec: 
      containers: #指定一下容器
      - name: nginx #指定名称
        image: nginx:1.7.9 指定镜像
        ports: #指定端口
        - containerPort: 80

YAML配置api参考地址:https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec

ReplicationController 和 ReplicaSet

ReplicationController 用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收。

在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationController。ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector。

虽然 ReplicaSet 可以独立使用,但一般还是建议使用 Deployment 来自动管理 ReplicaSet。

配置示例

apiVersion: extensions/v1beta1 #指定k8s版本
kind: ReplicaSet 指定对象
metadata:
  name: frontend 指定唯一标识
  labels:  #设定该对象的标签
    group: a0000
    number: a00001
spec: ##描述配置信息
  replicas: 3 #副本数量
   #标签选择器
   #ReplicaSet和ReplicationController的区别,只有ReplicaSet才有
  selector: 
	#matchExpressions 的一个元素,其键字段为“key”,运算符为“In”,values 数组仅包含“value”
    matchLabels:
      group: a0000
  #matchExpressions 是标签选择器要求的列表,内部是and运算,可以写很多个
    matchExpressions:
      - {key: tier, operator: In, values: [frontend]}
  template: #指定模板
    metadata: #指定唯一标识
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers: ##指定多个容器
      - name: php-redis #指定容器名称
        image: gcr.io/google_samples/gb-frontend:v3 #指定镜像
        resources:
          requests: #需求限制
            cpu: 100m #指定100毫核
            memory: 100Mi
          limits: #最大限制,需要大于等于requests配置
          	cpu: 100m
            memory: 100Mi
        env:
      - name: GET_HOSTS_FROM
        value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below.
          # value: env
        ports:
        - containerPort: 80

K8s的资源:

  • CPU

​ 2核2线程的CPU,可被系统识别为4个逻辑CPU,在K8s中对CPU的分配限制是对逻辑CPU做分片限制的。也就是说分配给容器一个CPU,实际是分配一个逻辑CPU。
而且1个逻辑CPU还可被单独划分子单位,即 1个逻辑CPU,还可被划分为1000个millicore(毫核)
豪核:可简单理解为将CPU的时间片做逻辑分割,每一段时间片就是一个豪核心。
所以:500m 就是500豪核心,即0.5个逻辑CPU.

  • 内存:
    K,M,G,T,P,E #通常这些单位是以1000为换算标准的。
    Ki, Mi, Gi, Ti, Pi, Ei #这些通常是以1024为换算标准的。

img

Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的 ReplicationController 来方便的管理应用。典型的应用场景包括:

  • 定义 Deployment 来创建 Pod 和 ReplicaSet

  • 滚动升级和回滚应用

  • 扩容和缩容

  • 暂停和继续 Deployment

注:Deployment是一种为无状态服务而设计

配置示例

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
  • 执行扩容:
#手动扩容
kubectl scale deployment nginx-deployment --replicas 10
#设置自动扩展
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
  • 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  • 回滚
kubectl rollout undo deployment/nginx-deployment

StatefulSet

StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序,是为了解决有状态服务的问题

StatefulSet 适用于有以下某个或多个需求的应用:

  • 稳定,唯一的网络标志。

  • 稳定,持久化存储。

  • 有序,优雅地部署和 scale。

  • 有序,优雅地删除和终止。

  • 有序,自动的滚动升级。

StatefulSet中每个Pod的DNS格式为

statefulSetName-{0…N-1}.serviceName.namespace.svc.cluster.local

其中

  • serviceName为Headless Service的名字

  • 0…N-1为Pod所在的序号,从0开始到N-1

  • statefulSetName为StatefulSet的名字

  • namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace

  • .cluster.local为Cluster Domain

什么是 DaemonSet?

DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

使用 DaemonSet 的一些典型用法:

  • 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。

  • 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。

  • 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。

一个简单的用法是,在所有的 Node 上都存在一个 DaemonSet,将被作为每种类型的 daemon 使用。 一个稍微复杂的用法可能是,对单独的每种类型的 daemon 使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU要求。

Job

Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。

Job Spec格式

  • spec.template格式同Pod

  • RestartPolicy仅支持Never或OnFailure

  • 单个Pod时,默认Pod成功运行后Job即结束

  • .spec.completions标志Job结束需要成功运行的Pod个数,默认为1

  • .spec.parallelism标志并行运行的Pod的个数,默认为1

  • spec.activeDeadlineSeconds标志失败Pod的重试最大时间,超过这个时间不会继续重试

一个简单的例子:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    metadata:
      name: pi
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
$ kubectl create -f ./job.yaml
job "pi" created
$ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name})
$ kubectl logs $pods -c pi
3.141592653589793238462643383279502...

CronJob

Cron Job 管理基于时间的 Job,即:

  • 在给定时间点只运行一次
  • 周期性地在给定时间点运行

一个 CronJob 对象类似于 crontab (cron table)文件中的一行。它根据指定的预定计划周期性地运行一个 Job,格式可以参考 Cron

CronJob Spec

  • .spec.schedule:调度,必需字段,指定任务运行周期,格式同 Cron

  • .spec.jobTemplate:Job 模板,必需字段,指定需要运行的任务,格式同 Job

  • .spec.startingDeadlineSeconds :启动 Job 的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限

  • .spec.concurrencyPolicy:并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。

    • Allow(默认):允许并发运行 Job
    • Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个
    • Replace:取消当前正在运行的 Job,用一个新的来替换
  • .spec.suspend :挂起,该字段也是可选的。如果设置为 true,后续所有执行都会被挂起。它对已经开始执行的 Job 不起作用。默认值为 false。

  • .spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit :历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 3 和 1。设置限制的值为 0,相关类型的 Job 完成后将不会被保留。

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

启动删除

kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
kubectl delete cronjob hello
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐