1、Kong的概述

Kong是一个clould-native、快速的、可扩展的、分布式的微服务抽象层(也称为API网关、API中间件或在某些情况下称为服务网格)框架。Kong作为开源项目在2015年推出,它的核心价值是高性能和可扩展性。Kong被广泛用于从初创企业到全球5000家公司以及政府组织的生产环境中。

如果构建Web、移动或IoT(物联网)应用,可能最终需要使用通用的功能来实现这些应用。Kong充当微服务请求的网关(或侧车),通过插件能够提供负载平衡日志记录、身份验证、速率限制、转换等能力。

2、功能特性

  • 云本土化(Cloud-Native):Kong可以在Kubernetes或物理环境上运行;
  • 动态负载平衡(Dynamic Load Balancing):跨多个上游服务的负载平衡业务。
  • 基于哈希的负载平衡(Hash-based Load Balancing):一致的散列/粘性会话的负载平衡。
  • 断路器(Circuit-Breaker):智能跟踪不健康的上游服务。
  • 健康检查(Health Checks):主动和被动监控您的上游服务。
  • 服务发现(Service Discovery):解决如Consul等第三方DNS解析器的SRV记录。
  • 无服务器(Serverless):从Kong中直接调用和保证AWS或OpenWhisk函数安全。
  • WebSockets:通过WebSockets与上游服务进行通信。
  • OAuth2.0:轻松的向API中添加OAuth2.0认证。
  • 日志记录(Logging):通过HTTP、TCP、UDP记录请求或者相应的日志,存储在磁盘中。
  • 安全(Security):ACL,Bot检测,IPs白名单/黑名单等。
  • 系统日志(Syslog):记录信息到系统日志。
  • SSL:为基础服务或API设置特定的SSL证书。
  • 监视(Monitoring):能够实时对关键负载和性能指标进行监控。
  • 转发代理(Forward Proxy):使端口连接到中间透明的HTTP代理。
  • 认证(Authentications):支持HMAC,JWT和BASIC方式进行认证等等。
  • 速率限制(Rate-limiting):基于多个变量的阻塞和节流请求。
  • 转换(Transformations):添加、删除或操作HTTP请求和响应。
  • 缓存(Caching):在代理层进行缓存和服务响应。
  • 命令行工具(CLI):能够通过命令行控制Kong的集群。
  • REST API:可以通过REST API灵活的操作Kong。
  • GEO复制:在不同的区域,配置总是最新的。
  • 故障检测与恢复(Failure Detection & Recovery):如果Cassandra节点失效,Kong并不会受影响。
  • 群集(Clustering):所有的Kong节点会自动加入群集,并更新各个节点上的配置。
  • 可扩展性(Scalability):通过添加节点,实现水平缩放。
  • 性能(Performance):通过缩放和使用Nigix,Kong能够轻松处理负载。
  • 插件(Plugins):基于插件的可扩展体系结构,能够方便的向Kong和API添加功能。

3、Kong依赖的技术

Kong部署在Nginx和Apache Cassandra或PostgreSQL等可靠技术之上,并提供了易于使用的RESTful API来操作和配置系统。下面是Kong的技术逻辑图。基于这些技术,Kong提供相关的特性支持:

  • Nginx
    • 经过验证的高性能基础;
    • HTTP和反向代理服务器;
    • 处理低层级的操作。
  • OpenRestry
    • 支持Lua脚本;
    • 拦截请求/响应生命周期;
    • 基于Nginx进行扩展。
  • Clustering&Datastore
    • 支持Cassandra或PostgreSQL数据库;
    • 内存级的缓存;
    • 支持水平扩展。
  • Plugins
    • 使用Lua创建插件;
    • 功能强大的定制能力;
    • 与第三方服务实现集成。
  • Restful Administration API
    • 通过Restful API管理Kong;
    • 支持CI/CD&DevOps;
    • 基于插件的可扩展。

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

实践Kong for Kubernetes

Kong之前都是使用Admin API来进行管理的,Kong主要暴露两个端口管理端口8001和代理端口8000,管理Kong主要的是为上游服务配置Service、Routes、Plugins、Consumer等实体资源,Kong按照这些配置规则进行对上游服务的请求进行路由分发和控制。在Kubernetes集群环境下,Admin API方式不是很适应Kubernetes声明式管理方式。所以Kong在Kubernetes集群环境下推出Kong Ingress Controller。Kong Ingress Controller定义了四个CRDs(CustomResourceDefinitions),基本上涵盖了原Admin API的各个方面。

  • kongconsumers:Kong的用户,给不同的API用户提供不同的消费者身份。
  • kongcredentials:Kong用户的认证凭证。
  • kongingresses:定义代理行为规则,是对Ingress的补充配置。
  • kongplugins:插件的配置。
Kong创建的CRDs:

