- 下载 istio:
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.9.0
export PATH=$PWD/bin:$PATH #将 istioctl 加入环境变量
然后需要通过 helm 部署好 istio,此处省略。
- 命名空间添加标签:
方便 Istio 在部署应用的时候,自动的注入 Envoy sidecar 代理:
kubectl label namespace default istio-injection=enabled
- 部署 Bookinfo 示例应用:
cat samples/bookinfo/platform/kube/bookinfo.yaml
apiVersion: v1
kind: Service
metadata:
name: details
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-details
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: details-v1
labels:
app: details
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: details
version: v1
template:
metadata:
labels:
app: details
version: v1
spec:
serviceAccountName: bookinfo-details
containers:
- name: details
image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
apiVersion: v1
kind: Service
metadata:
name: ratings
labels:
app: ratings
service: ratings
spec:
ports:
- port: 9080
name: http
selector:
app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-ratings
labels:
account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v1
labels:
app: ratings
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v1
template:
metadata:
labels:
app: ratings
version: v1
spec:
serviceAccountName: bookinfo-ratings
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
apiVersion: v1
kind: Service
metadata:
name: reviews
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
labels:
app: reviews
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {
}
- name: tmp
emptyDir: {
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
labels:
app: reviews
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {
}
- name: tmp
emptyDir: {
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {
}
- name: tmp
emptyDir: {
}
---
apiVersion: v1
kind: Service
metadata:
name: productpage
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-productpage
labels:
account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
labels:
app: productpage
version: v1
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {
}
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
kubectl get pod
NAME READY STATUS RESTARTS AGE
details-v1-66b6955995-wmghv 2/2 Running 0 3m35s
productpage-v1-5d9b4c9849-d96lb 2/2 Running 0 3m35s
ratings-v1-fd78f799f-mhp49 2/2 Running 0 3m35s
reviews-v1-6549ddccc5-675t5 2/2 Running 0 3m35s
reviews-v2-76c4865449-24pmj 2/2 Running 0 3m36s
reviews-v3-6b554c875-gn2d6 2/2 Running 0 3m36s
- 验证:
通过检查返回的页面标题,来验证应用是否已在集群中运行,并已提供网页服务:
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -s productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
- 对外开放应用程序:
此时,BookInfo 应用已经部署,但还不能被外界访问。 要开放访问,你需要创建 Istio 入站网关(Ingress Gateway), 它会在网格边缘把一个路径映射到路由。
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
istioctl analyze #确保配置文件没有问题
✔ No validation issues found when analyzing namespace: default.
- 确定入站 IP 和端口:
按照说明,为访问网关设置两个变量:INGRESS_HOST
和 INGRESS_PORT
。
执行下面命令进行判断:Kubernetes 集群环境是否支持外部负载均衡:
kubectl get svc istio-ingressgateway -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.105.62.5 <pending> 15021:31847/TCP,80:30108/TCP,443:31550/TCP,15012:31559/TCP,15443:31955/TCP 43m
由于 EXTERNAL-IP
一直显示为 <pending>
,所以当前环境中没有提供可作为入站流量网关的外部负载均衡,这样可以选择一个节点端口来代替。
设置入站的端口:
export INGRESS_PORT=$(kubectl get service -n istio-system istio-ingressgateway -o jsonpath='{
.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl get service -n istio-system istio-ingressgateway -o jsonpath='{
.spec.ports[?(@.name=="https")].nodePort}')
设置入站的 IP:
export INGRESS_HOST=$(kubectl get pod -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
设置环境变量 GATEWAY_URL:
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
echo "$GATEWAY_URL"
192.168.30.130:30108
- 验证外部访问:
用浏览器查看 Bookinfo 应用的产品页面,验证 Bookinfo 已经实现了外部访问。
运行下面命令,获取 Bookinfo 应用的外部访问地址。
echo "http://$GATEWAY_URL/productpage"
http://192.168.30.130:30108/productpage
把上面命令的输出地址复制粘贴到浏览器并访问,确认 Bookinfo 应用的产品页面是否可以打开。
- 查看仪表板:
Istio 和几个遥测应用做了集成。遥测能帮助了解服务网格的结构、展示网络的拓扑结构、分析网格的健康状态。
使用下面说明部署 Kiali 仪表板、Prometheus、Grafana 以及 Jaeger。
安装 Kiali 和其他插件:
kubectl apply -f samples/addons #报错则运行两次
kubectl rollout status deployment/kiali -n istio-system
访问 Kiali 仪表板:
istioctl dashboard kiali
http://localhost:20001/kiali
Failed to open browser; open http://localhost:20001/kiali in your browser.
netstat -lntp |grep 20001
tcp 0 0 127.0.0.1:20001 0.0.0.0:* LISTEN 60323/istioctl
tcp6 0 0 ::1:20001 :::* LISTEN 60323/istioctl
由于此处是虚拟机,所以浏览器无法访问虚拟机上绑定 127.0.0.1 的端口,因此需要做转发。
yum install -y nginx
vim /etc/nginx/conf.d/kiali.conf
server {
listen 20002;
server_name 192.168.30.128;
access_log /var/log/nginx/kiali.access.log main;
error_log /var/log/nginx/kiali.error.log;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
location / {
proxy_pass http://localhost:20001;
proxy_set_header Origin "" ;
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 120s;
proxy_read_timeout 120s;
proxy_send_timeout 120s;
}
}
systemctl enable nginx && systemctl start nginx
访问 http://192.168.30.128:20002/kiali
,
Kiali 仪表板展示了网格的概览、以及 Bookinfo 示例应用的各个服务之间的关系,它还提供过滤器来可视化流量的流动。在左侧的导航菜单,选择 Graph
,然后在 Namespace
下拉列表中,选择 default
。