使用服务网格提升可观测性与管理能力
在微服务架构中,服务网格可以显著提升系统的可观测性和管理效率。本文将详细介绍如何创建服务网格、记录跟踪和跨度 ID 的传播、使用 Kiali 和 Jaeger 进行服务网格的观测,以及如何利用 Istio 增强服务网格的安全性。
1. 创建服务网格
在对源代码进行必要的更改后,我们可以通过以下步骤创建服务网格:
1.
构建 Docker 镜像
:
cd $BOOK_HOME/Chapter18
eval $(minikube docker-env -u)
./gradlew build
eval $(minikube docker-env)
docker-compose build
- 重新创建命名空间并设置为默认命名空间 :
kubectl delete namespace hands-on
kubectl apply -f kubernetes/hands-on-namespace.yml
kubectl config set-context $(kubectl config current-context) --namespace=hands-on
hands-on-namespace.yml
文件创建的
hands-on
命名空间带有
istio-injection: enabled
标签,这意味着在该命名空间中创建的 Pod 将自动注入
istio-proxy
容器作为边车。
3.
解析 Helm 图表依赖
:
- 更新
components
文件夹中的依赖:
for f in kubernetes/helm/components/*; do helm dep up $f; done
- 更新 `environments` 文件夹中的依赖:
for f in kubernetes/helm/environments/*; do helm dep up $f; done
- 使用 Helm 部署系统并等待部署完成 :
helm install hands-on-dev-env kubernetes/helm/environments/dev-env -n hands-on --wait
- 验证微服务 Pod 中有两个容器 :
kubectl get pods
运行微服务的 Pod 每个应报告有两个容器,即已将 Istio 代理作为边车注入。
6.
运行常规测试
:
./test-em-all.bash
2. 记录跟踪和跨度 ID 的传播
在尝试 Istio 及其组件之前,我们可以通过以下步骤记录跟踪和跨度 ID 的传播:
1.
编辑 ConfigMap
:
kubectl edit cm product-composite
查找以下行并取消注释:
# To see tracing headers, uncomment the following two lines and restart
# the product-composite service
spring.codec.log-request-details: true
logging.level.org.springframework.web.reactive.function.client.ExchangeFunctions: TRACE
-
重启
product-composite微服务 :
kubectl delete pod -l app=product-composite
- 打印日志输出 :
kubectl logs -f -l app=product-composite
- 获取访问令牌并进行请求 :
unset ACCESS_TOKEN
ACCESS_TOKEN=$(curl -k https://writer:secret-writer@minikube.me/oauth2/token -d grant_type=client_credentials -d scope="product:read product:write" -s | jq -r .access_token)
echo $ACCESS_TOKEN
curl -H "Authorization: Bearer $ACCESS_TOKEN" -k https://minikube.me/product-composite/1 -w "%{http_code}\n" -o /dev/null -s
验证命令返回的 HTTP 状态码为 200。
3. 观测服务网格
在使用 Kiali 和 Jaeger 观测服务网格之前,我们需要解决 Kubernetes 活性和就绪性探测产生的噪声问题。可以通过为健康检查使用不同的端口来简化此问题。以下是具体的操作步骤:
1.
启动低流量负载测试
:
ACCESS_TOKEN=$(curl https://writer:secret-writer@minikube.me/oauth2/token -d grant_type=client_credentials -d scope="product:read product:write" -ks | jq .access_token -r)
echo ACCESS_TOKEN=$ACCESS_TOKEN
siege https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN" -c1 -d1 -v
-
使用浏览器访问 Kiali 并进行操作
:
-
打开 Kiali 的 Web UI:
https://kiali.minikube.me。 -
点击
Overview标签。 -
点击
hands-on框中的菜单(右上角的三个垂直点)并选择Graph。 -
点击
Display按钮,取消选择除Response Time、Median和Traffic Animation之外的所有选项。 -
在
Hide…字段中指定name = jaeger以避免视图被发送到 Jaeger 的跟踪信息所杂乱。
-
打开 Kiali 的 Web UI:
-
使用 Jaeger 进行分布式跟踪
:
-
打开 Jaeger 的 Web UI:
https://tracing.minikube.me。 -
点击左侧菜单中的
Service下拉菜单,选择istio-ingressgateway.istio-system服务。 -
点击
Find Trace按钮。
-
打开 Jaeger 的 Web UI:
4. 增强服务网格的安全性
Istio 可以通过以下几种方式增强服务网格的安全性:
-
使用 HTTPS 和证书保护外部端点
:
- Istio 网关对象使用存储在名为
hands-on-certificate
的 Secret 中的 TLS 证书来保护其 HTTPS 端点。
- 这些证书由
cert-manager
根据
istio-system
Helm 图表中的配置创建。
- 可以使用以下命令验证 Istio 入口网关使用的证书:
keytool -printcert -sslserver minikube.me | grep -E "Owner:|Issuer:"
-
使用 OAuth 2.0/OIDC 访问令牌对外部请求进行身份验证
:
- Istio 入口网关可以要求并验证基于 JWT 的 OAuth 2.0/OIDC 访问令牌,以保护服务网格中的微服务免受外部未经身份验证的请求。
-
配置在
_istio_base.yaml模板中,相关的两个清单如下:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: product-composite-request-authentication
spec:
jwtRules:
- forwardOriginalToken: true
issuer: http://auth-server
jwksUri: http://auth-server.hands-on.svc.cluster.local/oauth2/jwks
selector:
matchLabels:
app.kubernetes.io/name: product-composite
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: product-composite-require-jwt
spec:
action: ALLOW
rules:
- {}
selector:
matchLabels:
app.kubernetes.io/name: product-composite
- 可以通过以下步骤验证 `RequestAuthentication` 是否生效:
1. 进行正常请求:
ACCESS_TOKEN=$(curl https://writer:secret-writer@minikube.me/oauth2/token -d grant_type=client_credentials -d scope="product:read product:write" -ks | jq .access_token -r)
echo ACCESS_TOKEN=$ACCESS_TOKEN
curl -k https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN" -i
验证返回的 HTTP 响应状态码为 200。
2. 编辑
RequestAuthentication
对象并临时更改颁发者:
kubectl edit RequestAuthentication product-composite-request-authentication
3. 验证更改:
kubectl get RequestAuthentication product-composite-request-authentication -o yaml
总结
通过以上步骤,我们可以创建一个服务网格,记录跟踪和跨度 ID 的传播,使用 Kiali 和 Jaeger 观测服务网格,并利用 Istio 增强服务网格的安全性。这些操作有助于提高微服务架构的可观测性和管理效率,确保系统的安全性和稳定性。
流程图
graph LR
A[创建服务网格] --> B[构建 Docker 镜像]
B --> C[重新创建命名空间]
C --> D[解析 Helm 依赖]
D --> E[使用 Helm 部署系统]
E --> F[验证 Pod 容器]
F --> G[运行常规测试]
G --> H[记录跟踪和跨度 ID 传播]
H --> I[编辑 ConfigMap]
I --> J[重启微服务]
J --> K[打印日志]
K --> L[获取访问令牌并请求]
L --> M[观测服务网格]
M --> N[启动负载测试]
N --> O[访问 Kiali]
O --> P[使用 Jaeger 跟踪]
P --> Q[增强服务网格安全性]
Q --> R[保护外部端点]
Q --> S[验证外部请求身份]
表格
| 操作步骤 | 描述 |
|---|---|
| 创建服务网格 | 构建 Docker 镜像、重新创建命名空间、解析 Helm 依赖、部署系统、验证 Pod、运行测试 |
| 记录跟踪和跨度 ID 传播 | 编辑 ConfigMap、重启微服务、打印日志、获取访问令牌并请求 |
| 观测服务网格 | 启动负载测试、访问 Kiali、使用 Jaeger 跟踪 |
| 增强服务网格安全性 | 保护外部端点、验证外部请求身份 |
使用服务网格提升可观测性与管理能力
5. 保护外部端点的具体配置分析
在保护外部端点时,我们详细了解了 Istio 网关对象使用的 TLS 证书相关配置。以下是创建证书和相关对象的具体清单内容:
selfsigned-issuer.yaml
用于定义内部自签名 CA:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ca-cert
spec:
isCA: true
commonName: hands-on-ca
secretName: ca-secret
issuerRef:
name: selfsigned-issuer
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-issuer
spec:
ca:
secretName: ca-secret
从上述清单可以看出:
- 创建了一个名为
selfsigned-issuer
的自签名颁发者。
- 使用该颁发者创建了一个自签名证书
ca-cert
,其通用名称为
hands-on-ca
。
- 最后,使用
ca-cert
作为根证书定义了一个自签名 CA
ca-issuer
。
hands-on-certificate.yaml
用于定义网关对象使用的证书:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: hands-on-certificate
spec:
commonName: minikube.me
subject:
...
dnsNames:
- minikube.me
- health.minikube.m
- dashboard.minikube.me
- kiali.minikube.me
- tracing.minikube.me
- prometheus.minikube.me
- grafana.minikube.me
- kibana.minikube.me
- elasticsearch.minikube.me
- mail.minikube.me
issuerRef:
name: ca-issuer
secretName: hands-on-certificate
从这份清单可知:
- 证书名为
hands-on-certificate
,通用名称为
minikube.me
。
- 指定了一些主题的可选额外细节(此处省略)。
- 所有其他主机名被声明为证书中的主题备用名称。
- 使用
ca-issuer
作为颁发者。
-
cert-manager
将 TLS 证书存储在名为
hands-on-certificate
的 Secret 中。
6. 身份验证配置的深入理解
在使用 OAuth 2.0/OIDC 访问令牌对外部请求进行身份验证时,我们配置了
RequestAuthentication
和
AuthorizationPolicy
。下面详细分析这两个对象的作用:
RequestAuthentication
对象
product-composite-request-authentication
配置如下:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: product-composite-request-authentication
spec:
jwtRules:
- forwardOriginalToken: true
issuer: http://auth-server
jwksUri: http://auth-server.hands-on.svc.cluster.local/oauth2/jwks
selector:
matchLabels:
app.kubernetes.io/name: product-composite
其作用为:
- 要求发送到
product-composite
服务的请求必须携带有效的 JWT 编码访问令牌。
- 根据标签选择器
app.kubernetes.io/name: product-composite
选择要进行请求身份验证的服务。
- 允许来自
http://auth-server
颁发者的令牌。
- 使用
http://auth-server.hands-on.svc.cluster.local/oauth2/jwks
URL 获取 JWKS,用于验证访问令牌的数字签名。
- 将访问令牌转发到底层服务(即
product-composite
微服务)。
AuthorizationPolicy
对象
product-composite-require-jwt
配置如下:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: product-composite-require-jwt
spec:
action: ALLOW
rules:
- {}
selector:
matchLabels:
app.kubernetes.io/name: product-composite
该对象配置为允许所有发送到
product-composite
服务的请求,不应用任何授权规则。
7. 服务网格操作注意事项
在整个服务网格的操作过程中,有一些注意事项需要我们关注:
-
访问令牌有效期
:为测试客户端(如
siege
)获取的访问令牌仅在一小时内有效。如果流量意外下降,检查
siege
的输出;如果报告 4XX 而非 200,就需要更新访问令牌。
-
自签名证书问题
:由于使用的是自签名证书,浏览器默认不会信任。大多数浏览器在用户确认安全风险后可以访问页面。对于 Chrome 浏览器,如果提示“您的连接不是私密连接”,可以点击“高级”按钮,然后点击“继续前往…(不安全)”链接。
流程图
graph LR
R --> R1[定义自签名 CA]
R --> R2[定义网关证书]
S --> S1[配置 RequestAuthentication]
S --> S2[配置 AuthorizationPolicy]
R1 --> R3[创建自签名颁发者]
R1 --> R4[创建自签名证书]
R1 --> R5[定义自签名 CA]
R2 --> R6[定义网关证书详情]
S1 --> S3[要求有效令牌]
S1 --> S4[选择服务]
S1 --> S5[允许特定颁发者]
S1 --> S6[获取 JWKS 验证]
S1 --> S7[转发令牌]
S2 --> S8[允许所有请求]
表格
| 操作 | 注意事项 |
|---|---|
| 测试客户端访问 | 访问令牌有效期为一小时,流量异常时检查输出并更新令牌 |
| 浏览器访问 | 自签名证书需用户确认风险,Chrome 可点击高级选项继续访问 |
通过以上对服务网格各个方面的详细介绍,我们可以更全面地了解如何创建、观测和保障服务网格的安全性,从而提升微服务架构的可观测性和管理能力。
超级会员免费看
901

被折叠的 条评论
为什么被折叠?



