istio是一个可以实现微服务之间的互联、微服务间通信的鉴权、对访问微服务的流量的控制以及对微服务进行监视的一个服务网格,其通过将代理注入到微服务所在的pod的方式,实现上述功能,可以让应用开发人员只专注于业务本身,提高了开发效率,下面我们就来在k8s集群上部署一下istio,并进行istio的实例测试(官方给的BookInfo微服务)
一、istio的安装:
集群环境:
master:Ubuntu16.04LTS 4cpu 4GB内存
node:(virtualbox)Ubuntu16.04 4cpu 4GB内存
1、安装方式:
采用helm去安装,helm相当于一个k8s的包管理工具,每个包称为一个Chart,一个Chart是一个目录,其包含了k8s资源相关的YAML文件;
2、首先,需要安装helm:
执行:
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.12.3-linux-amd64.tar.gz
tar -zxvf helm-v2.12.3-linux-amd64.tar.gz
cd linux-amd64/
cp helm /usr/local/bin/
输入helm version检查helm client是否安装成功
3、用helm安装istio:
a.下载istio的发布文件:
tar -zvxf istio-1.2.9-linux.tar.gz #解压
echo export PATH=$PATH:/home/rongshuai/istio/istio-1.2.9/bin >> ~/.bashrc
source ~/.bashrc #上面是将istioctl添加到环境变量中去
执行istioctl --help查看是否成功添加到了环境变量:
添加成功
b.为istio创建一个命名空间:
kubectl create namespace istio-system
命名空间创建成功
c.通过kubectl apply安装istio的CRDs,CRDs被提交到k8s的API-server需要等待几秒钟(在istio文件目录下安装):
helm template install/kubernetes/helm/istio-init/ --name istio-init --namespace istio-system | kubectl apply -f -
d.执行下面的指令确定全部23个istio CRDs都被提交给了k8s的API-server:
kubectl get crds | grep ‘istio.io’ | wc -l
e.渲染和提交istio的核心组件:
helm template install/kubernetes/helm/istio --name istio --namespace istio-system | kubectl apply -f -
f.验证部署成功:kubectl get pods -n istio-system
这些pod中的istio-policy-64f7777867-98k8p在第一次部署的时候总是处于pending状态,查看其细节,给出的问题是内存和CPU不足,所以我将虚拟机的CPU数调整到了4核,内存调整到了6144MB,然后再启动集群,既可以了。
kubectl get svc -n istio-system
二、istio实例测试:
1、这个实例包含了4个独立的微服务,用来展示书的信息(类似于线上书店),展示书的描述、书的细节(ISBN,页数等)和一些书评;
2、BookInfo被划分为以下4个微服务:
a.productpage:调用details和reviews这两个微服务去向每页输入数据;
b.details:该微服务包含了书的信息;
c.reviews:该微服务包含了书评,同时调用ratings这个微服务(用来产生不同书评的排名);
d.ratings:该微服务包含了书的等级信息(依据书评)
3、reviews微服务有以下3个版本:
a.版本一不会调用ratings服务;
b.版本二调用ratings服务,并将等级分为1-5黑星;
c.版本三调用ratings服务,并将等级分为1-5红星;
4、BookInfo的结构图如下:
5、部署该应用(部署到istio后的结构图如下):
如图所示:所有的微服务都将会被打包成“Envoy sidecar”,其将会拦截对其打包的应用的入站出站调用,通过istio的“控制面板”提供用来让外部控制的“钩子”,来实现路由、遥测收集以及整个应用程序的策略实施;
6、在istio上部署BookInfo应用:
a.将当前路径调整到istio的根路径;
b.向pod中注入istio的sidecar proxy,启动自动注入(每次创建新的pod都会被注入sidecar proxy):
kubectl label namespace default istio-injection=enabled
c.通过kubectl部署BookInfo应用:
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
7、结果验证:
可见,安装成功!
8、确定BookInfo这个应用运行起来了:
访问ratings这个pod:
kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o ".* "
9、确定入站IP和port:
现在,BookInfo这个服务已经running了,所以为了让外界可以访问这个处于k8s集群内的服务,需要进一步配置,这将会用到Istio Gateway。
a.定义该应用的入站网关:
kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
b.确定网关已经被创建:
kubectl get gateway
可见,网关已经被创建
c. 配置访问网关的入站host以及入站port的变量:
执行以下指令,判断当前的k8s集群是否运行在一个可以支持外部负载均衡器的环境中:
kubectl get svc istio-ingressgateway -n istio-system
根据官方文档:如果该服务的EXTERNAL-IP存在具体的值,那就说明当前环境有一个外部的负载均衡器可以提供给ingress gateway使用,如果EXTERNAL-IP的值为
采用“node port”的方式访问gateway:
设置入站端口:
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')
配置网关URL:
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
10、确定该应用可以从集群外被访问:
a.确定BookInfo可以从集群外被访问:
curl -s http://${GATEWAY_URL}/productpage | grep -o ".* "
访问成功!
b.确定BookInfo可以直接从浏览器访问:
先获取${GATEWAY_URL} :echo $GATEWAY_URL
这将会把网关地址的ip和端口返回,然后用这个地址去访问BookInfo这个集群内应用:
访问成功!该集群内部的应用已经可以被外界访问了!