[root@localhost konga]# kubectl get crds
NAME                                          CREATED AT
kongclusterplugins.configuration.konghq.com   2020-08-12T13:16:56Z
kongconsumers.configuration.konghq.com        2020-08-12T13:16:56Z
kongcredentials.configuration.konghq.com      2020-08-12T13:16:56Z
kongingresses.configuration.konghq.com        2020-08-12T13:16:56Z
kongplugins.configuration.konghq.com          2020-08-12T13:16:56Z

先决条件

  • Kubernetes集群:您可以使用MinikubeGKE集群。Kong与Kubernetes的所有发行版兼容。
  • kubectl访问权限:您应该已经kubectl安装并配置为与Kubernetes集群通信。

为Kubernetes安装Kong

使用以下安装方法之一安装Kong for Kubernetes:

YAML清单

要通过部署Kong kubectl,请使用:

kubectl apply -f https://bit.ly/kong-ingress-dbless

helm部署

Kong有一个官方的Helm Chart。要将Kong部署到带有Helm的Kubernetes集群上,请使用:

$ helm repo add kong https://charts.konghq.com
$ helm repo update

# Helm 2
$ helm install kong/kong

# Helm 3
$ helm install kong/kong --generate-name --set ingressController.installCRDs=false

Kustomize

可以使用Kubernetes的kustomize声明性地修补Kong的Kubernetes清单。远程定制构建的一个示例是:

kustomize build github.com/kong/kubernetes-ingress-controller/deploy/manifests/base

在Kong的存储库中可以使用Kustomization 进行不同类型的部署。

使用托管的Kubernetes云产品

如果您正在使用云提供商将Kong安装在托管的Kubernetes产品上,例如Google Kubernetes Engine(GKE),Amazon EKS(EKS),Azure Kubernetes Service(AKS)等,请确保已设置Kubernetes群集在云提供程序上,并已kubectl在您的工作站上进行了配置。

一旦您配置了Kubernetes集群并配置了kubectl,任何云提供商的安装都将使用上述方法之一(YAML manifestsHelm ChartKustomize)来安装Kong。

每个云提供商在允许如何配置特定资源(例如负载均衡器,存储卷等)方面都有一些细微的不同。我们建议您参考其文档来调整这些设置。

关于Kong的数据库使用

如果您使用的是数据库,我们建议您在Kubernetes内部以内存模式(也称为无DB)运行Kong,因为所有配置都存储在Kubernetes控制面板中。此设置简化了Kong的操作,因此无需担心数据库的设置,备份,可用性,安全性等。如果您决定使用数据库,建议您在Kubernetes之外运行数据库。您可以从云提供商使用Amazon RDS之类的服务或类似的托管Postgres服务来自动执行数据库操作。

我们不建议在Kubernetes部署中将Kong与Cassandra一起使用,因为Kong的Cassandra使用所涵盖的功能是通过Kubernetes中的其他方式处理的。

当前采用yaml清单方式实践

下载官方yaml 文件

通过浏览器打开官方下载地址https://bit.ly/kong-ingress-dbless,下载对应的yaml文件

wget https://raw.githubusercontent.com/Kong/kubernetes-ingress-controller/master/deploy/single/all-in-one-dbless.yaml

修改yaml文件

当前我们deployment配置的kong 最新版本默认没有用数据库,前面[关于kong的数据库使用]章节,我们已经说明。

当前kong:2.1,kong-ingress-controller:0.9.1版本,为适应当前环境,我们修改了如下的配置,漏掉的位置会在yaml 文件中进行标识

  1. 修改service配置为NodePort,默认是LoadBalancer
  2. 默认只开通了8444接口,对与接入不方便,修改成添加8001端口,KONG_ADMIN_LISTEN :value: 0.0.0.0:8001, 0.0.0.0:8444 ssl 参数
  3. 对应的service 里面也增加的8001端口进行对我映射

整体配置文件如下:

