PHP项目迁移K8s之OSS存储卷

前言

        最近一个老项目(PHP)需要迁移至阿里云K8s上,之前项目上各种资源都存在服务器上多个目录下,本文就针对其中资源迁移部署讲解。

一、选择OSS存储卷原因

出于多种原因选择挂载OSS存储卷:

  1. 项目后期开发功能设计上传,需要上传OSS服务(之前都是上传到ECS服务上)。
  2. 若挂载NAS存储卷,项目平时需要更换资源,OSS通过客户端上传替换更为方便。
  3. 项目静态资源量很大,且后期还不断增加,而OSS静态存储卷是阿里云对象存储OSS中的一种存储类型,用于存储静态数据,包括图片、视频、js、html、css等等。OSS静态存储卷具有海量、安全、低成本、高可靠等特性,支持数据读写和在线修改,适用于Web网站图片存储、动静资源分离等业务场景。
  4. 项目业务资源写少读多,OSS存储卷更适合,如果您的业务是将文件写入存储的场景,推荐使用NAS存储卷服务。
  5. OSS支持同时被多个Pod挂载。

二、通过kubectl命令行的方式使用OSS静态存储卷

1.创建Secret

  • 创建Secret(文件名:oss-secret.yaml)
apiVersion: v1
kind: Secret
metadata:
  name: oss-secret # 可自定义 secret name
  namespace: <your namespace>
data:
  akId: <your AccessKey ID>
  akSecret: <your AccessKey Secret>
type: Opaque
  •  执行以下命令创建保密字典
kubectl create -f oss-secret.yaml

2.使用Secret创建静态卷PV

  • 创建静态卷PV(pv-oss.yaml)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-oss # 可自定义 pv name
  labels:
    alicloud-pvname: pv-oss
spec:
  capacity:
    storage: 20Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  csi:
    driver: ossplugin.csi.alibabacloud.com
    volumeHandle: pv-oss # 需要和 PV 名字一致。
    nodePublishSecretRef:
      name: <your secret name> # 创建 Secret 中定义的名字。
      namespace: <your namespace>
    volumeAttributes:
      bucket: <your bucket name> # 需要挂载的 OSS Bucket
      url: "oss-cn-hangzhou.aliyuncs.com"
      otherOpts: '-o max_stat_cache_size=0 -o allow_other -o mp_umask=022 -o umask=022'
      path: "/"
  • 使用命令创建静态卷PV
kubectl create -f pv-oss.yaml

 参数解析:

name PV的名称。
labels 配置PV的标签。
storage OSS的可使用量。
accessModes 配置访问模式。
persistentVolumeReclaimPolicy PV回收策略。
driver 定义驱动类型。取值为ossplugin.csi.alibabacloud.com,表示使用OSS CSI插件。
nodePublishSecretRef 定义挂载PV时通过Secret对象来获取AccessKey信息。
volumeHandle 配置PV的名称。
bucket 需要挂载的OSS Bucket。
url 挂载OSS的接入域名。
  • 挂载节点和Bucket相同地域时,请使用私网地址。
  • 挂载节点和Bucket不同地域时,请使用公网地址。
  • 禁止使用VPC网络。

不同域名访问格式如下:

  • 内网访问域名格式:oss-{{regionName}}-internal.aliyuncs.com
  • 外网访问域名格式:oss-{{regionName}}.aliyuncs.com
otherOpts 挂载OSS时支持输入定制化参数,格式为:-o *** -o ***
path 表示挂载时相对Bucket根文件的目录结构,默认为/(v1.14.8.32-c77e277b-aliyun及之后版本支持)。

3.创建静态卷PVC

  • 创建PVC(文件名:oss-secret.yaml)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-oss # 自定义
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 20Gi
  selector:
    matchLabels:
      alicloud-pvname: pv-oss # 需要 pv 中 name 保持一致
参数 说明
name PVC的名称。
accessModes 配置访问模式。
storage 声明应用使用量,不能大于存储卷的总量。
alicloud-pvname 通过标签关联PV,与PV标签保持一致。

  • 使用命令创建PVC
kubectl create -f pvc-oss.yaml

三、创建应用

1.以Nginx服务挂载为例

1apiVersion: apps/v1
kind: Deployment
metadata:
  name: static
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
          - name: pvc-oss
            mountPath: "/data"
        livenessProbe:
          exec:
            command:
            - sh
            - -c
            - cd /data
          initialDelaySeconds: 30
          periodSeconds: 30
      volumes:
        - name: pvc-oss
          persistentVolumeClaim:
            claimName: pvc-oss
参数 说明
mountPath OSS在容器中挂载的位置。

