这个task描述Istio的流量隐蔽/监控能力。流量监控是一个强大的概念,它允许功能团队尽可能减少生产变化带来的风险。监控将实时流量的副本带入监控服务,这发生在主要服务的关键请求路径带外部。
Before you begin
- 安装Istio
- 开启能访问日志的 httpbin 服务的两个版本。
httpbin-v1:
cat <<EOF | istioctl kube-inject -f - | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpbin-v1
spec:
replicas: 1
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:8080", "httpbin:app"]
ports:
- containerPort: 8080
EOF
httpbin-v2:
cat <<EOF | istioctl kube-inject -f - | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpbin-v2
spec:
replicas: 1
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:8080", "httpbin:app"]
ports:
- containerPort: 8080
EOF
httpbin Kubernetes service:
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Service
metadata:
name: httpbin
labels:
app: httpbin
spec:
ports:
- name: http
port: 8080
selector:
app: httpbin
EOF
- 开启
sleep
服务,我们可以使用curl
提供负载
sleep service:
cat <<EOF | istioctl kube-inject -f - | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sleep
spec:
replicas: 1
template:
metadata:
labels:
app: sleep
spec:
containers:
- name: sleep
image: tutum/curl
command: ["/bin/sleep","infinity"]
imagePullPolicy: IfNotPresent
EOF
Mirroring
让我们建立一个方案来描述Istio的流量监控能力。我们有 httpbin
服务的两个版本。默认情况下,k8s将通过负载均衡访问服务的这两个版本。我们将使用Istio强制将所有流量打到 httpbin
服务的v1版本。
Creating default routing policy
1.让我们创建一个默认路由规则将所有流量路由到的 httpbin
服务的v1版本:
cat <<EOF | istioctl create -f -
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
现在所有路由应该进入 httpbin v1
。让我们尝试发送一些流量:
export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' | python -m json.tool
{
"headers": {
"Accept": "*/*",
"Content-Length": "0",
"Host": "httpbin:8080",
"User-Agent": "curl/7.35.0",
"X-B3-Sampled": "1",
"X-B3-Spanid": "eca3d7ed8f2e6a0a",
"X-B3-Traceid": "eca3d7ed8f2e6a0a",
"X-Ot-Span-Context": "eca3d7ed8f2e6a0a;eca3d7ed8f2e6a0a;0000000000000000"
}
}
如果我们检测我们 httpbin
pods中r v1
和v2
的日志,我们应该发现访问日志记录只有 v1
:
export V1_POD=$(kubectl get pod -l app=httpbin,version=v1 -o jsonpath={.items..metadata.name})
kubectl logs -f $V1_POD -c httpbin
127.0.0.1 - - [07/Mar/2018:19:02:43 +0000] “GET /headers HTTP/1.1” 200 321 “-” “curl/7.35.0”
export V2_POD=$(kubectl get pod -l app=httpbin,version=v2 -o jsonpath={.items..metadata.name})
kubectl logs -f $V2_POD -c httpbin
<none>
2.改变路由规则以监控v2版本的流量
cat <<EOF | istioctl replace -f -
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
EOF
这个路由规则指定我们路由100%的流量到v1。最后一节表明我们想要监控 httpbin v2
服务。当流量得到监控,请求带着它的 Host/Authority 请求头附加上 -shadow被发送给监控服务。例如,cluster-1 变成 cluster-1-shadow 。 意识到这些请求被当作“fire and forget”(换句话说,响应被丢弃)监控也同样重要。
现在如果我们发送流量:
kubectl exec -it $SLEEP_POD -c sleep -- sh -c 'curl http://httpbin:8080/headers' | python -m json.tool
我们将看到 v1
和 v2
都有访问日志。在 v2
中被创建的访问日志是实际上要发送到 v1
的监控请求。
kubectl logs -f $V1_POD -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”
kubectl logs -f $V2_POD -c httpbin
127.0.0.1 - - [07/Mar/2018:19:26:44 +0000] “GET /headers HTTP/1.1” 200 361 “-” “curl/7.35.0”
Cleaning up
1.移除规则。
istioctl delete virtualservice httpbin
istioctl delete destinationrule httpbin
2.关闭 httpbin 服务端和客户端。
kubectl delete deploy httpbin-v1 httpbin-v2 sleep
kubectl delete svc httpbin