目录
Pod 资源
spec.containers <[]object> - name <string> image <string> imagePullPolicy <string> 镜像获取策略 imagesPullPolicy:IfNotPresen # 行8解释 Always总是去远程仓库拉取, Never从来不去远程仓库拉取, IfNotPresent如果本地仓库不存在就去下载 默认情况:如果镜像指定为latest版本,那默认为Always,如果不是那默认就是IfNotPresent 如果镜像指定为latest版本,但不想去远程拉取,那么可以加上imagesPullPolicy:IfNotPresent
标签
每个资源都可以有多个标签,每个标签也可以添加到多个对象资源之上。
标签格式:key= value ==注==:键值最多使用63个字符
key: 字母 、 数字 、
-
、.
value: 可以为空,只能字母或数字开头结尾,中间可使用-
、.
查看pods
的标签:
[root@master manifests]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS myapp-84cd4b7f95-44qch 1/1 Running 0 7d5h pod-template-hash=84cd4b7f95,run=myapp myapp-84cd4b7f95-fzvsd 1/1 Running 0 7d5h pod-template-hash=84cd4b7f95,run=myapp myapp-84cd4b7f95-mlphg 1/1 Running 0 7d5h pod-template-hash=84cd4b7f95,run=myapp nginx-deploy-7689897d8d-lf8p7 1/1 Running 0 7d6h pod-template-hash=7689897d8d,run=nginx-deploy pod-demo 2/2 Running 0 29s app=myapp,tier=frontend
使用 -l 参数,来过滤标签
[root@master manifests]# kubectl get pods -l app NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 0 3m21s
给资源打标签
使用 kubectl label
Usage: kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version] [options] 实例: kubectl label pods pod-demo release=canary #给pod-demo打标签 kubectl label pods pod-demo release=stable --overwrite #修改pod-demo的release标签
标签选择器
- 等之关系:=、==、!= 来进行操作
- 集合关系
KEY in (VALUE1,VALUE2,...)
KEY notin (VALUE1,VALUE2,...)
[root@master manifests]# kubectl get pods -l release NAME READY STATUS RESTARTS AGE nginx-deploy-7689897d8d-lf8p7 1/1 Running 0 7d6h pod-demo 2/2 Running 0 11m [root@master manifests]# kubectl get pods -l release=canary NAME READY STATUS RESTARTS AGE nginx-deploy-7689897d8d-lf8p7 1/1 Running 0 7d6h [root@master manifests]# kubectl get pods -l release,app NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 0 12m [root@master manifests]# kubectl get pods -l release=stable,app=myapp NAME READY STATUS RESTARTS AGE pod-demo 2/2 Running 0 12m
许多资源支持内嵌字段定义其使用的标签选择器:
matchLabels: 直接给定键值
matchExpressions: 基于给定的表达式来定义使用标签选择器,{key:"KEY", operator: "OPERATOR", values: [VAL1,VAL2,...]}
操作符:
In, NotIn: values 字段的值必须为非空列表;
Exists, NotExists: values字段的值必须为空列表;
nodeSelector <map[string]string>
节点标签选择器,是可以影响pods调度算法的。
案例:
[root@master manifests]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-7689897d8d-lf8p7 1/1 Running 0 8d 10.244.3.2 node02.kubernetes <none> <none> [root@master manifests]# kubectl delete -f pod-demo.yaml pod "pod-demo" deleted [root@master manifests]# vim pod-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend #自行定义备注,此处意为层级架构中的最前端 spec: containers: - name: myapp image: ikubernetes/myapp:v1 - name: busybox image: busybox:latest imagePullPolicy: IfNotPresent command: - "/bin/sh" - "-c" - "sleep 3600" nodeSelector: disktype: ssd [root@master manifests]# kubectl create -f pod-demo.yaml pod/pod-demo created [root@master manifests]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES pod-demo 2/2 Running 0 4s 10.244.3.10 node01.kubernetes <none> <none>
nodeName
指定调度到节点的名称
annoitations (pod的注解信息,可用kubectl describe pod xxx查看)
与label不同的是,不能用于挑选资源对象,仅用于为对象提供"元数据",某些场景是必须的,无键值长度限制。
Pod 生命周期
Pod生命周期主要分为两个阶段:
1. 初始化容器初始化阶段 2. 主容器正常运行阶段
Pod 状态:
1. 首先Pod进入初始化阶段,使用初始化容器完成初始化,可以有多个初始化容器,但是串行。(上图中inin c) 2. 初始化之后主容器进入正式运行阶段。 3. 主容器启动之后,会执行一次命令,就是 'post start',也就是启动后钩子,执行结束后就退出了。 4. 命令执行只有,会有一个主容器存活状态检测,就是'liveness probe'。 5. 同时也会做就容器就绪性检测,检测主容器是否正常运行,就是 'readiness probe'。 6. 当主容器要退出的时候,也会有个结束前执行的命令,就是 'pre stop',结束前钩子,这个Pod就退出。
pod容器探测:
liveness probe # 用于探测主容器是否存活(存活性检测)
readiness probe # 判定容器中的主进程是否就绪,是否对外提供服务(服务就绪性检测)
无论哪一种,都支持三种。
- 自定义命令
- 向指定的TCP套接字发请求
- 向指定的HTTP服务发请求
Pod 状态:
Pending : 挂起状态,调度尚未完成,没有适合创建的节点,不满足存活的状态。 Runing : 运行状态 Failed : 失败状态 Succeeded : 成功状态 Unknown : 未知状态,有可能是目标node上的kubectl出现故障
创建Pod所经历的状态
1. 当用户创建Pod的时候,会去请求提交给apiserver,然后会把目标状态保存在etcd中, 2. 然后 apiserver 会去请求 scheduler进行调度,并且把调度的结果保存在ETCD中之前保存的Pod状态中。 3. 一旦存在ETCD中发生更新,假如调度在node01上,node01 上的kubelet通过apiserver当中状态变化会知道。
restartPolicy:(pod的重启策略)
Always(总是重启), OnFailure(只有状态为错误时才重启), Never(不重启)。默认是Always
pod状态探测
探针类型有三种:
1. ExecAction(直接执行自定义的命令) 2. TCPsocketAction 3. HTTPGetAction
这三种探针,livenessProbe
和 readinessProbe
都可以使用。
livenessProbe 状态探测
livenessProbe exec 测试
创建Pod的yaml文件:
[root@master manifests]# cat liveness-exec.yaml apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default spec: containers: - name: liveness-exec-container image: busybox:latest imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 3600"] # 生成存活性文件 livenessProbe: exec: command: ["test", "-e", "/tmp/healthy"] # 使用命令探测文件是否存在 initialDelaySeconds: 1 # 容器启动后,多久开始探测,单位秒 periodSeconds: 3 # 每次探测间隔时间,单位秒 successThreshold: 1 # 成功几次 failureThreshold: 2 # 失败几次后重启 timeoutSeconds: 2 # 开始探测后的超时时间,单位秒 [root@master manifests]# kubectl create -f liveness-exec.yaml pod/liveness-exec-pod created [root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 0 4s
等一会之后:
[root@master manifests]#kubectl get pods NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 1 2m20s [root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 2 2m40s
查看详细信息:
[root@master manifests]# kubectl describe pod liveness-exec-pod Name: liveness-exec-pod Namespace: default Priority: 0 Node: node03.kubernetes/10.0.20.23 Start Time: Fri, 19 Jul 2019 11:13:19 +0800 Labels: <none> Annotations: <none> Status: Running IP: 10.244.1.8 Containers: liveness-exec-container: Container ID: docker://e028a5c4796c9e138e9669292f5b82fc76244017463039ef2141dab3da9d5cdd Image: busybox:latest Image ID: docker-pullable://busybox@sha256:c94cf1b87ccb80f2e6414ef913c748b105060debda482058d2b8d0fce39f11b9 Port: <none> Host Port: <none> Command: /bin/sh -c touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 3600 State: Running Started: Fri, 19 Jul 2019 11:14:34 +0800 Last State: Terminated Reason: Error # 这里提示错误 Exit Code: 137 Started: Fri, 19 Jul 2019 11:13:20 +0800 Finished: Fri, 19 Jul 2019 11:14:34 +0800 Ready: True Restart Count: 1 # 提示被重启过一次 Liveness: exec [test -e /tmp/healthy] delay=1s timeout=2s period=10s #success=1 #failure=2 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-bc86p (ro) ........ ........
livenessProbe httpGet 测试
创建Pod的yaml文件:
[root@master manifests]# cat liveness-httpget.yaml apiVersion: v1 kind: Pod metadata: name: liveness-httpget-pod namespace: default spec: containers: - name: liveness-httpget-container image: ikubernetes/myapp:v1 # 此镜像自带80端口 imagePullPolicy: IfNotPresent ports: - name: http # 这里定义映射端口名称 containerPort: 80 # 指定端口 livenessProbe: httpGet: port: http # 这里直接使用定义的端口名称即可 path: /index.html # 定义探测http对应的路径 initialDelaySeconds: 1 periodSeconds: 3 successThreshold: 1 failureThreshold: 2 timeoutSeconds: 2 [root@master manifests]# kubectl create -f liveness-httpget.yaml pod/liveness-httpget-pod created [root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-httpget-pod 1/1 Running 0 3s
手动进入到容器中,然后删除index.html
文件
[root@master ~]# kubectl exec -it liveness-httpget-pod -- /bin/sh / # rm -f /usr/share/nginx/html/index.html / # command terminated with exit code 137
再来查看刚刚创建的pod状态:
[root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-httpget-pod 1/1 Running 1 7m14s # 这里可以看到已经被重启过一次了 [root@master manifests]# kubectl describe pods liveness-httpget-pod # 查看详细信息 Name: liveness-httpget-pod Namespace: default Priority: 0 Node: node02.kubernetes/10.0.20.22 Start Time: Fri, 19 Jul 2019 11:26:56 +0800 Labels: <none> Annotations: <none> Status: Running IP: 10.244.2.6 Containers: liveness-httpget-container: Container ID: docker://39d3905acd7dac561905e77772522e652843dc3f2e0023a07586d3db088ca87f Image: ikubernetes/myapp:v1 Image ID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513 Port: 80/TCP Host Port: 0/TCP State: Running Started: Fri, 19 Jul 2019 11:29:06 +0800 Last State: Terminated # 状态不正常 Reason: Completed Exit Code: 0 Started: Fri, 19 Jul 2019 11:26:57 +0800 Finished: Fri, 19 Jul 2019 11:29:06 +0800 Ready: True Restart Count: 1 # 这里看到被重启过一次 Liveness: http-get http://:http/index.html delay=1s timeout=2s period=3s #success=1 #failure=2 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-bc86p (ro) .... .... .... ....
这里只会被重启过一次,因为当readinessProbe侦察到容器不处于就绪状态后,就会重启容器,重启的容器中index.html 文件又会被重新生产。
readinessProbe 就绪性探针
创建Pod的yaml文件,配置readinessProbe就绪性探针:
[root@master manifests]# cat readiness-httpget.yaml apiVersion: v1 kind: Pod metadata: name: readiness-httpget-pod namespace: default spec: containers: - name: readiness-httpget-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 readinessProbe: httpGet: port: http path: /index.html initialDelaySeconds: 1 periodSeconds: 3 successThreshold: 1 failureThreshold: 2 timeoutSeconds: 2 [root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE readiness-httpget-pod 1/1 Running 0 53s
进入到 readiness-httpget-pod
中,手动删除index.html
主页文件,再次查看:
[root@master ~]# kubectl exec -it readiness-httpget-pod -- /bin/sh / # rm -rf /usr/share/nginx/html/index.html / # ps aux PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; # nginx依然运行这 6 nginx 0:00 nginx: worker process 7 root 0:00 /bin/sh 13 root 0:00 ps aux [root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE readiness-httpget-pod 0/1 Running 0 60s # 就绪状态的pod为 0 个 [root@master manifests]# kubectl describe pods readiness-httpget-pod Name: readiness-httpget-pod Namespace: default Priority: 0 Node: node03.kubernetes/10.0.20.23 Start Time: Mon, 22 Jul 2019 09:09:50 +0800 Labels: <none> Annotations: <none> Status: Running IP: 10.244.1.9 Containers: readiness-httpget-container: Container ID: docker://71009463c970b6712d97c8692990caa8c2192841b6e075a1d0db9ac15a2d1cd7 Image: ikubernetes/myapp:v1 Image ID: docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513 Port: 80/TCP Host Port: 0/TCP State: Running Started: Mon, 22 Jul 2019 09:09:51 +0800 Ready: False Restart Count: 0 Readiness: http-get http://:http/index.html delay=1s timeout=2s period=3s #success=1 #failure=2 Environment: <none> Mounts: /var/run/secrets/kubernetes.io/serviceaccount from default-token-bc86p (ro) Conditions: Type Status Initialized True Ready False # 详细信息中,显示为错误。 ContainersReady False PodScheduled True .... .... .... ....
当就绪性探针发现此Pod不可用时,service 调度会把此pod剔除集群
手动此创建Pod中的index.html
文件:
/ # echo 'hi' > /usr/share/nginx/html/index.html [root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE readiness-httpget-pod 1/1 Running 0 118s
已经恢复,此时service
又会把此Pod 重新加入到集群中。
Pod 控制器
ReplicaSet:
- 用户期望的Pod副本数量,支持多删少补
- 标签选择器,一遍选择自己管理和控制Pod副本
- Pod资源模板来完成Pod资源的新建
Deployment:
- 工作在ReplicaSet之上,不直接控制Pod,而是控制ReplicaSet
- 支持滚动更新和回滚等, 可滚动更新或回滚
- 提供声明式配置功能
DaemonSet
- 无状态的,必须是守护进程类的,
- 确保kubernetes所有节点只运行一个Pod
- 保障系统级的后台任务
- 只能管控无状态应用,关注群体,不关注个体
Job
- 只能执行一次性的作业
Cronjob
- 周期性执行,不执行不启动
StatefulSet
- 管理有状态应用
TPR
Third Party Resources, 1.2 版本开始能用,1.7版本后不可用
第三方资源CDR
Custom Defined Resource, 1.8 版本之后可用
第三方资源
ReplicaSet 控制器
创建一个ReplicaSet清单文件
[root@master manifests]# cat rs-demo.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: myapp namespace: default spec: replicas: 2 # Pod 副本数为 2 selector: matchLabels: # 定义标签选择器 app: myapp release: canary template: # 这里以下定义的和一个单独的Pod清单文件一样 metadata: # 定义Pod对应的标签,会被ReplicaSet控制器选择 name: myapp-pod namespace: default labels: app: myapp release: canary environment: qa spec: containers: - name: myapp-container image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 [root@master manifests]# kubectl create -f rs-demo.yaml replicaset.apps/myapp created [root@master manifests]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-k4m9l 1/1 Running 0 27s 10.244.1.13 node03.kubernetes <none> <none> myapp-p9dk9 1/1 Running 0 27s 10.244.3.14 node01.kubernetes <none> <none>
两个副本的Pod已经被创建。
可以直接使用kubectl edit
来编辑:
[root@master manifests]# kubectl edit rs myapp replicaset.extensions/myapp edited # 这里打开后,把replicas的值变更为3,也就是增加一个后。 [root@master manifests]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-p9dk9 1/1 Running 0 14m 10.244.3.14 node01.kubernetes <none> <none> myapp-vjnlq 1/1 Running 0 8s 10.244.1.14 node03.kubernetes <none> <none> myapp-wl9nh 1/1 Running 0 10m 10.244.2.10 node02.kubernetes <none> <none> # 这里立刻就会再次创建一个Pod 出来 道理相同,减少replicas的数量的时候,Pod对应的数量也会减少,、 也可以直接编辑对应的Pod版本,只是编辑后不会自动更新,但当手动删除一个Pod的时候,再次自动创建新的Pod的时候,就会更新清单中的Pod。 [root@master manifests]# kubectl edit rs myapp replicaset.extensions/myapp edited [root@master manifests]# kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp 3 3 3 15m myapp-container ikubernetes/myapp:v2 app=myapp,release=canary [root@master manifests]# curl 10.244.3.14 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> [root@master manifests]# kubectl delete pods myapp-p9dk9 pod "myapp-p9dk9" deleted [root@master manifests]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-fwnwz 1/1 Running 0 14s 10.244.3.15 node01.kubernetes <none> <none> myapp-vjnlq 1/1 Running 0 2m33s 10.244.1.14 node03.kubernetes <none> <none> myapp-wl9nh 1/1 Running 0 12m 10.244.2.10 node02.kubernetes <none> <none> [root@master manifests]# curl 10.244.3.15 Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
基于这种策略,可以实现蓝绿
发布,具体实现如下图:
Deployment 控制器
这里直接使用声明式创建,使用kubectl apply命令
首先创建清单
root@master manifests]# cat deploy-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 2 # 副本数为 2 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 [root@master manifests]# kubectl apply -f deploy-demo.yaml deployment.apps/myapp-deploy created
查看:
root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-f4db5d79c-md2kk 1/1 Running 0 4s myapp-deploy-f4db5d79c-wwx5n 1/1 Running 0 4s [root@master manifests]# kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE myapp-deploy 2/2 2 2 11s [root@master manifests]# kubectl get rs NAME DESIRED CURRENT READY AGE myapp-deploy-f4db5d79c 2 2 2 43s
- 2个Pod创建成功并正常运行
- Deployment 正常
- Deployment 会自动创建一个ReplicaSet,通过管理ReplicaSet,ReplicaSet再去管理Pod。
- Pod的名称是Deployment名称加上ReplicaSet最后面生产的hash值,再跟上自己的Hash值组成
查看 deployment 详细信息
root@master manifests]# kubectl get deploy NAME READY UP-TO-DATE AVAILABLE AGE myapp-deploy 3/3 3 3 2m34s [root@master manifests]# kubectl describe deploy myapp-deploy Name: myapp-deploy Namespace: default CreationTimestamp: Tue, 23 Jul 2019 17:05:49 +0800 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 # 每次的变化,都会被保存在 Annotations当中 kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"myapp-deploy","namespace":"default"},"spec":{"replicas":3... Selector: app=myapp,release=canary Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate # 默认的更新策略,滚动更新 MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge # 最大不可用是25%,最大可用是25%,不足一个的时候,补足一个 Pod Template: Labels: app=myapp release=canary Containers: myapp: Image: ikubernetes/myapp:v1 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: myapp-deploy-f4db5d79c (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 3m15s deployment-controller Scaled up replica set myapp-deploy-f4db5d79c to 2 Normal ScalingReplicaSet 50s deployment-controller Scaled up replica set myapp-deploy-f4db5d79c to 3
测试滚动更新
在一个窗口上来监控标签 app=myapp 的Pod
[root@master manifests]# kubectl get pods -l app=myapp -w # 这里执行后,会一直等待不动,知道有变化才会有更新 NAME READY STATUS RESTARTS AGE myapp-deploy-f4db5d79c-cvvl6 1/1 Running 0 2m20s myapp-deploy-f4db5d79c-md2kk 1/1 Running 0 4m45s myapp-deploy-f4db5d79c-wwx5n 1/1 Running 0 4m45s
在另一个窗口,重新编辑清单deploy-demo.yaml
文件中的副本数为 5
[root@master manifests]# cat deploy-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 5 # 这里副本数修改为 5 selector: matchLabels: app: myapp release: canary template: metadata: labels: app: myapp release: canary spec: containers: - name: myapp image: ikubernetes/myapp:v2 ports: - name: http containerPort: 80
然后直接使用kubectl apply
命令 声明式方式来变更
[root@master manifests]# kubectl apply -f deploy-demo.yaml deployment.apps/myapp-deploy configured
当执行完成后,监控的窗口就会出现变化
[root@master manifests]# kubectl get pods -l app=myapp -w NAME READY STATUS RESTARTS AGE myapp-deploy-f4db5d79c-cvvl6 1/1 Running 0 2m20s myapp-deploy-f4db5d79c-md2kk 1/1 Running 0 4m45s myapp-deploy-f4db5d79c-wwx5n 1/1 Running 0 4m45s myapp-deploy-f4db5d79c-cvvl6 1/1 Terminating 0 3m26s myapp-deploy-55b78d8548-zsl5d 0/1 Pending 0 0s myapp-deploy-55b78d8548-zsl5d 0/1 Pending 0 0s myapp-deploy-55b78d8548-zsl5d 0/1 ContainerCreating 0 0s myapp-deploy-f4db5d79c-cvvl6 0/1 Terminating 0 3m27s myapp-deploy-55b78d8548-zsl5d 1/1 Running 0 1s myapp-deploy-f4db5d79c-md2kk 1/1 Terminating 0 5m52s myapp-deploy-55b78d8548-l264b 0/1 Pending 0 0s myapp-deploy-55b78d8548-l264b 0/1 Pending 0 0s myapp-deploy-55b78d8548-l264b 0/1 ContainerCreating 0 0s myapp-deploy-f4db5d79c-cvvl6 0/1 Terminating 0 3m28s myapp-deploy-f4db5d79c-cvvl6 0/1 Terminating 0 3m28s myapp-deploy-f4db5d79c-md2kk 0/1 Terminating 0 5m53s myapp-deploy-55b78d8548-l264b 1/1 Running 0 2s myapp-deploy-f4db5d79c-wwx5n 1/1 Terminating 0 5m54s myapp-deploy-f4db5d79c-wwx5n 0/1 Terminating 0 5m54s myapp-deploy-f4db5d79c-md2kk 0/1 Terminating 0 6m1s myapp-deploy-f4db5d79c-md2kk 0/1 Terminating 0 6m1s myapp-deploy-f4db5d79c-wwx5n 0/1 Terminating 0 6m4s myapp-deploy-f4db5d79c-wwx5n 0/1 Terminating 0 6m4s
此时来再查看
[root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE myapp-deploy-55b78d8548-cw4r5 1/1 Running 0 5s myapp-deploy-55b78d8548-jwj2j 1/1 Running 0 5s myapp-deploy-55b78d8548-l264b 1/1 Running 0 4m20s myapp-deploy-55b78d8548-mnm95 1/1 Running 0 5s myapp-deploy-55b78d8548-zsl5d 1/1 Running 0 4m21s
查看 ReplicaSet
[root@master manifests]# kubectl get rs -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR myapp-deploy-55b78d8548 5 5 5 59s myapp ikubernetes/myapp:v2 app=myapp,pod-template-hash=55b78d8548,release=canary myapp-deploy-f4db5d79c 0 0 0 6m50s myapp ikubernetes/myapp:v1 app=myapp,pod-template-hash=f4db5d79c,release=canary
查看ReplicaSet后发现有两个,因为Deployment 会重新创建一个ReplicaSet来更新,IMAGES版本一列可以看出版本的不同,通过把新的Pod创建在新的ReplicaSet上来实现滚动更新
DaemonSet 控制器
DaemonSet 控制器主要用于系统级别的无状态环境。 默认创会在 kubernetes 集群中每一个节点创建一个Pod。
创建一个DaemonSet配置清单
[root@master manifests]# cat daemonset-demo.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: myapp-ds namespace: default spec: selector: matchLabels: app: filebeat release: stable template: metadata: labels: app: filebeat release: stable spec: containers: - name: filebeat image: ikubernetes/filebeat:5.6.5-alpine # 这里使用filebeat来进行测试 env: # 增加两个环境变量 - name: REDIS_HOST # 指定redis地址 value: redis.default.svc.cluster.local # 这里使用集群域名来解析redis地址 - name: REDIS_LOG_LEVEL # 指定日志级别 value: info # 日志级别为info [root@master manifests]# kubectl apply -f daemonset-demo.yaml daemonset.apps/myapp-ds created [root@master manifests]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-ds-jxwfq 1/1 Running 0 9s 10.244.1.22 node03.kubernetes <none> <none> myapp-ds-mw9vw 1/1 Running 0 9s 10.244.3.25 node01.kubernetes <none> <none> myapp-ds-xjqdb 1/1 Running 0 9s 10.244.2.18 node02.kubernetes <none> <none>
可以看到已经被创建成功,并且是每个节点都只有一个Pod。
查看详细信息
[root@master manifests]# kubectl describe ds myapp-ds Name: myapp-ds Selector: app=filebeat,release=stable Node-Selector: <none> Labels: <none> Annotations: deprecated.daemonset.template.generation: 1 kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"apps/v1","kind":"DaemonSet","metadata":{"annotations":{},"name":"myapp-ds","namespace":"default"},"spec":{"selector":{"matc... Desired Number of Nodes Scheduled: 3 Current Number of Nodes Scheduled: 3 Number of Nodes Scheduled with Up-to-date Pods: 3 Number of Nodes Scheduled with Available Pods: 3 Number of Nodes Misscheduled: 0 Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=filebeat release=stable Containers: filebeat: Image: ikubernetes/filebeat:5.6.5-alpine Port: <none> Host Port: <none> Environment: REDIS_HOST: redis.default.svc.cluster.local REDIS_LOG_LEVEL: info Mounts: <none> Volumes: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulCreate 22m daemonset-controller Created pod: myapp-ds-qjg6w Normal SuccessfulCreate 22m daemonset-controller Created pod: myapp-ds-ftxzb Normal SuccessfulCreate 22m daemonset-controller Created pod: myapp-ds-66hnj
同样,一个配置清单中,可以把多个资源配置写在一个清单中,使用 --- 来分割
在相同的清单文件中,再定义一个redis 的 Deployment
[root@master manifests]# cat daemonset-demo.yaml apiVersion: apps/v1 kind: Deployment metadata: name: redis namespace: default spec: replicas: 1 selector: matchLabels: app: redis role: logstor template: metadata: labels: app: redis role: logstor spec: containers: - name: redis image: redis:4.0-alpine ports: - name: redis containerPort: 6379 --- apiVersion: apps/v1 kind: DaemonSet metadata: name: myapp-ds namespace: default spec: selector: matchLabels: app: filebeat release: stable template: metadata: labels: app: filebeat release: stable spec: containers: - name: filebeat image: ikubernetes/filebeat:5.6.5-alpine env: - name: REDIS_HOST value: redis.default.svc.cluster.local - name: REDIS_LOG_LEVEL value: info
再次使用 kubectl apply
来执行此清单文件
[root@master manifests]# kubectl apply -f daemonset-demo.yaml deployment.apps/redis created daemonset.apps/myapp-ds created [root@master manifests]# kubectl get pods NAME READY STATUS RESTARTS AGE myapp-ds-66hnj 1/1 Running 0 59s myapp-ds-ftxzb 1/1 Running 0 59s myapp-ds-qjg6w 1/1 Running 0 59s redis-5c998b644f-wnzrd 1/1 Running 0 59s
创建一个redis 的service
[root@master manifests]# kubectl expose deployment redis --port=6379 service/redis exposed [root@master manifests]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 15d redis ClusterIP 10.111.151.200 <none> 6379/TCP 4s
进入到redis pod中,并尝试解析redis
[root@master manifests]# kubectl exec -it redis-5c998b644f-wnzrd -- /bin/sh /data # netstat -tnl Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN tcp 0 0 :::6379 :::* LISTEN /data # ls /data # nslookup redis.default.svc.cluster.local nslookup: can't resolve '(null)': Name does not resolve Name: redis.default.svc.cluster.local Address 1: 10.111.151.200 redis.default.svc.cluster.local # 可以看到解析正常
同样,DaemonSet 也支持滚动更新,但个Deployment不同的时候,DaemonSet只支持删除Pod后再次新建,来进行更新
更新方式有好几种,这里使用 kubectl set image
来更新
[root@master manifests]# kubectl set image daemonset myapp-ds filebeat=ikubernetes/filebeat:5.6.6-alpine daemonset.extensions/myapp-ds image updated [root@master manifests]# kubectl get pods -o wide -w NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-deploy-f4db5d79c-7hnfg 1/1 Running 0 22h 10.244.2.16 node02.kubernetes <none> <none> myapp-deploy-f4db5d79c-85hpm 1/1 Running 0 22h 10.244.3.22 node01.kubernetes <none> <none> myapp-deploy-f4db5d79c-b9h4s 1/1 Running 0 22h 10.244.2.15 node02.kubernetes <none> <none> myapp-deploy-f4db5d79c-tm9mt 1/1 Running 0 22h 10.244.1.20 node03.kubernetes <none> <none> myapp-deploy-f4db5d79c-xp8t6 1/1 Running 0 22h 10.244.3.23 node01.kubernetes <none> <none> myapp-ds-8tvmc 0/1 ContainerCreating 0 10s <none> node03.kubernetes <none> <none> myapp-ds-f2pp8 1/1 Running 0 30s 10.244.2.20 node02.kubernetes <none> <none> myapp-ds-ftxzb 1/1 Running 0 25m 10.244.3.26 node01.kubernetes <none> <none> redis-5c998b644f-wnzrd 1/1 Running 0 25m 10.244.1.24 node03.kubernetes <none> <none> myapp-ds-8tvmc 1/1 Running 0 14s 10.244.1.25 node03.kubernetes <none> <none> myapp-ds-ftxzb 1/1 Terminating 0 25m 10.244.3.26 node01.kubernetes <none> <none> myapp-ds-ftxzb 0/1 Terminating 0 25m 10.244.3.26 node01.kubernetes <none> <none> myapp-ds-ftxzb 0/1 Terminating 0 25m 10.244.3.26 node01.kubernetes <none> <none> myapp-ds-ftxzb 0/1 Terminating 0 25m 10.244.3.26 node01.kubernetes <none> <none> myapp-ds-cs2hw 0/1 Pending 0 0s <none> <none> <none> <none> myapp-ds-cs2hw 0/1 Pending 0 0s <none> node01.kubernetes <none> <none> myapp-ds-cs2hw 0/1 ContainerCreating 0 0s <none> node01.kubernetes <none> <none> myapp-ds-cs2hw 1/1 Running 0 17s 10.244.3.27 node01.kubernetes <none> <none>
这里会一个一个更新,删除后下载镜像更新启动Pod。