一般的服务不需要做过多修改,开启自动注入后,istio会自动注入siderbar等依赖服务和组件。
1.设置命名空间自动注入
这里新建一个命名空间(参照前面的文章)进行实验,并设置成默认空间
kubectl config set-context $(kubectl config current-context) --namespace=dwaynt-istio
开启siderbar默认注入,指定dwaynt-istio命名空间:
kubectl label namespace dwaynt-istio istio-injection=enabled
2.创建服务
Kubectl apply 部署应用。Siderbar会自动注入到该服务。
helloworld.yaml:
3.定义ingressgateway、VirtualService
Istio中使用ingressgateway作为入口,创建istio-gress.yaml,创建gateway规则,注意VirtualService中的route host指的是服务的hostname,同一个namespace里面就是service-name。port number要和istio初始化时使用的配置(manifests/profiles/demo.yaml)istio-ingressgateway中的设置对应(我选用的是demo配置),http协议80端口。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: spring-boot-istio-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http-hellogateway
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-istio
spec:
hosts:
- "www.helloworld.com"
gateways:
- spring-boot-istio-gateway
http:
- match:
- uri:
prefix: /helloworld
route:
- destination:
host: helloworld-master
port:
number: 17077
4.映射外网端口
kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o 'jsonpath={.items[0].status.hostIP}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
浏览器通过ip+port访问,路由设置了host,本地绑定域名,通过域名访问
http://www.helloworld.com:31779/helloworld
5.问题
upstream connect error or disconnect/reset before headers. reset reason: connection failure, transport failure reason: TLS error: 268436501:SSL routines:OPENSSL_internal:SSLV3_ALERT_CERTIFICATE_EXPIRED
解决方法:
重启istio服务
kubectl delete pods istio-egressgateway-65bdddf685-mzzmg istio-ingressgateway-7b545cdbc7-68pgx istiod-864977fd6c-qj75n -n istio-system
6.集群内服务调用
6.1coredns方式
查看集群内dns(找一个在集群内的服务查看容器内的设置):
增加到本地dns(在启动coredns时一般会自动修改/etc/resolve.conf,ubuntu18.04 systemd服务会刷新,所以需要修改该服务的配置):
测试服务请求:
服务地址一般为<service-name>.<namespace>.svc.cluster.local:port
7.服务调用例子(微服务调用另一个微服务)
增加一个helloworld-istio服务,和前面的helloworld-master服务区分,helloworld-istio调用helloworld-master服务:
@RestController
public class AController {
@Autowired
RestTemplate restTemplate;
@RequestMapping(value = "/hellosecond/helloworld", method = RequestMethod.GET)
public Response hello() {
Response res = new Response();
String result = restTemplate.getForObject("http://helloworld-master.dwaynt-istio.svc.cluster.local:17077/helloworld", String.class);
res.setMsg("helloworld-istio-second:" +
"get from master:" + result);
return res;
}
}
helloworld-istio.yaml示例:
apiVersion: v1
kind: Service
metadata:
name: helloworld-istio
namespace: dwaynt-istio
labels:
verison: "1.0.0"
env: "test"
spec:
selector:
app: helloworld-istio
release: master
ports:
- name: http
port: 17078
targetPort: 17002
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-istio
namespace: dwaynt-istio
spec:
replicas: 1
selector:
matchLabels:
app: helloworld-istio
release: master
template:
metadata:
labels:
app: helloworld-istio
release: master
version: "1.0.0"
spec:
containers:
- name: demo-hello-world-istio
image: dw/demo-hello-world-istio
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 17078
增加helloworld-istio服务的路由:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld-istio
spec:
hosts:
- "www.helloworld.com"
gateways:
- spring-boot-istio-gateway
http:
- match:
- uri:
prefix: /hellosecond
route:
- destination:
host: helloworld-istio
port:
number: 17078
- match:
- uri:
prefix: /helloworld
route:
- destination:
host: helloworld-master
port:
number: 17077
浏览器访问测试:
查看链路:
8.服务简单治理
8.1限流与熔断
DestinationRule组件,设置限流和熔断规则
参考:http://dljz.nicethemes.cn/news/show-99078.html
注意,对于HTTP1而言,限制并发数=maxConnections*maxRequestsPerConnection,对于HTTP2而言,限制并发数=http2MaxRequests,outlierDetection是异常检测,熔断机制,baseEjectionTime拒绝服务时间,maxEjectionPercent拒绝比例。
Yaml例子参考,设置hello-istio服务的限流和熔断:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: hello-rule
spec:
host: helloworld-istio
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
http2MaxRequests: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 30s
maxEjectionPercent: 100
8.2灰度控制
Helloworld-istio服务增加一个2.0.0版本:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld-istio-2
namespace: dwaynt-istio
spec:
replicas: 1
selector:
matchLabels:
app: helloworld-istio
release: master
template:
metadata:
labels:
app: helloworld-istio
release: master
version: "2.0.0"
spec:
containers:
- name: demo-hello-world-istio
image: dw/demo-hello-world-istio-2
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 17078
应用yaml:
kubectl apply -f helloworld.yaml
多次访问http://www.helloworld.com:31779/hellosecond/helloworld,查看调用链路。默认情况下负载是轮询,平均负载压力:
按比例灰度访问:
修改destinationrule,增加subset:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: hello-rule
spec:
host: helloworld-istio
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
http2MaxRequests: 1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 30s
maxEjectionPercent: 100
subsets:
- labels:
version: "1.0.0"
name: v1
- labels:
version: "2.0.0"
name: v2
修改virtualservice,增加比例,v1:v2按照4:1配置:
route:
- destination:
host: helloworld-istio
subset: v1
port:
number: 17078
weight: 80
- destination:
host: helloworld-istio
subset: v2
port:
number: 17078
weight: 20
测试,测试100次,基本是4:1的负载比例: