website/content/zh-cn/docs/tasks/run-application/run-single-instance-statefu...

10 KiB
Raw Blame History

title content_type weight
运行一个单实例有状态应用 tutorial 20

本文介绍在 Kubernetes 中如何使用 PersistentVolume 和 Deployment 运行一个单实例有状态应用。 该示例应用是 MySQL。

{{% heading "objectives" %}}

  • 在你的环境中创建一个引用磁盘的 PersistentVolume。
  • 创建一个 MySQL Deployment。
  • 在集群内以一个已知的 DNS 名称将 MySQL 暴露给其他 Pod。

{{% heading "prerequisites" %}}

  • {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
  • {{< include "default-storage-class-prereqs.md" >}}

部署 MySQL

你可以通过创建一个 Kubernetes Deployment 并使用 PersistentVolumeClaim 将其连接到 某已有的 PersistentVolume 来运行一个有状态的应用。 例如,这里的 YAML 描述的是一个运行 MySQL 的 Deployment其中引用了 PersistentVolumeClaim。 文件为 /var/lib/mysql 定义了卷挂载,并创建了一个 PersistentVolumeClaim寻找一个 20G 大小的卷。 该申领可以通过现有的满足需求的卷来满足,也可以通过动态供应卷的机制来满足。

注意:在配置的 YAML 文件中定义密码的做法是不安全的。具体安全解决方案请参考 Kubernetes Secrets

{{% code_sample file="application/mysql/mysql-deployment.yaml" %}} {{% code_sample file="application/mysql/mysql-pv.yaml" %}}

  1. 部署 YAML 文件中定义的 PV 和 PVC

    kubectl apply -f https://k8s.io/examples/application/mysql/mysql-pv.yaml
    
  1. 部署 YAML 文件中定义的 Deployment

    kubectl apply -f https://k8s.io/examples/application/mysql/mysql-deployment.yaml
    
  1. 展示 Deployment 相关信息:

    kubectl describe deployment mysql
    

    输出类似于:

    Name:                 mysql
    Namespace:            default
    CreationTimestamp:    Tue, 01 Nov 2016 11:18:45 -0700
    Labels:               app=mysql
    Annotations:          deployment.kubernetes.io/revision=1
    Selector:             app=mysql
    Replicas:             1 desired | 1 updated | 1 total | 0 available | 1 unavailable
    StrategyType:         Recreate
    MinReadySeconds:      0
    Pod Template:
      Labels:       app=mysql
      Containers:
       mysql:
        Image:      mysql:5.6
        Port:       3306/TCP
        Environment:
          MYSQL_ROOT_PASSWORD:      password
        Mounts:
          /var/lib/mysql from mysql-persistent-storage (rw)
      Volumes:
       mysql-persistent-storage:
        Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
        ClaimName:  mysql-pv-claim
        ReadOnly:   false
    Conditions:
      Type          Status  Reason
      ----          ------  ------
      Available     False   MinimumReplicasUnavailable
      Progressing   True    ReplicaSetUpdated
    OldReplicaSets:       <none>
    NewReplicaSet:        mysql-63082529 (1/1 replicas created)
    Events:
      FirstSeen    LastSeen    Count    From                SubobjectPath    Type        Reason            Message
      ---------    --------    -----    ----                -------------    --------    ------            -------
      33s          33s         1        {deployment-controller }             Normal      ScalingReplicaSet Scaled up replica set mysql-63082529 to 1
    
  1. 列举出 Deployment 创建的 Pod

    kubectl get pods -l app=mysql
    

    输出类似于:

    NAME                   READY     STATUS    RESTARTS   AGE
    mysql-63082529-2z3ki   1/1       Running   0          3m
    
  1. 查看 PersistentVolumeClaim

    kubectl describe pvc mysql-pv-claim
    

    输出类似于:

    Name:         mysql-pv-claim
    Namespace:    default
    StorageClass:
    Status:       Bound
    Volume:       mysql-pv-volume
    Labels:       <none>
    Annotations:    pv.kubernetes.io/bind-completed=yes
                    pv.kubernetes.io/bound-by-controller=yes
    Capacity:     20Gi
    Access Modes: RWO
    Events:       <none>
    

访问 MySQL 实例

前面 YAML 文件中创建了一个允许集群内其他 Pod 访问的数据库 Service。该 Service 中选项 clusterIP: None 让 Service 的 DNS 名称直接解析为 Pod 的 IP 地址。 当在一个 Service 下只有一个 Pod 并且不打算增加 Pod 的数量这是最好的。

运行 MySQL 客户端以连接到服务器:

kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword

此命令在集群内创建一个新的 Pod 并运行 MySQL 客户端,并通过 Service 连接到服务器。 如果连接成功,你就知道有状态的 MySQL 数据库正处于运行状态。

Waiting for pod default/mysql-client-274442439-zyp6i to be running, status is Pending, pod ready: false
If you don't see a command prompt, try pressing enter.

mysql>

更新

Deployment 中镜像或其他部分同往常一样可以通过 kubectl apply 命令更新。 以下是特定于有状态应用的一些注意事项:

  • 不要对应用进行规模扩缩。这里的设置仅适用于单实例应用。下层的 PersistentVolume 仅只能挂载到一个 Pod 上。对于集群级有状态应用,请参考 StatefulSet 文档
  • 在 Deployment 的 YAML 文件中使用 strategy: type: Recreate。 该选项指示 Kubernetes 使用滚动升级。滚动升级无法工作,因为这里一次不能运行多个 Pod。在使用更新的配置文件创建新的 Pod 前,Recreate 策略将保证先停止第一个 Pod。

删除 Deployment

通过名称删除部署的对象:

kubectl delete deployment,svc mysql
kubectl delete pvc mysql-pv-claim
kubectl delete pv mysql-pv-volume

如果通过手动的方式供应 PersistentVolume那么也需要手动删除它以释放下层资源。 如果是用动态供应方式创建的 PersistentVolume在删除 PersistentVolumeClaim 后 PersistentVolume 将被自动删除。 一些存储服务(比如 EBS 和 PD也会在 PersistentVolume 被删除时自动回收下层资源。

{{% heading "whatsnext" %}}