天天看點

KONG基礎使用 注冊API

kong是一個基于nginx的api gateway。提供了諸如身份認證,權限控制,流量控制,日志等一系列api相關的元件,可謂相當友善。

<a href="https://getkong.org/">kong項目首頁</a>

<a href="https://getkong.org/docs/0.8.x/getting-started/quickstart/">kong入門</a>

<a href="https://github.com/mashape/kong/">kong的github位址</a>

<a href="https://getkong.org/docs/0.8.x/admin-api/">kong admin api一覽</a>

<a href="https://getkong.org/plugins/">kong插件清單</a>

以linux redhat 6.2為例:

從此處下載下傳對應二進制rpm包,按操作安裝即可

<a href="https://getkong.org/install/redhat/">kong redhat release</a>

注意如果yum出現無法擷取metalink的錯誤,

<code>sudo vi /etc/yum.repos.d/epel.repo</code>

注釋掉所有mirrorlist,取消所有baseurl的注釋即可。

kong是一個api gateway,顧名思義,就是api的出口。

内部系統的api可以随意編寫,但如果要對外服務,就一定需要各種權限控制。

首先,我們寫一個mock api,進行測試之用。

<code>import tornado.ioloop</code>

<code>import tornado.web</code>

<code></code>

<code>class mainhandler(tornado.web.requesthandler):</code>

<code>call_cnt = 0</code>

<code>def get(self):</code>

<code>mainhandler.call_cnt+= 1</code>

<code>self.write("get / %s"%mainhandler.call_cnt)</code>

<code>def post(self):</code>

<code>self.write("post / %s"%mainhandler.call_cnt)</code>

<code>class testhandler(tornado.web.requesthandler):</code>

<code>testhandler.call_cnt += 1</code>

<code>self.write("get /test %s"%testhandler.call_cnt)</code>

<code>self.write("post /test %s"%testhandler.call_cnt)</code>

<code>def make_app():</code>

<code>return tornado.web.application([</code>

<code>(r"/", mainhandler),</code>

<code>(r"/test", testhandler)</code>

<code>])</code>

<code>if __name__ == "__main__":</code>

<code>app = make_app()</code>

<code>app.listen(8812)</code>

<code>tornado.ioloop.ioloop.current().start()</code>

這是一個用tornado寫的簡易rest測試 api,用以下指令背景啟動

<code>nohup python test_api.py 1&gt;/dev/null 2&gt;log &amp;;</code>

<code># 測試endpoint:/</code>

<code>curl -i -x get http://localhost:8812/</code>

<code>curl -i -x post http://localhost:8812/</code>

<code>curl -i -x delete http://localhost:8812/</code>

<code># 測試endpoint:/test</code>

<code>curl -i -x get http://localhost:8812/test</code>

<code>curl -i -x post http://localhost:8812/test</code>

<code>curl -i -x delete http://localhost:8812/test</code>

現在我們已經有一個正常工作的rest api了。是時候使用kong了。

kong的使用基本和nginx如出一轍。預設的工作目錄是<code>/usr/local/kong</code>,預設的配置檔案是<code>/etc/kong/kong.yml</code>。如果需要工作在1024以下的端口,則要求root權限。

kong的啟動指令很簡單,就是<code>kong start</code>

但是啟動之前需要編輯配置檔案。

需要關注的主要是幾個點:

發送匿名統計報告,(預設打開,一定要關閉)

後端資料庫的配置,(預設cassandra,建議postgres)

記憶體緩存大小配置,(預設128m,建議1g)

出口端口(預設http 8000,https 8443,建議直接改成80和443)

管理端口(預設8001,我改成8888比較吉利)

配置好之後,啟動kong即可。

使用什麼語言的http庫都可以完成這個工作,這裡直接使用linux自帶的curl。

第一步,我們需要先注冊我們的api

假設我們想把上面那個api挂載到/test路徑下,

執行

<code># 檢視目前已經注冊的api</code>

<code>curl -x get http://localhost:8888/apis/</code>

<code># 注冊一個新的api</code>

<code>curl -i -x post http://localhost:8888/apis/ -d "name=testapi" -d "request_path=/test" -d "upstream_url=http://localhost:8812/" -d "strip_request_path=true"</code>

這裡注冊url的幾個參數意思是,這個api注冊的名字叫testapi。它被挂載在網關的<code>/test</code>路徑下,上遊轉發到<code>http://localhost:8812</code>去處理,轉發的時候把前面的<code>/test</code>字首給去掉。

<code>{"upstream_url":"http:\/\/localhost:8812\/","request_path":"\/test","id":"a302c28c-eb8a-4e53-bac2-9acb68695f3b","created_at":1468379310000,"preserve_host":false,"strip_request_path":true,"name":"testapi"}</code>

