K8S精进之路-控制器StatefulSet有状态控制 -(2)

状态说明

在进行StatefulSet部署之前,我们首先可能要了解一下,什么是"有状态应用"和"无状态应用"。无状态应用就是pod无论部署在哪里,在哪台服务器上提供服务,都是一样的结果,比如经常用的nginx。有状态应用中,最经常用的那就属数据库了,因为数据库一般都是绑定了网络状态和存储状态。特别是主从数据库,哪些是主数据库,哪些是从数据库,都有明显的状态标识。离开标识的这台机器,可能就用不了了。

那在K8S中主要表现的状态有哪些呢,如果抽象成现实应用中,一般就是网络拓扑状态和存储状态。

网络拓扑:这意味着在k8s中运行中的应用对应的各个pod实例,都会有固定的启动顺序,而且不管实例pod销毁后新建,网络标识还是原来的网络标识,其它应用要找到它,还是通过原来的网络标识一样能找到。

存储状态:比如,当数据库实例销毁重建后,我存储的数据还是照样是原来的那份数据。数据库存储的数据是有状态的,是直接和这个应用绑定的,不论你pod实例重建多少次都会取到这份自己的数据。

我们先看看StatefulSet是怎样固定网络拓扑状态的。在网络中一般要标识一个地址,都是通过IP地址或者是域名。但是IP地址是不方便被记忆的,所以用一个域名是非常方便的。在K8S中,通过系统的Service DNS是可以确定一个POD的网络标识的。

固定网络拓扑

我们新建一个Headless的Service和nginx

yaml 复制代码
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:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22.1
        ports:
        - containerPort: 80
          name: web

创建之后发现两个Pod运行,分别为web-0,web-1,IP地址分别是10.244.3.18,10.244.2.20。虽然分配了ip但是ip是动态,唯一固定的是这两个pod的域名和它们创建启动的顺序,先创建web-0,然后是web-1。我们通过<pod-name>.<svc-name>.<namespace>.svc.cluster.local的方式来固定这两个pod的地址。

我们通过web-0.nginx.default.svc.cluster.local和web-1.nginx.default.svc.cluster.local可以在集群内部访问到这两个Pod。我们接下来通过k8s的coredns来解析这两个域名。先找到coredns的ip地址,然后通过dig来解析。

解析后发现pod的域名刚好指向这两个pod的ip地址。我现在删除上面的pod,然后重建,再解析他们的域名,发现ip地址变了,但是域名还是那个域名。

bash 复制代码
kubectl delete -f teststatefulpod.yaml ; kubectl apply -f teststatefulpod.yaml

固定存储状态

对于应用的存储,这里用pvc来固定应用的存储位置。相对开发人员这里只要熟悉pvc的配置即可,pv的配置一般由运维人员去配置安装。这里我们用分布式存储Rook+Ceph,安装方式可以参考这篇文章<<Centos7.9在K8s安装生产级别的分布式存储Rook+Ceph>>。

我们创建一个带存储的nginx配置

yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
   storage: 1Gi
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.22.1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      storageClassName: rook-ceph-block
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 1Gi

创建完成后,会出现两个自动创建的pvc,而且是根据pod名创建的。

我们分别对这两个nginx的首页加上特殊标志。

bash 复制代码
kubectl exec web-0 -- sh -c 'echo hello $(hostname) > /usr/share/nginx/html/index.html'
kubectl exec web-1 -- sh -c 'echo hello $(hostname) > /usr/share/nginx/html/index.html'

然后通过ip分别访问这两个nginx.各自首页分别返回了内容,一个是web-0,一个web-1.

然后删除这两个pod应用,再重建,发现pod虽然重建ip也变了,但是挂载的磁盘还是原来的,内容也没有变。存储状态也是一直保存着的。

bash 复制代码
kubectl delete -f teststatefulpod.yaml
kubectl apply -f teststatefulpod.yaml
相关推荐
mez_Blog16 分钟前
docker学习笔记(1.0)
笔记·学习·docker·容器
lldhsds1 小时前
Kubernetes云原生存储解决方案之 Rook Ceph实践探究
ceph·云原生·kubernetes
阿里云云原生1 小时前
Star 3w+,向更安全、更泛化、更云原生的 Nacos3.0 演进
安全·阿里云·云原生·nacos
petaexpress2 小时前
云服务器部署k8s需要什么配置?
运维·服务器·kubernetes
BUG弄潮儿2 小时前
k8s 部署 node exporter
云原生·容器·kubernetes
鱼跃鹰飞2 小时前
大厂面试真题-介绍以下Docker的Overlay网络
java·网络·docker·容器·面试·职场和发展
luming-023 小时前
Windows11安装Docker Desktop教程
运维·windows·docker·容器·bug
Maxx Space7 小时前
828华为云征文|部署漫画杂志媒体服务器 Komga
linux·服务器·docker·华为云
Databend9 小时前
探索 Snowflake 与 Databend 的云原生数仓技术与应用实践 | Data Infra NO.21 回顾
云原生