Kubernetes进阶之StatefulSet有状态部署

K8s有状态应用部署
目录:分为两类
1.Headless Service
2.StatefulSet

? 部署有状态应用
? 解决Pod独立生命周期,保持Pod启动顺序和唯一性

  1. 稳定,唯一的网络标识符,持久存储
  2. 有序,优雅的部署和扩展、删除和终止
  3. 有序,滚动更新
    应用场景:数据库
说在前面的话,像我们的Mysql或者Redis了,Zookerper等等这些适不适合部署在K8s中,其实呢不是太适合,但部署在里面也可以,比如部署一个Mysql来讲吧,部署到k8s中还是很容易的就一个Mysql实例,就像部署其他应用一样,通过service、IP去访问它,但是要是作为集群的状态去部署的话,那可能就比较麻烦了。
第一点:比如做一个Mysql的主从,Mysql主从它是有主从拓扑关系的,一个主一个从,而且各自的数据都不一样,这就意味着,你要想搭建一个Mysql的主从,你要知道它的相互的ip地址,就是从肯定要知道主的ip地址,然后从连接主的ip地址,做数据的同步。
第二点:它的存储,它两个存储的信息都不太一样,那怎么去保证它两个数据的存储保证持久化呢,一个集群中可能会有多个节点,要是部署到k8s中,必须要保证部署的应用,在任意的节点都能使用原来的状态,也就是说某一个节点挂了,上面的pod飘移到另一个节点,能不能用到之前的状态,所以要考虑这些问题。
而k8s设计的精髓在于并不是你部署一个单的实例,而是在于它的一个分布式一个部署,具有故障恢复能力的应用,所以就谈到了有状态和无状态应用。

有状态应用:DB,好比一个Mysql主从,考虑两点(自己的存储,必须是远程的存储,在任意节点挂载都恢复原来的状态)而且还有网络ID的唯一,需要做主从的连接,我们的pod是短暂的,重建一个ip就换了,得保证这个ip一直去使用,不管是重建还是迁移pod,都能去使用。
无状态应用:典型的就是web系统,本身就没有什么状态去维护,比如部署了三个副本,不需要考虑其他两个副本是什么样的,跟它没有直接的关系,本地也没有什么持久化的数据,即使其中有一个副本挂了,帮它在其他节点起来,仍然可以继续提供服务,对原基础服务是没有任何影响的,所以这是一个前提,典型的就是web。

在k8s中呢在1.10版本之后有状态部署才支持好一点,但是刚开始在落地K8s的时候,而不会去考虑有状态部署的,主要做无状态的部署,而数据库适不适合部署在k8s中,在看k8s的一些特性,k8s有适合的一些特性,比如具有一些访问比较大的应用,版本迭代快的应用,或者弹性伸缩的一些应用,凡是这些是适合放在k8s,k8s最早就支持无状态,也是一直在推荐,有状态的也是比较复杂,复杂点就在与有状态的都是一些集群化的,比如zookerper,
Mysql主从,这些都是需要自身的一个状态维护的,这些部署进去呢,可能去考虑它这个网络拓扑关系,还有存储状态的持久化,而数据库不具备这些特点,部署一个数据库一般配置比较高一些,可以会抗很多的并发量,而且要扩容的话也是很方便,而且传统的部署文章也很多,也比较成熟,在k8s中部署这些东西,那绝对是一种挑战,所以要根据不同的应用特点去考虑上k8s,不要一味地上k8s,而且得不偿失,达不到预期的效果,领导也会批你,所以在谈有状态部署的话,可以在两者出发,一个是Headless Service维护网络的,一个是StatefulSet维护存储状态的。

statefulSet是一个控制器,与Deployment存在的原则一样,都是部署应用的,而Statefulset它主要是部署有状态应用的,而deployment是部署无状态应用的

Headless Service 其实和service差不多,这不过定义的这个叫无头服务,它们之间唯一的区别就是将Cluster ip 设置为了none,不会帮你配置ip

[[email protected] demo]# mkdir headless-service
[[email protected] demo]# cd headless-service/
[[email protected] headless-service]# vim headless-svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  clusterIP: None
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

[[email protected] headless-service]# kubectl create -f headless-svc.yaml
service/my-service created
[[email protected] headless-service]# kubectl get svc

