kubernetes快速入门6-pod控制器

网友投稿 247 2022-10-27

kubernetes快速入门6-pod控制器

kubernetes快速入门6-pod控制器

ReplicaSet

副本控制器,使用kubectl explain ReplicaSet查看ReplicaSet资源的相应帮助信息,简写为kubectl explain rs。ReplicaSet确保任何时间Pod的副本数为指定的数量。

ReplicaSet资源定义格式:

KIND: ReplicaSet VERSION: apps/v1 # 属于apps组下的v1稳定版 metadata # rs的元数据信息 spec # rs的规格 replicas # 副本数量 selector # 选择器,必选项 template # rs资源的模板,下一级就Pod的定义 # 更加详细的信息通过帮助命令一级一级查看

事例

k8s@node01:~/my_manifests$ cat replicaset.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: myapp namespace: default spec: replicas: 2 selector: matchLabels: app: my-app release: canary template: metadata: name: myapp-pod labels: app: my-app release: canary environment: qa spec: containers: - name: myapp-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 readinessProbe: httpGet: path: / port: http scheme: HTTP k8s@node01:~/my_manifests$ kubectl create -f replicaset.yaml replicaset.apps/myapp created # 相应的rs资源被创建 k8s@node01:~/my_manifests$ kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp 2 2 2 8m20s myapp-container ikubernetes/myapp:v1 app=my-app,release=canary # rs中定义的Pod被创建,数量为replicas定义的数量 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-5ftmc 1/1 Running 0 8m27s myapp-rx5gz 1/1 Running 0 8m27s

通过ReplicaSet控制器管理的pod数量最终会与replicas字段定义的数值相等,pod数量少了会自动创建,多了会自动杀掉多余的。通过标签选择器ReplicaSet把拥有相应标签的pod资源关联在一起。

ReplicaSet资源的优势

实现动态扩缩容

# 方法一,直接使用 scale 命令 k8s@node01:~/my_manifests$ kubectl scale --replicas=3 replicaset myapp replicaset.apps/myapp scaled k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-5ftmc 1/1 Running 0 25m myapp-794h8 1/1 Running 0 23s myapp-rx5gz 1/1 Running 0 25m # 方法二,实时修改提交给apiserver的定义 k8s@node01:~/my_manifests$ kubectl edit replicaset myapp # 把 replicas: 3 # 修改为 replicas: 2 # 保存退出 # 又只有2个pod资源 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-5ftmc 1/1 Running 0 29m myapp-rx5gz 1/1 Running 0 29m

实现灰度发布和金丝雀发布

现在replicaset.yaml文件的template中使用的image为ikuberbetes/myapp:v1,现在需要升级到v2版本,操作如下:

k8s@node01:~/my_manifests$ kubectl edit replicaset myapp # 把 - image: ikubernetes/myapp:v1 # 修改为 - image: ikubernetes/myapp:v2 # 保存退出 # 确认apiserver返回该资源的IMAGES是对应的版本 8s@node01:~/my_manifests$ kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp 2 2 2 40m myapp-container ikubernetes/myapp:v2 app=my-app,release=canary # 手动删除其中一个pod k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-5ftmc 1/1 Running 0 41m myapp-rx5gz 1/1 Running 0 41m k8s@node01:~/my_manifests$ kubectl delete pod myapp-rx5gz pod "myapp-rx5gz" deleted k8s@node01:~/my_manifests$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-5ftmc 1/1 Running 0 41m 10.244.1.14 node02 myapp-hh6f4 0/1 Running 0 6s 10.244.2.34 node03 # 因replicas为2,会自动创建一个新的Pod,测试 k8s@node01:~/my_manifests$ curl 10.244.2.34 # 新pod已升级为v2 Hello MyApp | Version: v2 | Pod Name k8s@node01:~/my_manifests$ curl 10.244.1.14 # 旧的pod仍然为v1 Hello MyApp | Version: v1 | Pod Name

这样一个一个的替换旧的Pod实现灰度发布。

如果只是把其中的一个pod替换为新版本,让其运行几天来观察是否有用户反馈有无问题,如果无问题才把其他的pod也一一杀掉,让其升级到新版本,这种发布方式叫做金丝雀发布。

当然此实验没有引入service,实验并不完整。

实现蓝绿发布

