K8S工作负载(二)

K8S工作负载(2)

ReplicaSet

上一章我们讲到,一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力,那么这个 Replicaset 又是什么呢。

K8S 官方针对 ReplicaSet 的解释是ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性这句话的意思就是replicaset 是用来维护指定数量的 Pod并保障指定数量 Pod 的可用性的。

上述说了 Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。也因此,官方建议使用 Deployment 而不是直接使用 ReplicaSet, 除非你需要自定义更新业务流程或根本不需要更新。

kubectl get rs -n xxxx # 查看执行 namespace 下的副本集合

StatefulSet

在实际场景中,多个实例之间,往往有依赖关系,比如:主从关系,主备关系;还有就是数据存储类应用,它的多个实例,往往都会在本地磁盘上保存一份数据。而这些实例一旦被杀掉,即便重建出来,实例与数据之间的对应关系也已经丢失,从而导致应用失败。所以,这种实例之间有不对等关系,以及实例对外部数据有依赖关系的应用,就被称为“有状态应用”

Kubernetes 中的 StatefulSet就是用来管理有状态应用的工作负载API 对象。

  • StatefulSet给每个Pod提供固定名称,Pod名称增加从0-N的固定后缀,Pod重新调度后Pod名称和HostName不变。
  • StatefulSet通过Headless Service给每个Pod提供固定的访问域名,Service的概念会在后面章节中详细介绍。
  • StatefulSet通过创建固定标识的PVC保证Pod重新调度后还是能访问到相同的持久化数据。
    sts

Headless Service

如前所述,创建Statefulset需要一个Headless Service用于Pod访问,Service的概念会在后续章节中详细介绍,这里先介绍Headless Service的创建方法。

spec.clusterIP:#必须设置为None,表示Headless Service。
spec.ports.port:#Pod间通信端口号。
spec.ports.name:#Pod间通信端口名称。

这里我们创建一个 mysql 的 headless service

apiVersion: v1
kind: Service           # 对象类型为Service
metadata:
  name: mysql-default
  namespace: dsc
spec:
  clusterIP: None       # 必须设置为None,表示Headless Service
  ports: 
    - name: server      # Pod间通信的端口名称
      port: 3306        # Pod间通信的端口号
    - name: metrics     
      port: 9104
  selector:
    app.kubernetes.io/component: mysql-default    # 选择标签为对应的 pod
$ kubectl get svc -owide -n dsc 
NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP        PORT(S)                AGE      SELECTOR
mysql-default        ClusterIP   None            <none>             3306/TCP,9104/TCP      5m       app.kubernetes.io/component=mysql-default

Create StatefulSet

Statefulset的YAML定义与其他对象基本相同,主要有两个差异点:

  • serviceName指定了Statefulset使用哪个Headless Service,需要填写Headless Service的名称。
  • volumeClaimTemplates是用来申请持久化声明PVC ,storageClassName指定了持久化存储的类型;volumeMounts是为Pod挂载存储。当然如果不需要存储的话可以删除volumeClaimTemplates和volumeMounts字段。
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql-default
spec:
  replicas: 3
  serviceName: mysql-default                       # headless service的名称
  selector:
    matchLabels:
      app.kubernetes.io/component: mysql-default
  template:
    metadata:
      labels:
        app.kubernetes.io/component: mysql-default
    spec:
      imagePullSecrets:
        - name: inner
      containers:
        - name: mysql-exporter
          image: "mysqld-exporter:0.10.0-amd64"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http-metrics
              containerPort: 9104
          env:
            - name: DATA_SOURCE_NAME
              value: "exporter:exporter@(localhost:3306)/"
        - name: mysql
          image: "mariadb:10.3.28-4c6641b-amd64"
          imagePullPolicy: IfNotPresent
          ports:
            - name: mysql
              containerPort: 3306
          resources:
            limits:
              cpu: "2"
              memory: 8Gi
            requests:
              cpu: "1"
              memory: 4Gi
          volumeMounts:                       # Pod挂载的存储
            - name: volume0
              mountPath: /var/lib/mysql       # 存储挂载到/var/lib/mysql
  volumeClaimTemplates:
  - metadata:
      name: volume0
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: storageclass-local-mysql
      resources:
        requests:
          storage: 9.5G                       # 持久化存储的类型

命令执行后,查询一下StatefulSet和Pod,Pod的名称后缀从0开始到2,逐个递增。

$ kubectl get sts 
NAME               READY   AGE
mysql-default      3/3     5m

$ kubectl get pod 
NAME                                  READY   STATUS      RESTARTS          AGE
mysql-default-0                       2/2     Running     0                 5m
mysql-default-1                       2/2     Running     0                 4m
mysql-default-2                       2/2     Running     0                 3m

$ kubectl get pvc 
NAME                          STATUS   VOLUME              CAPACITY   ACCESS MODES   STORAGECLASS                            AGE
volume0-mysql-dsc-0           Bound    local-pv-519f8522   186Gi      RWO            storageclass-local-mysql                5m
volume0-mysql-dsc-1           Bound    local-pv-8fee3347   186Gi      RWO            storageclass-local-mysql                5m
volume0-mysql-dsc-2           Bound    local-pv-f89adf61   186Gi      RWO            storageclass-local-mysql                5m

网络标识

StatefulSet创建后,Pod是有固定名称的,Headless Service是使用DNS,为Pod提供固定的域名,这样Pod间就可以使用域名访问,即便Pod被重新创建而导致Pod的IP地址发生变化,这个域名也不会发生变化。

Headless Service创建后,每个Pod的IP都会有下面格式的域名。

...svc.cluster.local

我们通过在集群内的一个工具的 pod,使用nslookup查看pod 的对应域名:

$ kubectl exec -it toolbox-xxx bash 
//
nslookup mysql-default-0.mysql-default.default
Server:		169.254.25.10
Address:	169.254.25.10#53

Name:	mysql-default-0.mysql-default.default.svc.cluster.local
Address: 10.225.94.8  #对应的 mysql-default-0 的 pod 的 podIP

//
nslookup mysql-default-1.mysql-default.default
Server:		169.254.25.10
Address:	169.254.25.10#53

Name:	mysql-default-1.mysql-default.default.svc.cluster.local
Address: 10.231.90.191  #对应的 mysql-default-1 的 pod 的 podIP

//
nslookup mysql-default-2.mysql-default.default
Server:		169.254.25.10
Address:	169.254.25.10#53

Name:	mysql-default-2.mysql-default.default.svc.cluster.local
Address: 110.228.119.81  #对应的 mysql-default-2 的 pod 的 podIP

若通过手动删除1和2的 pod, pod 被重新拉起的后,通过nslookup 会发现,对应的域名仍然会被解析到对应的 pod 上。

存储状态

通过PVC做持久化存储,保证Pod重新调度后还是能访问到相同的持久化数据,在删除Pod时,PVC不会被删除。下图就是sts 的 pod 的重建过程
sts-pvc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值