傳回結果表明api建立的結果。一般會傳回一個api的id。

這就表明api注冊完成,我們可以測試一下:

<code>curl -i -x get http://localhost/test</code>

<code>curl -i -x post https://localhost/test/test --insecure</code>

如同我們預期的一樣傳回正确的結果,說明api已經成功注冊。

當然,僅僅把api注冊了開放出去,其實也就是把多個api內建到一個endpoint,實際意義并不大,下面我們來試一試進階一點的功能。

kong自帶插件目前可以分為以下幾類:

身份認證,安全,流量控制,分析監控,格式轉換,日志。

有的api完全開放,不需要任何認證,有的api會涉及敏感資料,權限控制需要非常嚴格。有的api完全不在乎調用頻次或者日志,有的則反過來。

值得高興的是,kong的插件獨立作用于每一個api,不同的api可以使用完全不同的插件。提供了相當靈活的配置政策。

現在我們首先給這個測試api加上基本的權限驗證。

<code>curl -x post http://localhost:8888/apis/testapi/plugins -d "name=key-auth"</code>

<code># 這個時候再去調用這個api就會傳回401 unauthorized</code>

樸素的api可能壓根沒有嚴格的使用者概念,端口大開,随便哪個阿貓阿狗都能進來掃一掃看一看。這可不行。

kong有一個consumer的概念,consumer是全局共用的。

比如某個api啟用了key-auth,那麼沒有身份的通路者就無法調用這個api了。

需要首先建立一個consumer,然後在key-auth插件中為這個consumer生成一個key。

然後就可以使用這個key來透過權限驗證通路api了。

同理,如果另外一個api也開通了key-auth插件,那麼這個consumer也是可以通過key-auth驗證通路這個api的,如果要控制這種情況,就需要acl插件。

(認證與權限乃是兩個不同的事物)

首先我們建立一個名為test_user的consumer

<code># 擷取所有consumer清單</code>

<code>curl -x get http://localhost:8888/consumers/</code>

<code># 建立一個新的consumer</code>

<code>curl -x post http://localhost:8888/consumers/ -d "username=testuser"</code>

然後,我們在key-auth插件中為它建立一個key

<code>curl -x post http://localhost:8888/consumers/testuser/key-auth -d "key=testkey"</code>

這次加上apikey首部進行驗證,成功調用

<code>curl -i -x get http://localhost/test --header "apikey: testkey"</code>

删除使用者

<code>curl -i -x delete http://localhost:8888/consumers/testuser</code>

删除插件

<code># 查詢api擁有的插件id</code>

<code>curl -i -x get http://localhost:8888/apis/testapi/plugins/</code>

<code># 根據插件id删除插件。</code>

<code>curl -i -x delete http://localhost:8888/apis/testapi/plugins/e49a2b2e-4c36-4c6a-bd1a-b5b065e63bb8</code>

以上是基本的api,consumer,plugin的基本介紹。

<code># 注冊overseas_index api</code>

<code>curl -x post http://localhost:8888/apis/ -d "name=overseas_index" -d "upstream_url=http://10.182.20.128:8848/" -d "request_path=/stat/overseas" -d "strip_request_path=true"</code>

<code># 為海外版api注冊key-auth插件</code>

<code>curl -x post http://localhost:8888/apis/overseas_index/plugins --data "name=key-auth"</code>

<code># 建立overseas_user 使用者</code>

<code>curl -x post http://localhost:8888/consumers/ -d "username=overseas_test"</code>

<code># 為overseas_test建立權限驗證</code>

<code>curl -x post http://localhost:8888/consumers/overseas_test/key-auth -d ""</code>

<code># 嘗試查詢海外版名額接口</code>

<code>curl -x post https://10.182.20.127/stat/overseas/realtime -d "app_id=53ace32656240b11c2071b1a" -d "date=2015-07-22" -h "apikey: 5e3b2a7a735744b39aeea9ebc2de1f01" --insecure</code>

<code># 給測試api</code>

<code>curl -x post https://10.182.20.128/test -d "app_id=53ace32656240b11c2071b1a" -d "date=2015-07-22" -h "apikey: 5e3b2a7a735744b39aeea9ebc2de1f01" --insecure</code>

設定acl插件

<code># 給另外一個testapi加上權限驗證插件,現在任何通過認證的使用者都可以調用此api</code>

<code># 這不是我們所希望的,是以需要加入acl控制</code>

<code>curl -x post http://localhost:8888/apis/testapi/plugins --data "name=key-auth"</code>

<code># 為使用者overseas_test建立acl群組:overseas_user</code>

<code>curl -x post http://localhost:8888/consumers/overseas_test/acls \</code>

<code>--data "group=overseas_user"</code>