一、环境介绍
- Centos 7
- Istio-1.9.0
- Go1.15
- Istio BookInfo
下述步骤是以istio基础组件均已部署好为前提,即istio-system命名空间下的组件均已正常工作。
Istio安装部署 可以参考: Linux安装部署istio及使用_水是睡着的冰的博客-CSDN博客_linux安装istio
部署Istio bookinfo 可以请参考 部署Istio bookinfo_水是睡着的冰的博客-CSDN博客
二、准备工作
1、准备好三个命名空间(不同环境灵活配置):
命名空间 | 功能 | 说明 |
vali-system | 部署gateway和virtual service | |
vali-service-green | 绿环境。部署绿环境的应用 | 需要加上label:istio-injection=enabled |
vali-service-blue | 蓝环境。部署蓝环境的应用 | 需要加上label:istio-injection=enabled |
2、配置命名空间 vali-system
vali-system.yaml:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
namespace: vali-system # gateway命名空间
name: vali-system-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80 # gateway对外端口
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
namespace: vali-system # gvirtual service命名空间
name: vali-system-vs
spec:
hosts:
- "*"
gateways:
- vali-system-gateway # 匹配上述gateway
http:
- match:
- headers:
cookie:
regex: ^.*env=green.*$ # 绿环境cookie匹配规则
route:
- destination:
host: apiservice.vali-service-green.svc.cluster.local # 绿环境api service域名
port:
number: 8080 # 绿环境api service端口
subset: apiservice # 绿环境DestinationRule配置中subsets中的name
- match:
- headers:
cookie:
regex: ^.*env=blue.*$ # 蓝环境cookie匹配规则
route:
- destination:
host: apiservice.vali-service-blue.svc.cluster.local # 蓝环境api service域名
port:
number: 8080 # 蓝环境api service端口
subset: apiservice # 蓝环境DestinationRule配置中subsets中的name
kubectl create -f vali-system.yaml
3、配置命名空间 vali-service-green
注意:下面yaml里的go服务镜像 gin-demo:v1 的生成可以参考文章 Docker容器化Golang服务_水是睡着的冰的博客-CSDN博客
vali-service-green.yaml
# 配置destination rule
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
namespace: vali-service-green
name: api-dr-green
spec:
host: apiservice.vali-service-green.svc.cluster.local # 和上述destination下host匹配
subsets:
- name: apiservice # 和上述destination下subset匹配上
labels:
app: apiservice # 匹配pod label
---
#应用(如deployment)需要配上service,并且要给pod打上上述destination rule中的label,示例如下:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: vali-service-green
name: api
spec:
selector:
matchLabels:
app: apiservice
replicas: 1
template:
metadata:
labels:
app: apiservice # 注意加上和destination rule相同的label
spec:
imagePullSecrets: # 如果该命名空间需要通过default这个secret拉取镜像需要配置该项
- name: default
containers:
- name: api
image: gin-demo:v1 #这里换成你自己的镜像仓库地址
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: "env"
value: "green"
---
apiVersion: v1
kind: Service
metadata:
namespace: vali-service-green
name: apiservice # 名称需要和上述host对应上
spec:
selector:
app: apiservice #service和pod关联上
ports:
- name: default
protocol: TCP
port: 8080 # service端口
targetPort: 8080 # 服务端口
kubectl create -f vali-service-green.yaml
4、配置命名空间 vali-service-blue
参考上一步不再赘述
5、调整
为了方便浏览器访问验证,我们将一些service的类型由ClusterIP改为NodePort。
5.1 修改kiali service的类型
将kiali service的类型由ClusterIP模式改为NodePort,其他不用修改。 将 ClusterIP 改为 NodePort
kubectl -n istio-system edit svc kiali -oyaml
修改完之后再次edit service可以看到service已经分配了一个NodePort 30059,如下:
ports:
- name: http
nodePort: 30059
选任一node的IP加端口30059在浏览器上访问,比如:http://192.168.1.11:30059
这时候页面上可以看到一些命名空间下的信息,如图:
5.2 修改golang服务的service类型
把我们的golang服务apiservice的类型改为NodePort
kubectl -n vali-service-blue edit svc apiservice -oyaml
查看service
[root@k8s-master ~]# kubectl -n vali-service-blue get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
apiservice NodePort 10.1.120.231 <none> 8080:31774/TCP 36h
修改完后其对应的端口是31774, 浏览器访问以下地址:
http://192.168.1.11:31774/
然后再刷新kiali的页面。可以看到我们的golang服务的访问请求流向:
- 圆形代表工作负载,
- 正方形代表 应用
- 三角形代表服务,即service
进入另外一个namespace里的pod访问我们的golang服务。
kubectl -n vali-service-green exec -it api-6bb64cdc6d-bk67g /bin/sh
sh-4.4# curl apiservice.vali-service-blue.svc.cluster.local:8080
{"message":"http: named cookie not present"}
sh-4.4#
此时对应kiali的图像是这样的: