<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>API Gateway on 勇气</title><link>https://courages.us/tag/api-gateway/</link><description>Recent content in API Gateway on 勇气</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Wed, 04 Nov 2020 10:59:32 +0800</lastBuildDate><atom:link href="https://courages.us/tag/api-gateway/index.xml" rel="self" type="application/rss+xml"/><item><title>API 网关 Kong</title><link>https://courages.us/api-%E7%BD%91%E5%85%B3-kong/</link><pubDate>Wed, 28 Oct 2020 10:35:51 +0800</pubDate><guid>https://courages.us/api-%E7%BD%91%E5%85%B3-kong/</guid><description>&lt;p&gt;从前开发一个互联网服务程序，大概可以在一台机器上完成：数据库、应用都在一起。随着业务发展壮大，会把数据库独立出来，以便扩展拆分。然后再把一部分公用业务独立出来扩展，譬如文件存储、缓存等。接着业务也才拆分，比如会员、商品。微服务大行其道，各个团队维护着许多服务、API。这么多服务，前端业务逻辑该怎么接入呢？&lt;br&gt;&#10;如今单一的前端UI也可能是多个团队共同开发的结果。当你在本地开发一个小功能时，甚至会牵扯到多个前端UI/后端API。一个前端页面除了加载自己的资源外，还加载V2/V3的API（为什么会同时存在V1/V2/V3的API），甚至嵌入了另外一个页面（React看起来也不错），该怎么调试这种混合开发呢？cookie都传递不过去，好吧，使用&lt;a class="link" href="http://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html" target="_blank" rel="noopener"&#10; &gt;JWT&lt;/a&gt;代替，再设置一下&lt;a class="link" href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS" target="_blank" rel="noopener"&#10; &gt;跨源资源共享（CORS）&lt;/a&gt;。。。但是那些旧的应用怎么办？&lt;br&gt;&#10;当我们启动一个Node.js应用时npm run start，默认监听3000端口。当然我们也可以让它监听80端口。但是当我们多开几个应用时，只好让它们都监听不同端口了，怎么样才能统一端口监听呢？当然Node.js可以通过诸如&lt;a class="link" href="https://github.com/http-party/node-http-proxy" target="_blank" rel="noopener"&#10; &gt;node-http-proxy&lt;/a&gt;来转发这些请求，但是代理转发跟应用业务无关吧？如果是其他编程语言呢？都重复这些代理配置/开发吗？Don’t Repeat Yourself。&lt;br&gt;&#10;&lt;a class="link" href="https://www.redhat.com/zh/topics/cloud-native-apps/what-is-faas" target="_blank" rel="noopener"&#10; &gt;Faas&lt;/a&gt;也日渐流行，比如&lt;a class="link" href="https://aws.amazon.com/lambda/" target="_blank" rel="noopener"&#10; &gt;AWS Lambda&lt;/a&gt;， 强调仅仅专注某个功能，根据事件驱动进行计算，那么每个服务也要开发一整套路由分发/认证/日志吗？&lt;br&gt;&#10;这些问题可以使用反向代理来解决，提供统一的服务入口，对前端/客户端隐藏背后的细节，最简单的当然是Nginx。Nginx监听来自某个端口（比如80）的请求，然后根据不同的来源/端口/域名/url分发给不同的后端服务器。这看起来跟云服务厂商各自开发的负载均衡器差不多，比如&lt;a class="link" href="https://aws.amazon.com/cn/elasticloadbalancing/" target="_blank" rel="noopener"&#10; &gt;AWS ELB&lt;/a&gt;。&lt;br&gt;&#10;在本地开发的时候，我们当然不会使用ELB来解决。直接使用Nginx当然也没啥问题，编辑一下配置文件，重启应用。但是如果有个UI就更好了，如果还有API就非常好了-这样就能方便的在线注册/更改路由而不需要重启服务器，在这个快速发展、弹性开发的年代更需要这个能力。&lt;br&gt;&#10;&lt;a class="link" href="https://konghq.com/kong/" target="_blank" rel="noopener"&#10; &gt;Kong&lt;/a&gt;是一个基于OpenResty的网关服务器，可以进行路由（转发/负载），插件（日志/认证/监控）管理，并提供RESTful API。而&lt;a class="link" href="https://openresty.org/" target="_blank" rel="noopener"&#10; &gt;OpenResty&lt;/a&gt; 是一个基于Nginx与Lua的高性能Web平台，使用Lua来构建动态网关。听起来像是在Nginx上面编程，这跟在Apache上面使用PHP模块进行编程有什么区别？最大的区别在于，这里的编程对象是Nginx（或者公共模块），扩展Nginx能力，比如负载均衡/日志/认证/监控，而不是输出web页面/业务逻辑。这些东西抽出来以后，就不需要每个模块再重复开发了，比如认证/安全。&lt;br&gt;&#10;在本地可以使用docker来运行Kong服务，麻烦在于数据库迁移工作。通常部署Kong需要几个步骤，比如初始化数据库，迁移升级等等。网上的配置大都过时了，这里可以使用官方提供&lt;a class="link" href="https://github.com/Kong/docker-kong/blob/master/compose/docker-compose.yml" target="_blank" rel="noopener"&#10; &gt;docker-compose.yml&lt;/a&gt;来做数据库工作，并且使用&lt;a class="link" href="https://github.com/pantsel/konga" target="_blank" rel="noopener"&#10; &gt;Konga&lt;/a&gt;作为管理UI&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ kong ls&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;POSTGRES_PASSWORD data docker-compose.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ kong ls data&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;postgresql&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ kong cat POSTGRES_PASSWORD&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kong&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ kong cat docker-compose.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;version: &lt;span style="color:#e6db74"&gt;&amp;#39;3.7&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kong_data: &lt;span style="color:#f92672"&gt;{}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;networks:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kong-net:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; external: false&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;services:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kong-migrations:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_DOCKER_TAG&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong:latest&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; command: kong migrations bootstrap&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; depends_on:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_DATABASE: postgres&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_DATABASE: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_DATABASE&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_HOST: db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_USER: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_USER&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_PASSWORD_FILE: /run/secrets/kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; secrets:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; networks:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong-net&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; deploy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart_policy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; condition: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kong-migrations-up:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_DOCKER_TAG&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong:latest&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; command: kong migrations up &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; kong migrations finish&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; depends_on:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_DATABASE: postgres&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_DATABASE: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_DATABASE&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_HOST: db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_USER: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_USER&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_PASSWORD_FILE: /run/secrets/kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; secrets:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; networks:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong-net&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; deploy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart_policy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; condition: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kong:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_DOCKER_TAG&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong:latest&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user: &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_USER&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; depends_on:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_ADMIN_ACCESS_LOG: /dev/stdout&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_ADMIN_ERROR_LOG: /dev/stderr&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_ADMIN_LISTEN: &lt;span style="color:#e6db74"&gt;&amp;#39;0.0.0.0:8001&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_CASSANDRA_CONTACT_POINTS: db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_DATABASE: postgres&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_DATABASE: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_DATABASE&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_HOST: db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_USER: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_USER&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PROXY_ACCESS_LOG: /dev/stdout&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PROXY_ERROR_LOG: /dev/stderr&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; KONG_PG_PASSWORD_FILE: /run/secrets/kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; secrets:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; networks:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong-net&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ports:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;8000:8000/tcp&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;127.0.0.1:8001:8001/tcp&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;8443:8443/tcp&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#34;127.0.0.1:8444:8444/tcp&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; healthcheck:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test: &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;CMD&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;kong&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;health&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval: 10s&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timeout: 10s&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; retries: &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; deploy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart_policy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; condition: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; db:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: postgres:9.5&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; POSTGRES_DB: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_DATABASE&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; POSTGRES_USER: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_USER&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; POSTGRES_PASSWORD_FILE: /run/secrets/kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; secrets:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong_postgres_password&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; healthcheck:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; test: &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;CMD&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;pg_isready&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;-U&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_USER&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; interval: 30s&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; timeout: 30s&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; retries: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; deploy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart_policy:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; condition: on-failure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; stdin_open: true&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tty: true&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; networks:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong-net&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - /Users/xxxx/docker/kong/data/postgresql:/var/lib/postgresql/data&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; konga:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: pantsel/konga&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; TOKEN_SECRET: channing.token&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DB_ADAPTER: postgres&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DB_HOST: db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DB_USER: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_USER&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DB_PASSWORD: kong&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DB_DATABASE: &lt;span style="color:#e6db74"&gt;${&lt;/span&gt;KONG_PG_DATABASE&lt;span style="color:#66d9ef"&gt;:-&lt;/span&gt;kong&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ports:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - 1337:1337&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; networks:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - kong-net&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; depends_on:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;secrets:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kong_postgres_password:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; file: ./POSTGRES_PASSWORD&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;运行docker-composer up就可以看到&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ kong docker ps&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;20ebe7885c0d kong:latest &lt;span style="color:#e6db74"&gt;&amp;#34;/docker-entrypoint.…&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; hours ago Up &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt; seconds &lt;span style="color:#f92672"&gt;(&lt;/span&gt;healthy&lt;span style="color:#f92672"&gt;)&lt;/span&gt; 0.0.0.0:8000-&amp;gt;8000/tcp, 127.0.0.1:8001-&amp;gt;8001/tcp, 0.0.0.0:8443-&amp;gt;8443/tcp, 127.0.0.1:8444-&amp;gt;8444/tcp kong_kong_1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;4a7a39c863ae pantsel/konga &lt;span style="color:#e6db74"&gt;&amp;#34;/app/start.sh&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; hours ago Up &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt; seconds 0.0.0.0:1337-&amp;gt;1337/tcp kong_konga_1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aa732758fc51 postgres:9.5 &lt;span style="color:#e6db74"&gt;&amp;#34;docker-entrypoint.s…&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; hours ago Up &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt; seconds &lt;span style="color:#f92672"&gt;(&lt;/span&gt;health: starting&lt;span style="color:#f92672"&gt;)&lt;/span&gt; 5432/tcp kong_db_1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;访问http://127.0.0.1:1337/即可以进入Konga 管理界面了。8000/8443端口是需要监听转发的端口，8001/8444则是Kong RESTFUl管理API的端口。这里也可以把8000/8443改为80/443，这样访问的时候就可以直接使用域名/localhost而不必加端口了。&lt;br&gt;&#10;注册登录进去后首先要添加Kong RESTFUl管理API的地址，这里使用的是docker环境，IP是动态分配的，所以使用链接名就可以了&lt;br&gt;&#10;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.20.50-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="562px" data-flex-grow="234" height="128" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.20.50-PM-300x128.png" width="300"&gt;&lt;/a&gt;&lt;br&gt;&#10;连接上Kong API后可以看到dashboard列出了支持的插件&lt;br&gt;&#10;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-09-29-at-3.57.34-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="545px" data-flex-grow="227" height="132" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-09-29-at-3.57.34-PM-300x132.png" width="300"&gt;&lt;/a&gt;&lt;br&gt;&#10;Kong里面的管理对象是service，路由转发/插件都是围绕service展开的，添加一个service&lt;br&gt;&#10;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.27.19-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="433px" data-flex-grow="180" height="166" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.27.19-PM-300x166.png" width="300"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.27.28-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="354px" data-flex-grow="147" height="203" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.27.28-PM-300x203.png" width="300"&gt;&lt;/a&gt;&lt;br&gt;&#10;在它上面添加一个路由，这里我们在服务只监听以/api开头的url，并转发到后端服务器去&lt;br&gt;&#10;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.30.37-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="431px" data-flex-grow="179" height="167" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.30.37-PM-300x167.png" width="300"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.30.48-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="260px" data-flex-grow="108" height="276" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.30.48-PM-300x276.png" width="300"&gt;&lt;/a&gt;&lt;br&gt;&#10;注意这里在route里面的path里面也需要添加/api，否则转发的时候会出错（多拼api）。最简单就是service监听不指定path，在route里指定。一个service下面可以有多个转发路由，每个可以独立管理、设置超时等。&lt;br&gt;&#10;还可以为每个service绑定不同的插件进行处理，比如认证/安全/日志等等，这样就不用在不同的系统里面重复开发这些功能，使得各个团队更加专注也本业务开发&lt;br&gt;&#10;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.44.18-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="404px" data-flex-grow="168" height="178" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.44.18-PM-300x178.png" width="300"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.45.03-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="365px" data-flex-grow="152" height="197" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.45.03-PM-300x197.png" width="300"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.45.13-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="336px" data-flex-grow="140" height="214" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-4.45.13-PM-300x214.png" width="300"&gt;&lt;/a&gt;&lt;br&gt;&#10;有效插件还可以进行流量限制、请求头/响应头修改等等。这些插件的功能需要基于consumer来开发管理，功能可以非常强大，详细可以参考&lt;a class="link" href="https://github.com/qianyugang/kong-docs-cn/blob/master/HUB/basic-auth.md" target="_blank" rel="noopener"&#10; &gt;文档&lt;/a&gt;。&lt;br&gt;&#10;Kong还有一项功能Upstream配置，与Nginx的&lt;a class="link" href="http://nginx.org/en/docs/http/ngx_http_upstream_module.html" target="_blank" rel="noopener"&#10; &gt;ngx_http_upstream_module&lt;/a&gt;差不多，可以作为负载均衡、流量分发控制使用。可以用命令行测试基于hostname的路由，&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ kong curl -i -X GET &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --url http://localhost:8000/ &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --header &lt;span style="color:#e6db74"&gt;&amp;#39;Host: dev1.example.com&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HTTP/1.1 &lt;span style="color:#ae81ff"&gt;404&lt;/span&gt; Not Found&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Date: Tue, &lt;span style="color:#ae81ff"&gt;27&lt;/span&gt; Oct &lt;span style="color:#ae81ff"&gt;2020&lt;/span&gt; 08:41:58 GMT&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Content-Type: application/json; charset&lt;span style="color:#f92672"&gt;=&lt;/span&gt;utf-8&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Connection: keep-alive&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Content-Length: &lt;span style="color:#ae81ff"&gt;48&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;X-Kong-Response-Latency: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Server: kong/2.1.4&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;{&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;no Route matched with those values&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt; ➜ kong curl -i -X GET &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --url http://localhost:8000/ &lt;span style="color:#ae81ff"&gt;\&#10;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; --header &lt;span style="color:#e6db74"&gt;&amp;#39;Host: dev.example.com&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;HTTP/1.1 &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt; OK&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Content-Type: text/html; charset&lt;span style="color:#f92672"&gt;=&lt;/span&gt;UTF-8&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Transfer-Encoding: chunked&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Connection: keep-alive&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Date: Tue, &lt;span style="color:#ae81ff"&gt;27&lt;/span&gt; Oct &lt;span style="color:#ae81ff"&gt;2020&lt;/span&gt; 08:42:21 GMT&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Server: Apache/2.2.15 &lt;span style="color:#f92672"&gt;(&lt;/span&gt;CentOS&lt;span style="color:#f92672"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;X-Powered-By: PHP/5.6.40&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Set-Cookie: PHPSESSID&lt;span style="color:#f92672"&gt;=&lt;/span&gt;0uc3aoc735j21sk3ni5s72vjc1; path&lt;span style="color:#f92672"&gt;=&lt;/span&gt;/&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Expires: Thu, &lt;span style="color:#ae81ff"&gt;19&lt;/span&gt; Nov &lt;span style="color:#ae81ff"&gt;1981&lt;/span&gt; 08:52:00 GMT&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Cache-Control: no-store, no-cache, must-revalidate, post-check&lt;span style="color:#f92672"&gt;=&lt;/span&gt;0, pre-check&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Pragma: no-cache&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Access-Control-Allow-Credentials: true&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Access-Control-Allow-Headers: X-CSRF-Token,Authorization,X-Accept-Charset,X-Accept,Content-Type&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;X-Kong-Upstream-Latency: &lt;span style="color:#ae81ff"&gt;8397&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;X-Kong-Proxy-Latency: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Via: kong/2.1.4&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;!DOCTYPE html PUBLIC &lt;span style="color:#e6db74"&gt;&amp;#34;-//W3C//DTD XHTML 1.0 Strict//EN&amp;#34;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&amp;#34;&lt;/span&gt;&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;...&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;作为一个API网关，Kong能做的很多。如果只是在本地简单的做反向代理，可以使用&lt;a class="link" href="https://github.com/jc21/nginx-proxy-manager" target="_blank" rel="noopener"&#10; &gt;nginx-proxy-manager&lt;/a&gt;，这也是一个基于Nginx开发的网关，根据WEB UI动态生成Nginx配置文件，然后执行/usr/sbin/nginx -s reload生效。有些参数不能通过UI配置（比如超时设置），可以直接写Nginx配置，upstream则支持直接转发tcp请求，支持websockets代理转发，甚至集成了&lt;a class="link" href="https://courages.us/lets-encrypt/" target="_blank" rel="noopener"&#10; &gt;Let’s encrypt&lt;/a&gt;自动申请SSL证书（需要验证域名）&lt;br&gt;&#10;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.03.05-PM.jpg" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="576px" data-flex-grow="240" height="125" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.03.05-PM-300x125.jpg" width="300"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.10.57-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="217px" data-flex-grow="90" height="300" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.10.57-PM-272x300.png" width="272"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.11.47-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="123px" data-flex-grow="51" height="300" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.11.47-PM-154x300.png" width="154"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.11.54-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="219px" data-flex-grow="91" height="300" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.11.54-PM-274x300.png" width="274"&gt;&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;a class="link" href="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.13.20-PM.png" target="_blank" rel="noopener"&#10; &gt;&lt;img class="gallery-image" data-flex-basis="666px" data-flex-grow="277" height="108" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://courages.us/wp-content/uploads/2020/10/Screen-Shot-2020-10-27-at-5.13.20-PM-300x108.png" width="300"&gt;&lt;/a&gt;&lt;br&gt;&#10;本地同样可以使用docker跑起来，默认监听80/443端口，81端口即管理界面&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ nginx-proxy-manager ls -lah&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;total &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;drwxr-xr-x &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt; xxxx domain users 192B Sep &lt;span style="color:#ae81ff"&gt;29&lt;/span&gt; 10:24 .&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;drwxr-xr-x &lt;span style="color:#ae81ff"&gt;15&lt;/span&gt; xxxx domain users 480B Sep &lt;span style="color:#ae81ff"&gt;29&lt;/span&gt; 09:15 ..&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-rw-r--r-- &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; xxxx domain users 2.3K Sep &lt;span style="color:#ae81ff"&gt;29&lt;/span&gt; 09:42 config.json&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;drwxr-xr-x &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt; xxxx domain users 256B Sep &lt;span style="color:#ae81ff"&gt;29&lt;/span&gt; 09:31 data&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;-rw-r--r-- &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; xxxx domain users 740B Sep &lt;span style="color:#ae81ff"&gt;29&lt;/span&gt; 10:24 docker-compose.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;drwxr-xr-x &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; xxxx domain users 96B Oct &lt;span style="color:#ae81ff"&gt;27&lt;/span&gt; 16:38 letsencrypt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ nginx-proxy-manager cat docker-compose.yml&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;version: &lt;span style="color:#e6db74"&gt;&amp;#34;3&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;services:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; app:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: &lt;span style="color:#e6db74"&gt;&amp;#39;jc21/nginx-proxy-manager:latest&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart: always&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ports:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Public HTTP Port:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#39;80:80&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Public HTTPS Port:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#39;443:443&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Admin Web Port:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#39;81:81&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# TCP Forward Example:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#e6db74"&gt;&amp;#39;8022:8022&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Make sure this config.json file exists as per instructions above:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ./config.json:/app/config/production.json&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ./data:/data&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ./letsencrypt:/etc/letsencrypt&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; depends_on:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - db&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; db:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: jc21/mariadb-aria&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; restart: always&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; environment:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MYSQL_ROOT_PASSWORD: &lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MYSQL_DATABASE: &lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MYSQL_USER: &lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MYSQL_PASSWORD: &lt;span style="color:#e6db74"&gt;&amp;#39;npm&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ./data/mysql:/var/lib/mysql&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ nginx-proxy-manager docker ps&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;3dd58e9cff1f jc21/nginx-proxy-manager:latest &lt;span style="color:#e6db74"&gt;&amp;#34;/init&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; weeks ago Up &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt; days &lt;span style="color:#f92672"&gt;(&lt;/span&gt;healthy&lt;span style="color:#f92672"&gt;)&lt;/span&gt; 0.0.0.0:80-81-&amp;gt;80-81/tcp, 0.0.0.0:443-&amp;gt;443/tcp, 0.0.0.0:8022-&amp;gt;8022/tcp nginx-proxy-manager_app_1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;a033151b28ed jc21/mariadb-aria &lt;span style="color:#e6db74"&gt;&amp;#34;/scripts/run.sh&amp;#34;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; weeks ago Up &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt; days 3306/tcp nginx-proxy-manager_db_1&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;nginx-proxy-manager会将配置写在data目录下面，可以直接编辑这些文件，Nginx reload之后便会生效，可以看到这些文件，具体的加载规则参考&lt;a class="link" href="https://nginxproxymanager.com/advanced-config/#custom-nginx-configurations" target="_blank" rel="noopener"&#10; &gt;文档&lt;/a&gt;&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ nginx-proxy-manager ls data/nginx&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dead_host default_host default_www dummycert.pem dummykey.pem proxy_host redirection_host stream temp&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ nginx-proxy-manager cat data/nginx/proxy_host/1.conf&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ------------------------------------------------------------&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# dev.example.com&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ------------------------------------------------------------&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set $forward_scheme http;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set $server &lt;span style="color:#e6db74"&gt;&amp;#34;192.168.33.14&amp;#34;&lt;/span&gt;;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; set $port 80;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; listen 80;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;listen &lt;span style="color:#f92672"&gt;[&lt;/span&gt;::&lt;span style="color:#f92672"&gt;]&lt;/span&gt;:80;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; server_name dev.example.com;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; access_log /data/logs/proxy_host-1.log proxy;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;proxy_connect_timeout 600;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;proxy_send_timeout 600;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;proxy_read_timeout 600;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;send_timeout 600;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location /Login &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header Host $host;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Scheme $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Proto $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-For $remote_addr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass https://login.example.com:443;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location /api/v2 &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header Host $host;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Scheme $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Proto $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-For $remote_addr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass http://192.168.33.14:9070;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location /api/v3 &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header Host $host;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Scheme $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Proto $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-For $remote_addr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass https://dev.ops.example.com:443;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location /Chat &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header Host $host;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Scheme $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Proto $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-For $remote_addr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass https://dev.ops.example.com:443;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location /Catalog &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header Host $host;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Scheme $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Proto $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-For $remote_addr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass http://192.168.33.1:3000;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location /static &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header Host $host;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Scheme $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Proto $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-For $remote_addr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass http://192.168.33.1:3000;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location /css &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header Host $host;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Scheme $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-Proto $scheme;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_set_header X-Forwarded-For $remote_addr;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass http://192.168.33.1:3000;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; location / &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Proxy!&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; include conf.d/include/proxy.conf;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Custom&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; include /data/nginx/custom/server_proxy&lt;span style="color:#f92672"&gt;[&lt;/span&gt;.&lt;span style="color:#f92672"&gt;]&lt;/span&gt;conf;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜ nginx-proxy-manager cat data/nginx/stream/1.conf&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ------------------------------------------------------------&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# 8022 TCP: 1 UDP: 0&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ------------------------------------------------------------&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;server &lt;span style="color:#f92672"&gt;{&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; listen 8022;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;listen &lt;span style="color:#f92672"&gt;[&lt;/span&gt;::&lt;span style="color:#f92672"&gt;]&lt;/span&gt;:8022;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; proxy_pass 192.168.33.14:22;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Custom&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; include /data/nginx/custom/server_stream&lt;span style="color:#f92672"&gt;[&lt;/span&gt;.&lt;span style="color:#f92672"&gt;]&lt;/span&gt;conf;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; include /data/nginx/custom/server_stream_tcp&lt;span style="color:#f92672"&gt;[&lt;/span&gt;.&lt;span style="color:#f92672"&gt;]&lt;/span&gt;conf;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;}&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;在docker-compose.yml里面设置一下upstream监听转发的端口，就可以通过8022端口访问192.168.33.14的22端口了&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;➜  nginx-proxy-manager telnet 127.0.0.1 &lt;span style="color:#ae81ff"&gt;8022&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Trying 127.0.0.1...&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Connected to localhost.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Escape character is &lt;span style="color:#e6db74"&gt;&amp;#39;^]&amp;#39;&lt;/span&gt;.&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;SSH-2.0-OpenSSH_5.3&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;^C^C^C^C^C^C^CConnection closed by foreign host.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;不论是Kong还是nginx-proxy-manager均有提供API，极大的增强服务网关的可编程性，为动态上线/弹性扩展/自动化运维提供了便利。&lt;/p&gt;&#10;&lt;p&gt;参考链接：&lt;br&gt;&#10;&lt;a class="link" href="https://aws.amazon.com/cn/blogs/china/iaas-faas-serverless/" target="_blank" rel="noopener"&#10; &gt;从IaaS到FaaS—— Serverless架构的前世今生&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://developer.51cto.com/art/202004/615649.htm" target="_blank" rel="noopener"&#10; &gt;聊一聊微服务网关 Kong&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://cloud.tencent.com/developer/article/1435756" target="_blank" rel="noopener"&#10; &gt;KONG网关 — KongA管理UI使用&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://juejin.im/post/6844903924911063053" target="_blank" rel="noopener"&#10; &gt;云原生架构下的 API 网关实践： Kong （二）&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://xie.infoq.cn/article/ba0f7503c73b86126017c0d32" target="_blank" rel="noopener"&#10; &gt;微服务 API 网关 -Kong 详解&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://dev.to/bambattajb/creating-an-api-with-lua-using-openresty-42mc" target="_blank" rel="noopener"&#10; &gt;Creating a web API with Lua using Nginx OpenResty&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://cloud.tencent.com/developer/article/1027563" target="_blank" rel="noopener"&#10; &gt;Nginx基于TCP/UDP端口的四层负载均衡（stream模块）配置梳理&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://www.jianshu.com/p/45cb044ba99d" target="_blank" rel="noopener"&#10; &gt;Nginx支持TCP代理和负载均衡-stream模块&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://www.scienjus.com/api-gateway-and-netflix-zuul/" target="_blank" rel="noopener"&#10; &gt;聊聊 API Gateway 和 Netflix Zuul&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://www.servicemesher.com/envoy/intro/what_is_envoy.html" target="_blank" rel="noopener"&#10; &gt;Envoy 是什么？&lt;/a&gt;&lt;/p&gt;&#10;</description></item></channel></rss>