草庐IT

kubernetes之Deployment控制器(一)

海棠 2023-03-28 原文

1.什么是Deployment?

Deployment(简写为deploy)是kubernetes控制器的又一种实现,构建于ReplicasSet控制器之上,可以为Pod和ReplicaSet提供声明式更新。相比较而言,Pod和ReplicaSet很少用来直接使用,而是借助于控制器来使用。Deployment Controller核心功能也是保证Pod资源的正常使用,大部分功能调用ReplicaSet来实现。

1.2我们只需要描述Deployment中目标Pod期望状态,而Deployment控制器以控制更改为实际状态,使其变成期望状态。我们不需要直接使用Pod和ReplicaSet来实现,Deployment控制器在ReplicaSet的基础上增加了部分特性:

1.事件和状态查看: 可以通过特定的命令查看Deployment对象的更新进度和状态;
2.版本记录: 将Deployment对象的历史更新操作都进行保存,以便于后续执行回滚操作使用;
3.多种更新方案: Recreate重建,可以实现单批次更新所有的Pod。RollingUpdate可以实现多批次替换Pod至新版本。

2.Deployment的构成部分

Deployment是标准的k8s资源,Deployment构建于ReplicaSet之上,spec字段嵌套了包含了replicaset控制器支持的selector、replicas、template、minReadySeconds
2.1 Selector: 标签选择器,匹配并关联Pod,并对其受控制的Pod进行管理;
2.2 Replicas: 期望的Pod的副本数,期望在集群所运行的Pod对象的数量;
2.3 template: Pod的模板;实际上定义了Pod的内容,相当于把一个Pod的描述信息以模板的方式嵌套在ReplicaSet;
2.4 Deployment是生产中最常用的控制器,适合用来发布无状态应用。
2.5 Deployment的创建流程;

  1. 首先是 kubectl 发起一个创建 deployment 的请求;
  2. apiserver 接收到创建deployment 请求,将相关资源写入etcd;之后所有组件与apiserver/etcd的交互都是类似的;
  3. deployment Controller list/watch 资源变化并发起创建ReplicaSet请求;
  4. ReplicaSet Controller list/watch资源变化并发起创建Pod请求;
  5. Scheduler检测到未绑定的Pod资源,通过一系列匹配以及过滤选择合适的Node进行绑定;
  6. kubelet发现自己Node上需创建新Pod,负责Pod 的创建及后续生命周期管理;
  7. kube-Proxy负责初始化Service相关的资源,包括服务发现、负载均衡等网络规则;
  8. 至此,经过 kubenetes各组件的分工协调,完成了从创建一个 Deployment请求开始到具体各Pod 正常运行的全过程。

3.Deployment的资源规范

apiVersion: apps/v1   # API群组及版本;
kind: Deployment      # 资源类型;
metadata:             # Pod元数据;
   name:              # 资源名称,在作用域中要唯一;
   namespace: <string>         # 名称空间,Deployment隶属名称空间级别;
spec:             
  minReadySeconds: <integer>   # Pod就绪后多少秒内任一容器无Crash方可为就绪,来控制滚动更新的速度,默认值为0,表示新建的Pod对象一旦"就绪"将立即被视作可用,随后开始下一轮更新。如果设定了spec.minReadySeconds: 3表示新建的Pod对象至少要成功运行多久才会被视作可用,即就绪之后还要等待指定的3s才能开始下一批次的更新,在一个批次内新建的所有Pod就绪探测失败,都会导致滚动更新被终止,因此为minReadySeconds设定一个合理的值,不仅能够减缓更新的速度,还能够让Deployment提前发现一部分程序因为Bug导致的升级故障,生产环境中为Pod设置指针探测。
  replicas: <integer>          # 期望的Pod副本数,默认为1;
  selector: <Object>           # 标签选择器,必须匹配template字段中Pod模板中的标签;
  template: <Object>           # Pod模板对象;
  
  revisionHistoryLimit: <integer>  # 滚动更新历史记录数量,默认为10;
  strategy: <Object>               # 滚动更新策略;
    type: <string>                 # 滚动更新类型,可用值有Recreate和Rollingupdate;
    rollingUpdate: <Object>       # 滚动更新参数,专用于RollingUpdate类型;
      maxSurge: <string>           # 更新期间可比期望的Pod数量多出的数量和比例;
      maxUnavailable: <string>     # 更新期间可比期望的Pod数量缺少的数量或比例;
   progressDeadlineSeconds: <integer>  # 滚动更新故障超时时长,默认为600;在升级的过程中可能会因为各种原因卡住(比如拉取镜像等。)如果配置progressDeadlineSeconds,当到一定时间还卡住,则会上报这个异常,这个时候Deployment的状态就会被标记False,并标注,它不会阻止Deployment继续进行卡住之后的升级操作。
   paused: <boolean>                   # 是否暂停部署过程;

