十、K8s 其他控制器(DS、RC、RS、STS)
daemonset–ds:相比于deployment,daemonset不需要设置副本数,而是会自适应节点数,而是会自动在每个节点上创建一个pod,例如对一些特殊的应用,监控每个节点的信息,这时候就可以使用daemonset的方式来部署。...
实验环境:
按照图示部署好了K8s集群,一个Master,两个worker nodes。
DaemonSet(DS):
相比于deployment,daemonset不需要设置副本数,而是会自适应节点数,而是会自动在每个节点上创建一个pod。
应用场景:
- 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph;
- 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash;
- 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。
创建daemonset:
可以根据deployment 的yaml文件来修改:
kubectl create deployment ds1 --image=nginx --dry-run=client -o yaml >ds1.yaml
修改其yaml文件:修改kind类型,删除掉replicas、strategy和status三个元素即可。同时可以添加terminationGracePeriodSeconds和imagePullPolicy。
[root@vms201 daemonset]# cat ds1.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
labels:
app: ds1
name: ds1
spec:
selector:
matchLabels:
app: ds1
template:
metadata:
creationTimestamp: null
labels:
app: ds1
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
resources: {}
创建ds,可以看到其分布在2个work nodes上:
[root@vms201 daemonset]# kubectl apply -f ds1.yaml
daemonset.apps/ds1 created
[root@vms201 daemonset]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ds1-48x5f 1/1 Running 0 9s 10.244.58.212 vms202.rhce.cc <none> <none>
ds1-hn8q6 1/1 Running 0 9s 10.244.185.67 vms203.rhce.cc <none> <none>
如果控制ds仅在部分节点运行,可以通过如下方法实现:
首先给一个node打上标签:
[root@vms201 daemonset]# kubectl label nodes vms202.rhce.cc disktype=ssd
node/vms202.rhce.cc labeled
修改daemonset的yaml文件,增加nodeSelector,用标签的方式指定调度在哪个node上:
[root@vms201 daemonset]# kubectl edit daemonsets.apps ds1
daemonset.apps/ds1 edited
apiVersion: apps/v1
kind: DaemonSet
metadata:
creationTimestamp: null
labels:
app: ds1
name: ds1
spec:
selector:
matchLabels:
app: ds1
template:
metadata:
creationTimestamp: null
labels:
app: ds1
spec:
terminationGracePeriodSeconds: 0
nodeSelector:
disktype: ssd
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
resources: {}
查看ds是否修改成功:
[root@vms201 daemonset]# kubectl get ds ds1
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
ds1 1 1 1 1 1 disktype=ssd 58s
k8s组件中由daesonset创建的有如下的pod:
[root@vms201 daemonset]# kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
calico-node 3 3 3 3 3 kubernetes.io/os=linux 6d12h
kube-proxy 3 3 3 3 3 kubernetes.io/os=linux 6d12h
二、ReplicationController(RC):
ReplicationController (RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的pod来替代;而异常多出来的容器也会自动回收。
修改RC的yaml文件:
[root@vms201 daemonset]# cat rc1.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myrc
spec:
replicas: 3
selector:
app: nginx
template:
metadata:
name: nginx
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 0
containers:
- image: nginx
name: nginx
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
创建RC并查看:
[root@vms201 daemonset]# kubectl apply -f rc1.yaml
replicationcontroller/myrc created
[root@vms201 daemonset]# kubectl get rc myrc -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myrc 3 3 3 58s nginx nginx app=nginx
伸缩副本数:
[root@vms201 daemonset]# kubectl scale rc myrc --replicas=2
replicationcontroller/myrc scaled
[root@vms201 daemonset]# kubectl get rc
NAME DESIRED CURRENT READY AGE
myrc 2 2 2 4m38s
删除掉RC:
[root@vms201 daemonset]# kubectl delete -f rc1.yaml
replicationcontroller "myrc" deleted
三、ReplicaSet (RS)
在新版的Kubernetes中建议使用ReplicaSet (RS)来取代ReplicationController。ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,但ReplicaSet支持集合式selector。
虽然 ReplicaSets 可以独立使用,但如今它主要被Deployments 用作协调 Pod 的创建、删除和更新的机制。当使用 Deployment 时,你不必担心还要管理它们创建的 ReplicaSet,Deployment 会拥有并管理它们的ReplicaSet。所以说Deployment本质上是通过管理RS来管理pod的。
修改RS的yaml文件:
[root@vms201 daemonset]# cat rs1.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: myrs
labels:
app: guestbook
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
app: guestbook
tier: frontend
spec:
terminationGracePeriodSeconds: 0
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
创建并查看RS:
[root@vms201 daemonset]# kubectl apply -f rs1.yaml
replicaset.apps/myrs created
[root@vms201 daemonset]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myrs 3 3 3 88s nginx nginx tier=frontend
修改副本数:
[root@vms201 daemonset]# kubectl scale rs myrs --replicas=2
replicaset.apps/myrs scaled
[root@vms201 daemonset]# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
myrs 2 2 2 2m37s nginx nginx tier=frontend
删除RS:
[root@vms201 daemonset]# kubectl delete -f rs1.yaml
replicaset.apps "myrs" deleted
四、StatefulSet(STS):
概述:
StatefulSet(k8s v1.9 中的stable-GA)是一种用于管理有状态应用程序的 Kubernetes 资源。它管理一组 Pod 的部署和扩展,并为这些 Pod 的排序和唯一性提供保证。
StatefulSet 也是一个 Controller,但与 Deployments 不同,它不会创建 ReplicaSet,而是自己创建具有唯一命名约定的 Pod。例如,如果用户创建一个名称为counter的 StatefulSet ,它将创建一个名称为counter-0的 pod ,对于一个 statefulset 的多个副本,它们的名称将像counter-0、counter-1、counter-2 等一样递增。
有状态集的每个副本都有自己的状态,每个 Pod 都将创建自己的 PVC(持久卷声明)。因此,具有 3 个副本的 statefulset 将创建 3 个 pod,每个 pod 都有自己的 Volume,因此总共 3 个 PVC。
相比于Deployments,StatefulSet能做到每一个容器的有自己的存储卷(数据不同),但是无法做到负载分担。
什么时候考虑使用StatefulSet:
一些应用,只适用于内部,并不行对外提供服务,且每个pod需要有自己的存储,且个pod挂掉再重启,还需要连接之前的pv,不能连到别的pv上,考虑使用StatefulSet。
sts和deploy的区别:
详细请参考:
https://blog.csdn.net/nickDaDa/article/details/90401635
实验测试:
sts不能直接创建,可以在K8s官网上找到对应的模板,然后进行修改:
[root@vms201 sts]# cat sts1.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
spec:
serviceName: "nginx"
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
terminationGracePeriodSeconds: 0
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: "mysc"
resources:
requests:
storage: 500Mi
仅创建一个Nginx的pod。其中 volumeClaimTemplates,每设置一个副本都会创建一个pvc。这里pvc通过指定的sc生成pv。
动态卷供应相关内容,请参考:https://blog.csdn.net/tushanpeipei/article/details/118493324?spm=1001.2014.3001.5501
创建sts服务后查看:可以看到已经自己已经生成了PVC,连接到了SC上,最终挂载到了远端NFS存储上。
[root@vms201 sts]# kubectl apply -f sts1.yaml
statefulset.apps/web created
[root@vms201 sts]# kubectl get pod web-0
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 17s
[root@vms201 sts]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
www-web-0 Bound pvc-a6928573-5d1d-4895-b36f-943658d1c11f 500Mi RWX mysc 3h30m
扩展副本数后可以发现,命名为web-1,序号依次增加:
[root@vms201 sts]# kubectl scale statefulset web --replicas=2
statefulset.apps/web scaled
[root@vms201 sts]# kubectl get pods | grep web
web-0 1/1 Running 0 9m13s
web-1 1/1 Running 0 68s
可以在NFS数据卷中找到数据信息:可以看到两个pod的信息是分别存储的。
[root@nfs cc]# ls
sts-www-web-0-pvc-a6928573-5d1d-4895-b36f-943658d1c11f sts-www-web-1-pvc-310b70de-71a6-48fc-b8de-d769d572328e
修改pod的主页,以做区别:
[root@vms201 sts]# kubectl exec -it web-0 -- sh -c "echo 111 > /usr/share/nginx/html/index.html"
[root@vms201 sts]# kubectl exec -it web-1 -- sh -c "echo 222 > /usr/share/nginx/html/index.html"
然后将副本数清空后重新增加:
[root@vms201 sts]# kubectl scale statefulset web --replicas=0
statefulset.apps/web scaled
[root@vms201 sts]# kubectl scale statefulset web --replicas=2
statefulset.apps/web scaled
[root@vms201 sts]# kubectl get pods | grep web
web-0 1/1 Running 0 30s
web-1 1/1 Running 0 29s
可以看到名称没有改变,然后再去查看每个pod中的数据,可以发现依然和副本关闭前一致(存储不会错乱):
[root@vms201 sts]# kubectl exec -it web-0 -- sh -c "cat /usr/share/nginx/html/index.html"
111
[root@vms201 sts]# kubectl exec -it web-1 -- sh -c "cat /usr/share/nginx/html/index.html"
222
主要注意的是,重新创建的pod名称和存储的信息都和之前保持一致,但是IP地址不同。
headless service:
由于每个pod中保存的信息不同,如果使用svc负载的方式将流量负载到不同的pod中,会导致访问到的内容不同。而直接访问pod,由于同一个pod删除,重新创建后,IP地址不同,也是一个问题。所以这个时候就可以实验headless service(无头服务)来解决问题。
可以通过指定 Cluster IP(spec.clusterIP)的值为 “None” 来创建 Headless Service。对于STS的无头无法不能直接创建,我看可以在SVC的yaml文件中修改:
[root@vms201 sts]# cat headless.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx
应用并查看服务信息,这里的CLUSTER-IP为None:
[root@vms201 sts]# kubectl apply -f headless.yaml
service/nginx created
[root@vms201 sts]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx ClusterIP None <none> 80/TCP 39s app=nginx
访问headless服务下的pod:访问格式: 容器名.服务名,这里也就是web-0.nginx和web-1.nginx。
[root@vms201 sts]# kubectl run -it testpod --image=yauritux/busybox-curl --rm --image-pull-policy=IfNotPresent -- sh
If you don't see a command prompt, try pressing enter.
/home # curl web-0.nginx
111
/home # curl web-1.nginx
222
参考资料:
《老段CKA课程》
https://medium.com/stakater/k8s-deployments-vs-statefulsets-vs-daemonsets-60582f0c62d4
更多推荐
所有评论(0)