istio gateway在GCP上的最佳实践

背景

没啥背景,就是想折腾,后续慢慢更新,这次先使用istio中的gateway相关。

快速安装

我目前选择helm安装istio相关组件,首先你需要准备好一些东西:

  • 下载好istio安装包
  • helm版本在3以上

官方文档在这里,可以瞧一瞧:点击我

额外说明

我们目前暂时只是用到istio的gateway,至于流量管理,这一块我们后续再研究、再开启(注入sidecar)。
所以我们目前就只部署istiod和ingress。

下载istio配置istioctl

1
2
3
# curl -L https://istio.io/downloadIstio | sh -
# cd istio-1.11.4
# 把./istio-1.11.4/bin加到你的环境变量里

验证istioctl

1
2
3
# istioctl version
no running Istio pods in "istio-system"
1.11.4

开始部署

我们使用helm部署,所有的chart都在manifests/charts里面,可以进去看看。

  • 创建ns
1
# kubectl create namespace istio-system
  • 部署istio-base

这一步做了哪些工作呢?
答:Installs Istio cluster resources: CRDs, cluster bindings and associated service accounts.

1
# helm install istio-base manifests/charts/base -n istio-system
  • 部署istio-discovery

这一步做了哪些工作呢?
答:Installs istiod service.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# helm install istiod manifests/charts/istio-control/istio-discovery -n istio-system
# 默认istiod配置了2G的内存,测试的话可以配置少一点
# kubectl get all -n istio-system
NAME READY STATUS RESTARTS AGE
pod/istiod-576c699795-4fq4f 1/1 Running 0 76s

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/istiod ClusterIP 10.101.203.193 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 76s

NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/istiod 1/1 1 1 76s

NAME DESIRED CURRENT READY AGE
replicaset.apps/istiod-576c699795 1 1 1 76s

NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
horizontalpodautoscaler.autoscaling/istiod Deployment/istiod <unknown>/80% 1 5 1 76s

如果你想配置nodeSelector,原生的chart虽然有这个配置,但是是不生效的,所以我们需要修改如下:
具体可以看我提的这个issues:https://github.com/istio/istio/issues/36110

1
2
3
4
5
6
7
8
9
# vim manifests/charts/istio-control/istio-discovery/templates/deployment.yaml
添加
spec:
{{- if .Values.pilot.nodeSelector }}
nodeSelector: {{ toYaml .Values.pilot.nodeSelector | nindent 8 }}
{{- end }}
# 然后我们再去values.yaml中设置我们想要的nodeselector
nodeSelector:
nodetype: istio-gateway
  • 部署istio-ingress

这一步做了哪些工作呢?
答:

1
2
3
# 1.修改配置,gateways.type: 从LoadBalancer修改成NodePort
# 2.修改配置,gateways.autoscaleEnabled:关闭hpa
# 3.修改配置,从deployment部署方式调整成dasmonset方式,由于官方chart没有这样的支持,我单独fork了一个仓库做修改,有兴趣可以看看。

仓库地址:https://github.com/gsgs-libin/istio-charts

部署过程中遇到的问题,提了一个issue,具体可以看这里:https://github.com/istio/istio/issues/36128

开始部署:

1
helm install istio-ingress manifests/charts/gateways/istio-ingress -n istio-system

额外说明

由于我们只用了gateway相关的功能,所以我们先不要对服务namespace进行注入动作,后续有需要再说。

测试

  • 创建secret
1
2
3
# kubectl create secret generic  x-abc-com-20211118 --from-file=cert=x.abc.com.cer  --from-file=key=x.abc.com.key -n istio-system
# kubectl get secret -n istio-system
x-abc-com-20211118 Opaque 2 12s
  • 创建gateway
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
# vim test.yaml
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
labels:
host: www.abc.com
name: gateway-www-abc-com
namespace: my-cluster1-gateway
spec:
selector:
app: istio-ingressgateway
istio: ingressgateway
servers:
- hosts:
- www.abc.com
port:
name: www.abc.com-80
number: 80
protocol: HTTP
tls:
httpsRedirect: true
- hosts:
- www.abc.com
port:
name: https-www.abc.com-443
number: 443
protocol: HTTPS
tls:
credentialName: x-abc-com-20211118
mode: SIMPLE
# kubectl apply -f test.yaml
  • 查看gateway监听
1
2
3
4
5
6
7
8
# exec it 进入gateway容器
# netstat -antulp | grep LISTEN | grep -E "80|443"
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 17/envoy
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 17/envoy
# 由于是hostnetwork模式,所以到宿主机上看看
# istio-node # netstat -antulp | grep LISTEN | grep -E "80|443"
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1846819/envoy
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 1846819/envoy
  • 创建一个四层的负载均衡器

我们创建一个四层的负载均衡器代理到我们的gateway上,

1
2
3
1. 创建一个公网的和一个内网的
2. 代理80和443
3. 健康检查使用15021/healthz/ready

png1

  • 创建vs
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
# vim vs.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
labels:
host: www.abc.com
name: vs-www.abc.com
namespace: my-cluster1-vs
spec:
gateways:
- my-cluster1-gateway/gateway-www-abc-com
hosts:
- www.abc.com
http:
- match:
- uri:
prefix: /
name: www.abc.com-/
retries: {}
route:
- destination:
host: test-svc.test-ns.svc.cluster.local
port:
number: 80
weight: 100
timeout: 75s
- match:
- uri:
prefix: /api
name: www.abc.com-/api
retries: {}
route:
- destination:
host: test-svc.test-ns.svc.cluster.local
port:
number: 80
weight: 100
timeout: 75s
# kubectl apply -f vs.yaml
  • 验证
1
2
3
4
5
6
# kubectl get gateway -n my-cluster1-gateway
NAME AGE
gateway-www-abc-com 16h
# kubectl get vs -n my-cluster1-vs
NAME GATEWAYS HOSTS AGE
vs-www.abc.com ["my-cluster1-gateway/www-abc-com"] ["www.abc.com"] 58m
1
# curl -x your_public_ip:443 "https://www.abc.com" -vvv

推广

目前新的博客地址:dgsfor.com
托管于:zeno
文档:点击我