API网关Kong学习笔记(二十):Kong 1.0.3的安装部署和与Kubernetes的对接

作者: 李佶澳   转载请保留:原文地址   更新时间:2019-03-15 13:54:34 +0800

说明

前段时间折腾公司老集群的升级方案,kong和envoy的学习研究停顿了一段时间,现在重新捡起来,正式推进。Kong的版本已经发布到1.0.3了,这里按照kong给出的部署方法部署体验一下,同时回忆一下之前的工作。

相关笔记

如果是刚开始学习kong,直接从1.x开始,0.x已经不再维护,0.15是0.x的最后一个版本。

前19篇笔记是刚开始接触kong时记录的,使用的版本是0.14.1,当时对kong一知半解,笔记比较杂乱,从第二十篇开始是再次折腾时的笔记,使用的版本是1.0.3,笔记相对好一些。

从0.x到1.x需要关注的变化有:1. 插件全部使用pdk;2. 0.x中不鼓励使用的特性都被移除了;3. 全部使用kong.db,以前独立的dao彻底清除,代码简洁清晰了。

kong官方文档给出的做法

如果对Helm比较熟悉,可以试一下Kong via Helm,更关心部署细节所以这里用的是Kong via Manifest Files,相关文件位于仓库Kong/kong-dist-kubernetes中,用git获取:

git clone https://github.com/Kong/kong-dist-kubernetes.git
cd kong-dist-kubernetes
git checkout 2.0.0

文档中前两步分别是准备Kubernetes集群、部署数据库,已经有现成的环境不需要再折腾,直接进入第三步: 数据库初始化,使用的数据库是PostgreSQL。 文档中给出的方法是kubectl create -f kong_migration_postgres.yaml,yaml文件内容如下,创建了一个Job:

apiVersion: batch/v1
kind: Job
metadata:
  name: kong-migration
spec:
  template:
    metadata:
      name: kong-migration
    spec:
      containers:
      - name: kong-migration
        image: kong
        env:
          - name: KONG_NGINX_DAEMON
            value: 'off'
          - name: KONG_PG_PASSWORD
            value: kong
          - name: KONG_PG_HOST
            value: postgres.default.svc.cluster.local
        command: [ "/bin/sh", "-c", "kong migrations up" ]
      restartPolicy: Never

Job中的操作很简单,就是执行kong migrations up,完成数据库的初始化,环境变量KONG_PG_PASSWORDKONG_PG_HOST的值要根据自己的环境更改。 这里更让人关心的是image是从哪来的?包含哪些内容?使用的kong的版本是多少?

DockerHub中能够搜索到这里使用的kong的镜像,它是docker官方提供的镜像,不是第三方用户上传的,页面上给出了对应的Dockerfile,例如kong: 1.0.3-centos的dockerfile

FROM centos:7
LABEL maintainer="Kong Core Team <[email protected]>"

ENV KONG_VERSION 1.0.3

ARG SU_EXEC_VERSION=0.2
ARG SU_EXEC_URL="https://github.com/ncopa/su-exec/archive/v${SU_EXEC_VERSION}.tar.gz"