[root@localhost kong-gateway]# cat kong-all-in-one-dbless.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: kong
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: kongclusterplugins.configuration.konghq.com
spec:
  additionalPrinterColumns:
  - JSONPath: .plugin
    description: Name of the plugin
    name: Plugin-Type
    type: string
  - JSONPath: .metadata.creationTimestamp
    description: Age
    name: Age
    type: date
  - JSONPath: .disabled
    description: Indicates if the plugin is disabled
    name: Disabled
    priority: 1
    type: boolean
  - JSONPath: .config
    description: Configuration of the plugin
    name: Config
    priority: 1
    type: string
  group: configuration.konghq.com
  names:
    kind: KongClusterPlugin
    plural: kongclusterplugins
    shortNames:
    - kcp
  scope: Cluster
  validation:
    openAPIV3Schema:
      properties:
        config:
          type: object
        configFrom:
          properties:
            secretKeyRef:
              properties:
                key:
                  type: string
                name:
                  type: string
                namespace:
                  type: string
              required:
              - name
              - namespace
              - key
              type: object
          type: object
        disabled:
          type: boolean
        plugin:
          type: string
        protocols:
          items:
            enum:
            - http
            - https
            - grpc
            - grpcs
            - tcp
            - tls
            type: string
          type: array
        run_on:
          enum:
          - first
          - second
          - all
          type: string
      required:
      - plugin
  version: v1
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: kongconsumers.configuration.konghq.com
spec:
  additionalPrinterColumns:
  - JSONPath: .username
    description: Username of a Kong Consumer
    name: Username
    type: string
  - JSONPath: .metadata.creationTimestamp
    description: Age
    name: Age
    type: date
  group: configuration.konghq.com
  names:
    kind: KongConsumer
    plural: kongconsumers
    shortNames:
    - kc
  scope: Namespaced
  validation:
    openAPIV3Schema:
      properties:
        credentials:
          items:
            type: string
          type: array
        custom_id:
          type: string
        username:
          type: string
  version: v1
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: kongcredentials.configuration.konghq.com
spec:
  additionalPrinterColumns:
  - JSONPath: .type
    description: Type of credential
    name: Credential-type
    type: string
  - JSONPath: .metadata.creationTimestamp
    description: Age
    name: Age
    type: date
  - JSONPath: .consumerRef
    description: Owner of the credential
    name: Consumer-Ref
    type: string
  group: configuration.konghq.com
  names:
    kind: KongCredential
    plural: kongcredentials
  scope: Namespaced
  validation:
    openAPIV3Schema:
      properties:
        consumerRef:
          type: string
        type:
          type: string
      required:
      - consumerRef
      - type
  version: v1
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: kongingresses.configuration.konghq.com
spec:
  group: configuration.konghq.com
  names:
    kind: KongIngress
    plural: kongingresses
    shortNames:
    - ki
  scope: Namespaced
  validation:
    openAPIV3Schema:
      properties:
        proxy:
          properties:
            connect_timeout:
              minimum: 0
              type: integer
            path:
              pattern: ^/.*$
              type: string
            protocol:
              enum:
              - http
              - https
              - grpc
              - grpcs
              - tcp
              - tls
              type: string
            read_timeout:
              minimum: 0
              type: integer
            retries:
              minimum: 0
              type: integer
            write_timeout:
              minimum: 0
              type: integer
          type: object
        route:
          properties:
            headers:
              additionalProperties:
                items:
                  type: string
                type: array
              type: object
            https_redirect_status_code:
              type: integer
            methods:
              items:
                type: string
              type: array
            path_handling:
              enum:
              - v0
              - v1
              type: string
            preserve_host:
              type: boolean
            protocols:
              items:
                enum:
                - http
                - https
                - grpc
                - grpcs
                - tcp
                - tls
                type: string
              type: array
            regex_priority:
              type: integer
            strip_path:
              type: boolean
        upstream:
          properties:
            algorithm:
              enum:
              - round-robin
              - consistent-hashing
              - least-connections
              type: string
            hash_fallback:
              type: string
            hash_fallback_header:
              type: string
            hash_on:
              type: string
            hash_on_cookie:
              type: string
            hash_on_cookie_path:
              type: string
            hash_on_header:
              type: string
            healthchecks:
              properties:
                active:
                  properties:
                    concurrency:
                      minimum: 1
                      type: integer
                    healthy:
                      properties:
                        http_statuses:
                          items:
                            type: integer
                          type: array
                        interval:
                          minimum: 0
                          type: integer
                        successes:
                          minimum: 0
                          type: integer
                      type: object
                    http_path:
                      pattern: ^/.*$
                      type: string
                    timeout:
                      minimum: 0
                      type: integer
                    unhealthy:
                      properties:
                        http_failures:
                          minimum: 0
                          type: integer
                        http_statuses:
                          items:
                            type: integer
                          type: array
                        interval:
                          minimum: 0
                          type: integer
                        tcp_failures:
                          minimum: 0
                          type: integer
                        timeout:
                          minimum: 0
                          type: integer
                      type: object
                  type: object
                passive:
                  properties:
                    healthy:
                      properties:
                        http_statuses:
                          items:
                            type: integer
                          type: array
                        interval:
                          minimum: 0
                          type: integer
                        successes:
                          minimum: 0
                          type: integer
                      type: object
                    unhealthy:
                      properties:
                        http_failures:
                          minimum: 0
                          type: integer
                        http_statuses:
                          items:
                            type: integer
                          type: array
                        interval:
                          minimum: 0
                          type: integer
                        tcp_failures:
                          minimum: 0
                          type: integer
                        timeout:
                          minimum: 0
                          type: integer
                      type: object
                  type: object
                threshold:
                  type: integer
              type: object
            host_header:
              type: string
            slots:
              minimum: 10
              type: integer
          type: object
  version: v1
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: kongplugins.configuration.konghq.com
spec:
  additionalPrinterColumns:
  - JSONPath: .plugin
    description: Name of the plugin
    name: Plugin-Type
    type: string
  - JSONPath: .metadata.creationTimestamp
    description: Age
    name: Age
    type: date
  - JSONPath: .disabled
    description: Indicates if the plugin is disabled
    name: Disabled
    priority: 1
    type: boolean
  - JSONPath: .config
    description: Configuration of the plugin
    name: Config
    priority: 1
    type: string
  group: configuration.konghq.com
  names:
    kind: KongPlugin
    plural: kongplugins
    shortNames:
    - kp
  scope: Namespaced
  validation:
    openAPIV3Schema:
      properties:
        config:
          type: object
        configFrom:
          properties:
            secretKeyRef:
              properties:
                key:
                  type: string
                name:
                  type: string
              required:
              - name
              - key
              type: object
          type: object
        disabled:
          type: boolean
        plugin:
          type: string
        protocols:
          items:
            enum:
            - http
            - https
            - grpc
            - grpcs
            - tcp
            - tls
            type: string
          type: array
        run_on:
          enum:
          - first
          - second
          - all
          type: string
      required:
      - plugin
  version: v1
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tcpingresses.configuration.konghq.com
spec:
  additionalPrinterColumns:
  - JSONPath: .status.loadBalancer.ingress[*].ip
    description: Address of the load balancer
    name: Address
    type: string
  - JSONPath: .metadata.creationTimestamp
    description: Age
    name: Age
    type: date
  group: configuration.konghq.com
  names:
    kind: TCPIngress
    plural: tcpingresses
  scope: Namespaced
  subresources:
    status: {}
  validation:
    openAPIV3Schema:
      properties:
        apiVersion:
          type: string
        kind:
          type: string
        metadata:
          type: object
        spec:
          properties:
            rules:
              items:
                properties:
                  backend:
                    properties:
                      serviceName:
                        type: string
                      servicePort:
                        format: int32
                        type: integer
                    type: object
                  host:
                    type: string
                  port:
                    format: int32
                    type: integer
                type: object
              type: array
            tls:
              items:
                properties:
                  hosts:
                    items:
                      type: string
                    type: array
                  secretName:
                    type: string
                type: object
              type: array
          type: object
        status:
          type: object
  version: v1beta1
