曾国藩:一勤天下无难事

K8s部署kong之yaml

2019.05.09

官方文档

官方安装:https://getkong.org/install/kubernetes/

简介:

Kong 是在客户端和(微)服务间转发API通信的API网关,通过插件扩展功能。

Kong 有两个主要组件:

  • Kong Server :基于 nginx 的服务器,用来接收 API 请求。
  • Apache Cassandra & :用来存储操作数据。

注:Ambassador没有数据库 - 它依赖于ConfigMap来存储状态

Kong 基本功能:

  • HTTP 基本认证、密钥认证、CORS( Cross-origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API 请求限流、请求转发以及 nginx 监控
  • Serf是一个去中心化的集群成员管理、故障检测解决方案,Kong用它做清缓存,看来Kong里面核心的数据consumer、api、plugin都是做了缓存的,还可以做集群节点的监控

Kong 不足:

  • 数据库不支持常用的mysql,只支持Postgres/Cassandra
  • 扩展Kong需要会写lua脚本
  • 不修改源码的情况下,无法自定义nginx配置文件,因为重启后会重新初始化有变更的nginx配置文件【nginx.conf|nginx-kong.conf】
  • 安装过程中会创建一个 Postgres 的 StatefulSet,前面提到,这一版本对 Kubernetes 集群的最低版本要求是 1.8

Kong的限流

  • 本地限流(local)
  • 数据库限流(cluster)
  • Redis限流

注:Kong的这三种限流方式都没有考虑并发情况

限流:https://my.oschina.net/chinamerp/blog/851613

当到达限流的临界值(max-1)时,此时有多条请求同时执行get_usage,计算结果全部通过,而我们期望的是仅有一条请求能通过

8000端口是可以给用户访问,就是说用户发送请求先到 Kong 项目的 8000 端口,然后Kong 项目帮你转到你的后端应用api。

Kong api简单使用

8001 端口是管理端口,比如说,管理员可以通过 8001端口来得到你加入过的 api

  • 列出 所加过的 api

    curl localhost:8001/apis/ 
    
  • 加入 api

    curl -i -X POST --url http://localhost:8001/apis/ --data 'upstream_url=http://camp.uats.cc' --data 'request_path=login'   
    

    上面这段命令表示:

    • --url:http://localhost:8001/apis/ 固定的,加入 api 就得写这个,表示给 kong管理。
    • upstream_url:表示我们的网站。相当于一个请求前缀。
    • request_path:就是具体我们的 api。
  • 删除 api

    curl -i -X DELETE localhost:8001/apis/00f90ca9-cf2d-4830-c842-3b90f6cd08af  
    

    后面 这个串表示 加入的api的 id。

初始设置

  • 下载或克隆以下代码

    git clone https://github.com/Kong/kong-dist-kubernetes.git
    cd kong-dist-kubernetes
    
  • 修改配置文件主要是k8s对应service的类型修改为type:nodePort

    apiVersion: v1
    kind: Service
    metadata:
    name: kong-proxy
    spec:
    type: LoadBalancer  ## 将这里修改为nodeport
    loadBalancerSourceRanges:
    - 0.0.0.0/0
    ports:
    - name: kong-proxy
        port: 8000
        targetPort: 8000
        protocol: TCP
    selector:
        app: kong
    

部署数据存储

注意:这里使用pg数据库

  • 创建数据库

    apiVersion: v1
    kind: Service
    metadata:
    name: postgres
    spec:
    ports:
    - name: pgql
        port: 5432
        targetPort: 5432
        protocol: TCP
    selector:
        app: postgres
    ---
    apiVersion: v1
    kind: ReplicationController
    metadata:
    name: postgres
    spec:
    replicas: 1
    template:
        metadata:
        labels:
            app: postgres
        spec:
        containers:
            - name: postgres
            image: postgres:9.6
            env:
                - name: POSTGRES_USER
                value: kong
                - name: POSTGRES_PASSWORD
                value: kong
                - name: POSTGRES_DB
                value: kong
                - name: PGDATA
                value: /var/lib/postgresql/data/pgdata
            ports:
                - containerPort: 5432
            volumeMounts:
                - mountPath: /var/lib/postgresql/data
                name: pg-data
        volumes:
            - name: pg-data
            emptyDir: {}
    
    kubectl create -f postgres.yaml   
    
  • 准备数据库运行迁移作业,以下为kong_migration_postgres.yaml

    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 bootstrap" ]
        restartPolicy: Never
    
    kubectl create -f kong_migration_postgres.yaml 
    
  • 将Kong管理员,代理服务和Deployment控制器部署到集群

    apiVersion: v1
    kind: Service
    metadata:
    name: kong-proxy
    spec:
    type: LoadBalancer
    loadBalancerSourceRanges:
    - 0.0.0.0/0
    ports:
    - name: kong-proxy
        port: 8000
        targetPort: 8000
        protocol: TCP
    selector:
        app: kong
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: kong-proxy-ssl
    spec:
    type: LoadBalancer
    loadBalancerSourceRanges:
    - 0.0.0.0/0
    ports:
    - name: kong-proxy-ssl
        port: 8443
        targetPort: 8443
        protocol: TCP
    selector:
        app: kong
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: kong-admin
    spec:
    type: LoadBalancer
    loadBalancerSourceRanges:
    - 0.0.0.0/0
    ports:
    - name: kong-admin
        port: 8001
        targetPort: 8001
        protocol: TCP
    selector:
        app: kong
    ---
    apiVersion: v1
    kind: Service
    metadata:
    name: kong-admin-ssl
    spec:
    type: LoadBalancer
    loadBalancerSourceRanges:
    - 0.0.0.0/0
    ports:
    - name: kong-admin-ssl
        port: 8444
        targetPort: 8444
        protocol: TCP
    selector:
        app: kong
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    name: kong-rc
    spec:
    replicas: 3
    template:
        metadata:
        labels:
            name: kong-rc
            app: kong
        spec:
        containers:
        - name: kong
            image: kong
            env:
            - name: KONG_ADMIN_LISTEN
                value: "0.0.0.0:8001, 0.0.0.0:8444 ssl"
            - name: KONG_PG_PASSWORD
                value: kong
            - name: KONG_PG_HOST
                value: postgres
            - name: KONG_PROXY_ACCESS_LOG
                value: "/dev/stdout"
            - name: KONG_ADMIN_ACCESS_LOG
                value: "/dev/stdout"
            - name: KONG_PROXY_ERROR_LOG
                value: "/dev/stderr"
            - name: KONG_ADMIN_ERROR_LOG
                value: "/dev/stderr"
            ports:
            - name: admin
            containerPort: 8001
            protocol: TCP
            - name: proxy
            containerPort: 8000
            protocol: TCP
            - name: proxy-ssl
            containerPort: 8443
            protocol: TCP
            - name: admin-ssl
            containerPort: 8444
            protocol: TCP
    
    kubectl create -f kong_postgres.yaml
    
  • 验证您的部署 您现在可以看到已经使用的资源kubectl:

    kubectl get all
    

    一旦EXTERNAL_IP可用于Kong代理和管理服务,您可以通过发出以下请求来测试Kong:

    curl <kong-admin-ip-address>:8001
    curl https://<admin-ssl-ip-address>:8444
    curl <kong-proxy-ip-address>:8000
    curl https://<kong-proxy-ssl-ip-address>:8443
    

    我这可以看到kong以及启动了,kong-rc都是running, 举例测试例如:

    curl 192.168.1.216:31572
    

kong UI管理工具--dashboard