Kong和Konga在K8s部署真的很难吗?

时间:2021-10-15 14:09:07

Kong和Konga在K8s部署真的很难吗?

背景

随着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

  1. $catkong-ui-pre.yaml
  2. ---
  3. apiVersion:apps/v1
  4. kind:Deployment
  5. metadata:
  6. labels:
  7. appName:konga-ui-aggre-sit
  8. appEnv:sit
  9. name:konga-ui-aggre-sit
  10. namespace:kong
  11. spec:
  12. replicas:1
  13. selector:
  14. matchLabels:
  15. appName:konga-ui-aggre-sit
  16. appEnv:sit
  17. template:
  18. metadata:
  19. labels:
  20. appName:konga-ui-aggre-sit
  21. appEnv:sit
  22. spec:
  23. imagePullSecrets:
  24. -name:registry-auth
  25. containers:
  26. -env:
  27. -name:NODE_ENV
  28. value:"production"
  29. -name:DB_ADAPTER
  30. value:"postgres"
  31. -name:DB_HOST
  32. value:"你自己的pgsql地址"
  33. -name:DB_PORT
  34. value:"你自己的pgsql端口"
  35. -name:DB_USER
  36. value:"kong"
  37. -name:DB_PASSWORD
  38. value:"你自己的pgsql密码"
  39. -name:DB_DATABASE
  40. value:"konga"
  41. -name:TOKEN_SECRET
  42. value:"自己生成随机字符串"
  43. -name:NO_AUTH
  44. value:"false"
  45. -name:NODE_TLS_REJECT_UNAUTHORIZED
  46. value:"0"
  47. image:registry.ayunw.cn/kube-system/pantsel/konga:0.14.9
  48. imagePullPolicy:IfNotPresent
  49. livenessProbe:
  50. failureThreshold:3
  51. httpGet:
  52. path:/
  53. port:1337
  54. scheme:HTTP
  55. initialDelaySeconds:5
  56. periodSeconds:10
  57. successThreshold:1
  58. timeoutSeconds:1
  59. name:konga-ui-aggre-sit
  60. ports:
  61. -containerPort:1337
  62. name:kong-ui
  63. protocol:TCP
  64. readinessProbe:
  65. failureThreshold:3
  66. httpGet:
  67. path:/
  68. port:1337
  69. scheme:HTTP
  70. initialDelaySeconds:5
  71. periodSeconds:10
  72. successThreshold:1
  73. timeoutSeconds:1
  74. serviceAccountName:kong-serviceaccount

我部署kong和konga的时候使用的是pgsql,根据GitHub上的文档上说明得知,在使用NODE_ENV为production的时候需要手动去初始化pgsql。看了一下kong官网的文档来初始化,官网文档:https://docs.konghq.com/install/docker/

初始化pgsql报错

  1. $dockerrun--rm--network=kong-net-e"KONG_DATABASE=postgres"\
  2. >-e"KONG_PG_HOST=pgsql地址"\
  3. >-e"KONG_PG_USER=konga"\
  4. >-e"KONG_PG_PASSWORD=pgsql密码"\
  5. >-e"KONG_PG_DATABASE=konga"\
  6. >-e"KONG_PG_PORT=3306"\
  7. >registry.ayunw.cn/kong/kong-custom:382-ffaf4d50kongmigrationsup
  8. Unabletofindimage'registry.ayunw.cn/kong/kong-custom:382-ffaf4d50'locally
  9. 382-ffaf4d50:Pullingfromkong/kong-custom
  10. 0a6724ff3fcd:Pullcomplete
  11. 274efec6805c:Pullcomplete
  12. 4bb58967a4ce:Pullcomplete
  13. 3f59fb9af44b:Pullcomplete
  14. 7e3ec18b9226:Pullcomplete
  15. ce8acfac03f7:Pullcomplete
  16. Digest:sha256:453dea194d4e39275ea771d062262f0868e29120fc529702dea10278677413c2
  17. Status:Downloadednewerimageforregistry.ayunw.cn/kong/kong-custom:382-ffaf4d50
  18. Error:[PostgreSQLerror]failedtoretrievePostgreSQLserver_version_num:temporaryfailureinnameresolution
  19. Runwith--v(verbose)or--vv(debug)formoredetails