status:
  acceptedNames:
    kind: ""
    plural: ""
  conditions: []
  storedVersions: []
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kong-serviceaccount
  namespace: kong
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: kong-ingress-clusterrole
rules:
- apiGroups:
  - ""
  resources:
  - endpoints
  - nodes
  - pods
  - secrets
  verbs:
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.io
  - extensions
  - networking.internal.knative.dev
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - events
  verbs:
  - create
  - patch
- apiGroups:
  - networking.k8s.io
  - extensions
  - networking.internal.knative.dev
  resources:
  - ingresses/status
  verbs:
  - update
- apiGroups:
  - configuration.konghq.com
  resources:
  - tcpingresses/status
  verbs:
  - update
- apiGroups:
  - configuration.konghq.com
  resources:
  - kongplugins
  - kongclusterplugins
  - kongcredentials
  - kongconsumers
  - kongingresses
  - tcpingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - configmaps
  verbs:
  - create
  - get
  - update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: kong-ingress-clusterrole-nisa-binding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kong-ingress-clusterrole
subjects:
- kind: ServiceAccount
  name: kong-serviceaccount
  namespace: kong
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
  name: kong-proxy
  namespace: kong
spec:
  ports:
  - name: proxy
    port: 80
    protocol: TCP
    targetPort: 8000
  - name: proxy-ssl
    port: 443
    protocol: TCP
    targetPort: 8443
  - name: kong-admin
    port: 8001
    protocol: TCP
    targetPort: 8001
  - name: kong-admin-ssl
    port: 8444
    protocol: TCP
    targetPort: 8444
  selector:
    app: ingress-kong
  type: NodePort
---
apiVersion: v1
kind: Service
metadata:
  name: kong-validation-webhook
  namespace: kong
