应用上云-在kubernetes中部署MySQL

在kubernetes中部署MySQL。

       

目录

 使用Deployment部署MySQL

 创建pvc

创建msyql-pod

创建service

登录mysql

讨论一下为什么要用StatefulSet部署MySQL

使用StatefulSet部署MySQL


       在kubernetes中部署mysql除了需要部署mysql-pod,还要给mysql-pod创建一个pvc来持久化存储数据库的数据,以及一个service来暴露mysql服务的端口。因此本次部署共分以下三个步骤:

1、创建一个PVC,用于持久化mysql数据,即存储mysql数据

2、创建一个pod,pod中运行mysql容器

3、创建一个service用来暴露mysql的3306端口

 使用Deployment部署MySQL

 创建pvc

创建一个PVC,用于持久化mysql数据,即存储mysql数据 。

#这里采用动态pv/pvc,已创建名为rook-ceph-block的ceph块存储StorageClasses

vim pvc-mysql-01.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-mysql-01
spec:
  storageClassName: rook-ceph-block
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi


#命令解释:

apiVersion: v1
#定义资源类型为pvc
kind: PersistentVolumeClaim
metadata:
  name: pvc-mysql-01
spec:
  #指定存储类的名称,即由那个存储类来自动创建和绑定对应的pv
  storageClassName: rook-ceph-block
  #设置用户对存储资源的访问权限,块存储仅支持ReadWriteOnce
  accessModes:
    - ReadWriteOnce
  #描述对存储资源的请求,这里申请10G大小的存储空间
  resources:
    requests:
      storage: 10Gi


#访问模式(accessModes)
 用于描述用户应用对存储资源的访问权限,访问权限包括下面几种方式:
 ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载(块存储不能共享只能被单个节点挂载)
 ReadOnlyMany(ROX): 只读权限,可以被多个节点挂载
 ReadWriteMany(RWX):读写权限,可以被多个节点挂载

创建msyql-pod

生产环境中通常采用StatefulSet pod控制器来部署mysql数据库,达到一主多从的效果,本次测试部署单节点数据库,不需要主从,故采用deployment的方式创建mysql pod 。

vim mysql-01.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-01
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql   
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: 1qaz@wsx
          ports:
            - containerPort: 3306
              name: mysql  
          volumeMounts:
            - name: mysql-volume
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-volume
          persistentVolumeClaim:
            claimName: pvc-mysql-01



命令解释:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-01
spec:
  selector:
    matchLabels:
      app: mysql
  #设置pod更新策略为recreate    
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          #设置容器的环境变量,这里是指定mysql的root密码为1qaz@wsx
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: 1qaz@wsx
          ports:
            - containerPort: 3306
              name: mysql
          #自定义一个volume,并挂载到/var/lib/mysql目录下    
          volumeMounts:
            - name: mysql-volume
              mountPath: /var/lib/mysql
      #设置volume的参数,这里使用名为mysql-pvc-01的pvc去请求pv来填充mysql-volume       
      volumes:
        - name: mysql-volume
          persistentVolumeClaim:
            claimName: pvc-mysql-01

创建service

创建一个service用来向集群外暴露mysql的3306端口。

vim svc-mysql-01.yaml

apiVersion: v1
kind: Service
metadata:
  name: svc-mysql-01
spec:
  selector:
    app: mysql
  type: NodePort
  ports:
    - port: 3306
      targetPort: 3306
      nodePort: 30001

登录mysql

部署完成后如何登录mysql?


[root@master ~]# kubectl get pod -o wide
NAME                               READY   STATUS    RESTARTS   AGE     IP               NODE     NOMINATED NODE   READINESS GATES
mysql-01-6c49f78548-z6hkl          1/1     Running   0          17h     10.122.104.61    node2    <none>           <none>

[root@master ~]# kubectl get svc -o wide
NAME              TYPE           CLUSTER-IP    EXTERNAL-IP   PORT(S)          AGE     SELECTOR
svc-mysql-01      NodePort       10.10.3.110   <none>        3306:30001/TCP   17h     app=mysql

