背景
某程序有读写对象存储文件的业务逻辑,该程序一直正常运行,可正常读写对象存储中的文件。不过,该程序之前访问的对象存储产品为AWS的S3、自建的对象存储minio和Dell EMC的硬件对象存储集群。
该程序部署到阿里云并且使用阿里云对象存储oss后,发现业务无法通过http方式正常读取oss中的文件了。检查发现,原来对象存储支持两种风格的访问,分别是virtual-hosted–style和path-style。
以AWS S3为例,
virtual-hosted–style的
访问格式是这样的:https://bucket-name.s3.Region.amazonaws.com/keyname,
具体访问url举例:https://my-bucket.s3.us-west-2.amazonaws.com/puppy.png
path-style的
访问格式是这样的:https://s3.Region.amazonaws.com/bucket-name/keyname
具体访问url举例:https://s3.us-west-2.amazonaws.com/mybucket/puppy.jpg
该程序使用的是path-style,而阿里云的对象存储oss不支持path-style风格,所以原因找到了。
因为修改程序代码工作量较大,我们所有的程序又都部署在kubernetes集群中,为了快速解决问题,我们决定使用kubernetes ingress代理阿里云oss并进行重定向。
实施
1.先在kubernetes集群中创建一个代理阿里云oss mybucket的service oss-mybucket
apiVersion: v1
kind: Service
metadata:
name: oss-mybucket
namespace: infra
spec:
type: ExternalName
externalName: mybucket.oss-cn-hangzhou.aliyuncs.com
2.创建一个对应的ingress指向创建好的service oss-mybucket
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /$2
labels:
app.kubernetes.io/component: oss-mybucket
app.kubernetes.io/instance: oss-mybucket
app.kubernetes.io/name: oss-mybucket
name: oss-mybucket
namespace: infra
spec:
rules:
- host: oss-mybucket.mydomain.com
http:
paths:
- path: /mybucket(/|$)(.*)
pathType: Prefix
backend:
serviceName: oss-mybucket
servicePort: 80
ingress中需要注意的地方:
nginx.ingress.kubernetes.io/rewrite-target: /$2
上面这个配置保证重定向时去掉源访问url中的bucketname
- path: /mybucket(/|$)(.*)
上面这个配置保证使用path-style访问时,根据bucketname进行重定向;如果不是path-style风格,而是bucket中有该目录,将会出错
3.配置域名指向ingress(略)
4.测试访问
curl http://mybucket.mydomain.com/mybucket/test.jpg -o test.jpg
出现报错
SecondLevelDomainForbidden
The bucket you are attempting to access must be addressed using OSS third level domain.
6093333222AAFC30350BA527
mybucket.oss-cn-hangzhou.aliyuncs.com
需要为oss bucket绑定域名:登陆阿里云对象存储控制台,选择bucket,如mybucket,进入bucket详情页,选择传输管理-域名管理,绑定域名,为bucket绑定一个域名,如mybucket.mydomain.com
等待约一分钟,重新测试访问
curl http://mybucket.mydomain.com/mybucket/test.jpg -o test.jpg
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 203k 100 203k 0 0 682k 0 --:--:-- --:--:-- --:--:-- 682k
访问成功
5.修改程序配置
将程序配置中的oss endpoint地址由oss-cn-hangzhou.aliyuncs.com更改为mybucket.mydomain.com,程序功能恢复,可正常使用http方式读取oss中的文件
总结
aws s3对象存储支持virtual-hosted–style和path-style两种访问风格,而阿里云oss只支持virtual-hosted–style风格。
使用kubernetes ingress代理阿里云oss并rewrite url后,程序可继续使用path-style访问阿里云oss。
代理阿里云oss bucket后,需要在bucket的域名管理中绑定代理的域名。
此方案仅是换一种临时解决问题的方法,可能不是最佳实践。