spec:
  ports:
  - name: webhook
    port: 443
    protocol: TCP
    targetPort: 8080
  selector:
    app: ingress-kong
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: ingress-kong
  name: ingress-kong
  namespace: kong
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ingress-kong
  template:
    metadata:
      annotations:
        kuma.io/gateway: enabled
        prometheus.io/port: "8100"
        prometheus.io/scrape: "true"
        traffic.sidecar.istio.io/includeInboundPorts: ""
      labels:
        app: ingress-kong
    spec:
      containers:
      - env:
        - name: KONG_PROXY_LISTEN
          value: 0.0.0.0:8000, 0.0.0.0:8443 ssl http2
        - name: KONG_ADMIN_LISTEN
          value: 0.0.0.0:8001, 0.0.0.0:8444 ssl
        - name: KONG_STATUS_LISTEN
          value: 0.0.0.0:8100
        - name: KONG_DATABASE
          value: "off"
        - name: KONG_NGINX_WORKER_PROCESSES
          value: "1"
        - name: KONG_ADMIN_ACCESS_LOG
          value: /dev/stdout
        - name: KONG_ADMIN_ERROR_LOG
          value: /dev/stderr
        - name: KONG_PROXY_ERROR_LOG
          value: /dev/stderr
        image: kong:2.1
        lifecycle:
          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - kong quit
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /status
            port: 8100
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: proxy
        ports:
        - containerPort: 8000
          name: proxy
          protocol: TCP
        - containerPort: 8443
          name: proxy-ssl
          protocol: TCP
        - containerPort: 8100
          name: metrics
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /status
            port: 8100
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        securityContext:
          runAsUser: 1000
      - env:
        - name: CONTROLLER_KONG_ADMIN_URL
          value: https://127.0.0.1:8444
        - name: CONTROLLER_KONG_ADMIN_TLS_SKIP_VERIFY
          value: "true"
        - name: CONTROLLER_PUBLISH_SERVICE
          value: kong/kong-proxy
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        image: kong-docker-kubernetes-ingress-controller.bintray.io/kong-ingress-controller:0.9.1
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: ingress-controller
        ports:
        - containerPort: 8080
          name: webhook
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
      serviceAccountName: kong-serviceaccount

执行该yaml 文件

[root@localhost kong-gateway]# kubectl apply -f all-in-one-dbless.yaml
namespace/kong created
customresourcedefinition.apiextensions.k8s.io/kongclusterplugins.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongconsumers.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongcredentials.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongingresses.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongplugins.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/tcpingresses.configuration.konghq.com created
serviceaccount/kong-serviceaccount created
clusterrole.rbac.authorization.k8s.io/kong-ingress-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/kong-ingress-clusterrole-nisa-binding created
service/kong-proxy created
service/kong-validation-webhook created
deployment.apps/ingress-kong created

查看启动情况

[root@localhost kong-gateway]# kubectl get po -n kong -l app=ingress-kong
NAME                            READY   STATUS    RESTARTS   AGE
ingress-kong-5f8b45fbff-4cdtv   2/2     Running   2          20m
ingress-kong-5f8b45fbff-mkkq9   2/2     Running   2          20m
ingress-kong-5f8b45fbff-qt8tw   2/2     Running   1          12h
[root@localhost kong-gateway]# kubectl get svc -n kong
NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                    AGE
service/kong-proxy                NodePort    10.97.22.195    <none>        80:32284/TCP,443:32083/TCP,8001:32704/TCP,8444:30658/TCP   39h
service/kong-validation-webhook   ClusterIP   10.101.75.177   <none>        443/TCP

开放kong-proxy对外8001接口ingress配置文件

当前配置文件时为了开放kong-proxy-admin的接口,可以让用户使用ingress域名进行访问,限制kong admin管理接口为8001和8443

[root@localhost kong-gateway]# cat kong-proxy-admin.ingress-demo.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  labels:
    ingresscontroller: kong
  annotations:
    kubernetes.io/ingress.class: kong
  name: kong-proxy
  namespace: kong
spec:
  rules:
  - host: kong-proxy-admin.mydomain.com
    http:
      paths:
      - backend:
          serviceName: kong-proxy
          servicePort: 8001
        path: /

[root@localhost kong-gateway]# kubectl get ing -n kong
kong-proxy   <none>   kong-proxy-admin.mydomain.com   172.18.0.2   80      10h

[root@localhost kong-gateway]# kubectl describe  ing -n kong kong-proxy
Name:             kong-proxy
Namespace:        kong
Address:          172.18.0.2
Default backend:  default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
  Host                           Path  Backends
  ----                           ----  --------
  kong-proxy-admin.mydomain.com
                                 /   kong-proxy:8001 (10.244.0.20:8001,10.244.0.21:8001,10.244.0.22:8001)
Annotations:                     kubernetes.io/ingress.class: kong
Events:                          <none>

安装Konga 管理UI

Kong 企业版提供了管理UI,开源版本是没有的。但是有很多的开源的管理 UI ,其中比较好用的是Konga。项目地址:https://github.com/pantsel/konga

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

Konga 特性

Konga 主要是用 AngularJS 写的,运行于nodejs服务端。具有以下特性:

  • 管理所有Kong Admin API对象。
  • 支持从远程源(数据库,文件,API等)导入使用者。
  • 管理多个Kong节点。使用快照备份,还原和迁移Kong节点。
  • 使用运行状况检查监视节点和API状态。
  • 支持电子邮件和闲置通知。
  • 支持多用户。
  • 易于数据库集成(MySQL,postgresSQL,MongoDB,SQL Server)。

