前段时间折腾公司老集群的升级方案,kong和envoy的学习研究停顿了一段时间,现在重新捡起来,正式推进。Kong的版本已经发布到1.0.3了,这里按照kong给出的部署方法部署体验一下,同时回忆一下之前的工作。
2019-05-06 16:28:56:kong 1.1.x有了一个重大变换,实现了db-less模式,可以不使用数据库了,见笔记二十六:查看全部笔记。
如果是刚开始学习kong,直接从1.x开始,0.x已经不再维护,0.15是0.x的最后一个版本。
前19篇笔记是刚开始接触kong时记录的,使用的版本是0.14.1,当时对kong一知半解,笔记比较杂乱。第二十篇开始是再次折腾时的笔记,使用的版本是1.0.3,笔记相对条理一些。
从0.x到1.x需要关注的变化有:
如果对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_PASSWORD
和KONG_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入门,基础概念和安装部署中的做法:
继续看文档,文档中第五步部署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对接起来,使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相关的变量。其它几个关键资源的用途是:
名为kong-migrations
的Job执行命令kong migrations bootstrap
,完成初始化设置。
名为kong-proxy
的Service以及它指向的Deployment是部署在Kubernetes中的kong,这些kong的admin监听端口被关闭,只作为数据平面的组件承担处理转发请求的任务。
名为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的源码创建,要制作自己的镜像比较麻烦。下一节先解决这个问题,毕竟用容器的方式部署利大于弊。
先制作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-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
kubectl create -f https://raw.githubusercontent.com/introclass/kubernetes-yamls/master/kong-deploy/kong-dashboard.yaml