美文网首页Docker
kong与kubernetes集成(ingress)

kong与kubernetes集成(ingress)

作者: GoddyWu | 来源:发表于2018-12-10 17:13 被阅读74次

Reference

之前设想kong和k8s结合使用https://docs.konghq.com/install/kubernetes/?_ga=2.265164879.1330610937.1543828237-1627235705.1540276193 中的Kong via Manifest Files方案,对应仓库https://github.com/Kong/kong-dist-kubernetes,即

  • kubectl create -f postgres.yaml
  • kubectl create -f kong_migration_postgres.yaml
  • kubectl delete -f kong_migration_postgres.yaml
  • kubectl create -f kong_postgres.yaml

    但是公司大牛调研后推荐Kubernetes Ingress Controller for Kong的方案,那么我们来看下。

本文涉及的技术:

实践

helm 安装kong

(helm 是kubernetes的包管理器,这里不再赘述。)

$ helm search kong
$ helm fetch stable/kong
这时已下载kong的charts文件到本地,因为我们只会更改它的values.yml文件,所以拷贝一份出来,目录结构类似:

对于kubernetes ingress来说,ingress controller是核心,这里我们配置ingressController的enabled为true。
kong会暴露两组端口至外部,一个是admin api(这里为admin), 另一个是resource api(这里为proxy)。因为我们需要使用oauth插件, kong的oauth endpoint必须为https,所以proxy需要使用https,admin可以改为http方便使用。

# helm启动
$ helm install --name my-kong kong --namespace kong --values values.yaml 

# helm更新(较慢,需要等kong ns下的kong-upgrade-migrations执行完毕)
$ helm upgrade my-kong kong -f values.yaml

# 永久删除
$ helm delete my-kong --purge

配置resource 服务

这里给一个简单示例

kind: Service
apiVersion: v1
metadata:
  name: python-service
  # annotations:
    # plugins.konghq.com: rl-by-ip
spec:
  # type: NodePort
  selector:
    app: python
  ports:
    - protocol: TCP
      port: 5000
      # targetPort: 80
      # nodePort: 31203
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: python-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: python
  template:
    metadata:
      labels:
        app: python
    spec:
      containers:
      - name: python-controller
        image: godbaby/kong-python:1.0
        ports:
        - containerPort: 5000
        #volumeMounts:
       # - mountPath: /code/app.py
          #name: python-volume
      #volumes:
      #- name: python-volume
        #hostPath:
          #path: /Users/goddy/test/kong/docker/resource.py
        # readinessProbe:
        #   httpGet:
        #     path: /debug/version
        #     port: 80
        #   initialDelaySeconds: 5
        #   periodSeconds: 10
        #   successThreshold: 5
        # resources:
        #   requests:
        #     memory: "400Mi"
        #     cpu: "100m"
        #   limits:
        #     memory: "800Mi"
        #     cpu: "200m"
---

这里注释的为了方便调试和记住这些配置项,可以忽略。
注意这里未使用nodePort的方式暴露端口,而是使用clusterIP的方式,来达到kong作为唯一集群外的访问终端。

配置KongIngress

Ingress是kubernetes已定义好的资源。
KongIngress是helm已经帮我们定义好的kubernetes 自定义资源,作为Ingress的额外配置,而且它必须创建于Ingress上(即metadata一致)。

apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: tls-example-ingress
proxy:
  path: /
route:
  strip_path: true
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
  # annotations:
    # plugins.konghq.com: rl-by-ip
    # plugins.konghq.com: oauth
    # ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: test 
      http:
        paths:
        - path: /te
          backend:
            serviceName: python-service
            servicePort: 5000
        # - path: /2
        #   backend:
        #     serviceName: python-service
        #     servicePort: 5000
    # - host: dashboard
    #   http:
    #     paths:
    #     - path: /
    #       backend:
    #         serviceName: kong-dashboard
    #         servicePort: 8080

示例中的strip path就是一种常见的需求。

  • 设置成false时(或不设置):资源服务内部分接口生效,Ingress的path类似一个正则过滤器,不符合的则访问不到。
  • true时:比如有两个资源服务,同时想占用同一个域名,如 前端使用www.test.com,而后端使用 www.test.com/api(这样前端直接用`location.origin/api`访问即可),此时就需要开启strip_path.

kong dashboard

因为kong-kubernetes ingress的方案提倡声明式的资源,所以GUI其实没啥用。而且目前版本的kong是不可以使用admin api创建数据的。

---
apiVersion: v1
kind: Service
metadata:
  name: kong-dashboard
  namespace: kong