4.Deployment的配置示例:

# 可以通过命令来查看帮助文档;
kubectl explain deployment
# 以Nginx应用为示例配置
root@kubernetes-master01:~# cat nginx-deployment-test.yaml 
apiVersion: apps/v1     # 资源群组
kind: Deployment        # 资源类型
metadata:               # 元数据
  name: deployment-nginx-test  # Pod名称
  namespace: default           # Pod所在的名称空间
spec:
  replicas: 2                  # Pod的副本数
  selector:                    # 标签选择器
    matchLabels:
      app: nginx-deployment     # Pod的标签

  template:                      # 定义Pod的模板
    metadata:                    # 
      labels:                    # 标签同上要一致
        app: nginx-deployment
    spec:                         # 定义容器的
      containers:                 
      - name: nginx                # 容器名称
        image: nginx               # 容器镜像
        imagePullPolicy: IfNotPresent # 容器拉取策略
        ports:                     # 定义容器的端口
        - name: http         
          containerPort: 80          # 容器端口为80

# 
root@kubernetes-master01:~# kubectl apply -f nginx-deployment-test.yaml
deployment.apps/deployment-nginx-test created

4.1查看Pod,Deployment的名称-Replicaset的名称-随机字符串hash值是由Deployment Controller自动生成。Pod对应的名称遵循ReplicaSet控制器的命名格式,它以Replicaset控制器的名称为签注,后跟5位随机字符。

root@kubernetes-master01:~/cloud-Native/deployment/replicas# kubectl get pods 
NAME                                    READY   STATUS    RESTARTS   AGE
deployment-nginx-test-dd5bdc67f-b5dlz   1/1     Running   0          6m12s
deployment-nginx-test-dd5bdc67f-t94j7   1/1     Running   0          6m12s
# NAME: 列出了集群中Deployment的名称。
# READY: 显示应用程序的可用的"副本数"显示的模式是"就绪个数/期望个数"
# UP-TO-DATE: 标识已经达到期望状态的Pod的副本数量。
# AVAILABLE: 表示当前处于可用状态的Pod的数量。

4.2查看replicaset,Deployment控制器会自动创建相关的ReplicaSet控制器资源,并以[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]格式为其命名,其中的hash值由Deployment控制器自动生成,由Deployment创建的ReplicaSet对象会自动使用相同的标签选择器。

root@kubernetes-master01:~# kubectl get replicaset deployment-nginx-test-dd5bdc67f 
NAME                              DESIRED   CURRENT   READY   AGE
deployment-nginx-test-dd5bdc67f   2         2         2       9m34s

5.为Pod创建Service资源以实现负载均衡。

root@kubernetes-master01:~# cat  nginx-service-test.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-deployment-test
  namespace: default
spec:
  type: ClusterIP  # 类型为ClusterIP
  selector:    # 标签选择器跟Pod的标签相匹配,才能被识别为后端端点。
    app: nginx-deployment
  ports:
  - name: http
    protocol: TCP
    port: 80  
    targetPort: 80
# 
root@kubernetes-master01:~# kubectl apply -f nginx-service-test.yaml 
service/nginx-deployment-test created

6.进行访问测试

6.1我提前修改了Nginx的index文件。方便效果。

root@kubernetes-master01:~# echo "nginx-1-haitang.net" > /usr/share/nginx/html/index.html 
root@kubernetes-master01:~# echo "nginx2-haitang.com" > /usr/share/nginx/html/index.html 