kubernetes   ClusterIP   10.1.0.1      <none>        443/TCP        23h
my-service   ClusterIP   None          <none>        80/TCP         6s
service      NodePort    10.1.207.32   <none>        80:30963/TCP   87m
zhao         ClusterIP   10.1.75.232   <none>        80/TCP         9m1s
zhaocheng    ClusterIP   10.1.27.206   <none>        80/TCP         10m

怎么去访问?我们给它定义一个标识
创建完之后会有这个标识符,它会使用这个DNS来解析这个名称,来相互的访问,headless就不会通过ip去访问了,必须通过名称去访问,

[[email protected] headless-service]# vim statefulset.yaml
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: nginx-statefulset
  namespace: default
spec:
  serviceName: my-service
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

[[email protected] headless-service]# kubectl create -f statefulset.yaml
[[email protected] headless-service]# kubectl get pod

my-pod                                   1/1     Running   0          3h50m
nfs-744d977b46-dh9xj                     1/1     Running   0          22h
nfs-744d977b46-kcx6h                     1/1     Running   0          22h
nfs-744d977b46-wqhc6                     1/1     Running   0          22h
nfs-client-provisioner  1/1     Running   0          4h
nginx-797db8dc57-tdd5s                   1/1     Running   0          100m
nginx-statefulset-0                      1/1     Running   0          73s
nginx-statefulset-1                      1/1     Running   0          46s
nginx-statefulset-2                      1/1     Running   0          24s

这里的statfulset的 serviceName: my-service字段要关联起来,这样才能去基于名称去访问
可以通过busybox测试工具通过nslookup去测试解析。解析我们的my-service就能解析到
这里会分配一个名称,这个my-service和这个编号是永久的,可以通过这个名称访问pod
要是mysql主从的话就可以通过访问这个标签来连接我们从库的状态,这个是维护的网络状态
然后再来看一下存储状态

官方文档这个实例
https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
这个其实我们也是部署一个nginx,使用的headless,ClusterIP为none,然后用headless来维护statefulset起得pod网络id为1,以 volumeClaimTemplates:来维护pod独立的一个存储

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # has to match .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # by default is 1
  template:
    metadata:
      labels:
        app: nginx # has to match .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:

- name: nginx
        image: nginx
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "managed-nfs-storage"
      resources:
        requests:
          storage: 1Gi

这是我们的存储要写我们nfs的名称
managed-nfs-storage

[[email protected] headless-service]# kubectl get sc

managed-nfs-storage   fuseim.pri/ifs   22h

这里会给我们自动创建pv,并挂载到我们的NFS上

[[email protected] headless-service]# kubectl get pod

my-pod                                   1/1     Running            0          6h4m
nfs                     1/1     Running            0          24h
nfs                    1/1     Running            0          24h
nfs                     1/1     Running            0          24h
nfs-client-provisioner-fbc  1/1     Running            0          6h23m
nginx-797db8dc57-tdd5s                   1/1     Running            0          3h54m
nginx-a1-6d5fd7b8dd-w647x                1/1     Running            0          3m28s
nginx-statefulset-0                      1/1     Running            0          135m
nginx-statefulset-1                      1/1     Running            0          135m
nginx-statefulset-2                      1/1     Running            0          134m
web-0                                    1/1     Running            0          3
web-1                                    1/1     Running            0          85s
web-2                                    1/1     Running            0          57s
[[email protected] headless-service]# kubectl get pv

pvc-06  1Gi        RWO            Delete           Bound    default/www-web-2   managed-nfs-storage            63s
pvc-4f   1Gi        RWO            Delete           Bound    default/www-web-0   managed-nfs-storage            6m3s
pvc-a2   5Gi        RWX            Delete           Bound    default/my-pvc      managed-nfs-storage            6h4m
pvc-bc 1Gi        RWO            Delete           Bound    default/www-web-1   managed-nfs-storage           

headless保证它的网络,statefulset存储模版来保证每个pod存储的唯一性,这样才解决了有状态应用的两大痛点

原文地址:https://blog.51cto.com/14143894/2436459

时间: 2024-08-30 16:27:27

Kubernetes进阶之StatefulSet有状态部署的相关文章

Kubernetes进阶之ingress-nginx

Kubernetes进阶之ingress-nginx 目录:一 从外部访问应用最佳方式 二 配置管理 三 数据卷与数据持久卷 四 再谈有状态应用部署 五 K8S 安全机制 说在前面的话,选择nodeport的方式去暴露端口,那你需要得去判断暴露的端口有没有被占用,再创建新的应用会判断端口有没有被分配出去 nodeport本身是基于默认的iptables的代理模式做的网络转发,也就是SANT,DANT,基于四层的,做七层是做不了的,性能差一点,因为它需要防火墙的转发和过滤. 一.从外部访问应用最佳

