背景
随着k8s的成熟,在k8s上使用ingress-nginx、traefik、apisix等各类ingress的人也越来越多。ingress-kong也可以作为k8s的ingress使用,当然kong也可以单独作为微服务的gateway网关来使用。
如果kong是作为ingress来使用,那么需要使用kong镜像来部署一个ingress-kong和一个kong/kubernetes-ingress-controller镜像来部署一个kong的ingress-controller。还需要部署sa账号和rbac,还有CRD资源。
如果kong只是作为一个gateway来替换springcloud中的gateway来使用,那么只需要部署sa账号和rbac,然后用kong镜像部署一个pod即可当做gateway使用,crd也就不需要了。
kong和konga支持MySQL、MongoDB、PostgresSQL三种数据库。而我这里选择的是PostgresSQL。因为公司都是all in docker,all in kubernetes,因此这里也就选择了在k8s中部署kong和konga。下面记录了一下部署kong和konga过程中遇到的一些报错和排查解决方案思路手段。
部署konga
$ cat kong-ui-pre.yaml --- apiVersion: apps/v1 kind: Deployment metadata: labels: appName: konga-ui-aggre-sit appEnv: sit name: konga-ui-aggre-sit namespace: kong spec: replicas: 1 selector: matchLabels: appName: konga-ui-aggre-sit appEnv: sit template: metadata: labels: appName: konga-ui-aggre-sit appEnv: sit spec: imagePullSecrets: - name: registry-auth containers: - env: - name: NODE_ENV value: "production" - name: DB_ADAPTER value: "postgres" - name: DB_HOST value: "你自己的pgsql地址" - name: DB_PORT value: "你自己的pgsql端口" - name: DB_USER value: "kong" - name: DB_PASSWORD value: "你自己的pgsql密码" - name: DB_DATABASE value: "konga" - name: TOKEN_SECRET value: "自己生成随机字符串" - name: NO_AUTH value: "false" - name: NODE_TLS_REJECT_UNAUTHORIZED value: "0" image: registry.ayunw.cn/kube-system/pantsel/konga:0.14.9 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: / port: 1337 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 name: konga-ui-aggre-sit ports: - containerPort: 1337 name: kong-ui protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: / port: 1337 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 serviceAccountName: kong-serviceaccount
我部署kong和konga的时候使用的是pgsql,根据GitHub上的文档上说明得知,在使用NODE_ENV为production的时候需要手动去初始化pgsql。看了一下kong官网的文档来初始化,官网文档:https://docs.konghq.com/install/docker/
初始化pgsql报错
$ docker run --rm --network=kong-net -e "KONG_DATABASE=postgres" \ > -e "KONG_PG_HOST=pgsql地址" \ > -e "KONG_PG_USER=konga" \ > -e "KONG_PG_PASSWORD=pgsql密码" \ > -e "KONG_PG_DATABASE=konga" \ > -e "KONG_PG_PORT=3306" \ > registry.ayunw.cn/kong/kong-custom:382-ffaf4d50 kong migrations up Unable to find image 'registry.ayunw.cn/kong/kong-custom:382-ffaf4d50' locally 382-ffaf4d50: Pulling from kong/kong-custom 0a6724ff3fcd: Pull complete 274efec6805c: Pull complete 4bb58967a4ce: Pull complete 3f59fb9af44b: Pull complete 7e3ec18b9226: Pull complete ce8acfac03f7: Pull complete Digest: sha256:453dea194d4e39275ea771d062262f0868e29120fc529702dea10278677413c2 Status: Downloaded newer image for registry.ayunw.cn/kong/kong-custom:382-ffaf4d50 Error: [PostgreSQL error] failed to retrieve PostgreSQL server_version_num: temporary failure in name resolution Run with --v (verbose) or --vv (debug) for more details
想了一下,他这个完全是docker部署kong而不是k8s中部署kong,因此他会需要创建一个docker的network为kong-net
,然后保证所有kong相关的服务都跑在同一个网络中。那我这里是部署在k8s中,且pgsql也是买的云的服务,所以我这里其实是不应该这样子来进行初始化的。
然后上github,找到https://github.com/pantsel/konga/tree/master
文档上的Production Docker Image
步骤中的Prepare the database
来操作。
但是里面可能有一个参数解释的不是很清楚,我自己一开始也是比较模糊的,就是https://github.com/pantsel/konga
上Production Docker Image
步骤下的Prepare the database
步骤中的connection-uri
参数,你会发现他似乎没给出connection-uri
的这个uri
的例子是什么样子的。但是其实你会发现在这个github中的Production步骤有写一条url和这个比较类似的,告诉你在使用MySQL
或者PostgresSQL
的时候应该怎么初始化,命令是:node ./bin/konga.js prepare --adapter postgres --uri postgresql://localhost:5432/konga
。但是注意,这个命令他应该不是在你将konga部署在k8s中来使用的。但是这里就有一条url:
postgresql://localhost:5432/konga
,可以用来参考,那么也就是说差不多就是这个样子的url了,但是应该还需要带上用户名和密码。
其实这里我还犯了一个错误,就是其实一开始我初始化的pgsql命令中pgsql的url写错了,看了https://github.com/pantsel/konga/tree/master
中的文档后,手敲命令,将postgresql://localhost:5432/konga
敲成了
postgre://localhost:5432/konga
,所以初始化的时候也报错了。
更改后重新初始化
$ docker run registry.ayunw.cn/kube-system/pantsel/konga:0.14.9 -c prepare -a postgres -u postgresql://konga:pgsql密码@pgsql地址:pgsql端口/konga debug: Preparing database... Using postgres DB Adapter. Failed to connect to DB Error: getaddrinfo EAI_AGAIN konga at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:64:26) { errno: 'EAI_AGAIN', code: 'EAI_AGAIN', syscall: 'getaddrinfo', hostname: 'konga' }
然后想到了因为“#”导致的问题。甚至尝试了将密码用单引号或者双引号括起来尝试,仍然报错,然后将整个连接pgsql的url全部用单引号或者双引号括起来,也都是没有用。再查了一下google发现需要将“#”符号改成%23
。
再次初始化
$ docker run registry.ayunw.cn/kube-system/pantsel/konga:0.14.9 -c prepare -a postgres -u postgresql://konga:pgsql密码@pgsql地址:pgsql端口/konga debug: Preparing database... Using postgres DB Adapter. Database exists. Continue... debug: Hook:api_health_checks:process() called debug: Hook:health_checks:process() called debug: Hook:start-scheduled-snapshots:process() called debug: Hook:upstream_health_checks:process() called debug: Hook:user_events_hook:process() called debug: Seeding User... debug: User seed planted debug: Seeding Kongnode... debug: Kongnode seed planted debug: Seeding Emailtransport... debug: Emailtransport seed planted debug: Database migrations completed!
初始化成功
总结部署konga遇到的问题
❝❞
- 1、文档中写的connection-uri的话必须不能写错,postgresql不要写成postgres
- 2、密码中有符号“#”要改成
%23
部署kong
--- # Source: kong-custom-pre-master/templates/deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: kong-custom-pre-master namespace: kong labels: appEnv: pre appName: kong-custom appGroup: kong spec: replicas: 1 progressDeadlineSeconds: 1800 minReadySeconds: 5 strategy: type: RollingUpdate rollingUpdate: maxUnavailable: 50% maxSurge: 50% selector: matchLabels: appEnv: pre appName: kong-custom appGroup: kong template: metadata: labels: appEnv: pre appName: kong-custom appGroup: kong spec: dnsPolicy: ClusterFirst terminationGracePeriodSeconds: 10 serviceAccountName: kong-serviceaccount imagePullSecrets: - name: registry-auth-kong-pro initContainers: - name: wait-for-migrations image: "registry.ayunw.cn/kong/kong-custom:398-c44f9085" command: - /bin/sh - -c - while true; do kong migrations bootstrap; if [[ 0 -eq 0 ]]; then exit 0; fi; sleep 2; done; env: # 注意这里KONG_DATABASE的value是错误的,应该将Kong改成postgres - name: KONG_DATABASE value: "kong" - name: KONG_PG_USER value: "kong" - name: KONG_PG_PORT value: "pgsql端口" - name: KONG_PG_PASSWORD value: "pgsql密码" - name: KONG_PG_HOST value: "pgsql地址" containers: - name: kong-custom-pre-master image: "registry.ayunw.cn/kong/kong-custom:398-c44f9085" ports: - name: proxy containerPort: 8000 protocol: TCP - name: proxy-ssl containerPort: 9443 protocol: TCP - name: metrics containerPort: 8100 protocol: TCP - name: admin-url containerPort: 8444 protocol: TCP resources: limits: cpu: "5000m" memory: "1024Mi" requests: cpu: "100m" memory: "512Mi" lifecycle: preStop: exec: command: - /bin/sh - -c - kong quit env: - name: "KONG_PROXY_LISTEN" value: "0.0.0.0:8000, 0.0.0.0:9443 ssl http2" - name: "KONG_PORT_MAPS" value: "80:8000, 443:8443" - name: "KONG_ADMIN_LISTEN" value: "0.0.0.0:8444 ssl" - name: "KONG_STATUS_LISTEN" value: "0.0.0.0:8100" - name: "KONG_NGINX_WORKER_PROCESSES" value: "2" - name: "KONG_ADMIN_ACCESS_LOG" value: "/dev/stdout" - name: "KONG_ADMIN_ERROR_LOG" value: "/dev/stderr" - name: "KONG_PROXY_ERROR_LOG" value: "/dev/stderr" # 注意这里KONG_DATABASE的value是错误的,应该将Kong改成postgres - name: KONG_DATABASE value: "kong" - name: KONG_PG_USER value: "kong" - name: KONG_PG_PORT value: "pgsql端口" - name: KONG_PG_PASSWORD value: "pgsql密码" - name: KONG_PG_HOST value: "pgsql地址"
查看kong的日志报错
$ kubectl logs -f --tail=20 -n kong kong-custom-sit-9c5cf7b69-4q29l stack traceback: [C]: in function 'error' /usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16: in function 'check_state' /usr/local/share/lua/5.1/kong/init.lua:455: in function 'init' init_by_lua:3: in main chunk nginx: [error] init_by_lua error: /usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16: Database needs bootstrapping or is older than Kong 1.0. To start a new installation from scratch, run 'kong migrations bootstrap'. To migrate from a version older than 1.0, migrated to Kong 1.5.0 first. If you still have 'apis' entities, you can convert them to Routes and Services using the 'kong migrations migrate-apis' command in Kong 1.5.0. stack traceback: [C]: in function 'error' /usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16: in function 'check_state' /usr/local/share/lua/5.1/kong/init.lua:455: in function 'init' init_by_lua:3: in main chunk
很明显是因为没有执行kong migrations
的命令。但是明明在deployment.yaml中的initContainers中已经写了,为何没执行?
原因
是因为kong的deployment.yaml中的initContainers下的env环境变量中KONG_DATABASE写错了,我写成了kong。而根据github:
https://github.com/pantsel/konga/tree/master
上README.md
文档中的Environment variables
中所知,KONG_DATABASE
这个变量是要指明使用postgres
或者MySQL
或者off
三个选项其中的一个。因为我用的是pgsql,因此这里需要指定postgres
,那么初始化就回去pgsql中创建库、表、创建数据等操作,这样才会成功。
更改后,kong启动正常。
写在最后
我在konga的github上没找到manifests直接可以用的yaml清单文件,只找到了chart包,因此我是渲染出来以后然后根据自己的实际环境进行了更改。初次使用难免会遇到杂七杂八的问题。其实也是由于我个人的不细心,没仔细多看几遍文档导致的。有读者如果找到了konga的manifests清单文件也可下方留言交流。也提醒各位小伙伴们,平常也需要注意一下习惯,减少和我犯同样的错误!