这里要引入service的概念才好描述,rs1资源通过标签选择器选择关联到pod1和pod2,serivce通过标签选择器也关联到pod1和pod2;要进行发布时重新创建rs2资源,并关联pod3和pod4,当pod3和pod4就绪可接收服务请求后,再修改service的标签选择器让其关联到pod3和pod4,再删除rs1资源。

Deployment

建构在ReplicaSet之上,可管理多个rs,仅有1个处于活动状态,并可回滚版本,默认最多可保留10个版本,可自定义。

Deployment能提供滚动式自定义控制的更新发布,并可控制更新节奏和更新逻辑。在更新期间能设定pod数量可以多于或少于replicas规定的数量

通过控制更新的节奏和逻辑就能实现蓝绿,金丝雀发布

deployment资源使用说明

deployment可简写为deploy,可通过kubectl explain deploy查看相应的帮助信息。

KIND: Deployment VERSION: apps/v1 所属于群组和版本 FIELDS: spec revisionHistoryLimit 更新保留的版本数,默认为10个 selector 必选项,指定标签选择器的标签 template 必选项,定义pod的模板 replicas pod副本数 strategy 新pod替换旧pod的部署策略 type 部署类型,"Recreate" or "RollingUpdate".默认为 RollingUpdate Recreate 表示重建式更新,删一个pod,新建一个pod RollingUpdate 表示滚动式更新,更新策略由 rollingUpdate 字段设定 rollingUpdate 滚动更新 maxSurge 指定在更新时允许超出replicaset设置的目标副本数的个数或百分比,默认25% maxUnavailable 指在更新时最多不可用pod数或百分比,默认25%

deployment资源创建事例

kubectl create -f YAML_FILE与kubectl apply -f YAML_FILE的区别:

create只能创建指定的资源,后续yaml清单里的资源属性发生变动,不能再继续使用该文件应用到相应的资源使其对相应属性的变更,只能调用一次create命令;

apply则如果资源不存在就创建,资源存在就调用apiserver获取存放在etcd中的资源清单,对比出两次yaml清单不同的部分,以此不同部分来对资源做应用变更,可以多次调用apply命令。

k8s@node01:~/my_manifests$ cat deployment-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 2 revisionHistoryLimit: 5 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 readinessProbe: httpGet: port: http path: / scheme: HTTP # 应用清单文件 k8s@node01:~/my_manifests$ kubectl apply -f deployment-demo.yaml deployment.apps/myapp-deploy created k8s@node01:~/my_manifests$ kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE myapp-deploy 2/2 2 2 31s # 在清单文件中没有定义replicaset资源,但创建deployment资源后会自动创建rs资源,期望的副本数为清单文件中replicas定义的数量 # rs名称为资源清单中定义的deploy名称加上template的hash值 k8s@node01:~/my_manifests$ kubectl get rs NAME DESIRED CURRENT READY AGE myapp-deploy-679fcdf84 2 2 2 40s # 创建了相应副本数的Pod资源,pod名称为 rs 名称加上 hash码 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-679fcdf84-46z7s 1/1 Running 0 58s myapp-deploy-679fcdf84-5vw2z 1/1 Running 0 61s

如果想对定义的deploy资源清单中的属性进行更改,想扩容pod的数量为3,直接修改yaml文件再次执行apply操作即可

k8s@node01:~/my_manifests$ kubectl get pods # 扩容后变为3个pod NAME READY STATUS RESTARTS AGE myapp-deploy-679fcdf84-46z7s 1/1 Running 0 3m15s myapp-deploy-679fcdf84-5vw2z 1/1 Running 0 3m18s myapp-deploy-679fcdf84-x7wfb 1/1 Running 0 16s k8s@node01:~/my_manifests$ kubectl describe deploy myapp-deploy # 查看deploy的详细信息 Name: myapp-deploy Namespace: default CreationTimestamp: Sun, 26 Jul 2020 14:33:17 +0800 Labels: Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp,release=canary Replicas: 3 desired | 2 updated | 2 total | 2 available | 1 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp release=canary Containers: myapp: Image: ikubernetes/myapp:v1 Port: 80/TCP ......

deployment pod更新

滚动更新

推荐直接编辑yaml文件后再apply。如需要把myapp:v1版本升级到myapp:v2版本,直接修改yaml后再次apply,通过kubectl get pods -l app=myapp -w来监控更新过程