Kubernetes进阶之secret及configmap配置管理

Kubernetes进阶之secret及configmap配置管理 目录: 一 从外部访问应用最佳方式 二 配置管理 三 数据卷与数据持久卷 四 再谈有状态应用部署 五 K8S 安全机制 二.配置管理Pod使用secret两种方式: ? 变量注入 (就是我们在写yaml的时候直接让它以变量的方式注入进去,注入pod中,去引用这个变量,去做相关的处理)? 挂载(直接从volume的形式挂载到我们指定的目录下)Configmap与Secret类似,区别在于ConfigMap保存的是不需要加密配置信息

Kubernetes控制器之StatefulSet

参考:https://kubernetes.io/zh/docs/concepts/workloads/controllers/statefulset/ https://www.kubernetes.org.cn/deployment StatefulSet StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现 稳定的网络标志,

Kubernetes 集群的两种部署过程(daemon部署和容器化部署)以及glusterfs的应用!

ClusterIp:通过VIP来访问, NodePort: 需要自己搭建负载据衡器 LoadBalancer:仅仅用于特定的云提供商 和 Google Container Engine https://www.nginx.com/blog/load-balancing-kubernetes-services-nginx-plus/ port:相当于服务端口(对及集群内客户访问) targetPort: 相当于pods端口 nodePort: 宿主机端口(也是服务端口,只不过是对集群外客户访问)

宝塔面板 + Rancher + 阿里云镜像仓库 + +Docker + Kubernetes,添加集群、部署 web 应用

目录 一,安装宝塔面板(V 6.8) 二,使用宝塔安装 Docker,配置阿里云容器服务 三,安装 Rancher (Server) 四,管理 Rancher.添加集群 五,添加 Rancher 应用.服务,与 Nginx 六,ASP.NET Core 应用部署 七,相关文章推荐 前言: 本文使用 Centos 7.x 进行操作,Rancher 官方推荐使用 Ubuntu. Docker 对内核要求 大于 3.10,你可以使用 uname -r 检测系统内容版本. 通过 Rancher,可以很方

Kubernetes进阶之PersistentVolume 静态供给实现NFS网络存储

Kubernetes进阶之PersistentVolume 静态供给实现NFS网络存储网络存储 NFS是一种很早的技术,单机的存储在服务器方面还是非常主流的,但nfs唯一的就是缺点比较大就是没有集群版,做集群化还是比较费劲的,文件系统做不了,这是一个很大的弊端,大规模的还是需要选择一些分布式的存储,nfs就是一个网络文件存储服务器,装完nfs之后,共享一个目录,其他的服务器就可以通过这个目录挂载到本地了,在本地写到这个目录的文件,就会同步到远程服务器上,实现一个共享存储的功能,一般都是做数据的共

Kubernetes强制删除一直处于Terminating状态的pod。

在dashboard界面删除容器,发现无法删除.使用命令查看发现该pod一直处于terminating的状态Kubernetes强制删除一直处于Terminating状态的pod. 1.使用命令获取pod的名字kubectl get po -n NAMESPACE |grep Terminating2.使用kubectl中的强制删除命令kubectl delete pod podName -n NAMESPACE --force --grace-period=0 原文地址:https://blo

kubernetes 1.14.2 kubeadm 方式部署

kubernetes 1.14.2 kubeadm方式部署 主机 192.168.100.111 k8s-master192.168.100.112 k8s-node1192.168.100.113 k8s-node2 基本环境 systemctl stop firewalld ystemctl disable firewalld sed -i 's/enforcing/disabled/' /etc/selinux/config setenforce 0 swapoff -a vim /etc

基于 Kubernetes v1.14.0 之 CoreDNS部署

1.部署容器前说明: 1.1.如果没有特殊指明,本文档的所有操作均在 k8s-operation 节点上执行: kuberntes 自带插件的 manifests yaml 文件使用 gcr.io 的 docker registry,国内被墙,需要手动替换为其它 registry 地址: 1.2.由于k8s-master 没有部署容器服务于路由服务,但是k8s-master 又要访问容器网络跟k8s集群网络,1.在上级路由器写入静态路由让其能访问容器网络与k8s集群网络.2.在k8s-maste