spec:
  # type: NodePort
  selector:
    app: dashboard
  ports:
  - port: 8080
    protocol: TCP
---

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: kong-dashboard
  namespace: kong
spec:
  template:
    metadata:
      labels:
        name: dashboard
        app: dashboard
    spec:
      containers:
      - name: kong-dashboard
        args:
        - start
        - --kong-url http://bot-gateway-kong-admin:8444
        # - --basic-auth admin=admin
        image: pgbi/kong-dashboard:latest
        ports:
        - containerPort: 8080

对于oauth插件来说,还需要创建以下资源

开启插件

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: oauth
config:
  scopes: read,write
  mandatory_scope: true
  enable_password_grant: true
  global_credentials: true
  provision_key: frh1REQndMbcEVuO1DV4EpWtR7Wnmfac
plugin: oauth2

config的选项和kong官网的一致,这里不赘述。
多个Ingress可以声明同一个KongPlugin,理论上kong不支持单服务使用同一个插件,这里kubernetes的方案会自动帮我们创建多个一致的插件到不同服务,只是我们看起来它们同时使用一个kong的oauth插件。

创建consumer

apiVersion: configuration.konghq.com/v1
kind: KongConsumer
metadata:
  name: team-a
username: goddy
---
apiVersion: configuration.konghq.com/v1
kind: KongCredential
metadata:
  name: credential-a
consumerRef: team-a
type: oauth2
config:
  name: goddy
  client_id: kvcKEfrBn402kZkblQgRwe4j3Fv3A7GH
  client_secret: 3ZwsnUIon3VWafhn39kjJ2iSFT75lFJf
  redirect_uri: http://www.baidu.com

backend服务

参照https://www.jianshu.com/p/4ddb916d3195方案中的code repo。


还有一些调研的资料,也分享给大家

  • [x] 泛域名配置
    • 配置*.dev.ruyi.ai或其他直接指向kong的内网host和port即可,通过kong反向代理分配域名(配置service、route)
  • [x] postgreSQL数据保护策略
    • 1)数据volume出来,xxx:/var/lib/postgresql/data
    • 2)手动备份出来
      • pg_dump -U kong kong > /kong.bak
      • docker cp postgresql_postgres_1:/kong.bak /Users/goddy/test/kong/postgresql
      • 导入:pg_dump -U kong kong > /kong.bak
  • [x] postgreSQL数据库故障后的应对策略
    • 1)docker-compose配置healthcheck和restart
      healthcheck:
        test: ["CMD", "pg_isready", "-U", "postgres"]
        interval: 30s
        timeout: 30s
        retries: 3
      restart: on-failure
      
    • 2)docker-compose手动重启
    • 3)bak文件导入
  • [x] kong扩展策略
    • 复用k8s策略
  • [x] 和k8s切合的方案
  • [ ] 在生产环境怎么划分scope
  • [ ] consumer和user对应关系,找一些例子
    • 两种实施方案:
      • consumer与实际用户一一对应
        • 创建:1.通过auth项目验证用户是否存在 2.通过auth项目创建用户: 1)填充uid、scope等信息,创建用户 2)创建用户及其uid对应的consumer至kong 3)添加oauth凭证至consumer
        • 访问:1.auth项目验证用户名密码是否相符 2.通过uid获取到consumer的oauth凭证的client_id和client_secret 3.访问kong获取token
      • 示例项目:https://gist.github.com/ernsheong/b4deb7ce391d43dad6a63272b94b8e2e
      • 优点:kong的consumer是区分用户的最小级别,如果使用kong的log等插件,比较契合。
      • 风险:kong依赖的postgresql需要存储一份用户数据信息,和auth依赖的数据库用户一一对应,每次访问需要请求kong获取一次client信息,[-对于kong kubernetes ingress(声明式)无法实现-]
      • consumer与client对应,即一组用户共用一个client
        • 创建:通过auth项目填充uid、scope等信息,创建用户
        • 登录:auth项目验证用户名密码是否相符,使用公用的client信息,访问kong获取token
      • 优点:简单
      • 风险:用户使用kong的其他登录方式很难做到,
  • [ ] oauth/token地址固定一个
    • oauth插件是基于service或这service下的route的,所以endpoint会在服务的host生成,如hbrainlab.ruyi.ai/oauth2/token, 如果想固定一个地址的话,需要有一个获取token的服务,这个服务要求地址固定,而且生成的token对于其他服务都有效,那么[-其他服务对应的oauth plugin的global creditials需要设置为true-]

资料:

相关文章

网友评论

    本文标题:kong与kubernetes集成(ingress)

    本文链接:https://www.haomeiwen.com/subject/lshicqtx.html