kubernetes ingress代理访问阿里云oss记

背景

某程序有读写对象存储文件的业务逻辑,该程序一直正常运行,可正常读写对象存储中的文件。不过,该程序之前访问的对象存储产品为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的域名管理中绑定代理的域名。

此方案仅是换一种临时解决问题的方法,可能不是最佳实践。



上一篇:CRM WebClient UI里的文件是如何上传到Netweaver后台的


下一篇:云效DevOps训练营第2天打卡任务