-
在k8s上安装Istio
1
2
3
4
5
6
7
8
9
10#下载istio
export ISTIO_VERSION=1.5.0
curl -L https://istio.io/downloadIstio | sh -
mv ./istio-1.5.0 /opt/istio
#修改/etc/environment,将/opt/istio/bin加入PATH
sudo echo PATH=$PATH:/opt/istio/bin > /etc/environment
source /etc/environment
#在k8s上安装istio,此处我们使用default模式安装
#在进行这一步之前,需要确保用户目录中已配置kubeconfig(~/.kube/config)
istioctl manifest apply --set profile=default --set addonComponents.kiali.enabled=true可在安装时添加 –set addonComponents.xxx.enabled=true(xxx为组件名称)进行安装
-
kiali初始化配置
新版kiali由于未在docker环境变量中设置登录名与密码,导致初始登录时报错。解决办法:在kiali Deployment.spec.template.spec.containters.env中加入以下环境变量:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20{
"name": "SERVER_CREDENTIALS_USERNAME",
"valueFrom": {
"secretKeyRef": {
"name": "kiali",
"key": "username",
"optional": true
}
}
},
{
"name": "SERVER_CREDENTIALS_PASSWORD",
"valueFrom": {
"secretKeyRef": {
"name": "kiali",
"key": "passphrase",
"optional": true
}
}
}然后为kiali创建configmap:
1
kubectl create secret generic kiali -n istio-system --from-literal=username=admin --from-literal=passphrase=admin
用户名:admin,密码:admin
-
解决istio中的外部鉴权问题
istio官方推荐使用jwt进行鉴权,这种鉴权方法需要用户先去鉴权服务请求一个token,然后将此token置于http request的header之中。由于我们使用的token是由yy UDB生成的,此种鉴权方法并不适合我们。在ServiceMesh v1版本我们开发了一个ext-authz服务进行鉴权,要想在istio中使用,只需要编写envoyfilter,在envoy.route之前加入envoy.ext_authz,把流量导入ext-authz服务。
ingress-gateway-ef.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: ingress-gateway-ef
namespace: istio-system
spec:
workloadSelector:
labels:
app: istio-ingressgateway
configPatches:
- applyTo: HTTP_FILTER
match:
context: ANY
listener:
portNumber: 80
filterChain:
filter:
name: envoy.http_connection_manager
subFilter:
name: envoy.router
patch:
operation: INSERT_BEFORE
value:
name: envoy.ext_authz
config:
grpc_service:
envoy_grpc:
cluster_name: outbound|8888||ext-authz.default.svc.cluster.local istio使用地域感知
由于我们的k8s集群是单集群-跨机房部署,请求需要优先就近路由到本地机房服务去处理以降低请求延时。istio1.1版本以上提供了地域感知的功能(Locality Load Balancing),能够在无侵入的情况下实现就近路由的功能。配置方法如下:
在istio pilot Deployment.spec.template.spec.containters.env中加入环境变量:1
2
3
4
5{
"name": "PILOT_ENABLE_LOCALITY_LOAD_BALANCING",
"value": "1"
},在名为istio的configmap中找到localityLbSetting项,确保其处于enabled: true状态(默认处于开启状态),如果流量控制需要更加细化,可以参考 LocalityLoadBalancerSetting进行配置
在k8s node上打上region/zone标签,标签全称请参考:k8s知名标签
1
2
3
4
5
6
kubectl label node worker-sz02 topology.kubernetes.io/region=shenzhen
kubectl label node worker-sz03 topology.kubernetes.io/region=shenzhen
kubectl label node worker-bj02 topology.kubernetes.io/region=beijing
kubectl label node worker-wx02 topology.kubernetes.io/region=wuxi由于 #12947,我们需要在DestinationRule中为Service配置熔断规则,地域感知才会生效。DestinationRule示例如下:
1
2
3
4
5
6
7
8
9
10
11apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: outlier
spec:
host: "google.com"
trafficPolicy:
outlierDetection:
consecutiveErrors: 7
interval: 5m
baseEjectionTime: 15m配置完成后进行测试,在DestinationRule中配置LoadBalance规则,无论是轮询还是一致性hash,请求都是在本地机房处理的(例如从深圳ingress-gateway进来的请求,只会在深圳机房内进行处理),满足我们的设计需要
istio+k8s服务暴露方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50深圳机房
Physical Server1
+-----------------------------------------------------+
| PodA |
| +---------------------+ |
| Docker端口直接映射到主机端口 | DeamonSet+HostPort | |
|<--------------------------->|+k8sService |-|---------------+
| |istio-ingress-gateway| | |
| +---------------------+ | |
| | | |
| |flannel | |
| PodB V | |
| +--------------------------+ | |
| | DeploymentSet+k8sService| | |flannel
| | BIZ-Service1 | | |
| | | | |
| +--------------------------+ | |
| | |
| | |
| | |
| | |
+-----------------------------------------------------+ |
|
|
|
Physical Server2 |
+------------------------------------------------------+ |
| PodC | |
| +------------------------+ | |
| |DeploymentSet+k8sService| | |
| | BIZ_Service2 |<--------|--------------+
| | | |
| +------------------------+ |
| | |
| |flannel |
| PodD V |
| +--------------------------+ |
| | DeploymentSet+k8sService| |
| | BIZ_Service3 | |
| | | |
| +-------------------------+| |
| |
| |
| |
| |
+------------------------------------------------------+
istio-ingresss-gateway使用DaemonSet进行部署,在DaemonSet中添加NodeSelector,对打上了front_end=true标签的节点进行部署,由于我们使用HostPort的方式进行服务暴露,部署时需要确定物理机上的80/443等端口未被占用。为了使用istio地域感知功能,需要为ingress-gateway配置k8s Service,否则地域感知不生效。内部的业务服务使用Deployment+k8sService的方式进行部署,可配置水平伸缩容器。
A&Q
istio-ingress-gateway为什么不使用k8s NodePort进行服务暴露?如下图所示,使用NodePort的情况下,从节点1进入的请求可能被转发到节点2进行处理,不适用于跨机房k8s集群
为何不使用k8s官方推荐的LoadBalance作为istio-ingress-gateway的暴露方式?
使用LB需要网络设备的支持(LoadBalancer在数据链路层发送ARP),需要服务器处于同一交换机内。对于跨机房k8s集群不适用。LB原理
使用sds进行https单向证书配置
在istio-ingressgateway Gateway.spec.servers添加tls1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41kind: Gateway
apiVersion: networking.istio.io/v1alpha3
metadata:
name: ingressgateway
namespace: istio-system
selfLink: >-
/apis/networking.istio.io/v1alpha3/namespaces/istio-system/gateways/ingressgateway
uid: ad31ce80-6caf-11ea-b592-6c92bf4940c4
resourceVersion: '490919'
generation: 3
creationTimestamp: '2020-03-23T02:40:36Z'
labels:
operator.istio.io/component: IngressGateways
operator.istio.io/managed: Reconcile
operator.istio.io/version: 1.5.0
release: istio
annotations:
kubectl.kubernetes.io/last-applied-configuration: >
{"apiVersion":"networking.istio.io/v1alpha3","kind":"Gateway","metadata":{"annotations":{},"labels":{"operator.istio.io/component":"IngressGateways","operator.istio.io/managed":"Reconcile","operator.istio.io/version":"1.5.0","release":"istio"},"name":"ingressgateway","namespace":"istio-system"},"spec":{"selector":{"istio":"ingressgateway"},"servers":[{"hosts":["*"],"port":{"name":"http","number":80,"protocol":"HTTP"}}]}}
spec:
servers:
- hosts:
- '*'
port:
name: http
number: 80
protocol: HTTP
- hosts:
- front.100.com
port:
name: https
number: 443
protocol: HTTPS
tls:
credentialName: yy-cr
mode: SIMPLE
privateKey: sds
serverCertificate: sds
selector:
istio: ingressgateway在终端输入
1
2#注意文件名称必须为cert与key,否则sds不识别
kubectl create secret generic cr-yy --from-file=cert --from-file=key -n istio-system