k8s@node01:~$ kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-679fcdf84-46z7s 1/1 Running 0 4m7s myapp-deploy-679fcdf84-5vw2z 1/1 Running 0 4m10s myapp-deploy-679fcdf84-x7wfb 1/1 Running 0 68s myapp-deploy-9d8d5cb4c-rgxp2 0/1 Pending 0 0s myapp-deploy-9d8d5cb4c-rgxp2 0/1 Pending 0 2s myapp-deploy-9d8d5cb4c-rgxp2 0/1 ContainerCreating 0 5s myapp-deploy-9d8d5cb4c-rgxp2 0/1 Running 0 10s myapp-deploy-9d8d5cb4c-rgxp2 1/1 Running 0 10s myapp-deploy-679fcdf84-x7wfb 1/1 Terminating 0 3m31s myapp-deploy-679fcdf84-x7wfb 0/1 Terminating 0 3m32s myapp-deploy-9d8d5cb4c-xsm6b 0/1 Pending 0 1s myapp-deploy-679fcdf84-x7wfb 0/1 Terminating 0 3m35s myapp-deploy-679fcdf84-x7wfb 0/1 Terminating 0 3m35s myapp-deploy-9d8d5cb4c-xsm6b 0/1 Pending 0 2s myapp-deploy-9d8d5cb4c-xsm6b 0/1 ContainerCreating 0 3s myapp-deploy-9d8d5cb4c-xsm6b 0/1 Running 0 7s myapp-deploy-9d8d5cb4c-xsm6b 1/1 Running 0 12s myapp-deploy-679fcdf84-46z7s 1/1 Terminating 0 6m46s myapp-deploy-9d8d5cb4c-kn7fk 0/1 Pending 0 0s myapp-deploy-9d8d5cb4c-kn7fk 0/1 Pending 0 3s myapp-deploy-679fcdf84-46z7s 0/1 Terminating 0 6m49s myapp-deploy-679fcdf84-46z7s 0/1 Terminating 0 6m49s myapp-deploy-679fcdf84-46z7s 0/1 Terminating 0 6m49s myapp-deploy-9d8d5cb4c-kn7fk 0/1 ContainerCreating 0 4s myapp-deploy-9d8d5cb4c-kn7fk 0/1 Running 0 9s myapp-deploy-9d8d5cb4c-kn7fk 1/1 Running 0 11s myapp-deploy-679fcdf84-5vw2z 1/1 Terminating 0 9m38s myapp-deploy-679fcdf84-5vw2z 0/1 Terminating 0 9m41s myapp-deploy-679fcdf84-5vw2z 0/1 Terminating 0 9m49s myapp-deploy-679fcdf84-5vw2z 0/1 Terminating 0 9m49s # 查看deploy资源,镜像已是v2版本 k8s@node01:~$ kubectl get deploy -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR myapp-deploy 3/3 3 3 12m myapp ikubernetes/myapp:v2 app=myapp,release=canary # 查看replicaset资源,保留了相应的历史版本,如果有需要可以进行版本回退 k8s@node01:~$ kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-deploy-679fcdf84 0 1 1 12m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=679fcdf84,release=canary myapp-deploy-9d8d5cb4c 3 3 3 6m18s myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=9d8d5cb4c,release=canary # 查看deploy的滚动历史 k8s@node01:~$ kubectl rollout history deploy myapp-deploy deployment.apps/myapp-deploy REVISION CHANGE-CAUSE 1 2

通过直接修改yaml清单文件对资源进行变更,也可以使用kubectl patch打补丁的方式对资源进行变更,此种操作的资源变化不能反映在yaml文件中,一般用于暂时性测试某个功能时使用,比如把replicas扩容到5个

k8s@node01:~$ kubectl patch deploy myapp-deploy -p '{"spec":{"replicas":5}}' #-p 选项的值与yaml清单文件中结构对应 deployment.apps/myapp-deploy patched k8s@node01:~$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-9d8d5cb4c-7zv7s 1/1 Running 0 18s myapp-deploy-9d8d5cb4c-89brd 1/1 Running 0 18s myapp-deploy-9d8d5cb4c-kn7fk 1/1 Running 0 6m59s myapp-deploy-9d8d5cb4c-rgxp2 1/1 Running 0 7m30s myapp-deploy-9d8d5cb4c-xsm6b 1/1 Running 0 7m12s

