Kubernetes Pod 控制器

在机器人技术和自动化中,控制环是一个控制系统状态的不终止的循环node

这是一个控制环的例子:"房间里的温度自动调节器"
当你设置了温度,告诉了温度自动调节器你的"指望状态",房间的实际温度是"当前状态"。经过对设备的开关控制,温度自动调节器让其当前状态无限接近于指望状态。
控制器经过 k8s的apiserver 去监控集群的公共状态,并致力于将当前状态转变为所指望的状态。nginx

kubernetes 之Pod控制器(Controller)git

Controller是kubernetes中用于对Pod进行管理的控制器,经过该控制器可让Pod始终维持在一个用户本来设定或指望的状态下。如节点宕机或Pod因其余缘由死亡,则在其余节点起一个相同的Pod来替代该Pod。github

  • 经常使用的内置控制器类型,它一般与集群API服务器进行交互:
    ReplicaSet:是Replication Controller 升级版本,区别是对选择器的支持;
    Deployments:管理RS并提供对Pod的更新等功能,建议使用它管理RS,除非自定义更新编排;
    DaemonSet:用于确保集群中的每个节点只运行一个Pod副本,一般用来实现系统级的后台任务;
    StatefulSets:一般用来管理有状态应用;
    Job:一次性任务执行;
    Crontab:定时任务执行;
    任意控制器学习方法可参考中文官方站点:Kubernetes 内置控制器
  • 举个例子:
    运行Pod以前,尽可能把镜像给先下载到本地,依据Pod调度结果使用docker save load导入导出
[root@node1 controllers]# cat replicaset-demo.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: myapp
  namespace: default
spec:
  replicas: 1
  selector: 
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      name: myapp-httpd
      labels:
        app: myapp
        release: canary
        environment: qa
    spec:
      containers:
      - name: myapp-container
        image: httpd
                imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
[root@node1 controllers]#

Kubernetes 最小运行单元 Pod,了解Pod是什么你须要了解容器web

容器本质其实是一个进程,是一个视图被隔离,资源受限的进程。
容器的设计自己是"单进程"模型,不是容器里只能起一个进程,由于容器的应用等于进程,只能管理PID=1的进程。(Linux 容器的"单进程"模型,指的是容器的生命周期等同于 PID=1 的进程的生命周期,而不是说容器里不能建立多进程),也能够启动多个进程,可是只有PID=1的进程被容器所管理,这时其它进程则处于tuoguan状态。若是这个时候PID=1的这个进程出问题了被kill掉了或者是fail了没人知道,而后其它的进程资源怎么办呢?就没人管,没人回收......
因此每每在容器当中运行一个复杂程序是比较苦难的,但kubernetes的控制器的脱引而出,为它奠基了其在容器当中运行多个应用的历史地位,至少现阶段是的。docker

Pod 是什么apache

让Kubernetes集群能跑起来的基础组件就叫 Pod。 api

  • Pod 是 Kubernetes 应用程序的基本执行单元,即它是 Kubernetes 对象模型中建立或部署的最小和最简单的单元。Pod 表示在 集群 上运行的一个进程。
  • Pod 能够是封装了单个应用程序的容器(或多个)、存储资源、惟一网络 IP 以及控制容器应该如何运行的选项。 Pod 表示部署单元:"Kubernetes 中应用程序的单个实例",它可能由单个 容器 或少许紧密耦合并共享资源的容器组成。
  • Docker 是 Kubernetes Pod 中最经常使用的容器运行时,但 Pod 也能支持其余的容器运行。

Pod = "进程组"tomcat

在 Kubernetes 里面,Pod 实际上正是 Kubernetes 项目为你抽象出来的一个能够类比为进程组的概念。
简单点就是在kubernets当中会把多个应用定义为多个容器,而后把多个容器运行在一个Pod资源里面,你也能够说是多个容器的组合就叫作 Pod。当Kubernetes把定义在一个Pod组合里的容器运行起来后,你会看到多个容器在运行。它们会同时去共享系统底层的某些资源(共享同一个底层的net、uts、ipc、等...),而这些资源都属于 Pod。
Pod 在 Kubernetes 里面只有一个逻辑单位,Pod 是 Kubernetes 分配资源的一个单位。由于里面的容器要共享某些资源,因此Pod 它也是 Kubernetes 的原子调度单位。服务器

Pod 的工做特色

  • 自主式Pod,自主式管理;
  • 将多个容器链接起来,给容器作成抽象封装;
  • 一个Pod包含多个容器,共享同一个底层的 UTS、IPC、Network、等......;
  • Pod模拟传统虚拟机,一个Pod建议只运行一个容器;
  • 共享存储卷,再也不属于容器而属于Pod;
  • Pod在各node上运行,取决其节点容忍度;
  • Pod控制器:Replication Controller、ReplicaSet、DeployMent、StatefulSet、DaemonSet、Job;

Kubernetes 中Pod 的运行方式

  • 运行单个容器的 Pod
    "每一个 Pod 一个容器"的模型是最多见的 Kubernetes 用例,即one-container-per-Pod模式。在这种状况下能够将 Pod 看做单个容器的包装器,而且 Kubernetes 直接管理 Pod,而不是容器。
  • 运行多个协同工做的容器的 Pod
    Pod 可能封装由多个紧密耦合且须要共享资源的共处容器组成的应用程序。即sidecar模式,Pod 封装了一组紧耦合、共享资源、协同寻址的容器,将这组容器做为一个管理单元做为一个可管理的实体。
    举个例子:
    自包含式容器设计Sidecar示例,镜像可私有仓库建立打包并上传至github
[root@node1 controllers]# cat pod-tomcat-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: web-2
  namespace: default
