本文主要介绍下pod控制器(Controllers),涉及到的pod控制器仅包括ReplicaSet(副本集),DeployMent(部署),ReplicationController(复制控制器),和DaemonSet(守护程序集)。
一般很少会直接在Kubernetes中创建单个Pod,因为单个pod不好管理,容易被删除,无自我修复功能。
通过Controller可以创建和管理多个Pod,通过创建删除来保证集群内资源数量更接近所需状态。类似恒温器。例如,如果某个node发生故障,则Controller可能会在另一个node上安排相同的替换操作来自动替换故障Pod。
Controller Manager作为集群内部的管理控制中心,负责集群内的Node、Pod副本、服务端点(Endpoint)、命名空间(Namespace)、服务账号(ServiceAccount)、资源定额(ResourceQuota)的管理,当某个Node意外宕机时,Controller Manager通过apiserver的监控机制会及时发现并执行自动化修复流程,确保集群始终处于预期的工作状态。
Controller Manager管理的Controllers有很多,如:
本文主要介绍和pod有关的Controllers:ReplicaSet
,DeployMent
,ReplicationController
,和DaemonSet
。
ReplicaSet的目的是维护在任何给定时间运行的稳定的副本Pod集。因此,它通常用于保证指定数量的相同Pod的可用性。
如果需要自定义更新编排或根本不需要更新,可以使用ReplicaSet(副本集),否则建议使用DeployMent(部署)。DeployMent是一个高级概念,用于管理ReplicaSet,并提供对Pod的声明性更新以及许多其他有用的功能。所以我们就愉快的使用DeployMent吧,不看这个了。emmmmだめだ,果然还是要测试下,看下区别吧。
# rs-test.yaml,ReplicaSet和DeployMent写法差不多
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: mynginx
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: mynginx
release: canary
template:
metadata:
labels:
app: mynginx
release: canary
spec:
containers:
- name: mynginx
image: xlbubble/hostname:1.0
ports:
- name: http
containerPort: 8000
通过创建下看下,执行以下命令,可以看到执行结果和之前的deployment结果一样,没什么差异。
# kubectl apply -f rs-test.yaml
# kubectl get pods -l app
# kubectl delete po mynginx-8ssf5 mynginx-w2fmg
# kubectl get pods -w -l app
# kubectl scale --replicas=5 rs mynginx
若pod down或被删,控制器会创建新的pod,名字和ip会更改,需要service映射
通过replicas创建的pod,down后会服务暂停重新创建pod,需要通过deployment支持滚动更新。
但是在更新镜像时就有点问题了,通过replicaset创建的pod,不支持滚动更新,只能先手动delete之前的pod后才会更新为set设置的镜像2.0。所以需要通过deployment支持滚动更新。
# 创建个service
# kubectl expose rs mynginx --name=nginx --port=80 --target-port=8000 --protocol=TCP
# curl看下
# while true;do echo `curl 10.10.98.98 -s`;sleep 2;done
Version: 1.0 | mynginx-tbsjp
Version: 1.0 | mynginx-hhn7d
Version: 1.0 | mynginx-tbsjp
Version: 1.0 | mynginx-tbsjp
Version: 1.0 | mynginx-tbsjp
Version: 1.0 | mynginx-hhn7d
Version: 1.0 | mynginx-tbsjp
# 更换容器镜像
# kubectl set image replicaset mynginx mynginx=xlbubble/hostname:2.0
# 再curl,结果和第一次curl一样,镜像没有更换
# while true;do echo `curl 10.10.98.98 -s`;sleep 2;done
Version: 1.0 | mynginx-hhn7d
Version: 1.0 | mynginx-hhn7d
Version: 1.0 | mynginx-tbsjp
Version: 1.0 | mynginx-tbsjp
Version: 1.0 | mynginx-hhn7d
Version: 1.0 | mynginx-tbsjp
Version: 1.0 | mynginx-tbsjp
# delete之后curl看下,可以看到更换为2.0了
# kubectl delete po mynginx-hhn7d mynginx-tbsjp
# while true;do echo `curl 10.10.184.179 -s`;sleep 2;done
Version: 2.0 | mynginx-crznh
Version: 2.0 | mynginx-crznh
Version: 2.0 | mynginx-crznh
Version: 2.0 | mynginx-kdktw
Version: 2.0 | mynginx-kdktw
Version: 2.0 | mynginx-crznh
当然,也可以通过patch更新镜像,patch会直接更新yaml字段。
建立于ReplicaSet之上,支持滚动更新等功能,管理无状态应用。kubectl explain deployment
具体操作见上一篇博客。
ReplicationController比ReplicaSet还不可取,因为之前不可取的ReplicaSet是建立在更不可取ReplicationController之上的。两者基本相同,但ReplicationController还不支持标签选择器。因此,还是选DeployMent吧。
DaemonSet确保集群中每个(部分)node运行一份pod副本,当node加入集群时创建pod,当node离开集群时回收pod。如果删除DaemonSet,其创建的所有pod也被删除,DaemonSet中的pod覆盖整个集群。
当需要在集群内每个node运行同一个pod,建议使用DaemonSet,以下是典型使用场景:
运行集群存储守护进程,如glusterd、ceph。
运行集群日志收集守护进程,如fluentd、logstash。
运行节点监控守护进程,如Prometheus Node Exporter, collectd, Datadog agent, New Relic agent, or Ganglia gmond。
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
demo: redis
role: logstor
template:
metadata:
labels:
demo: redis
role: logstor
spec:
containers:
- name: redis
image: redis:4.0-alpine
ports:
- name: redis
containerPort: 6379
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
namespace: default
spec:
selector:
matchLabels:
demo: filebeat
release: canary
template:
metadata:
labels:
demo: filebeat
release: canary
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 -f daemon-demo.yaml
kubectl get pods -l "demo in (filebeat,redis)"
kubectl expose deploy redis --port=6379
kubectl exec -it redis-99cdd6586-cvlg6 -- /bin/sh
/data # redis-cli -h redis.default.svc.cluster.local
kubectl exec -it filebeat-ds-9x7kj -- /bin/sh
可以看到各pod之间用service调用。daemonset每个节点一个,更新支持rollingUpdate和ondelete方式。
kubectl explain ds.spec.updateStrategy
kubectl explain ds.spec.updateStrategy.rollingUpdate
滚动更新并观察
kubectl set image daemonsets filebeat-ds filebeat=ikubernetes/filebeat:5.6.7-alpine
kubectl get pods -l "demo in (filebeat,redis)" -w