Kubernetes安装Konga数据库postgres

  1. 我们今天通过Kubernetes来安装Konga。安装步骤同样遵循先配置postgres数据库,初始化数据库,启动容器的流程

  2. 第二步配置konga 容器,然后连接postgres数据库,启动konga

  3. 配置konga连接kong admin 8001或者8444端口,配置kong的参数

Kubernetes 部署 Konga数据库容器postgres

要在Kubernetes上部署PostgreSQL,我们需要遵循以下步骤:

  • Postgres Docker映像
  • 用于存储Postgres配置的配置映射
  • 永久存储量
  • PostgreSQL部署
  • PostgreSQL服务

PostgreSQL Docker映像

我们正在使用公共注册表中的PostgreSQL 10.4 Docker映像。该映像将提供提供PostgreSQL自定义配置/环境变量(如用户名,密码,数据库名称和路径等)的功能。

PostgreSQL配置的配置映射

我们将使用配置映射来存储PostgreSQL相关信息。在这里,我们在配置映射中使用数据库,用户和密码,部署模板中的PostgreSQL pod将使用该数据库,用户和密码。

文件:postgres-configmap.yaml

[root@localhost postgres]# cat postgres-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  namespace: kong
  labels:
    app: postgres
data:
  POSTGRES_DB: postgresdb
  POSTGRES_USER: admin
  POSTGRES_PASSWORD: admin

创建Postgres配置资源

$ kubectl create -f postgres-configmap.yaml

永久存储量StorageClass

众所周知,容器本质上是短暂的。容器实例终止后,由容器或容器中生成的所有数据都将丢失。

为了保存数据,我们将在Kubernetes中使用持久卷和持久卷声明资源将数据存储在持久存储中。

当前我们配置了StorageClass 动态存储使用,会在下面进行调用,不过配置Deployment模式不支持直接挂载StorageClass ,需要将控制器修改成StatefulSet 模式进行挂载。

PostgreSQL部署

用于部署PostgreSQL容器的PostgreSQL清单使用PostgreSQL 10.4映像。它使用的是PostgreSQL配置,例如用户名,密码和我们之前创建的configmap中的数据库名。它还会挂载从持久卷创建的卷,并声明使PostgreSQL容器的数据持久化。

[root@localhost postgres]# cat postgres-statefulSet.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: kong
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:10.4
          imagePullPolicy: "IfNotPresent"
          ports:
            - containerPort: 5432
          envFrom:
            - configMapRef:
                name: postgres-config
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgredb
  volumeClaimTemplates:
  - metadata:
      name: postgredb
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi
      storageClassName: "standard"

创建Postgres部署

$ kubectl create -f postgres-deployment.yaml

PostgreSQL Service

要访问部署或容器,我们需要配置PostgreSQL服务。Kubernetes提供了不同类型的服务,例如ClusterIP,NodePort和LoadBalancer。

使用ClusterIP,我们可以在Kubernetes中访问PostgreSQL服务。NodePort可以在Kubernetes节点上公开服务端点。为了从外部访问PostgreSQL,我们需要使用Load Balancer服务类型,该服务类型可以在外部公开该服务。

文件:postgres-service.yaml

[root@localhost postgres]# cat postgres-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: kong
  labels:
    app: postgres
spec:
  type: NodePort
  ports:
   - port: 5432
  selector:
   app: postgres

创建Postgres服务

$ kubectl create -f postgres-service.yaml

连接到PostgreSQL

为了连接PostgreSQL,我们需要从服务部署中获取Node端口。

[root@localhost postgres]# kubectl get svc postgres -n kong
NAME       TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
postgres   NodePort   10.98.211.186   <none>        5432:30761/TCP   14h

我们需要使用端口31070从kubernetes集群中存在的机器/节点连接到PostgreSQL,并使用前面configmap中给出的凭据。

$ psql -h localhost -U admin --password -p 30761 postgresdb
# 通过psql 命令进行连接

PostgreSQL结论

与仅使用虚拟机时相比,在Kubernetes上运行PostgreSQL有助于以更好的方式利用资源。Kubernetes还使用同一虚拟机或Kubernetes集群中的PostgreSQL提供其他应用程序的隔离。

是否可以使用StatefulSets吗?

在Kubernetes中,需要StatefulSets来扩展有状态的应用程序。可以使用StatefulSets通过单个命令轻松扩展PostgreSQL。

Kubernetes安装Konga

  1. 我们今天通过Kubernetes来安装Konga。安装步骤同样遵循先配置postgres数据库,初始化数据库,启动容器的流程

  2. 第二步配置konga 容器,然后连接postgres数据库,启动konga

  3. 配置konga连接kong admin 8001或者8444端口,配置kong的参数

配置konga Secret加密信息