spec:
  initContainers:
  - image: ik8s.io/sample:v2
    imagePullPolicy: IfNotPresent
    name: war
    command: [ "cp", "/sample.war", "/app" ]
    volumeMounts:
    - mountPath: /app
      name: app-volume
  containers:
  - image: ik8s.io/tomcat:8.0
    imagePullPolicy: IfNotPresent
    name: tomcat8
    command: [ "sh", "-c", "/root/apache-tomcat-8.0.5/bin/start.sh" ]
    volumeMounts:
    - mountPath: /root/apache-tomcat-8.0.5/webapps
      name: app-volume
    ports:
    - containerPort: 8080
      hostPort: 8008
  volumes:
  - name: app-volume
    emptyDir: {}
[root@node1 controllers]#

利用DeployMents控制器实现滚动更新及灰度应用发布

  • 任意应用程序建立必须知足三个核心组件:
    用户指望的Pod副本、标签选择器、Pod模版(现有Pods数量不够副本中所定义的指望Pod)
    命令帮助:
[root@node1 controllers]# kubectl explain deploy
[root@node1 controllers]# kubectl explain deploy.spec
[root@node1 controllers]# kubectl explain deploy.spec.strategy

此示例中会告诉您怎么实现一组应用的滚动更新,版本回退,Pod数量更新等。

[root@node1 controllers]# cat deployment-myapp-demo.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  namespace: default
spec:
  replicas: 2
  selector: 
    matchLabels:
      app: myapp
      release: canary
  template:
    metadata:
      labels:
        app: myapp
        release: canary
    spec:
      containers:
      - name: myapp
        image: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
[root@node1 controllers]#
[root@node1 controllers]# kubectl apply -f deployment-myapp-demo.yaml 
deployment.apps/myapp-deployment created
[root@node1 controllers]# 
[root@node1 controllers]# kubectl delete -f deployment-myapp-demo.yaml 
deployment.apps "myapp-deployment" deleted
[root@node1 controllers]# 
[root@node1 controllers]# kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
myapp-deployment-5b776d9cf7-29s7b   1/1     Running   0          9m26s
myapp-deployment-5b776d9cf7-8hb8c   1/1     Running   0          9m26s
[root@node1 controllers]# 
[root@node1 controllers]# kubectl logs myapp-deployment-5b776d9cf7-8hb8c
[root@node1 controllers]# 
[root@node1 controllers]# kubectl describe pods myapp-deployment-5b776d9cf7-8hb8c
.............
Events:
Type    Reason     Age        From               Message
    ----    ------     ----       ----               -------
    Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/myapp-deployment-5b776d9cf7-8hb8c to node2
    Normal  Pulled     10h        kubelet, node2     Container image "nginx" already present on machine
    Normal  Created    10h        kubelet, node2     Created container myapp
    Normal  Started    10h        kubelet, node2     Started container myapp
[root@node1 controllers]#
  • 更新Pod数量,滚动更新
    经过打补丁的方式进行更新,也可直接编辑文件进行更新,其值默认为1
# 更新当前副本集为5个
[root@node1 controllers]# kubectl patch deployment myapp-deploy -p '{"spec":{"relicas":5}}' 
# 实时查看更新状态
[root@node1 controllers]# kubectl get pods -w
  • 更新image版本号,滚动更新
    所运用到的命令:kubectl set、kubectl edit、kubectl apply、kubectl rollout
# 更新容器镜像版本至最新
[root@node1 controllers]# kubectl set image deployment/myapp-deployment nginx=nginx:latest 
# 查看滚动更新历史
[root@node1 controllers]# kubectl rollout history deployment myapp-deployment 
# 查看ReplicaSet空间image版本号状态
[root@node1 controllers]# kubectl get rs -l app=myapp -o wide
# 查看image字段
[root@node1 controllers]# kubectl describe pods myapp-deployment-5b776d9cf7-8hb8c | grep 'Image' 
# 查看其更新的过程是怎么更新的,作了什么
[root@node1 controllers]# kubectl describe deployment/myapp-deployment
  • 模拟金丝雀发布
    更改maxSurge和maxUnavailable更新策略
# 命令帮助
[root@node1 controllers]# kubectl explain deploy.spec.strategy.rollingUpdate
# 先打补丁,更改当前更新策略,以模拟金丝雀发布
[root@node1 controllers]# kubectl patch deployment myapp-deployment -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}'
# 查看
[root@node1 controllers]# kubectl describe deploy myapp-deployment
# 再更新(金丝雀发布)
[root@node1 controllers]# kubectl set image deployment myapp-deployment myapp=nginx:v1  && kubectl rollout pause deployment myapp-
Waiting for deployment "myapp-deployment" rollout to finish: 1 out of 3 new replicas have been updated...
# 查看历史版本,使用 "--record" 参数可看到每一个版本所使用的命令
[root@node1 controllers]# kubectl rollout history deployment myapp-deployment 
# 回滚不加版本号,默认回退到上一个版本
[root@node1 controllers]# kubectl rollout undo deployment myapp-deployment
# 使用 "--to-reversion=[N]" 回滚到指定版本
[root@node1 controllers]# kubectl rollout undo deploy myapp-deployment --to-reversion=1
# 如以上没问题,再次执行更新操做
[root@node1 controllers]# kubectl rollout resume deploy myapp-deployment

更多DeployMents控制器的Pod和ReplicaSet使用可参考 ---> 中文官方 DeployMnet 控制器使用

利用DaemonSet 运行指定一个Pod副本,把系统某个目录做为存储卷

更多 "DaemonSet" 控制器的使用可参考官网 ---> 中文官方 DaemonSet 控制器使用

再补充......

相关文章
相关标签/搜索