This is an automated email from the ASF dual-hosted git repository. kvn pushed a commit to branch kv/docs in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git
commit 4b4fd103ed93e13ae90b54a0339884970158cadd Author: kv <[email protected]> AuthorDate: Sat Dec 5 15:15:18 2020 +0800 feat: add usage and design docs --- .DS_Store | Bin 0 -> 6148 bytes README.md | 7 +- docs/.DS_Store | Bin 0 -> 6148 bytes docs/design.md | 91 ++++++++++++++++++++- docs/images/diff-flow.png | Bin 0 -> 567116 bytes docs/images/first.png | Bin 0 -> 417922 bytes docs/images/hierarchical.png | Bin 0 -> 233974 bytes docs/images/module-1.png | Bin 0 -> 484116 bytes docs/images/scene.png | Bin 0 -> 1106847 bytes docs/images/struct-compare.png | Bin 0 -> 4306037 bytes docs/usage.md | 175 +++++++++++++++++++++++++++++++++++++++++ 11 files changed, 268 insertions(+), 5 deletions(-) diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..e30cd8a Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index 97b3c1f..0296a58 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ kubectl apply -f samples/deploy/configmap/cloud.yaml ### Deploy ingress controller -[How to build image from master branch?](# Master branch builds) +[How to build image from master branch?](#Master-branch-builds) ```shell kubectl apply -f samples/deploy/deployment/ingress-controller.yaml @@ -145,6 +145,11 @@ kubectl apply -f samples/deploy/deployment/ingress-controller.yaml docker build -t apache/ingress-controller:v0.1.0 . ``` +## User stories + +- [aispeech: Why we create a new k8s ingress controller?(Chinese)](https://mp.weixin.qq.com/s/bmm2ibk2V7-XYneLo9XAPQ) +- [Tencent Cloud: Why choose Apache APISIX to implement the k8s ingress controller?(Chinese)](https://www.upyun.com/opentalk/448.html) + ## Seeking help - Mailing List: Mail to [email protected], follow the reply to subscribe the mailing list. diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000..cfe3975 Binary files /dev/null and b/docs/.DS_Store differ diff --git a/docs/design.md b/docs/design.md index 9a512a5..01dea00 100644 --- a/docs/design.md +++ b/docs/design.md @@ -2,9 +2,9 @@ Apache APISIX ingress for Kubernetes. -## Design +## Modules - + ### 1.Ingress-types @@ -36,6 +36,89 @@ Apache APISIX ingress for Kubernetes. - match and covert Apisix-ingress-types to Apisix-types before handing the control over to the above module seven; -## Sequence Diagram +## CRD design - +Currently `apisix-ingress-controller` CRDs consist of 3 parts: ApisixRoute/ApisixService/ApisixUpstream. The design follows the following ideas. + +1. The most important part of the gateway is the routing part, which is used to define the distribution rules of the gateway traffics. +2. In order to facilitate understanding and configuration, the design structure of `ApisixRoute` is basically similar to Kubernetes Ingress. +3. In the design of annotation, the structure of Kubernetes Ingress is used for reference, but the internal implementation is based on the plug-in of Apache APISIX. +4. Both `ApisixRoute` and `ApisixService` can be bound to plug-ins, which is consistent with Apache APISIX. +5. In the simplest case, you only need to define `ApisixRoute`, and the Ingress controller will automatically add `ApisixService` and `ApisixUpstream`. +6. `ApisixService`, like Apache APISIX service, is a grouping of routes, which can simplify the configuration complexity of the same plug-in. +7. `ApisixUpstream` can define some details on Apache APISIX upstream, such as load balancing/health check, etc. + +## Monitoring CRDs + +`apisix-ingress-controller` is responsible for interacting with the Kubernetes Apiserver, applying for accessible resource permissions (RBAC), monitoring changes, and implementing object conversion within the Ingress controller, comparing the changes, and then synchronizing to Apache APISIX. + +### Timing diagram + + + +### Conversion structure + +`apisix-ingress-controller` provides external configuration methods for CRDs. It is aimed at operators such as daily operation and maintenance, who often need to process a large number of routes in batches, hoping to handle all related services in the same configuration file, and at the same time have convenient and understandable management capabilities. Apache APISIX is designed from the perspective of the gateway, and all routes are independent. This leads to obvious differences in th [...] + +Taking into account the usage habits of different groups of people, the data structure of CRDs draws on the data structure of Kubernetes Ingress, and is basically the same in shape. + +A simple comparison is as follows, they have different definitions: + + + +They are a many-to-many relationship.Therefore, `apisix-ingress-controller` has to do some conversion of CRDs to adapt to different gateways. + +### Cascade update + +At present, we have defined multiple CRDs, and these CRDs are responsible for the definition of their respective fields. `ApisixRoute`/ `ApisixService` / `ApisixUpstream` correspond to objects such as `route`/ `service` / `upstream` in Apache APISIX. As the strong binding relationship between APISIX objects, when modifying and deleting batch data structures such as CRDs, you have to consider the impact of cascading between objects. + +So, in `apisix-ingress-controller`, a broadcast notification mechanism is designed through `channel`, that is, the definition of any object must be notified to other objects related to it and trigger the corresponding behavior. + + + +In a typical scenario, there is a many-to-many relationship between `ApisixRoute` and `ApisixService`, and a one-to-one relationship between `ApisixService` and `ApisixUpstream`. + +* When the `ApisixService` changes, it needs to be notified upwards to the `ApisixRoute`, and also needs to be notified downwards to the corresponding `ApisixUpstream`. +* When one of the `http-route` in `ApisixRoute` changes, the relevant `ApisixService` and `ApisixUpstream` need to be notified. + +This is particularly prominent in `modify` and `delete`. + +**We can initiate discussions in this area and propose a more reasonable design plan** + +### Diff rules + +The `seven` module internally saves memory data structures, which is currently very similar to the Apache Apisix resource object. When the Kubernetes resource object is newly changed, `seven` will compare the memory objects and update incrementally according to the result of the comparison. + +The current comparison rule is based on the grouping of `route` / `service` / `upstream` resource objects, compare them separately, and make corresponding broadcast notifications after finding the differences. + + + +### Service Discovery + +According to the `namespace` `name` `port` defined in the `ApisixUpstream` resource object, `apisix-ingress-controller` will register the `endpoints` node information in the `running` state to the nodes in Apache APISIX Upstream. And according to Kubernetes Endpoint status is synchronized in real time. + +Based on service discovery, Apache APISIX Ingress can directly access back-end Pod nodes. Bypassing Kubernetes Service, it is possible to implement customized load balancing strategies. + +### Annotation implementation + +Unlike the implementation of Kubernetes Nginx Ingress, the implementation of Annotation by `apisix-ingress-controller` is based on the plug-in mechanism of Apache APISIX. + +For example, the settings of the black and white list can be configured through the `k8s.apisix.apache.org/whitelist-source-range` annotation in the `ApisixRoute` resource object. + +```yaml +apiVersion: apisix.apache.org/v1 +kind: ApisixRoute +metadata: + annotations: + k8s.apisix.apache.org/whitelist-source-range: 1.2.3.4,2.2.0.0/16 + name: httpserver-route + namespace: cloud +spec: + ... +``` + +The black and white list here is implemented by the `ip-restriction` plugin. + +There will be more annotation implementations in the future to facilitate the definition of some common configurations, such as CORS. + +If you have some annotation needs, welcome to [issue](https://github.com/apache/apisix-ingress-controller/issues) to discuss, let’s discuss how to implement it. diff --git a/docs/images/diff-flow.png b/docs/images/diff-flow.png new file mode 100644 index 0000000..d2a5c4d Binary files /dev/null and b/docs/images/diff-flow.png differ diff --git a/docs/images/first.png b/docs/images/first.png new file mode 100644 index 0000000..134cebb Binary files /dev/null and b/docs/images/first.png differ diff --git a/docs/images/hierarchical.png b/docs/images/hierarchical.png new file mode 100644 index 0000000..789be1f Binary files /dev/null and b/docs/images/hierarchical.png differ diff --git a/docs/images/module-1.png b/docs/images/module-1.png new file mode 100644 index 0000000..318708d Binary files /dev/null and b/docs/images/module-1.png differ diff --git a/docs/images/scene.png b/docs/images/scene.png new file mode 100644 index 0000000..bcc5444 Binary files /dev/null and b/docs/images/scene.png differ diff --git a/docs/images/struct-compare.png b/docs/images/struct-compare.png new file mode 100644 index 0000000..701cf8a Binary files /dev/null and b/docs/images/struct-compare.png differ diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..a90031c --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,175 @@ +# Usage of Ingress controller + +In this article, we will use ingress controller CRDs (CustomResourceDefinition) to define routing rules against the admin api of Apache APISIX. + +## Scenes + +Configure a simple routing rule through the ingress controller CRDs. After synchronizing to the gateway, the data traffic is accessed to the back-end service through Apache APISIX. Then, we gradually add or remove plug-ins to the routing to achieve functional expansion. + +As shown below. + + + +## A simple example + +Define the simplest route to direct traffic to the back-end service, the back-end service is named `httpserver`. + +When using admin api, we define as below. + +```shell +# 1. Define upstream: foo-upstream id=1 +curl -XPUT http://127.0.0.1:9080/apisix/admin/upstreams/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -d ' +{ + "nodes": { + "10.244.143.48:8080": 100, + "10.244.102.43:8080": 100, + "10.244.102.63:8080": 100 + }, + "desc": "foo-upstream", + "type": "roundrobin" +} +' +# 2. Define service: foo-service, id=2, binding upstream: foo-upstream +curl -XPUT http://127.0.0.1:9080/apisix/admin/services/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -d ' +{ + "desc": "foo-service", + "upstream_id": 1 +} +' + +# 3. Define route: foo-route, id=3, binding service: foo-service + +curl -XPUT http://127.0.0.1:9080/apisix/admin/routes/3 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -d ' +{ + "desc": "foo-route", + "uri": "/hello*", + "host": "test.apisix.apache.org", + "service_id": "2" +}' +``` + +Now we change to the definition of CRDs as follows. + +1. Define Upstream with `ApisixUpstream` + +```yaml +apiVersion: apisix.apache.org/v1 +kind: ApisixUpstream +metadata: + name: foo + namespace: cloud +spec: + ports: + - port: 8080 + loadbalancer: + type: chash + hashOn: header + key: hello +``` + +2. Define Service with `ApisixService` + +```yaml +apiVersion: apisix.apache.org/v1 +kind: ApisixService +metadata: + name: foo + namespace: cloud +spec: + upstream: foo + port: 8080 +``` + +3. Define Route with `ApisixRoute` + +```yaml +apiVersion: apisix.apache.org/v1 +kind: ApisixRoute +metadata: + name: foo-route + namespace: cloud +spec: + rules: + - host: test.apisix.apache.org + http: + paths: + - backend: + serviceName: foo + servicePort: 8080 + path: /hello* +``` + +Tips: When defining ApisixUpstream, there is no need to define a specific pod ip list, the ingress controller will do service discovery based on namespace/name/port composite index. + +As shown below. + + + +## Add a plugin + +Next, take the `proxy-rewrite` plugin as an example. + +Add plug-ins through admin api to achieve the purpose of rewriting upstream uri. + +e.g. test.apisix.apache.org/hello -> test-rewrite.apisix.apache.org/copy/hello + +With admin api + +```shell +curl http://127.0.0.1:9080/apisix/admin/services/2 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "desc": "foo-service", + "upstream_id": "1", + "plugins": { + "proxy-rewrite": { + "regex_uri": ["^/(.*)", "/copy/$1"], + "scheme": "http", + "host": "test-rewrite.apisix.apache.org" + } + } +}' +``` + +With CRDs, use `ApisixService` as example. + +```yaml +apiVersion: apisix.apache.org/v1 +kind: ApisixService +metadata: + name: foo + namespace: cloud +spec: + upstream: foo + port: 8080 + plugins: + - enable: true + name: proxy-rewrite + config: + regex_uri: + - '^/(.*)' + - '/copy/$1' + scheme: http + host: test-rewrite.apisix.apache.org +``` + +It can be found that the way of defining plugins is almost the same, except that the format is changed from `json` to `yaml`. + +By defining the plug-in in CRDs, you can disable the plug-in by setting `enable: false` without deleting it. Keep the original configuration for easy opening next time. + +Tips: ApisixRoute and ApisixService both support plugins definition. + +## FAQ + +1. How to bind between Service and Upstream? + +All resource objects are uniquely determined by the namespace / name / port combination Id. If the combined Id is the same, the `service` and `upstream` will be considered as a binding relationship. + +2. When modifying a CRD, how do other binding objects perceive it? + +This is a cascading update problem, see for details [apisix-ingress-controller Design ideas](./design.md) + +3. Can I mix CRDs and admin api to define routing rules? + +No, currently we are implementing one-way synchronization, that is, CRDs file -> Apache AIPSIX. If the configuration is modified separately through admin api, it will not be synchronized to CRDs in Kubernetes. + +This is because CRDs are generally declared in the file system, and Apply to enter Kubernetes etcd, we follow the definition of CRDs and synchronize to Apache Apisix Data Plane, but the reverse will make the situation more complicated.