pod内:
#推荐:mysql -uroot -p1qaz@wsx
# mysql -h 10.122.104.61 -uroot -p1qaz@wsx
# mysql -h 172.31.246.31 -P 30001 -uroot -p1qaz@wsx

集群内:
#推荐:mysql -h 10.10.3.110 -uroot -p1qaz@wsx
# mysql -h 10.122.104.61 -uroot -p1qaz@wsx
# mysql -h 172.31.246.31 -P 30001 -uroot -p1qaz@wsx

集群外:
# mysql -h 172.31.246.31 -P 30001 -uroot -p1qaz@wsx


总结:
在pod内:直接使用账号密码即可;即:mysql -uroot -p1qaz@wsx
在集群内:可以指定主机IP为service-IP,pod-ip,以及node-ip,这里推荐在集群内部使用service-ip来登录mysql。因为service本身的作用就是为pods提供一个稳定的IP,不会因为pod调度而变化。
在集群外:只能通过node-ip加nodeport来登录mysql。 

讨论一下为什么要用StatefulSet部署MySQL

以上就是使用deployment控制器部署MySQL的全部内容,但是mysql作为一个有状态应用,显然使用statefulset控制器部署更合适。

Deployment适合无状态应用程序的部署,它的优点是可以自动创建和管理Pod,并支持快速水平扩展。但是,MySQL是有状态的应用程序,它需要稳定的网络标识符(hostname),以便跨Pod保持持久的连接和数据一致性。Deployment不是为有状态应用程序设计的,因此不是最佳选择。

相反,StatefulSet提供了有状态应用程序的部署和管理,它会给每个Pod分配稳定的网络标识符,支持Pod的有序部署和有序回收,保证了Pod之间的数据稳定性。在数据处理应用程序中,StatefulSet通常是更好的选择。

当副本数为1时,使用Deployment和StatefulSet部署mysql有什么区别呢?

资源命名:StatefulSet允许为每个副本指定唯一的名称,即Pod的名称,而在Deployment中使用的Pod名称是随机生成的。这意味着,在StatefulSet中,每个Pod可以直接通过应用名称来访问数据库实例,而在Deployment中,需要通过Service名称来访问实例。(这一点在上述实验过程可以验证,当我们在集群内访问mysql时,-h需要指定service的IP,如果使用StatefulSet可以-h mysql pod 的名称。)

稳定的网络标识:StatefulSet提供了每个Pod的稳定网络标识,即DNS名称,而在Deployment中,Pod名称是不稳定的,这意味着在StatefulSet中,可以方便地进行Pod的扩容、缩容等操作,而不会影响其他组件的网络标识。

使用StatefulSet部署MySQL

将使用Deployment部署的yaml改为使用StatefulSet,如下所示:

使用这两种方式在yaml文件上有哪些区别呢?

首先,pvc和service部分是一样的,没有变化,只需修改pod部分。

1、将 Deployment 中的 kind 改为 StatefulSet。
2、在 StatefulSet 的 spec 中,添加了使用 serviceName 指定对应的 Service 名称,deployment中是不需要的。

使用StatefulSet部署应用需要在spec中使用serviceName指定对应的Service名称,是因为StatefulSet控制器创建的Pod具有稳定的网络标识符(Stable Network Identifiers)。每个Pod都有一个唯一的索引,例如pod-0,pod-1,pod-2等。这些索引用于在网络中区分和定位每个Pod。

通过指定serviceName,StatefulSet可以确保其Pod的网络标识符与关联的Service进行匹配。这样,每个Pod都可以通过Service名称而不是Pod名称进行访问,从而实现透明的服务发现和负载均衡。

此外,如果StatefulSet的规模发生变化(例如扩展或缩减Pod数量),服务名称将保持不变。这意味着重新创建或删除Pod时,将保留与之关联的Service,并且不会中断对其的访问。这种稳定的网络标识符对于有状态应用特别重要,它们需要保持持久化数据和网络连接的一致性。

