服务网格
服务网格是为本地、云或混合云基础设施提供安全的服务到服务通信的专用层。服务网格通常与微服务架构模式一起使用,但可以在涉及复杂网络的任何场景中提供价值。
服务网格通常由控制平面和数据平面组成。控件平面维护一个中央注册表,可跟踪所有服务及其各自的 IP 地址,这被称为服务发现。只要应用程序在控制平面注册,控制平面就可以与服务网格的其他成员共享如何与应用程序通信并强制规定谁能彼此通信。
控制平面负责保护网格,促进服务发现、健康检查、策略执行和其他类似的操作问题。数据平面处理服务之间的通信。许多服务网格解决方案采用 sidecar 代理来处理数据平面通信,因此限制了服务对网络环境的感知水平。
服务发展
单体服务
- 模块间函数调用,以纳秒为单位
- 参数传递,数据无需加密
- 导入模块,增加功能
- 子系统出现问题,得重新发布整个系统
微服务
为了提升开发效率,降低特性发布周期,开始走向微服务架构
- 模块间网络调用,以毫秒为单位
- 数据在网络中传输,需要加密
- 访问 IP:Port 获取服务
挑战:
- 服务发现
- 服务配置
- 服务分界:外部,业务,数据
- 服务地址由负载均衡器(如 nginx)硬编码,微服务通过负载均衡器地址调用其依赖的服务
服务网格
- 服务发现:微服务服务在中央服务进行注册
- 服务配置:中央服务 K/V 数据库存储配置
- 服务分界:中央服务定义微服务之间的通信规则(Service Graph)
- 服务鉴权:不同的服务有不同的 TLS 证书,服务间进行双向 TLS 鉴权
sidecar proxy
部署 Consul
前置要求:
- 克隆示例存储库
1
| git clone https://github.com/hashicorp/learn-consul-kubernetes.git --depth=1
|
- 切换到教程目录
1
| cd learn-consul-kubernetes/service-mesh/deploy
|
- 添加 chart 仓库
1
| helm repo add hashicorp https://helm.releases.hashicorp.com
|
- 更新 chart 仓库
- 部署 consul
1
| helm install -f config.yaml consul hashicorp/consul --create-namespace -n consul --version "0.39.0"
|
- 验证安装
1
| kubectl get pods --namespace consul --selector app=consul
|
Output:
1
2
3
4
5
6
7
| NAME READY STATUS RESTARTS AGE
consul-bz8xw 1/1 Running 0 23m
consul-connect-injector-webhook-deployment-8d4f5c97b-56vk5 1/1 Running 1 (22m ago) 23m
consul-connect-injector-webhook-deployment-8d4f5c97b-lp9zh 1/1 Running 0 23m
consul-controller-7b588d978-2thrf 1/1 Running 0 23m
consul-server-0 1/1 Running 0 23m
consul-webhook-cert-manager-78669db499-wnlq8 1/1 Running 0 23m
|
- 转发 UI 端口
1
| kubectl --namespace consul port-forward service/consul-ui 18500:80 --address 0.0.0.0
|
这里推荐使用 VSCode Remote SSH,提供的端口转发功能可以轻易的访问服务器的服务。
更新 consul 配置
- 修改
config.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
29
| global:
name: consul
datacenter: dc1
metrics:
enabled: true
enableAgentMetrics: true
acls:
manageSystemACLs: true
gossipEncryption:
autoGenerate: true
tls:
enabled: true
enableAutoEncrypt: true
verify: true
server:
replicas: 1
ui:
enabled: true
connectInject:
enabled: true
controller:
enabled: true
prometheus:
enabled: true
|
- 使用 helm 升级
1
| helm upgrade consul hashicorp/consul --namespace consul --version "0.39.0" --values ./config.yaml --wait
|
- 获取 ACL 令牌
1
| kubectl get secrets/consul-bootstrap-acl-token -n consul --template='{{.data.token | base64decode }}'
|
部署微服务
- 部署示例服务
依然是在刚刚的目录下,应用 hashicups 文件夹中的配置文件
1
| kubectl apply -f hashicups/
|
Output:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| service/frontend created
serviceaccount/frontend created
servicedefaults.consul.hashicorp.com/frontend created
configmap/nginx-configmap created
deployment.apps/frontend created
service/postgres created
serviceaccount/postgres created
servicedefaults.consul.hashicorp.com/postgres created
deployment.apps/postgres created
service/product-api created
serviceaccount/product-api created
servicedefaults.consul.hashicorp.com/product-api created
configmap/db-configmap created
deployment.apps/product-api created
service/public-api created
serviceaccount/public-api created
servicedefaults.consul.hashicorp.com/public-api created
deployment.apps/public-api created
|
查看 pods
1
| kubectl get pods --selector consul.hashicorp.com/connect-inject-status=injected
|
Output:
1
2
3
4
5
| NAME READY STATUS RESTARTS AGE
frontend-699cb4546-vj78k 2/2 Running 0 25m
postgres-54966b4458-7gdk2 2/2 Running 0 25m
product-api-688d79df6c-fk7zw 2/2 Running 0 25m
public-api-5975bd4f4c-vkhrs 2/2 Running 0 25m
|
- 转发服务端口
1
| kubectl port-forward service/frontend 18080:80 --address 0.0.0.0
|
- 浏览器打开 localhost:18080
配置零信任网络
- 拒绝所有请求
进入 zero-trust-network 文件夹
1
| cd service-mesh/zero-trust-network
|
应用规则
1
| kubectl apply -f deny-all.yaml
|
- 查看管理界面
访问 http://127.0.0.1:18080/
得到 Error :(
- 允许特定服务间的通信
1
| kubectl apply -f service-to-service.yaml
|
该文件允许下列请求的发生
- frontend -> public-api
- public-api -> product-api
- product-api -> postgres
查看管理界面
- intention
intention 包含四个部分
- 源服务 - 指定发出请求的服务。它可以是一个服务的全称,也可以*指代所有的服务。
- 目标服务 - 指定接收请求的服务。即在服务定义中配置的上游。它可以是一个服务的全称,也可以*指代所有的服务。
- 权限 - 定义是否允许源和目标之间的通信。这可以设置为 allow 或 deny。
- 描述 - 可选,描述 intention 的字段。
1
2
3
4
5
6
7
8
9
10
| apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceIntentions
metadata:
name: product-api-to-postgres
spec:
destination:
name: postgres
sources:
- name: product-api
action: allow
|