Kubernetes

    Discovery also provides a node query interface in accordance with the .

    Kubernetes service discovery both support single-cluster and multi-cluster mode, applicable to the case where the service is distributed in a single or multiple Kubernetes clusters.

    A detailed configuration for single-cluster mode Kubernetes service discovery is as follows:

    If the Kubernetes service discovery runs inside a pod, you can use minimal configuration:

    1. discovery:
    2. kubernetes: { }

    If the Kubernetes service discovery runs outside a pod, you need to create or select a specified ServiceAccount, then get its token value, and use following configuration:

    1. discovery:
    2. kubernetes:
    3. service:
    4. schema: https
    5. host: # enter apiserver host value here
    6. port: # enter apiserver port value here
    7. client:
    8. token: # enter serviceaccount token value here
    9. #token_file: # enter file path here

    The Kubernetes service discovery provides a query interface in accordance with the APISIX Discovery Specification.

    function: nodes(service_name)

    description: nodes() function attempts to look up the ngx.shared.DICT for nodes corresponding to servicename, \ service_name should match pattern: [namespace]/[name]:[portName]_

    • namespace: The namespace where the Kubernetes endpoints is located

    • name: The name of the Kubernetes endpoints

    • portName: The ports.name value in the Kubernetes endpoints, if there is no ports.name, use targetPort, port instead

    a nodes(“default/plat-dev:port”) call will get follow result:

    1. {
    2. {
    3. host="10.5.10.109",
    4. port= 3306,
    5. weight= 50,
    6. },
    7. {
    8. host="10.5.10.110",
    9. port= 3306,
    10. weight= 50,
    11. },
    12. }

    A detailed configuration for multi-cluster mode Kubernetes service discovery is as follows:

    1. discovery:
    2. kubernetes:
    3. - id: release # a custom name refer to the cluster, pattern ^[a-z0-9]{1,8}
    4. service:
    5. # apiserver schema, options [http, https]
    6. schema: https #default https
    7. # apiserver host, options [ipv4, ipv6, domain, environment variable]
    8. host: "1.cluster.com"
    9. port: "6443"
    10. client:
    11. # serviceaccount token or token_file
    12. #token: |-
    13. # eyJhbGciOiJSUzI1NiIsImtpZCI6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEif
    14. # 6Ikx5ME1DNWdnbmhQNkZCNlZYMXBsT3pYU3BBS2swYzBPSkN3ZnBESGpkUEEifeyJhbGciOiJSUzI1NiIsImtpZCI
    15. default_weight: 50 # weight assigned to each discovered endpoint. default 50, minimum 0
    16. # kubernetes discovery support namespace_selector
    17. # you can use one of [equal, not_equal, match, not_match] filter namespace
    18. namespace_selector:
    19. # only save endpoints with namespace equal default
    20. equal: default
    21. # only save endpoints with namespace not equal default
    22. #not_equal: default
    23. # only save endpoints with namespace match one of [default, ^my-[a-z]+$]
    24. #match:
    25. #- default
    26. #- ^my-[a-z]+$
    27. # only save endpoints with namespace not match one of [default, ^my-[a-z]+$]
    28. #not_match:
    29. #- default
    30. #- ^my-[a-z]+$
    31. # kubernetes discovery support label_selector
    32. # for the expression of label_selector, please refer to https://kubernetes.io/docs/concepts/overview/working-with-objects/labels
    33. label_selector: |-
    34. first="a",second="b"
    35. # reserved lua shared memory size,1m memory can store about 1000 pieces of endpoint
    36. shared_size: 1m #default 1m

    Multi-Kubernetes service discovery does not fill default values for service and client fields, you need to fill them according to the cluster configuration.

    The Kubernetes service discovery provides a query interface in accordance with the .

    function: nodes(service_name)

    description: nodes() function attempts to look up the ngx.shared.DICT for nodes corresponding to servicename, \ service_name should match pattern: [id]/[namespace]/[name]:[portName]_

    • id: value defined in service discovery configuration

    • namespace: The namespace where the Kubernetes endpoints is located

    • name: The name of the Kubernetes endpoints

    • portName: The ports.name value in the Kubernetes endpoints, if there is no ports.name, use targetPort, port instead

    return value: if the Kubernetes endpoints value is as follows:

    1. {
    2. host="10.5.10.109",
    3. port= 3306,
    4. weight= 50,
    5. {
    6. host="10.5.10.110",
    7. port= 3306,
    8. weight= 50,
    9. },
    10. }

    Q: Why only support configuration token to access Kubernetes APIServer?

    A: Usually, we will use three ways to complete the authentication of Kubernetes APIServer:

    • mTLS
    • Token
    • Basic authentication

    Because lua-resty-http does not currently support mTLS, and basic authentication is not recommended, so currently only the token authentication method is implemented.

    Q: APISIX inherits Nginx’s multiple process model, does it mean that each nginx worker process will kubernetes endpoints resources?

    A: The Kubernetes service discovery only uses privileged processes to List-Watch Kubernetes endpoints resources, then store theirs value into ngx.shared.DICT, worker processes get results by querying ngx.shared.DICT.

    Q: What permissions do require?

    A: ServiceAccount requires the permissions of cluster-level [ get, list, watch ] endpoints resources, the declarative definition is as follows:

    1. kind: ServiceAccount
    2. apiVersion: v1
    3. metadata:
    4. name: apisix-test
    5. namespace: default
    6. ---
    7. kind: ClusterRole
    8. apiVersion: rbac.authorization.k8s.io/v1
    9. metadata:
    10. name: apisix-test
    11. rules:
    12. - apiGroups: [ "" ]
    13. resources: [ endpoints ]
    14. verbs: [ get,list,watch ]
    15. ---
    16. apiVersion: rbac.authorization.k8s.io/v1
    17. kind: ClusterRoleBinding
    18. metadata:
    19. name: apisix-test
    20. roleRef:
    21. apiGroup: rbac.authorization.k8s.io
    22. kind: ClusterRole
    23. name: apisix-test
    24. subjects:
    25. - kind: ServiceAccount
    26. name: apisix-test
    27. namespace: default

    Q: How to get ServiceAccount token value?

    A: Assume your located in namespace apisix and name is Kubernetes-discovery, you can use the following steps to get token value.

    1. Get secret name. You can execute the following command, the output of the first column is the secret name we want: