diff --git a/content/zh/docs/tasks/traffic-management/mirroring/index.md b/content/zh/docs/tasks/traffic-management/mirroring/index.md index 32c418abb6e98..51d1a70fbab4c 100644 --- a/content/zh/docs/tasks/traffic-management/mirroring/index.md +++ b/content/zh/docs/tasks/traffic-management/mirroring/index.md @@ -16,218 +16,215 @@ test: yes {{< boilerplate gateway-api-support >}} -## 开始之前{#before-you-begin} +## 开始之前 {#before-you-begin} -* 按照[安装指南](/zh/docs/setup/)中的说明设置 Istio。 +1. 按照[安装指南](/zh/docs/setup/)设置 Istio。 +1. 首先部署已启用访问日志记录的两个版本的 [httpbin]({{< github_tree >}}/samples/httpbin) 服务: -* 首先部署两个版本的 [Httpbin]({{< github_tree >}}/samples/httpbin) 服务,并开启访问日志功能: + 1. 部署 `httpbin-v1`: - **httpbin-v1:** + {{< text bash >}} + $ kubectl create -f - <<EOF + apiVersion: apps/v1 + kind: Deployment + metadata: + name: httpbin-v1 + spec: + replicas: 1 + selector: + matchLabels: + app: httpbin + version: v1 + template: + metadata: + labels: + app: httpbin + version: v1 + spec: + containers: + - image: docker.io/kennethreitz/httpbin + imagePullPolicy: IfNotPresent + name: httpbin + command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"] + ports: + - containerPort: 80 + EOF + {{< /text >}} + + 1. 部署 `httpbin-v2`: + + {{< text bash >}} + $ kubectl create -f - <<EOF + apiVersion: apps/v1 + kind: Deployment + metadata: + name: httpbin-v2 + spec: + replicas: 1 + selector: + matchLabels: + app: httpbin + version: v2 + template: + metadata: + labels: + app: httpbin + version: v2 + spec: + containers: + - image: docker.io/kennethreitz/httpbin + imagePullPolicy: IfNotPresent + name: httpbin + command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"] + ports: + - containerPort: 80 + EOF + {{< /text >}} + + 1. 部署 `httpbin` Kubernetes Service: + + {{< text bash >}} + $ kubectl create -f - <<EOF + apiVersion: v1 + kind: Service + metadata: + name: httpbin + labels: + app: httpbin + spec: + ports: + - name: http + port: 8000 + targetPort: 80 + selector: + app: httpbin + EOF + {{< /text >}} + +1. 部署用于向 `httpbin` 服务发送请求的 `sleep` 工作负载: {{< text bash >}} - $ cat <<EOF | istioctl kube-inject -f - | kubectl create -f - + $ cat <<EOF | kubectl create -f - apiVersion: apps/v1 kind: Deployment metadata: - name: httpbin-v1 + name: sleep spec: replicas: 1 selector: matchLabels: - app: httpbin - version: v1 + app: sleep template: metadata: labels: - app: httpbin - version: v1 + app: sleep spec: containers: - - image: docker.io/kennethreitz/httpbin + - name: sleep + image: curlimages/curl + command: ["/bin/sleep","3650d"] imagePullPolicy: IfNotPresent - name: httpbin - command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"] - ports: - - containerPort: 80 EOF {{< /text >}} - **httpbin-v2:** +## 创建一个默认路由策略 {#creating-a-default-routing-policy} + +默认情况下,Kubernetes 在 `httpbin` 服务的两个版本之间进行负载均衡。 +在此步骤中会更改该行为,把所有流量都路由到 `v1` 版本。 + +1. 创建一个默认路由规则,将所有流量路由到服务的 `v1` 版本: + + {{< tabset category-name="config-api" >}} + + {{< tab name="Istio APIs" category-value="istio-apis" >}} {{< text bash >}} - $ cat <<EOF | istioctl kube-inject -f - | kubectl create -f - - apiVersion: apps/v1 - kind: Deployment + $ kubectl apply -f - <<EOF + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService metadata: - name: httpbin-v2 + name: httpbin spec: - replicas: 1 - selector: - matchLabels: - app: httpbin + hosts: + - httpbin + http: + - route: + - destination: + host: httpbin + subset: v1 + weight: 100 + --- + apiVersion: networking.istio.io/v1alpha3 + kind: DestinationRule + metadata: + name: httpbin + spec: + host: httpbin + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: version: v2 - template: - metadata: - labels: - app: httpbin - version: v2 - spec: - containers: - - image: docker.io/kennethreitz/httpbin - imagePullPolicy: IfNotPresent - name: httpbin - command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:80", "httpbin:app"] - ports: - - containerPort: 80 EOF {{< /text >}} - **httpbin Kubernetes 服务:** + {{< /tab >}} + + {{< tab name="Gateway API" category-value="gateway-api" >}} {{< text bash >}} - $ kubectl create -f - <<EOF + $ kubectl apply -f - <<EOF apiVersion: v1 kind: Service metadata: - name: httpbin - labels: - app: httpbin + name: httpbin-v1 spec: ports: - - name: http - port: 8000 - targetPort: 80 + - port: 80 + name: http selector: app: httpbin - EOF - {{< /text >}} - -* 启动 `sleep` 服务,这样就可以使用 `curl` 来提供负载: - - **sleep 服务:** - - {{< text bash >}} - $ cat <<EOF | istioctl kube-inject -f - | kubectl create -f - - apiVersion: apps/v1 - kind: Deployment + version: v1 + --- + apiVersion: v1 + kind: Service metadata: - name: sleep + name: httpbin-v2 spec: - replicas: 1 + ports: + - port: 80 + name: http selector: - matchLabels: - app: sleep - template: - metadata: - labels: - app: sleep - spec: - containers: - - name: sleep - image: curlimages/curl - command: ["/bin/sleep","3650d"] - imagePullPolicy: IfNotPresent + app: httpbin + version: v2 + --- + apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httpbin + spec: + parentRefs: + - group: "" + kind: Service + name: httpbin + port: 8000 + rules: + - backendRefs: + - name: httpbin-v1 + port: 80 EOF {{< /text >}} -## 创建一个默认路由策略{#creating-a-default-routing-policy} + {{< /tab >}} -默认情况下,Kubernetes 在 `httpbin` 服务的两个版本之间进行负载均衡。在此步骤中会更改该行为,把所有流量都路由到 `v1` 版本。 + {{< /tabset >}} -1. 创建一个默认路由规则,将所有流量路由到服务的 `v1` 版本: - -{{< tabset category-name="config-api" >}} - -{{< tab name="Istio APIs" category-value="istio-apis" >}} - -{{< text bash >}} -$ kubectl apply -f - <<EOF -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: httpbin -spec: - hosts: - - httpbin - http: - - route: - - destination: - host: httpbin - subset: v1 - weight: 100 ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: httpbin -spec: - host: httpbin - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 -EOF -{{< /text >}} - -{{< /tab >}} - -{{< tab name="Gateway API" category-value="gateway-api" >}} - -{{< text bash >}} -$ kubectl apply -f - <<EOF -apiVersion: v1 -kind: Service -metadata: - name: httpbin-v1 -spec: - ports: - - port: 80 - name: http - selector: - app: httpbin - version: v1 ---- -apiVersion: v1 -kind: Service -metadata: - name: httpbin-v2 -spec: - ports: - - port: 80 - name: http - selector: - app: httpbin - version: v2 ---- -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: httpbin -spec: - parentRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - rules: - - backendRefs: - - name: httpbin-v1 - port: 80 -EOF -{{< /text >}} - -{{< /tab >}} - -{{< /tabset >}} - -2) 现在所有流量都转到 `httpbin:v1` 服务,并向此服务发送请求: +1. 现在所有流量都转到 `httpbin:v1` 服务,并向此服务发送请求: {{< text bash json >}} - $ export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) - $ kubectl exec "${SLEEP_POD}" -c sleep -- curl -sS http://httpbin:8000/headers + $ kubectl exec deploy/sleep -c sleep -- curl -sS http://httpbin:8000/headers { "headers": { "Accept": "*/*", @@ -244,145 +241,148 @@ EOF } {{< /text >}} -3) 分别查看 `httpbin` Pod的 `v1` 和 `v2` 两个版本的日志。您可以看到 `v1` 版本的访问日志条目,而 `v2` 版本没有日志: +1. 分别查看 `httpbin` Pod的 `v1` 和 `v2` 两个版本的日志。 + 您可以看到 `v1` 版本的访问日志条目,而 `v2` 版本没有日志: {{< text bash >}} - $ export V1_POD=$(kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items..metadata.name}) - $ kubectl logs "$V1_POD" -c httpbin + $ kubectl logs deploy/httpbin-v1 -c httpbin 127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] "GET /headers HTTP/1.1" 200 321 "-" "curl/7.35.0" {{< /text >}} {{< text bash >}} - $ export V2_POD=$(kubectl get pod -l app=httpbin,version=v2 -o jsonpath={.items..metadata.name}) - $ kubectl logs "$V2_POD" -c httpbin + $ kubectl logs deploy/httpbin-v2 -c httpbin <none> {{< /text >}} -## 镜像流量到 v2{#mirroring-traffic-to-v2} - -1. 改变流量规则将流量镜像到 v2: - -{{< tabset category-name="config-api" >}} - -{{< tab name="Istio APIs" category-value="istio-apis" >}} - -{{< text bash >}} -$ kubectl apply -f - <<EOF -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: httpbin -spec: - hosts: - - httpbin - http: - - route: - - destination: - host: httpbin - subset: v1 - weight: 100 - mirror: - host: httpbin - subset: v2 - mirrorPercentage: - value: 100.0 -EOF -{{< /text >}} +## 将流量镜像发送至 `httpbin-v2` {#mirroring-traffic-to-httpbin-v2} -这个路由规则发送 100% 流量到 `v1` 版本。最后一节表示您将 100% 的相同流量镜像(即发送)到 `httpbin:v2` 服务。 -当流量被镜像时,请求将发送到镜像服务中,并在 `headers` 中的 `Host/Authority` 属性值上追加 `-shadow`。 -例如 `cluster-1` 变为 `cluster-1-shadow`。 +1. 修改路由规则,将流量镜像发送至 `httpbin-v2`: -此外,重点注意这些被镜像的流量是『即发即弃』的,就是说镜像请求的响应会被丢弃。 + {{< tabset category-name="config-api" >}} + + {{< tab name="Istio APIs" category-value="istio-apis" >}} + + {{< text bash >}} + $ kubectl apply -f - <<EOF + apiVersion: networking.istio.io/v1alpha3 + kind: VirtualService + metadata: + name: httpbin + spec: + hosts: + - httpbin + http: + - route: + - destination: + host: httpbin + subset: v1 + weight: 100 + mirror: + host: httpbin + subset: v2 + mirrorPercentage: + value: 100.0 + EOF + {{< /text >}} -您可以使用 `mirrorPercentage` 属性下的 `value` 字段来设置镜像流量的百分比,而不是镜像所有请求。如果没有这个属性,将镜像所有流量。 + 此路由规则将 100% 的流量发送到 `v1` 。`RequestMirror` 过滤器指定您想要将 100% + 的相同流量镜像(即也发送)到 `httpbin:v2` 服务。当流量被镜像时, + 请求将发送到镜像服务,其 Host/Authority 标头附加有 `-shadow`。例如,`cluster-1` 变为 `cluster-1-shadow`。 -{{< /tab >}} + 这个路由规则发送 100% 流量到 `v1` 版本。最后一节表示您将 100% 的相同流量镜像(即发送)到 `httpbin:v2` 服务。 + 当流量被镜像时,请求将发送到镜像服务中,并在 `headers` 中的 `Host/Authority` 属性值上追加 `-shadow`。 + 例如 `cluster-1` 变为 `cluster-1-shadow`。 -{{< tab name="Gateway API" category-value="gateway-api" >}} + 此外,重点注意这些被镜像的流量是“即发即弃”的,就是说镜像请求的响应会被丢弃。 -{{< text bash >}} -$ kubectl apply -f - <<EOF -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: httpbin -spec: - parentRefs: - - group: "" - kind: Service - name: httpbin - port: 8000 - rules: - - filters: - - type: RequestMirror - requestMirror: - backendRef: - name: httpbin-v2 + 您可以使用 `mirrorPercentage` 属性下的 `value` 字段来设置镜像流量的百分比,而不是镜像所有请求。如果没有这个属性,将镜像所有流量。 + + {{< /tab >}} + + {{< tab name="Gateway API" category-value="gateway-api" >}} + + {{< text bash >}} + $ kubectl apply -f - <<EOF + apiVersion: gateway.networking.k8s.io/v1 + kind: HTTPRoute + metadata: + name: httpbin + spec: + parentRefs: + - group: "" + kind: Service + name: httpbin + port: 8000 + rules: + - filters: + - type: RequestMirror + requestMirror: + backendRef: + name: httpbin-v2 + port: 80 + backendRefs: + - name: httpbin-v1 port: 80 - backendRefs: - - name: httpbin-v1 - port: 80 -EOF -{{< /text >}} + EOF + {{< /text >}} -此路由规则将 100% 的流量发送到 `v1`。 -`RequestMirror` 过滤器指定您要将 100% 的相同流量镜像(即也发送)到 `httpbin:v2` 服务。 -当流量被镜像时,请求被发送到镜像服务,其 Host/Authority 请求头附加了 `-shadow`。 -例如,`cluster-1` 变为 `cluster-1-shadow`。 + 此路由规则将 100% 的流量发送到 `v1`。 + `RequestMirror` 过滤器指定您要将 100% 的相同流量镜像(即也发送)到 `httpbin:v2` 服务。 + 当流量被镜像时,请求被发送到镜像服务,其 Host/Authority 请求头附加了 `-shadow`。 + 例如,`cluster-1` 变为 `cluster-1-shadow`。 -此外,重要的是要注意这些请求被镜像为“即发即弃”,这意味着响应将被丢弃。 + 此外,重要的是要注意这些请求被镜像为“即发即弃”,这意味着响应将被丢弃。 -{{< /tab >}} + {{< /tab >}} -{{< /tabset >}} + {{< /tabset >}} -2) 发送流量: + 1. 发送流量: {{< text bash >}} - $ kubectl exec "${SLEEP_POD}" -c sleep -- curl -sS http://httpbin:8000/headers + $ kubectl exec deploy/sleep -c sleep -- curl -sS http://httpbin:8000/headers {{< /text >}} 现在就可以看到 `v1` 和 `v2` 版本中都有了访问日志。v2 版本中的访问日志就是由镜像流量产生的,这些请求的实际目标是 `v1` 版本。 {{< text bash >}} - $ kubectl logs "$V1_POD" -c httpbin + $ kubectl logs deploy/httpbin-v1 -c httpbin 127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] "GET /headers HTTP/1.1" 200 321 "-" "curl/7.35.0" 127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] "GET /headers HTTP/1.1" 200 321 "-" "curl/7.35.0" {{< /text >}} {{< text bash >}} - $ kubectl logs "$V2_POD" -c httpbin + $ kubectl logs deploy/httpbin-v2 -c httpbin 127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] "GET /headers HTTP/1.1" 200 361 "-" "curl/7.35.0" {{< /text >}} -## 清理{#cleaning-up} +## 清理 {#cleaning-up} -1. 删除规则: +1. 删除规则: -{{< tabset category-name="config-api" >}} + {{< tabset category-name="config-api" >}} -{{< tab name="Istio APIs" category-value="istio-apis" >}} + {{< tab name="Istio APIs" category-value="istio-apis" >}} -{{< text bash >}} -$ kubectl delete virtualservice httpbin -$ kubectl delete destinationrule httpbin -{{< /text >}} + {{< text bash >}} + $ kubectl delete virtualservice httpbin + $ kubectl delete destinationrule httpbin + {{< /text >}} -{{< /tab >}} + {{< /tab >}} -{{< tab name="Gateway API" category-value="gateway-api" >}} + {{< tab name="Gateway API" category-value="gateway-api" >}} -{{< text bash >}} -$ kubectl delete httproute httpbin -$ kubectl delete svc httpbin-v1 httpbin-v2 -{{< /text >}} + {{< text bash >}} + $ kubectl delete httproute httpbin + $ kubectl delete svc httpbin-v1 httpbin-v2 + {{< /text >}} -{{< /tab >}} + {{< /tab >}} -{{< /tabset >}} + {{< /tabset >}} -2) 关闭 [Httpbin]({{< github_tree >}}/samples/httpbin) 服务和客户端: +1. 删除 `httpbin` 和 `sleep` 部署以及 `httpbin` 服务: {{< text bash >}} $ kubectl delete deploy httpbin-v1 httpbin-v2 sleep