3、StatefulSet和deployment在定义pod更新策略上的区别:

在deployment中使用strategy来定义pod的更新策略:

  • strategy.type: Recreate表示使用重建策略,在更新期间删除所有旧的Pod,然后再创建新的Pod。
  • strategy.type: RollingUpdate表示使用滚动更新策略,逐个更新Pod。

在StatefulSet中使用updateStrategy来定义pod的更新策略:

  • updateStrategy.type: RollingUpdate表示使用滚动更新策略,逐个更新Pod,保证至少有指定数量的Pod在更新期间保持运行。
  • updateStrategy.type: OnDelete表示在Pod运行时不更新它们,只有在Pod被删除时才会更新。

4、在 StatefulSet 中使用 volumeClaimTemplates 来定义 PVC 模板,可以为每个 Pod 分别创建对应的 PVC。

在 Deployment 中,当创建多个副本(replicas)的 Pod 时,它们会共享一个PVC,但是在StatefulSet会根据volumeClaimTemplates为每个pod有序的创建单独的pvc。

 如下所示使用Deployment创建三副本的msyql,存储使用ceph rbd,提供rwo的读写方式: 

 如上所示,三副本的msyql只创建了一个pvc、一个pv,第一个pod使用后,另外两个将无法使用。可以使用cephfs提供rwm的读写方式来解决此问题。

如下图所示使用statefulset创建三副本MySQL,存储使用ceph rbd,提供rwo的读写方式:

如上图所示statefulset会自动创建三个pv、pvc,同时可以发现由于statefulset具有 volumeClaimTemplates字段,无需提前创建pvc,创建了它也不会用你的(pvc-mysql-01)。

以下是完整的使用statefulset部署MySQL的yaml文件:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: svc-mysql-01
  replicas: 3
  selector:
    matchLabels:
      app: mysql
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - image: mysql:5.6
          name: mysql
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: 1qaz@wsx
          ports:
            - containerPort: 3306
              name: mysql  
          volumeMounts:
            - name: mysql-volume
              mountPath: /var/lib/mysql
      volumes:
        - name: mysql-volume
          persistentVolumeClaim:
            claimName: pvc-mysql-01
  volumeClaimTemplates:
    - metadata:
        name: mysql-volume
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 10Gi
        storageClassName: rook-ceph-block

---

apiVersion: v1
kind: Service
metadata:
  name: svc-mysql-01
spec:
  selector:
    app: mysql
  type: NodePort
  ports:
    - port: 3306
      targetPort: 3306
      nodePort: 30002

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是在 Kubernetes 部署 MySQL 的一些基本步骤: 1. 创建一个 Kubernetes Secret,用于存储 MySQL 的 root 密码。可以使用以下命令创建: ``` kubectl create secret generic mysql-pass --from-literal=password=<password> ``` 其 `<password>` 为你要设置的 MySQL root 密码。 2. 创建一个 PersistentVolumeClaim,用于存储 MySQL 数据。可以使用以下 YAML 文件创建: ``` apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi ``` 这里设置了一个 20GB 的存储空间,可以根据实际需求进行修改。 3. 创建一个 Deployment,用于部署 MySQL。可以使用以下 YAML 文件创建: ``` apiVersion: apps/v1 kind: Deployment metadata: name: mysql-deployment spec: selector: matchLabels: app: mysql strategy: type: Recreate template: metadata: labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim ``` 这里使用了 MySQL 5.7 镜像,设置了 MySQL 的 root 密码,并将数据存储在前面创建的 PersistentVolumeClaim 。 4. 创建一个 Service,用于访问 MySQL。可以使用以下 YAML 文件创建: ``` apiVersion: v1 kind: Service metadata: name: mysql-service spec: selector: app: mysql ports: - name: mysql port: 3306 targetPort: 3306 clusterIP: None ``` 这里创建了一个 ClusterIP 类型的 Service,用于在 Kubernetes 集群内部访问 MySQL。 完成上述步骤后,即可在 Kubernetes 部署 MySQL

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值