以打补丁的方式修改deploy的更新策略

k8s@node01:~$ kubectl patch deploy myapp-deploy -p '{"spec":{"strategy":{"rollingUpdate":{"maxSurge":1,"maxUnavailable":0}}}}' deployment.apps/myapp-deploy patched k8s@node01:~$ kubectl describe deploy myapp-deploy # 查看详细信息,确认更新策略是否被更新 ... StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 0 max unavailable, 1 max surge ...

金丝雀更新

myapp-deploy资源目前的更新策略为{"maxSurge":1,"maxUnavailable":0},即至多可多于replicas一个,pod数不能少于replicas数量。金丝雀发布在此种策略下就是创建一个新版本的pod后自动暂停后边的滚动更新,让pod多一个,此pod是运行新版本的程序,等运行一段时间后测试无问题再继续暂停的后续更新操作。

# 监视相应pods k8s@node01:~$ kubectl get pods -l app=myapp -w # 也可用以下命令监视,不过需要在执行“kubectl set image deploy myapp-deploy ...”之后再执行 k8s@node01:~$ kubectl rollout status deployment myapp-deploy # 更新到v3版本 k8s@node01:~/my_manifests$ kubectl set image deploy myapp-deploy myapp=ikubernetes/myapp:v3 && kubectl rollout pause deployment myapp-deploy # 前一个命令执行后接着就执行 pause 操作,如果监视窗口中发现未有新的Pod被创建,那就是还没来得及创建就被pause了,这时就需要把这两个命令分开写,先执行第一条命令,执行后就去观察监视pods变化的终端,一旦发现有新的pod被创建后就需要立刻执行 pause 指令让后边的更新暂停。 # 查看pods状态,前3个是才创建的pod,后3个是旧的Pod,共6个,因执行pause的时机问题,可能会多创建新pod,如果觉得过多可手动删除 k8s@node01:~/my_manifests$ kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-577b6ccbf8-4pzk6 1/1 Running 0 42s myapp-deploy-577b6ccbf8-l7d42 1/1 Running 0 17s myapp-deploy-577b6ccbf8-lqfnk 1/1 Running 0 31s myapp-deploy-9d8d5cb4c-kn7fk 1/1 Running 0 16m myapp-deploy-9d8d5cb4c-rgxp2 1/1 Running 0 17m myapp-deploy-9d8d5cb4c-xsm6b 1/1 Running 0 16m # 查看replicaset,可以看到3个pod是v2版本,另3个是v3版本 k8s@node01:~/my_manifests$ kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-deploy-577b6ccbf8 3 3 3 62s myapp ikubernetes/myapp:v3 app=myapp,pod-template-hash=577b6ccbf8,release=canary myapp-deploy-679fcdf84 0 0 0 23m myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=679fcdf84,release=canary myapp-deploy-9d8d5cb4c 3 3 3 17m myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=9d8d5cb4c,release=canary # 如果经过一段时间的运行,可以把剩下的v2版本的Pod升级为v3,那执行以下命令 k8s@node01:~$ kubectl rollout resume deployment myapp-deploy

当全部pod都升级到新版本后,突然又发现新版本有问题,需要回退版本,那可采取以下操作:

如果直接回退到上一个版本,kubectl rollout提供了undo操作,默认回退到上一个版本,使用--to-revision=VERSION_NUMBER选项指定回退到哪一个版本,使用kubectl rollout history TYPE/NAME查看相应资源的版本号 使用kubectl set image设定容器所需要回滚的镜像版本,让其快速滚动更新 修改yaml资源配置清单,推荐使用配置清单。

DaemonSet

每一个满足条件的工作节点上只运行一个pod,实现工作节点的管理功能。日志收集程序(filebeat)适用于此种控制器

daemonset 可简写为ds,使用kubectl explain ds查看资源清单中相应字段的帮助信息。

这里通过一个事例来说明daemonset控制器的使用场景

1. filebeat的pod需要使用daemonset控制器管理,实现每个工作节点只运行一个副本 2. filebeat需要使用redis服务,把收集到的日志写入redis队列 3. filebeat连接redis时使用域名,此域名即为redis的service的名称,service作为filebeat的连接端点 注: filebeat这个DaemonSet资源应该实现存储卷挂载工作节点的“/var/log/”目录,并对此目录下相应的日志文件进行收集,本配置清单中未实现卷的挂载,只在容器内部测试日志的收集。

