PHP项目迁移K8s之OSS存储卷
前言
最近一个老项目(PHP)需要迁移至阿里云K8s上,之前项目上各种资源都存在服务器上多个目录下,本文就针对其中资源迁移部署讲解。
一、选择OSS存储卷原因
出于多种原因选择挂载OSS存储卷:
- 项目后期开发功能设计上传,需要上传OSS服务(之前都是上传到ECS服务上)。
- 若挂载NAS存储卷,项目平时需要更换资源,OSS通过客户端上传替换更为方便。
- 项目静态资源量很大,且后期还不断增加,而OSS静态存储卷是阿里云对象存储OSS中的一种存储类型,用于存储静态数据,包括图片、视频、js、html、css等等。OSS静态存储卷具有海量、安全、低成本、高可靠等特性,支持数据读写和在线修改,适用于Web网站图片存储、动静资源分离等业务场景。
- 项目业务资源写少读多,OSS存储卷更适合,如果您的业务是将文件写入存储的场景,推荐使用NAS存储卷服务。
- 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的接入域名。
不同域名访问格式如下:
|
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在容器中挂载的位置。 |
|
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管理命令,操作性能好。
- 支持文件并发上传、断点续传。
- 支持文件目录(文件夹)的上传下载。