想了一下,他这个完全是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,所以初始化的时候也报错了。

更改后重新初始化

  1. $dockerrunregistry.ayunw.cn/kube-system/pantsel/konga:0.14.9-cprepare-apostgres-upostgresql://konga:pgsql密码@pgsql地址:pgsql端口/konga
  2. debug:Preparingdatabase...
  3. UsingpostgresDBAdapter.
  4. FailedtoconnecttoDBError:getaddrinfoEAI_AGAINkonga
  5. atGetAddrInfoReqWrap.onlookup[asoncomplete](dns.js:64:26){
  6. errno:'EAI_AGAIN',
  7. code:'EAI_AGAIN',
  8. syscall:'getaddrinfo',
  9. hostname:'konga'
  10. }

然后想到了因为“#”导致的问题。甚至尝试了将密码用单引号或者双引号括起来尝试,仍然报错,然后将整个连接pgsql的url全部用单引号或者双引号括起来,也都是没有用。再查了一下google发现需要将“#”符号改成%23。

再次初始化

  1. $dockerrunregistry.ayunw.cn/kube-system/pantsel/konga:0.14.9-cprepare-apostgres-upostgresql://konga:pgsql密码@pgsql地址:pgsql端口/konga
  2. debug:Preparingdatabase...
  3. UsingpostgresDBAdapter.
  4. Databaseexists.Continue...
  5. debug:Hook:api_health_checks:process()called
  6. debug:Hook:health_checks:process()called
  7. debug:Hook:start-scheduled-snapshots:process()called
  8. debug:Hook:upstream_health_checks:process()called
  9. debug:Hook:user_events_hook:process()called
  10. debug:SeedingUser...
  11. debug:Userseedplanted
  12. debug:SeedingKongnode...
  13. debug:Kongnodeseedplanted
  14. debug:SeedingEmailtransport...
  15. debug:Emailtransportseedplanted
  16. debug:Databasemigrationscompleted!

初始化成功

总结部署konga遇到的问题

1、文档中写的connection-uri的话必须不能写错,postgresql不要写成postgres

2、密码中有符号“#”要改成%23