# 一个yaml文件里可以定义多个类型的资源清单,使用“---”分隔 k8s@node01:~/my_manifests$ cat daemonset-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: redis-deploy namespace: default spec: selector: matchLabels: app: redis role: logstore replicas: 1 template: metadata: labels: app: redis role: logstore spec: containers: - name: redis4 image: redis:6.0.6-alpine ports: - name: redis-port containerPort: 6379 --- apiVersion: v1 kind: Service metadata: name: redis namespace: default spec: selector: app: redis role: logstore ports: - name: svc-port protocol: TCP port: 6379 targetPort: 6379 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat-ds namespace: default spec: selector: matchLabels: app: filebeat release: stable template: metadata: labels: app: filebeat release: stable spec: containers: - name: filebeat-pod image: ikubernetes/filebeat:5.6.5-alpine env: - name: REDIS_HOST value: redis.default.svc.cluster.local - name: REDIS_LOG_LEVEL value: info

# 应用清单 k8s@node01:~/my_manifests$ kubectl apply -f daemonset-demo.yaml deployment.apps/redis-deploy created service/redis created daemonset.apps/filebeat-ds created # 连接到filebeat的pod中查看filebeat收集的日志有哪些,并触发相应的日志写入,filebeat写redis k8s@node01:~/my_manifests$ kubectl exec -it filebeat-ds-8wwnz -- /bin/sh / # ps PID USER TIME COMMAND 1 root 0:00 /usr/local/bin/filebeat -e -c /etc/filebeat/filebeat.yml 11 root 0:00 /bin/sh 16 root 0:00 ps / # cat /etc/filebeat/filebeat.yml filebeat.registry_file: /var/log/containers/filebeat_registry filebeat.idle_timeout: 5s filebeat.spool_size: 2048 logging.level: info filebeat.prospectors: - input_type: log paths: - "/var/log/containers/*.log" - "/var/log/docker/containers/*.log" - "/var/log/startupscript.log" - "/var/log/kubelet.log" - "/var/log/kube-proxy.log" - "/var/log/kube-apiserver.log" - "/var/log/kube-controller-manager.log" - "/var/log/kube-scheduler.log" - "/var/log/rescheduler.log" - "/var/log/glbc.log" - "/var/log/cluster-autoscaler.log" symlinks: true json.message_key: log json.keys_under_root: true json.add_error_key: true multiline.pattern: '^\s' multiline.match: after document_type: kube-logs tail_files: true fields_under_root: true output.redis: hosts: ${REDIS_HOST:?No Redis host configured. Use env var REDIS_HOST to set host.} key: "filebeat" # 手动追加一个日志信息,触发写redis操作 / # echo "2020/07/26 17:12 test log data" > /var/log/containers/test.log # 连接到redis中查看是否有数据 k8s@node01:~$ kubectl exec -it redis-deploy-66856679cd-hth25 -- /bin/sh /data # redis-cli 127.0.0.1:6379> keys * 1) "filebeat" 127.0.0.1:6379> LLEN filebeat (integer) 1 127.0.0.1:6379> LINDEX filebeat 0 "{\"@timestamp\":\"2020-07-26T09:12:49.745Z\",\"beat\":{\"hostname\":\"filebeat-ds-8wwnz\",\"name\":\"filebeat-ds-8wwnz\",\"version\":\"5.6.5\"},\"input_type\":\"log\",\"json_error\":\"Error decoding JSON: json: cannot unmarshal number into Go value of type map[string]interface {}\",\"log\":\"2020/07/26 17:12 test log data\",\"offset\":31,\"source\":\"/var/log/containers/test.log\",\"type\":\"kube-logs\"}" 127.0.0.1:6379>

Job

只一次运行任务,运行完成后pod被中止,但并不会被删除pod。

Cronjob

周期性运行任务

StatefulSet

有状态控制器,管理有状态服务,如: redis cluster

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:玩转SQLite6:使用C语言来读写数据库
下一篇:Java利用策略模式实现条件判断,告别if else
相关文章

 发表评论

暂时没有评论,来抢沙发吧~