项目按甲方要求,部署在政务网,各种需要在系统中播放的视频存放于内部华为云;然后,系统需要在互联网上访问。
经过一天捣鼓,终于搞定。过程中遇到了许多问题,有nginx代理的,docker域名解析的,华为云存储桶默认设定的访问策略不支持公共读和匿名访问,https站点无法访问http资源,等等。最大的困难在于,政务网的管理员对华为云好像也不上心,一问三不知,没有示例,全凭自己摸索和分析;而且,服务器操作系统是linux,华为云只有一个名曰obsutil的命令行工具,只能敲命令和访问策略。
过程和技术点如下:
一、首先华为云存储桶中的资源应该有个地址
利用华为云所谓的对象存储工具obsutil,浏览事先上传的资源,都是 obs://。。。
这种格式,如图所示。这是什么地址?浏览器应该认不了这种地址吧。查了许多次政务云管理员推荐的华为云操作手册,认为应该会有个域名,询问政务云管理员,果然是有,格式为 桶名.华为云域名
。不问还不说。老实说,单凭他们刚开始给的资料,真的是摸不着头脑。看看华为云操作手册,跟世界上所有的操作手册一样,晦涩难懂,欲言又止,90%是废话。
二、存储桶的访问策略
如上所述,访问桶中对象,可通过 https://桶名.华为云域名/对象
这种地址。不过,服务器是linux,没有桌面,只有命令行。怎么测试能否访问这些资源呢?用wget。如下:
wget http://sthj.obsv3.huawei.inner-cloud.com/temp/test.txt
但结果提示:403,Forbidden。
如果将访问路径改为:
wget http://sthj.obsv3.huawei.inner-cloud.com/temp123/test.txt
则提示 404,Not Found。这说明,路径是正确的,可能是桶有什么安全策略,限制了。
解决如下:
1、设置桶属性
获取桶属性
./obsutil stat obs://sthj -acl
显示Acl为private,私有桶。改为public-read:
./obsutil chattri obs://sthj -acl=public-read
运行wget,仍然是403,forbidden。
2、设置桶策略
1)获取桶策略
将策略下载到/media/root/obsutil/temp/policy.json
./obsutil bucketpolicy obs://sthj -method=get -localfile=/media/root/obsutil/temp/policy.json
策略如下
{
"Statement": [
{
"Sid": "Customized1681356038822",
"Effect": "Allow",
"Principal": {
"ID": [
"domain/de389423d54b4fdca58169087700018e:user/44fc93c699b141928a3afacda4ef127c",
"domain/de389423d54b4fdca58169087700018e:user/8146a1dc3b2c41ab9b4c75e120ef451f",
"domain/de389423d54b4fdca58169087700018e:user/633787e9f6854af28bbcfa3a453c8d60"
]
},
"Action": [
"*"
],
"Resource": [
"sthj/*"
]
},
{
"Sid": "Customized1681356059187",
"Effect": "Allow",
"Principal": {
"ID": [
"domain/de389423d54b4fdca58169087700018e:user/44fc93c699b141928a3afacda4ef127c",
"domain/de389423d54b4fdca58169087700018e:user/8146a1dc3b2c41ab9b4c75e120ef451f",
"domain/de389423d54b4fdca58169087700018e:user/633787e9f6854af28bbcfa3a453c8d60"
]
},
"Action": [
"*"
],
"Resource": [
"sthj"
]
}
]
}
其中,sthj是桶名。"Effect"可选值为Allow或Deny;"Principal"为用户,如果为“*”则代表支持匿名;"Action"就是各种操作权限,如"GetObject"代表读。官方文章
2)修改桶策略文件
将桶下资源改为匿名可读(见第三项),如下:
{
"Statement": [
{
"Sid": "Customized1681356038822",
"Effect": "Allow",
"Principal": {
"ID": [
"domain/de389423d54b4fdca58169087700018e:user/44fc93c699b141928a3afacda4ef127c",
"domain/de389423d54b4fdca58169087700018e:user/8146a1dc3b2c41ab9b4c75e120ef451f",
"domain/de389423d54b4fdca58169087700018e:user/633787e9f6854af28bbcfa3a453c8d60"
]
},
"Action": [
"*"
],
"Resource": [
"sthj/*"
]
},
{
"Sid": "Customized1681356059187",
"Effect": "Allow",
"Principal": {
"ID": [
"domain/de389423d54b4fdca58169087700018e:user/44fc93c699b141928a3afacda4ef127c",
"domain/de389423d54b4fdca58169087700018e:user/8146a1dc3b2c41ab9b4c75e120ef451f",
"domain/de389423d54b4fdca58169087700018e:user/633787e9f6854af28bbcfa3a453c8d60"
]
},
"Action": [
"*"
],
"Resource": [
"sthj"
]
},
{
"Sid": "Customized1681356038822publicread",
"Effect": "Allow",
"Principal": "*",
"Action": [
"GetObject","RestoreObject","GetObjectVersion"
],
"Resource": [
"sthj/*"
]
}
]
}
3、更新桶策略
以上只是改了桶策略文件,还要将此文件更新桶策略才有效:
./obsutil bucketpolicy obs://sthj -method=put -localfile=/media/root/obsutil/conf/policy.json
至此,可通过wget访问。但桶属性和桶策略,有啥区别呢?它们是不是共同控制桶的访问呢?不懂,没时间尝试。
三、内部域名的转发
但是,系统部署在政务云,华为云算是内部的私有云。对应的域名,也是内部的,如果互联网需要访问这个华为云里面的东西,就需要在双网卡的服务器上用nginx做个转发,或曰反向代理。nginx配置如下:
location /obs/ {
proxy_pass http://sthj.obsv3.huawei.inner-cloud.com/;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
四、docker容器添加域名解析
但我们的nginx是运行在docker里的。上面这段配置写到nginx的配置文件后,该docker容器无法启动,提示不能解析域名sthj.obsv3.huawei.inner-cloud.com。其实不奇怪,docker就是一个容器,就像一个简单的操作系统,它里面没有相应的域名解析很正常。
参照网上教程Docker添加域名解析,删掉原nginx的docker容器,重新创建,在创建脚本中加入域名解析:
docker run \
--add-host=sthj.obsv3.huawei.inner-cloud.com:192.168.10.249 \
--name forward --privileged -it -p 80:80 \
-v /home/web/nginx/conf/forward.conf:/etc/nginx/nginx.conf:ro \
-v /home/web/nginx/html:/usr/share/nginx/html:rw \
-v /home/web/nginx/logs/forward:/var/log/nginx \
-d nginx:stable-alpine
nginx启动正常。
五、https站点无法访问http问题
忐忑不安地在浏览器中键入转发后的地址,结果显示无法访问,一盆冷水。不过,注意到转发地址为https。在https站点中,有个毛病,是无法连接http站点资源的。而华为云两种协议都支持,于是将nginx转发设置稍加修改,将http改为https。啊,月亮下去了,毛病出来了。
location /obs/ {
proxy_pass https://sthj.obsv3.huawei.inner-cloud.com/;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
obsutil工具使用说明:
对象存储服务工具指南(obsutil)