claimName

PVC的名称,用于绑定PVC

四、问题

1.OSS存储挂载权限问题

OSS挂载默认使用Linux的root权限进行挂载,此时目录和文件权限是400,由于权限问题,挂载之后无法向里面写入数据,如果需要修改挂载配置,可以在OSS静态卷PV中增加otherOpts字段的配置,添加配置的格式例如otherOpts: "-o max_stat_cache_size=0 -o allow_other -o mp_umask=133",具体配置权限说明如下。

  • -o max_stat_cache_size=0:设置最大状态缓存大小为0,表示不限制状态缓存的大小,可以提高目录列表显示性能。
  • -o allow_other:允许其他用户访问被www-data用户拥有的文件。
  • -o mp_umask=133:设置文件创建时的umask为133,这意味着新创建的文件将只有可读可写可执行的权限,可以保证文件的安全性。
  • 修改挂载掩码权限

    • 若指定挂载目录的权限为644,在otherOpts字段中增加配置:-o mp_umask=133

    • 若指定挂载目录里文件的权限为644,在otherOpts字段中增加配置:-o umask=133

  • 指定挂载目录里文件的角色权限

    • GroupID权限为指定权限,在otherOpts字段中增加配置:-o gid=XXX,其中,XXX为您在/etc/password中记录的角色组ID。

    • UserID权限为指定权限,在otherOpts字段中增加配置:-o uid=XXX,其中,XXX为您在/etc/password中记录的角色ID。

1.php-fpm执行文件和目录问题

由于项目是一个PHP项目,项目执行用户和用户组是www-data:www-data(镜像php-fpm默认配置),dockerfile打包到镜像中中默认是root:root,此时项目由于权限问题无法运行。可以通过dockerfile打包时执行文件用户和用户组,下面我展示php-fpm打包yaml文件,关注最后

FROM php:7.2.34-fpm-alpine

LABEL MAINTAINER="xxx xxxn@xxx.xxx"

# 参数
ENV TZ "Asia/Shanghai"
ENV ETC_DIR "/usr/local/etc"
ENV PHP_INI_DIR "/usr/local/etc/php"

# 配置 apk 阿里云镜像源
RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories

# 调整时区
RUN apk add tzdata && cp "/usr/share/zoneinfo/$TZ" /etc/localtime && echo "$TZ" > /etc/timezone

# install depends libraries
RUN apk --update add --no-cache --virtual .build-deps autoconf g++ libtool make curl-dev gettext-dev linux-headers

# 安装 Redis 扩展
RUN echo "---------- Install redis ----------" \
#    && mkdir redis \
#    && tar -xf redis-5.2.2.tgz -C redis --strip-components=1 \
#    && cd redis && phpize && ./configure && make -j$(nproc) && make install
#    && docker-php-ext-enable redis
    && pecl install redis \
    && docker-php-ext-enable redis

RUN echo "---------- Install zip ----------" \
    && apk add libzip libzip-dev \
    && docker-php-ext-install zip

RUN echo "---------- Install gettext ----------" \
    && apk add gettext-dev \
    && docker-php-ext-install gettext

RUN echo "---------- Install pdo_mysql ----------" \
    && docker-php-ext-install pdo_mysql

RUN echo "---------- Install gd ----------" \
    && apk add \
        freetype \
        freetype-dev \
        libpng \
        libpng-dev \
        libjpeg-turbo \
        libjpeg-turbo-dev \
        libwebp-dev \
    && docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-png-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-webp-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
    && apk del \
       freetype-dev \
       libpng-dev \
       libjpeg-turbo-dev

RUN echo "---------- Install bcmath ----------" \
	&& docker-php-ext-install bcmath

# 覆盖 php.ini 文件
COPY deploy/docker/php/php.ini $PHP_INI_DIR/conf.d/

# php 镜像的 www-data user uid & gid are 82, change them to 1000 (primary user)
RUN apk add shadow && usermod -u 1000 www-data && groupmod -g 1000 www-data

# 指定目录
WORKDIR /www

# COPY 项目 /www 目录,指定用户:用户组
COPY --chown=www-data:www-data . /www

五、迁移工具

由于判断的资源文件存在ECS上,在迁移前文件不断产生,如果手动复制文件就显示很麻烦,这里给大家推荐一个功能,可以轻松完成ECS资源同步OSS。

工具"ossutil",Object和Bucket的命令行管理工具。

  • 提供方便、简洁、丰富的Object和Bucket管理命令,操作性能好。
  • 支持文件并发上传、断点续传。
  • 支持文件目录(文件夹)的上传下载。