创建配置konga Secret加密信息连接PostgreSQL数据库。

[root@localhost konga]# cat konga-creds.yaml
apiVersion: v1
kind: Secret
metadata:
  name: kongcreds
  namespace: kong
type: Opaque
data:
  username: YWRtaW4=
  password: YWRtaW4=
  postgresdbname: cG9zdGdyZXNkYg==
#your secret in base64 echo -n 'admin' | base64 YWRtaW4=

[root@localhost konga]# kubectl get secret -n kong
NAME                              TYPE                                  DATA   AGE
kongcreds                         Opaque                                3      26h

配置konga Deployment Pod

通过Konga Deployment 引用secret 配置文件,同时在配置连接地址时,设置成service 内部dns 域名连接,具体配置文件如下:

[root@localhost konga]# cat konga-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: konga
  namespace: kong
spec:
  replicas: 1
  selector:
    matchLabels:
      app: konga
  template:
    metadata:
      labels:
        name: konga
        app: konga
    spec:
      containers:
      - name: konga
        image: pantsel/konga:latest
        env:
        - name: DB_ADAPTER
          value: postgres
        - name: DB_HOST
          value: postgres.kong.svc.cluster.local.
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: kongcreds
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: kongcreds
              key: password
        - name: DB_DATABASE
          value: postgresdb
        - name: TOKEN_SECRET
          value: somesecretstring
        ports:
        - containerPort: 1337
          protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: konga
  name: konga-svc
  namespace: kong
spec:
  ports:
    - protocol: TCP
      port: 443
      targetPort: 1337
  selector:
    app: konga

配置konga Ingress 域名对外

[root@localhost konga]# cat konga-admin-ingress-demo.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  labels:
    ingresscontroller: kong
  annotations:
    kubernetes.io/ingress.class: kong
  name: kong-admin
  namespace: kong
spec:
  rules:
  - host: konga-admin.mydomain.com
    http:
      paths:
      - backend:
          serviceName: konga-svc
          servicePort: 443
        path: /

测试访问konga 页面

通过Ingress 域名 konga-admin.mydomain.com访问,首先会进行管理员账号和密码创建,然后进入Connections 界面 连接对应kong节点。

  1. 登入Konga 界面

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

  1. 创建一个新的Kong 节点连接

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

  1. 创建成功之后点击连接

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

  1. 连接成功之后,可以看到整体的kong节点的配置和概况

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

  1. 因为我之前创建了两个Ingress 映射域名,所以在konga service选项和Routes选项会展示出来

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

[Kong 与 Konga 与 Postgres数据库] 之 Kuberneres 部署-LMLPHP

  1. 配置好konga管理后台之后,我们可以通过konga 后台直接对kong进行管理,图形化界面创建Service和Routes 或者其他功能和参数的修改,都可以在konga web 界面进行操作。本章到这里也就告一段落了,后面我会介绍下关于kong节点的配置文件。

Kong API Gateway 配置文件详解

两个主要组件

  • Kong Server,基于 nginx 的服务器,用来接收 API 请求。下面主要是对配置文件进行详解。后面也可以通过Kong API Gateway 管理API详解,对kong进行操作。Kong 功能强大注意还是因为它支持强大的插件功能。
  • Apache Cassandra,用来存储操作数据。

一、前言

Kong配置文件是Kong服务的核心文件,它配置了Kong以怎么的方式运行,并且依赖于这个配置生成Nginx的配置文件,本文通过解读Kong配置文件,以了解Kong的运行和配置。

在成功安装Kong以后,会有一个名为kong.conf.default默认的配置文件示例,如果是通过包管理器安装的,通常位于/etc/kong/kong.conf.default,我们要将其复制为kong.conf以便于我们修改使用他。

在Kong的配置文件中,约定了以下的几条规则:

  • 配置文件中以#开头的行均为注释行,程序不会读取这些内容。
  • 在官方提供的默认配置文件中,以#开头的有值的配置项目均为默认配置。
  • 所有的配置项,均可以在系统环境变量中配置,但是必须要加上KONG_为前缀。
  • 值为布尔型的配置,可以使用on/off或者true/false
  • 值为列表的,必须使用半角逗号分割。

Kong的配置,大概分为几种,分别是:

  • 常规配置:配置服务运行目录,插件加载,日志等等
  • NGINX配置:配置Nginx注入,例如监听IP和端口配置等等,用于Kong在启动的时候生成Nginx配置文件
  • 数据库存储配置:配数据库类型,地址、用户名密码等等信息
  • 数据库缓存配置:配置数据的缓存规则,Kong会缓存诸如API信息、用户、凭证等信息,以减少访问数据库次数提高性能
  • DNS解析器配置:默认情况会使用系统设置,如hostsresolv.conf的配置,你也可以通过DNS的解析器配置来修改
  • 其他杂项配置:继承自lua-nginx模块的其他设置允许更多的灵活性和高级用法。