RUN yum install -y -q gcc make unzip \
&& curl -sL "${SU_EXEC_URL}" | tar -C /tmp -zxf - \
&& make -C "/tmp/su-exec-${SU_EXEC_VERSION}" \
&& cp "/tmp/su-exec-${SU_EXEC_VERSION}/su-exec" /usr/bin \
&& rm -fr "/tmp/su-exec-${SU_EXEC_VERSION}" \
&& yum autoremove -y -q gcc make \
&& yum clean all -q \
&& rm -fr /var/cache/yum/* /tmp/yum_save*.yumtx /root/.pki

RUN useradd --uid 1337 kong \
    && yum install -y https://bintray.com/kong/kong-community-edition-rpm/download_file?file_path=centos/7/kong-community-edition-$KONG_VERSION.el7.noarch.rpm \
    && yum clean all

COPY docker-entrypoint.sh /docker-entrypoint.sh

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 8000 8443 8001 8444

STOPSIGNAL SIGTERM

CMD ["kong", "docker-start"]

从中能够看到CentOS中的kong以rpm的形式发布的,用yum安装:

yum install -y https://bintray.com/kong/kong-community-edition-rpm/download_file?file_path=centos/7/kong-community-edition-$KONG_VERSION.el7.noarch.rpm 

这个有些麻烦,因为如果对kong进行了修改,要先打成rpm文件,然后才能重新制作镜像,需要一个直接使用kong源代码生成镜像的Dockerfile,可以参考API网关Kong学习笔记(一):Nginx、OpenResty和Kong入门,基础概念和安装部署中的做法:

  1. 安装OpenResty
  2. 安装Luarocks
  3. 安装Kong

继续看文档,文档中第五步部署kong的命令是kubectl create -f kong_postgres.yaml,看了一下kong_postgres.yaml的内容,是在kubernetes中部署了一个Deployment、启动几个运行kong的容器。这不是期待的部署方式,目标不是把kong运行起来,而是让kong和kubernetes对接起来。下一节中看一下实现了此目标的Kong/kubernetes-ingress-controller是否随kong 1.0.3的发布同步更新了。

kong/kubernetes-ingress-controller的做法

Kong/kubernetes-ingress-controller将kong和kubernetes对接起来,使kong成为kubernetes集群的网关,在kubernetes中创建的服务会自动发布到kong中,并支持细粒度的调整,当前最新版本是0.3.0(2019-03-05 17:05:21)。

all-in-one-postgres.yaml是一个完整的部署文件,里面包括:多个Role、多个CRD、PostgreSQL的StatefuSet、初始化数据库的Job、Ingress Controller的Deploymen和Kong-Proxy的Deployment,文件内容比较多就不粘贴了。如果使用的Postgres已经提前准备好了,将all-in-one-postgres.yaml中的PostgreSQL的StatefuSet删除,并修改文件中与PostgreSQL相关的变量。其它几个关键资源的用途是:

  1. 名为kong-migrations的Job执行命令kong migrations bootstrap,完成初始化设置。

  2. 名为kong-proxy的Service以及它指向的Deployment是部署在Kubernetes中的kong,这些kong的admin监听端口被关闭,只作为数据平面的组件承担处理转发请求的任务。

  3. 名为kong-ingress-controller的Deployment中有2个常驻容器:第一个常驻容器是admin-api,这是一个开启了admin监听端口的kong,它只作为控制平面的组件,接受第二个容器下发的控制指令,不承担数据平面的处理任务;第二个常驻容器是ingress-controller,它监听Kubernetes中的资源变化,及时向kong的控制平面,也就是它的参数--publish-service=kong/kong-proxy指定的地址发送控制指令。

创建的kong容器使用的镜像是kong:1.0.0-centos, 是docker hub上的官方镜像,换成kong:1.0.3-centos应该没问题。关键还是上一节提到的问题,docker官方的kong镜像的不是直接用kong的源码创建,要制作自己的镜像比较麻烦。下一节先解决这个问题,毕竟用容器的方式部署利大于弊。

使用kong源代码生成镜像的Dockerfile

先制作Base镜像,减少后续镜像的制作时间,使用下面的Dockerfile:

FROM centos:7
LABEL maintainer="[email protected],https://www.lijiaocn.com"

RUN yum install -y yum-utils  epel-release\
&& yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo \
&& yum install -y openresty openresty-resty luarocks make git gcc lua-devel openssl-devel m4

RUN useradd --uid 1337 kong \
&& yum clean all

生成镜像lijiaocn/openresty:centos:

docker build -f ./Dockerfile.base -t lijiaocn/openresty:centos .

在Base镜像的基础上制作kong的镜像,将kong源码拷贝到镜像中,并安装,Dockerfile如下:

FROM lijiaocn/openresty:centos
LABEL maintainer="[email protected] https://www.lijiaocn.com"

ENV KONG_VERSION 1.0.3

COPY ./kong  /kong
COPY ./kong.sh /kong.sh
COPY ./kong.conf /kong.conf
COPY ./docker-entrypoint.sh /docker-entrypoint.sh

RUN useradd --uid 1337 kong && pushd /kong && make install && popd && chmod +x /kong.sh && ln -s  /kong.sh /usr/bin/kong

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 8000 8443 8001 8444

STOPSIGNAL SIGTERM

CMD ["kong", "docker-start"]

所有相关文件位于github.com/lijiaocn/containers中,可以直接用下面的操作:

git clone https://github.com/lijiaocn/containers
cd docker-kong
make base
make prod

在kubernetes中部署

使用kubernetes-ingress-controller提供的all-in-one-postgres.yaml,把其中的postgre地址以及kong镜像替换成自己的,然后提交给kubernetes就可以了。去掉了postgres的部署文件:kong-ingress-controller-0.3.0-with-kong-1.0.3.yaml.

kubectl create -f https://raw.githubusercontent.com/introclass/kubernetes-yamls/master/kong-deploy/kong-ingress-controller-0.3.0-with-kong-1.0.3.yaml

试用

创建一个完整k8s应用:

$ kubectl create -f https://raw.githubusercontent.com/introclass/kubernetes-yamls/master/all-in-one/echo-all-in-one.yaml
namespace/demo-echo created
ingress.extensions/ingress-echo created
service/echo created
deployment.apps/echo created

ingress中配置的hostname是echo.com

$ ./kubectl.sh -n demo-echo get ingress -o wide
NAME           HOSTS      ADDRESS   PORTS   AGE
ingress-echo   echo.com             80      3m14s

kong-proxy service的cluster ip是172.16.120.31,用cluster ip或者NodePort可以验证:

$ ./kubectl.sh  -n kong get service
NAME                      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
kong-ingress-controller   NodePort   172.16.80.137   <none>        8001:30690/TCP               6d1h
kong-proxy                NodePort   172.16.120.31   <none>        80:31406/TCP,443:30459/TCP   6d1h

访问kong-proxy,host指定为echo.com

$ curl -H "host: echo.com" 172.16.120.31
Hostname: echo-7cfbbd7d49-7mnt8
...

$ curl -H "host: echo.com" 10.10.64.58:31406
Hostname: echo-7cfbbd7d49-7mnt8
...

创建在demo-echo中创建几个kong-plugin:

$ kubectl.sh -f 
kongplugin.configuration.konghq.com/echo-bot-detection created
kongplugin.configuration.konghq.com/echo-cors created
kongplugin.configuration.konghq.com/echo-ip-restriction created

创建的kong-plugin内容如下:

$ ./kubectl.sh -n demo-echo get kp  -o wide
NAME                  PLUGIN-TYPE      AGE   DISABLED   CONFIG
echo-bot-detection    bot-detection    1m    false      map[blacklist:[curl/7.54.0]]
echo-cors             cors             1m    false      map[origins:* methods:GET,POST]
echo-ip-restriction   ip-restriction   1m    false      map[blacklist:1.1.1.1]

编辑ingress-echo:

./kubectl.sh -n demo-echo edit ingress ingress-echo

添加Annotations,绑定bot-detection:

metadata:
  annotations:
    plugins.konghq.com: echo-bot-detection

这时候访问因为User-Agent是curl/7.54.0而被拒绝:

$ curl -H "host:echo.com"  10.10.64.58:31406
{"message":"Forbidden"}%

换一个User-Agent就可以了:

$ curl -v  -H "host:echo.com" -H "User-Agent: XX"  10.10.64.58:31406
Hostname: echo-7cfbbd7d49-7mnt8

参考

  1. Kong via Manifest Files
  2. Kong via Helm
  3. helm
  4. Kong/kong-dist-kubernetes
  5. Docker Official Images: kong
  6. API网关Kong学习笔记(一):Nginx、OpenResty和Kong入门,基础概念和安装部署
  7. Kong/kubernetes-ingress-controller
  8. kubernetes-ingress-controller/deploy/single/all-in-one-postgres.yaml

本文原创首发于网站:www.lijiaocn.com

QQ交流群

区块链实践互助QQ群:576555864

Kubernetes实践互助QQ群:947371129

Prometheus实践互助QQ群:952461804

Kong/Envoy实践互助QQ群:952503851

Ansible实践互助QQ群:955105412

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作 友情链接: lijiaocn github.com