zoukankan      html  css  js  c++  java
  • 记录MindSphere On Cloud Foundry的一次尝试过程

    试验背景:

    开始时间:2019年12月11日

    结束时间:2019年12月13日

    最后一次更新:2020年4月30日(问题三)

    自己编写一个后台程序,尝试推送到Cloud Foundry上,并开放从MindSphere以外访问的权限。

    程序实现以下功能:

    1、使用MindSphere提供的API获得指定时序的Token

    2、启动定时任务,从时序数据中拉取数据,并打印在日志中。

    3、提供一个REST接口,用来获取数据。

    4、程序开启log日志,打印到Cloud Foundry的容器中。

    前提条件:

    1、电脑已经安装Power Shell。

    2、提前编写好要测试的程序。

    3、拥有MindSphere的Developer账号。

    操作随记:

    (一)编写程序

    程序地址:https://github.com/quchunhui/demo-macket/tree/master/mindsphere

    (二)登陆Cloud Foundry

    Cloud Foundry的登陆,可以参考上一篇博客。

    命令:cf login -a https://api.cf.cn1.mindsphere-in.cn --sso --skip-ssl-validation

    博客地址:https://www.cnblogs.com/quchunhui/p/12015167.html

    (三)创建CF空间并赋予权限

    1、切换到已有组织(org),相关命令如下:

    切换组织:cf target -o rexelcn0

    2、创建测试程序的运行空间(space),相关命令如下:

    创建空间:cf create-space rexel-mf-api-test 

    查看所有空间:cf spaces

    3、更新空间的Role(角色)及Permission(权限),相关命令如下:

    查看Space中的使用者及其权限:cf space-users rexelcn0 rexel-mf-api-test

    附加:

    如果希望使用其他账户完成后续的操作,可以使用一下命令来添加权限。

    为指定用户添加SpaceManager权限:cf set-space-role chunhui.qu@rexel.com.cn rexelcn0 rexel-mf-api-test SpaceManager

    为指定用户添加SpaceDeveloper权限:cf set-space-role chunhui.qu@rexel.com.cn rexelcn0 rexel-mf-api-test SpaceDeveloper

    (四)将应用程序部署到Cloud Foundry

    1、在程序根目录中创建manifest.yml文件

    文件内容如下:

    ---
    applications:
    - name: rexel-mindsphere-api-test
      instances: 1
      random-route: true
      path: target/rexel-mindspere-api-0.0.1.jar
      memory: 512M  
    

      

    2、将程序推送到CF的空间,相关命令如下:

    跳转入Spaces:cf target -s rexel-mf-api-test

    跳转到程序根目录:cd D:MyWork22_Github exel-cn exel-jarvis exel-mindsphere-api

    程序打包:mvn package(注意,如果程序修改了,一定要重新打包,因为cf push上传的jar包,不是源代码,这一点非常重要。)

    推送程序:cf push

    列出所有应用及运行状态:cf apps

    查看应用的详细状态:cf app rexel-mf-api-test

    【小插曲1】

    执行cf push的时候报错一个错误

    在程序根目录中使用mvn package重新编译打包,然后再次执行cf push之后问题解决。

    【小插曲2】

    程序上传之后,cf提示启动失败

    按照提示的命令查看了日志。命令:cf.exe logs rexel-mindsphere-api-test --recent

    可以看到提示内存不够。

    尝试将manifest.yml中配置的内存大小调高,重新推送之后解决。修改之后的manifest.yml文件内容

    ---
    applications:
    - name: rexel-mindsphere-api-test
      instances: 1
      random-route: true
      path: target/rexel-mindspere-api-0.0.1.jar
      memory: 1G 
    

    (五)SSH进入到空间查看运行

    官网操作手册:https://developer.mindsphere.io/zh/paas/paas-cloudfoundry-ssh.html

    1、检查空间SSH是否开启

    命令:cf space-ssh-allowed rexel-mf-api-test

    2、开始指定空间SSH权限:

    默认是开启的,如果没有开启,可以使用以下命令打开权限。

    命令:cf allow-space-ssh rexel-mf-api-test

    3、为应用开启SSh权限:

    命令:cf enable-ssh rexel-mindsphere-api-test

    注意不要弄错了空间名(rexel-mf-api-test)和应用名(rexel-mindsphere-api-test)

    4、重新启动应用:

    命令:cf restart rexel-mindsphere-api-test

    5、SSH进入应用空间:

    命令:cf ssh rexel-mindsphere-api-test

    6、进入日志所在路径:

    在spring程序的logback中,配置的日志路径为:/home/vcap/logs

    进入路径:cd /home/vcap/logs/

     7、查看日志是否正常:

    命令:less rexel-md-test2019-12-11.log

    (六)将程序注册到MindSphere

    1、使用MindSphere账号登录

    2、选择Developer Cockpit(开发驾驶舱)

      

    3、选择仪表盘选项卡。

    4、单击创建新的应用。

    类型:Standard

    基础设施:MindSphere Cloud Foundry。

    显示名称:Rexel MindSphere Api Test(字面上容易理解的就可以)

    内部名称:rexelmfapitest(这将会为成为应用URL的一部分。初始化创建后,内部名称不能被更改!)

    版本:1.0.0(MindSphere 支持 Major.Minor.Patch 方案。版本必须以 >=1 的主号码开头。保存之后版本不能被更改。)

    应用图标:随便上传一个就可以。我用了一个钢铁侠第一任人工智能助理Jarvis的图片。
    输入组件名称。 示例应用的组件名称为hello-spring-cloud。

    组件名称

    组件名称必须与 manifest.yml 中的 Cloud Foundry 应用名称匹配。否则,生产系统中的自动注册将会失败。

    组件名称:rexel-mindsphere-api-test(必须与 manifest.yml 中的 Cloud Foundry 应用名称匹配。否则,生产系统中的自动注册将会失败。)

    Cloud Foundry URL:rexel-mindsphere-api-test-comedic-hippopotamus-vl.apps.cn1.mindsphere-in.cn(使用 cf app {app_name} 来获取您部署的应用的 URL。)

    端点:为您的组件添加至少一个端点。使用 /** 来匹配您应用的所有路径。

    关于端点:
    您可以为端点使用任意路径。
    不允许使用 /api,因为这是为从相对路径(例如 /api/iot/v3/timeseries)调用 MindSphere api 预留的。
    避免使用keywords,因为这是为 SQL 操作预留的。
    您可以使用通配符。 * 匹配路径中任何字符,** 匹配任何字符和子路径。
    

    点击保存。将被重定向到应用详细信息。 应用程序处于In-Development状态,并且准备好注册了。

    可以看到应用创建成功。(有没有开心的感觉?)

     【小插曲】

    保存失败,因为说明中不能使用中文。

    使用有道词典,将中文翻译成应为,重新搞一次解决。 

    (七)配置应用角色和范围

    参考官网资料:https://developer.mindsphere.io/zh/howto/howto-cf-running-app.html

    1、切换到授权管理选项卡。

    2、选择应用。

    3、创建一个应用范围并选择分配给哪个角色。

    关于角色和范围:https://developer.mindsphere.io/zh/concepts/concept-roles-scopes.html

    这里暂时只赋予一个权限mdsp:core:iot.timUser(读取时间序列的权限)

    (八)注册应用

    1、切换到仪表盘选项卡,打开应用详细信息,单击注册。

    (九)分配应用角色

    1、从Launchpad 中打开 Settings 应用,并切换到角色选项卡。

    2、选择一个应用角色并单击编辑分配。

    分配一个或多个用户到应用角色。

    结束编辑。登出 MindSphere 并重新登陆。

    (十)授权管理

    使用密钥管理器API授权您的应用访问其他租户数据。该操作主要针对某个应用需要访问其他不同租户的数据的情形,例如,在没有用户交互的情况下频繁进行数据处理时。

    1、在 MindSphere Launchpad Developer/Operator Cockpit 授权管理应用凭证中,点击对应的 APP 名称,选择右侧签发访问权限

    2、选择所需权限类别,并提交

    3、将显示的对应信息保存,

    注意:此信息只显示一次

    注意:此信息只显示一次

    注意:此信息只显示一次

    4、将对应信息添加至应用 Manifest .yml 文件中,并重新上传应用

    ---
    applications:
    - name: rexel-mindsphere-api-test
      instances: 1
      random-route: true
      path: target/rexel-mindspere-api-0.0.1.jar
      memory: 1G
    env:
      HOST_ENVIRONMENT: cn1
      MDSP_OS_VM_APP_NAME: rexelmfapitest
      MDSP_OS_VM_APP_VERSION: 1.0.0
      MDSP_KEY_STORE_CLIENT_ID: <只显示一次的客户ID>
      MDSP_KEY_STORE_CLIENT_SECRET: <只显示一次的客户密钥>
    

      

    5、使用Postman测试是否部署成功

    先使用 base 64 工具加密客户ID与客户秘钥,格式为客户ID:客户秘钥(半角符号)

    工具地址:https://www.base64encode.org/

    工具截图:

    以获取Token为例,使用Postman测试一下:

    请求类型:POST

    请求地址:https://gateway.cn1.mindsphere-in.cn/api/technicaltokenmanager/v3/oauth/token

    Header:

    Body 选项卡设置格式为Raw ,格式为JSON,内容为:

    {
      "appName": "rexelmfapitest",
      "appVersion": "1.0.0",
      "hostTenant": "rexelcn0",
      "userTenant": "rexelcn0"
    }
    

    点击发送之后,可以看到已经可以正常获取Token信息

    (十一)从外部访问应用程序提供的接口

    与MindSphere的人员确认过了,目前暂不支持,直接从外部访问部署到MindSphere上的应用。

    有两种方式进行应用落地:

    方式一:

    开发一整套的应用(包括前端和后端,比如Spring + Vue),推送到CF,并注册到MindSphere上。

    这种方式的缺点是,必须拥有MindSphere账号的用户才有可能访问应用。

    方式二:

    在MindSphere之外,如阿里云上面开发独立的应用,通过MindSphere开放的API接口来获取数据,

    这种方式的缺点是,需要独立服务器以及数据库等配套组件支撑。好处是与MindSphere解耦。

    我尝试了第一种方式,自己写了一个最简单的页面(一个按钮,一个显示数据的文本框),尝试部署到MindSphere上。

    (十二)部署并测试Web页面

    写了一个最简单的web页面,部署的方式与Spring后台程序一样,

    唯一需要注意的是manifest.yml的内容必须多一个而配置就是:buildpack: staticfile_buildpack_offline

    用来告诉CF这是一个静态的文件。

    那么,如何访问后台应用app中的接口呢?

    将静态的页面推送上去之后,不管三七二十一,先访问一下后台试试(接口地址可能不对),结果从浏览器控制台上可以看到如下错误:

    Refused to connect to 'http://localhost:8081/rexel/timeseries/test' because it violates the following Content Security Policy directive: "default-src 'self' static.cn1.mindsphere-in.cn". Note that 'connect-src' was not explicitly set, so 'default-src' is used as a fallback.
    

     

    问了相关技术人员,建议我去看一下MindSphere->Cockpit下的content-security-policy(内容安全策略),

    MindSphere默认的CSP设置如下:

    default-src 'self' static.cn1.mindsphere-in.cn; style-src * 'unsafe-inline'; script-src 'self' 'unsafe-inline' static.cn1.mindsphere-in.cn; img-src * data:;
    

    网上找了一些资料,对Content Security Policy这个词进行了快速扫盲,试图找到解决办法

    网友博客:

    https://www.jianshu.com/p/74ea9f0860d2

    MindSphere官网介绍:

    https://developer.mindsphere.io/zh/concepts/concept-csp.html#_3

    https://developer.mindsphere.io/zh/howto/howto-csp.html

    CSP官网:

    https://content-security-policy.com/

    首先,尝试了取消CSP的安全限制,将CSP的设置修改如下

    default-src 'self' *; style-src * 'unsafe-inline'; script-src 'self' 'unsafe-inline' *; img-src * data:;
    

    然后界面返回了这么一个鬼东西,已经是完全懵逼状态, 

    MindSphere Gateway error: A redirect is required to get the users approval

    问了一下西门子的朋友,说是每次修改DSP之后,MindSphere后台服务会重启,需要等十几分钟再登陆。

    吃过午饭,回来重新试了一次之后,发现成功了,简直高兴的不得了。然而

    【小插曲】

    发现由于html里写的访问地址是localhost,刚好我电脑本地的后台程序也在运行中,

    所以,访问的是我本地的程序,并不是注册在Cloud Foundry上的程序,白他妈的高兴一场,还兴奋的去和老板报了喜,

    怎么办?自己挖的坑,哭着也得填完。

    于是重新想西门子的售后发起求助,寻求解决办法。

    最终,经过售后一顿猛如虎的操作之后终于解决。

    解决办法:

    地址1:http://localhost:8081/rexel/timeseries/test

    地址2:https://rexelcn0-rexelmfapitest-rexelcn0.cn1.mindsphere-in.cn/rexel/timeseries/test

    地址3:https://rexelcn0-rexelmfapitest-rexelcn0.cn1.mindsphere-in.cn/v1/rexel/timeseries/test

    地址4:https://rexelcn0-rexelmfapitest-rexelcn0.cn1.mindsphere-in.cn/api/rexelmfapitest-rexelcn0/v1/rexel/timeseries/test

    地址5:https://supplab-rexelcn0-staticweb-rexelcn0.cn1.mindsphere-in.cn-supplab.cn1.mindsphere-in.cn/api/rexelmfapitest-rexelcn0/v1/rexel/timeseries/test

    地址6:/api/rexelmfapitest-rexelcn0/v1/rexel/timeseries/test

    结果地址6最终生效,问题终于得以解决,吹出去的牛逼也算是能圆回来了,差点没让老衲圆寂在电脑前。

    2020/4/22追记:

    关于前端页面访问后端的地址,有一点需要注意:后端服务的注册版本对接口有影响

    如下图,我们的应用版本是纯数字,系统给的接口版本号是:大写的V1

    如果应用版本不是数字,而是如v1.0.0这样的,系统给的接口版本是:小写的v1

    (十三)注销应用

    万事有始有终,应用可以正常使用了,现在开始尝试将一个应用注销。

    先来回忆一下上线的步骤

    1、在cf上创建org、space

    2、赋予用户在space中的权限

    3、将应用push到cf并启动

    4、在ms(MindSphere的简称)上注册应用

    5、赋予相应的角色和范围

    所以,彻底下线应用的操作就应该和上面的相反,

    不过个人认为,上面的第5步应该不需要执行,删除了应用按理说应该可以自动取消相应的授权、角色和范围。

    所以,直接从上面的第4步开始,let's go go go......................

    1、在ms上注销应用(这里注销的是一个以前测试的应用)

    可以看到应用删除成功了

    检查一下,是否按照我的猜想,授权、角色和范围都已经删除干净。

    先检查一下授权:嗯,被删除的“myfirstapp”已经消失了。

    再来检查一下角色和范围:很好,这里也被删的很干净。

    2、从cf上停止并删除app

    先检查一下空间。命令:cf spaces

    我们要删除的应用在rexel-demo中。

    进入到要删除的空间,命令:cf space rexel-demo

    查看一下在空间中运行的应用,命令:cf apps

    暂停应用。命令:cf stop rexel-mindsphere-api-test

    删除应用。命令:cf delete cf stop rexel-mindsphere-api-test

    重新查看是否已经删除。命令:cf apps

    最后看到空间中已经没有任何app了,可以放心的删除空间了。

    3、删除空间

    删除空间。命令:cf delete-space rexel-demo

    查看空间,确认是否成功删除。命令:cf spaces

    (十四)Backing Services的创建及关联

    官网地址:https://developer.mindsphere.io/zh/paas/index.html

    1. 查看可用的Backing services:

    命令:cf marketplace

    会列出service的名字,不同套餐,及说明。具体套餐请参考官网介绍。

    2.创建Backing services实例

    命令:cf create-service elasticsearch5 elasticsearch-xs my-elasticsearch-service

    3. 检查创建的serivce状态

    命令:cf services

    刚刚创建完成的状态:create in progress

    过几分钟再次查看的状态:create succeeded

    4. 把App与Service进行关联

    命令:cf bind-service rexel-service my-elasticsearch-service

    需要注意的是,需要等待service创建成功之后才可以进行关联,如果service处于创建中状态进行关联,会提示如下错误:

    错误:An operation for service instance my-elasticsearch-service is in progress.

    5.重新载入或重新启动应用

    要使应用能够访问服务实例,请运行 cf restage 或 cf restart 来重新载入或重新启动应用。

    命令:cf restart rexel-service

    6.获取服务实例访问凭证

    将服务实例绑定到应用后,Elasticsearch 数据库的凭证将存储在应用的环境变量中。运行 cf env APP-NAME 显示环境变量。

    命令:cf env rexel-service

    应用环境变量样例:(用户名,密码,端口等敏感字段均进行了修改脱敏)

    System-Provided:
    {
     "VCAP_SERVICES": {
      "elasticsearch5": [
       {
        "binding_name": null,
        "credentials": {
         "host": [
          "http://eld521309a.service.dc1.a9ssvc:9213"
         ],
         "hosts": [
          "eld55509a-es-0.node.dc1.a9ssvc"
         ],
         "password": "a9sa1d17b178af842aa1a2349474997dd67bf438a2b",
         "port": 9213,
         "scheme": "http",
         "username": "a9s76348fd458842b5234cc5e3f5ce46c3582a3e7c38"
        },
        "instance_name": "my-elasticsearch-service",
        "label": "elasticsearch5",
        "name": "my-elasticsearch-service",
        "plan": "elasticsearch-xs",
        "provider": null,
        "syslog_drain_url": null,
        "tags": [
         "searchengine"
        ],
        "volume_mounts": []
       }
      ]
     }
    }
    
    {
     "VCAP_APPLICATION": {
      "application_id": "32309d25-88fb-4b5b-b16d-c449d1d7e1b9",
      "application_name": "rexel-service",
      "application_uris": [
       "rexel-service-shy-mongoose-wj.apps.cn1.mindsphere-in.cn"
      ],
      "application_version": "fffa6fd1-b50d-4d6f-8ce4-c2f155600af5",
      "cf_api": "https://api.cf.cn1.mindsphere-in.cn",
      "limits": {
       "disk": 512,
       "fds": 16384,
       "mem": 700
      },
      "name": "rexel-service",
      "organization_id": "d36d5255-6364-4d96-bab1-c2d5a0ca760a",
      "organization_name": "tenant0",
      "process_id": "32309d25-88fb-4b5b-b16d-c449d1d7e1b9",
      "process_type": "web",
      "space_id": "b64f9b6c-b09f-42a4-a4b7-ebcb6b4d4167",
      "space_name": "rexel-ids",
      "uris": [
       "rexel-service-shy-mongoose-wj.apps.cn1.mindsphere-in.cn"
      ],
      "users": null,
      "version": "fffa6fd1-b50d-4d6f-8ce4-c2f155600af5"
     }
    }
    
    User-Provided:
    HOST_ENVIRONMENT: cn1
    MDSP_KEY_STORE_CLIENT_ID: rexelcn0-rexelservice-1.0.0
    MDSP_KEY_STORE_CLIENT_SECRET: xxxxxxxxxxxxx
    MDSP_OS_VM_APP_NAME: rexelservice
    MDSP_OS_VM_APP_VERSION: 1.0.0
    
    No running env variables have been set
    
    No staging env variables have been set

    7.解绑服务实例

    命令:cf unbind-service rexel-service my-elasticsearch-service

    8.删除服务实例

    命令:cf delete-service my-elasticsearch-service

    查看一下服务实例状态。状态为:delete in progress

    过几分钟,再次查看服务实例状态。可以看到服务实例已经被删除。

    (十五)其他尝试

    这部分后面有时间会继续补充

    1、使用MindSphere的数据分析工具

    2、使用MindSphere提供的后台服务(以Mongodb为例)

    【总结】

    1、MindSphere整个基于Cloud Foundry开展的,Cloud Foundry是业界第一个开源PaaS云平台,

    整个验证过程一步一个坎,其根本原因是对Cloud Foundry的不熟悉,后续有时间需要多学习一下这个平台,

    如果时间允许,最好自己安装部署一遍。

    2、MindSphere的小白级的资料太少,如果是一点基础都没有的,很难顺利上手,

    而且资料不是基于“用户场景”的,像我的这种尝试场景,需要各处去寻找资料,知识也连不起来。

    对使用者来说不是很友好。

    附:其他可能遇到的问题

    【问题一】

    错误日志:

    You have exceeded your organization's memory limit: app requested more memory than available
    

    问题原因:

    每个org都有内存等限制,超过org的内存限制就会出现这个问题。

    查看Org的内存限制

    查看org详情。命令:cf org rexelcn0

    查看org的配额。命令:cf quota cf-quota-1552463110231

    注意应用的内存大小不要超过这个限制就可以。

    我尝试着将org中没有用到的空间给删除掉,重新push了一次应用。

    【问题二】

    问题描述:

    想ssh进入应用,查看一下运行状态,应用是重新部署上去的,结果提示以下错误。

    Error opening SSH connection: ssh: handshake failed: ssh: unable to authenticate, attempted methods [password none], no supported methods remain
    

    检查了space和app对ssh的支持状态都没有问题。

    问题原因:

    修改了app的ssh权限之后,需要重新启动一下app,否则权限不会生效。

    解决办法:

    重启app。命令:cf restart rexel-mindsphere-api-test

    ssh进入app。命令:cf ssh rexel-mindsphere-api-test

    【问题三】

    问题描述:

    前端页面中嵌入了地图,结果在显示的时候一直报错

    Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Centent Security Policy directive: 'self' 'unsafe-inline' static.cn1.mindsphere-in.cn"

    解决办法:

    在应用的内容安全策略(CSP)中增加unsafe-eval。

    default-src 'self' *; style-src * 'unsafe-inline'; script-src * 'self' 'unsafe-inline' 'unsafe-eval'; img-src * data:;

    附:角色范围整理

    附:CF操作命令:

    http://cli.cloudfoundry.org/zh-Hans/cf/ 

    --END--

    解绑服务实例

    运行 cf unbind-service 可以解除应用与服务间的绑定关系。

  • 相关阅读:
    RabbitMQ安装
    Redis安装
    spring boot 与 vue 配置 https
    JAVA 注解
    Java 获取两个日期之间的所有日期
    数组排序
    el-table表格高度自适应
    Windows使用Nexus搭建Maven私服
    SpringCloud 整合 Python
    SpringCloud 整合 Python
  • 原文地址:https://www.cnblogs.com/quchunhui/p/12024493.html
Copyright © 2011-2022 走看看