下面我们一个模块一个模块解释一下各项的配置。

二、常规配置

在常规配置中,主要是控制Kong一些运行时的一些配置,主要有如下配置:

在常规的配置中,主要配置了Kong运行的目录日志等信息。

无论如何,配置的文件或者目录Kong必须要用权限访问,否则会报错。

三、Nginx注入配置

Kong基于Nginx,当然需要配置Nginx来满足Kong的运行要求,Kong提供了Nginx的注入配置,使得我们更轻松控制。

在Nginx注入配置中,有如下配置:

在Nginx注入配置中,配置了Nginx的基本的参数,这些参数大部分和NGINX的配置值是一样的,可以通过Nginx的配置文档了解一下。

四、 数据库存储配置

数据库配置的模块配置数据库相关的连接信息等等。主要有如下配置:

五、 数据库缓存配置

在上一节中,配置了Kong持久化存储,显然如果每次的请求都需要去查询数据库中的相关信息那无疑是非常消耗资源,性能和稳定性也会大大降低,作为一个API网关肯定是不能忍的,解决这个问题的办法就是缓存,Kong将数据缓存在内存中,这样会大大提高性能,本节介绍Kong的缓存配置。

六、 DNS解析器配置

默认情况下,DNS解析器将使用标准配置文件/etc/hosts/etc/resolv.conf。如果设置了环境变量LOCALDOMAINRES_OPTIONS,那么后一个文件中的设置将被覆盖。

在DNS配置中,我们基本上不需要更改,官网的配置给出了最优的配置。如果我们需要在host文件中定义后端绑定的域名,一定要在编辑hosts文件后重载Kong的配置,或者重启Kong,无论hosts的文件是否是/etc/hosts,否则都不会生效的。

七、 其他杂项配置

杂项配置基本上关于LUA的配置,如果不熟悉请不要修改,按照官方默认即可。

Kong基本功能说明

基础功能(konga为例)

应用级菜单

  1. Connections Kong连接,用于配置Kong的AdminAPI地址,配置成功之后,将会开启Kong级菜单。
  2. Snapshots 快照,用于存储Kong节点快照,可快速恢复节点配置。

API网关菜单

  1. Consumers API网关消费者,用于各类认证以及限流控制等;
  2. Services 服务,用于配置上游服务的信息,主要包括服务名称、上游的Host以及Port等;
  3. Routes 路由,用于配置下游的路由信息,定义服务的出口路径,主要包括路由名称、Host、Path、Methods以及Http/Https等;
  4. Plugins 插件,可配置于Service或Route,主要包括认证、安全、限流、监控、日志以及自定义几大模块,官方提供了较为全面的基础插件功能;
  5. Upstreams 类nginx中的Upstream,用于配置上游的服务信息;
  6. Certificates 证书管理。

服务配置

1.添加服务: Services -> Create Services 实例:

说明:由于这里的Kong部署在K8S环境中,所以可以直接使用K8S中的服务名+端口号来定义服务的Host和Port。

2.添加路由: Services -> Service Detail -> Routes -> Add Route 实例:

配置完成之后,我们就可以访问我们的服务了。

# https://192.168.0.231:31617/config 或 http://192.168.0.231:32740/config Host: config.kong
> curl -ik -H "Host":"config.kong" https://192.168.0.231:31617/config/basic/dev
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Thu, 17 Oct 2019 02:05:16 GMT
Server: Kestrel
X-Kong-Upstream-Latency: 3
X-Kong-Proxy-Latency: 10007
Via: kong/1.3.0

{"logLevel":"Debug",...}
复制代码

插件配置

插件添加有两个入口: 1.服务插件 Servcies -> Service Detail -> Plugins -> Add Plugin 2.路由插件 Routes -> Route Detail -> Plugins -> Add Plugin

认证

 1.Basic 认证
 Header: Authorization Basic base64(username:password)

 2.Jwt认证
 支持三种认证参数传递:uri param,cookie and header,可自定义键名
 key claim一般为iss
 jwt生成 & 校验:https://jwt.io/

 3.OAuth2认证
 认证地址:oauth2/authorize
 获取token地址: oauth2/token
 刷新token地址: oauth2/token

安全

 1. Acl 访问控制列表
 2. Cors  跨域资源共享
 3. Ip Restriction IP限制
 4. Bot Detection 机器人检测

限流

 1. Rate Limiting 速率限制
 2. Response Ratelimiting 响应速率限制
 3. Request Size Limiting  请求大小限制
 4. Request Termination 请求阻断/终止

日志

监控

请求转发

自定义

Kong Admin API

AdminAPI

感谢参考

AdminAPI

shoy160

kirito-moe

非学无以广才

https://linuxops.org/blog/kong/admin.html

https://blog.csdn.net/twingao/article/details/104073289

08-14 23:47