部署kong

  1. ---
  2. #Source:kong-custom-pre-master/templates/deployment.yaml
  3. apiVersion:apps/v1
  4. kind:Deployment
  5. metadata:
  6. name:kong-custom-pre-master
  7. namespace:kong
  8. labels:
  9. appEnv:pre
  10. appName:kong-custom
  11. appGroup:kong
  12. spec:
  13. replicas:1
  14. progressDeadlineSeconds:1800
  15. minReadySeconds:5
  16. strategy:
  17. type:RollingUpdate
  18. rollingUpdate:
  19. maxUnavailable:50%
  20. maxSurge:50%
  21. selector:
  22. matchLabels:
  23. appEnv:pre
  24. appName:kong-custom
  25. appGroup:kong
  26. template:
  27. metadata:
  28. labels:
  29. appEnv:pre
  30. appName:kong-custom
  31. appGroup:kong
  32. spec:
  33. dnsPolicy:ClusterFirst
  34. terminationGracePeriodSeconds:10
  35. serviceAccountName:kong-serviceaccount
  36. imagePullSecrets:
  37. -name:registry-auth-kong-pro
  38. initContainers:
  39. -name:wait-for-migrations
  40. image:"registry.ayunw.cn/kong/kong-custom:398-c44f9085"
  41. command:
  42. -/bin/sh
  43. --c
  44. -whiletrue;dokongmigrationsbootstrap;if[[0-eq0]];thenexit0;fi;sleep2;done;
  45. env:
  46. #注意这里KONG_DATABASE的value是错误的,应该将Kong改成postgres
  47. -name:KONG_DATABASE
  48. value:"kong"
  49. -name:KONG_PG_USER
  50. value:"kong"
  51. -name:KONG_PG_PORT
  52. value:"pgsql端口"
  53. -name:KONG_PG_PASSWORD
  54. value:"pgsql密码"
  55. -name:KONG_PG_HOST
  56. value:"pgsql地址"
  57. containers:
  58. -name:kong-custom-pre-master
  59. image:"registry.ayunw.cn/kong/kong-custom:398-c44f9085"
  60. ports:
  61. -name:proxy
  62. containerPort:8000
  63. protocol:TCP
  64. -name:proxy-ssl
  65. containerPort:9443
  66. protocol:TCP
  67. -name:metrics
  68. containerPort:8100
  69. protocol:TCP
  70. -name:admin-url
  71. containerPort:8444
  72. protocol:TCP
  73. resources:
  74. limits:
  75. cpu:"5000m"
  76. memory:"1024Mi"
  77. requests:
  78. cpu:"100m"
  79. memory:"512Mi"
  80. lifecycle:
  81. preStop:
  82. exec:
  83. command:
  84. -/bin/sh
  85. --c
  86. -kongquit
  87. env:
  88. -name:"KONG_PROXY_LISTEN"
  89. value:"0.0.0.0:8000,0.0.0.0:9443sslhttp2"
  90. -name:"KONG_PORT_MAPS"
  91. value:"80:8000,443:8443"
  92. -name:"KONG_ADMIN_LISTEN"
  93. value:"0.0.0.0:8444ssl"
  94. -name:"KONG_STATUS_LISTEN"
  95. value:"0.0.0.0:8100"
  96. -name:"KONG_NGINX_WORKER_PROCESSES"
  97. value:"2"
  98. -name:"KONG_ADMIN_ACCESS_LOG"
  99. value:"/dev/stdout"
  100. -name:"KONG_ADMIN_ERROR_LOG"
  101. value:"/dev/stderr"
  102. -name:"KONG_PROXY_ERROR_LOG"
  103. value:"/dev/stderr"
  104. #注意这里KONG_DATABASE的value是错误的,应该将Kong改成postgres
  105. -name:KONG_DATABASE
  106. value:"kong"
  107. -name:KONG_PG_USER
  108. value:"kong"
  109. -name:KONG_PG_PORT
  110. value:"pgsql端口"
  111. -name:KONG_PG_PASSWORD
  112. value:"pgsql密码"
  113. -name:KONG_PG_HOST
  114. value:"pgsql地址"

查看kong的日志报错

  1. $kubectllogs-f--tail=20-nkongkong-custom-sit-9c5cf7b69-4q29l
  2. stacktraceback:
  3. [C]:infunction'error'
  4. /usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16:infunction'check_state'
  5. /usr/local/share/lua/5.1/kong/init.lua:455:infunction'init'
  6. init_by_lua:3:inmainchunk
  7. nginx:[error]init_by_luaerror:/usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16:DatabaseneedsbootstrappingorisolderthanKong1.0.
  8. Tostartanewinstallationfromscratch,run'kongmigrationsbootstrap'.
  9. Tomigratefromaversionolderthan1.0,migratedtoKong1.5.0first.
  10. Ifyoustillhave'apis'entities,youcanconvertthemtoRoutesandServices
  11. usingthe'kongmigrationsmigrate-apis'commandinKong1.5.0.
  12. stacktraceback:
  13. [C]:infunction'error'
  14. /usr/local/share/lua/5.1/kong/cmd/utils/migrations.lua:16:infunction'check_state'
  15. /usr/local/share/lua/5.1/kong/init.lua:455:infunction'init'
  16. init_by_lua:3:inmainchunk

很明显是因为没有执行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清单文件也可下方留言交流。也提醒各位小伙伴们,平常也需要注意一下习惯,减少和我犯同样的错误!

原文链接:https://mp.weixin.qq.com/s/YhqOdIDGyvJGVctj-B9-1A