6.2访问Service的IP,因为是ClusterIP,只能在集群内访问。也是没有问题的。

root@kubernetes-master01:~# curl 10.107.246.117
nginx2-haitang.com
root@kubernetes-master01:~# curl 10.107.246.117
nginx-1-haitang.net
root@kubernetes-master01:~# curl 10.107.246.117
nginx2-haitang.com
root@kubernetes-master01:~# curl 10.107.246.117
nginx-1-haitang.net

7.Pod的伸缩

7.1比如现在两个副本有点无法应对突发的流量,可以通过命令的方式修改replicas也可以通过修改配置文件的方式去修改。

1.1# 命令方式来伸缩
root@kubernetes-master01:~# kubectl scale deployment deployment-nginx-test --replicas=3
deployment.apps/deployment-nginx-test scaled

1.2# 缩容的话就是=多少副本数即可。 例如=2
root@kubernetes-master01:~# kubectl scale deployment deployment-nginx-test --replicas=2

1.3# 修改配置文件vim nginx-deployment-test.yaml 修改spec字段的replicas即可。

7.2伸缩完成后,Service就会发现带有同样标签的Pod,Pod就绪后加入到后端的可用端点。
再次访问测试。也是没有问题。

root@kubernetes-master01:~# curl 10.107.246.117
nginx2-haitang.com
root@kubernetes-master01:~# curl 10.107.246.117
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
root@kubernetes-master01:~# curl 10.107.246.117
nginx-1-haitang.net

7.3也可以通过describe命令来查看Events事件。

root@kubernetes-master01:~# kubectl describe deploy deployment-nginx-test  
Pod Template:
  Labels:  app=nginx-deployment
  Containers:
   nginx:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Progressing    True    NewReplicaSetAvailable
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  <none>
NewReplicaSet:   deployment-nginx-test-dd5bdc67f (3/3 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  36s   deployment-controller  Scaled up replica set deployment-nginx-test-dd5bdc67f to 3

8.故障测试。

8.1现在删除Pod会发生什么?

root@kubernetes-master01:~# kubectl delete pods deployment-nginx-test-dd5bdc67f-2vggw  
pod "deployment-nginx-test-dd5bdc67f-2vggw" deleted

# 有控制器管理的Pod删除会自动重建,没有控制器管理的Pod删除就是删除了不可能会自动重建。我们创建的Pod受控于Deployment Controller。所以能重建。
root@kubernetes-master01:~# kubectl get pods
deployment-nginx-test-dd5bdc67f-2vggw   1/1     Running   0          4s
deployment-nginx-test-dd5bdc67f-lc6nm   1/1     Running   0          4s

有关kubernetes之Deployment控制器(一)的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  5. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  6. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  7. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  8. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  9. ruby-on-rails - ruby 新手,有人可以帮我从控制台破译这个错误吗? - 2

    我真的只是不确定这意味着什么或我应该做什么才能让网页在我的本地主机上运行。现在它只是显示一个错误,上面写着“我们很抱歉,但出了点问题。”当我运行railsserver并在chrome中打开localhost:3000时。这是控制台输出:StartedGET"/users/sign_in"for127.0.0.1at2013-07-0512:07:07-0400ProcessingbyDevise::SessionsController#newasHTMLCompleted500InternalServerErrorin55msNoMethodError(undefinedmethod`

  10. ruby-on-rails - Rails 控制台的 YAML 输出 - 2

    在Rails控制台中执行类似yGrau.all的命令时,我得到这些奇怪的!binary字符串而不是属性名称。知道如何解决这个问题吗?谢谢。irb(main):003:0>yGrau.all←[1m←[36mGrauLoad(0.0ms)←[0m←[1mSELECT"graus".*FROM"gr←[1m←[35mEXPLAIN(0.0ms)←[0mEXPLAINQUERYPLANSELECT"grauEXPLAINfor:SELECT"graus".*FROM"graus"0|0|0|SCANTABLEgraus(~1000000rows)----!ruby/object:Grauat

随机推荐