創建topologies
cd /usr/hdp/current/knox-server
touch conf/topologies/haha.xml
haha.xml
<?xml version="1.0" encoding="utf-8"?>
<topology>
<gateway>
<provider>
<role>authentication</role>
<name>ShiroProvider</name>
<enabled>false</enabled>
<param>
<name>main.ldapRealm</name>
<value>org.apache.hadoop.gateway.shirorealm.KnoxLdapRealm</value>
</param>
<param>
<name>main.ldapContextFactory</name>
<value>org.apache.hadoop.gateway.shirorealm.KnoxLdapContextFactory</value>
</param>
<param>
<name>main.ldapRealm.contextFactory</name>
<value>$ldapContextFactory</value>
</param>
<param>
<name>main.ldapRealm.contextFactory.url</name>
<value>ldap://fsmanager</value>
</param>
<param>
<name>main.ldapRealm.contextFactory.authenticationMechanism</name>
<value>simple</value>
</param>
<param>
<name>main.ldapRealm.userDnTemplate</name>
<value>uid={0},ou=people,dc=hadoop,dc=apache,dc=org</value>
</param>
<param>
<name>urls./**</name>
<value>authcBasic</value>
</param>
</provider>
<provider>
<role>identity-assertion</role>
<name>Default</name>
<enabled>true</enabled>
</provider>
<provider>
<role>hostmap</role>
<name>static</name>
<enabled>true</enabled>
<param>
<name>localhost</name>
<value>sandbox,sandbox.hortonworks.com,fsmanager</value>
</param>
</provider>
<provider>
<role>federation</role>
<name>SSOCookieProvider</name>
<enabled>true</enabled>
<param>
<name>sso.authentication.provider.url</name>
<value>https://fsmanager:8443/gateway/knoxsso/api/v1/websso</value>
</param>
</provider>
</gateway>
<service>
<role>HAHAUIIII</role>
<url>http://fsmanager:5000</url>
</service>
</topology>
創建Server
mkdir -p /data/services/hahauiiii/2.4.0
touch {service, rewrite}.xml
service.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service role="HAHAUIIII" name="hahauiiii" version="2.4.0">
<routes>
<!-- https://fsmanager:8443/gateway/haha/hahauiiii -->
<route path="/hahauiiii/?**">
<rewrite apply="HAHAUIIII/hahauiiii/inbound" to="request.url"/>
</route>
<!-- https://fsmanager:8443/gateway/haha/hahauiiii/v1/?op=LISTSTATUS -->
<route path="/hahauiiii/v1/?**">
<rewrite apply="HAHAUIIII/hahauiiii/inbound/version" to="request.url"/>
</route>
</routes>
<service>
rewrite.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rules>
<rule dir="IN" name="HAHAUIIII/hahauiiii/inbound" pattern="*://*:*/**/hahauiiii">
<rewrite template="{$serviceUrl[HAHAUIIII]}"/>
</rule>
<rule dir="IN" name="HAHAUIIII/hahauiiii/inbound/version" pattern="*://*:*/**/hahauiiii/{version}/?{**}">
<rewrite template="{$serviceUrl[HAHAUIIII]}/{version}/?{**}"/>
</rule>
</rules>
重新部署cluster
bin/knoxcli.sh redeploy --cluster haha
重新啓動KNOX
bin/gataway.sh stop
bin/gateway.sh start
Server文件內容簡介
Server 目錄結構
data
└── services
└── hahauiiii
└── 2.4.0
├── rewrite.xml
└── service.xml
service.xml
<service role="HAHAUIIII" name="hahauiiii" version="2.4.0">
<routes>
<route path="/hahauiiii/?**"></route>
</routes>
</service>
<service role="HAHAUIIII">
- 這裏的role需要匹配 topology 文件中的
<topology><service><role>
屬性
<service name="hahauiiii">
- 這裏的name需要匹配
<GATEWAY_HOME>/data/services
中相應的目錄名稱,這裏是指hahauiiii
這個目錄名稱
<service version="2.4.0">
- 假如存在多個版本的server實現,version必須對應於相應的版本,及
<GATEWAY_HOME>/data/services
, 這裏是指2.4.0
這個目錄名稱
<route path="/hahauiiii/?**"></route>
- path指明瞭URL的基本形式,這裏的形式爲 https://fsmanager:8443/gateway/haha/hahauiiii
rewrite.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rules>
<rule dir="IN" name="HAHAUIIII/hahauiiii/inbound" pattern="*://*:*/**/hahauiiii">
<rewrite template="{$serviceUrl[HAHAUIIII]}"/>
</rule>
<rule dir="IN">
<rule name="HAHAUIIII/hahauiiii/inbound">
- 表明該條規則是應用於來自客戶端的requests還是應用於gateway於對客戶端response
<rule pattern="*://*:*/**/hahauiiii">
- 匹配指定的URL,類似於正則表達式
<rewrite template="{$serviceUrl[HAHAUIIII]}"/>
{$serviceUrl[HAHAUIIII]}
會去尋找topologies中的指定ROLE中定義的URL, 這裏指的是haha.xml
中ROLE爲HAHAUIIII
中定義的URL<url>http://fsmanager:5000</url>
常見錯誤
500: rewrite.xml
內容可能有問題,特別是partern
可能有誤
404:service.xml
內容有問題,特別是path
可能有誤
Refenerce
Understanding Rewrite Rules for Apache Knox
Adding a service to Apache Knox
Knox SSO Integration for UIs
Appendix
創建臨時可用的web服務代碼,基於flask
from flask import Flask, request
app = Flask(__name__)
@app.route("/")
def hello():
return "<h1>Hello World!</h1>"
@app.route("/v1/")
def version():
return "<h1>Hello Stranger -> {0}</h1>".format(request.args.get("op"))
if __name__ == "__main__":
app.run(host="0.0.0.0")