Istio 适配器配置与安全策略详解
1. Istio 适配器概述
Istio 1.2 拥有丰富的适配器,如 Zipkin、StatsD、Stackdriver、CloudWatch 等。完整的适配器列表可在 https://istio.io/docs/reference/config/policy-and-telemetry/adapters/ 查看。
2. 适配器组件配置
- Handler :描述如何调用适配器,提供配置相关适配器行为的必要选项。可用的 Handler 列表取决于服务网格中部署的适配器。以
fluentds.config.istio.io适配器为例,其用于将访问日志发送到 fluentd 聚合器守护进程,配置如下:
apiVersion: config.istio.io/v1alpha2
kind: handler
metadata:
name: fluentdhandler
namespace: istio-system
spec:
compiledAdapter: fluentd
params:
address: "fluentd-aggregator-host:port"
- Instance :定义请求需要捕获的数据,数据以属性集的形式表示。属性由名称和类型组成,类型定义了属性所包含的数据种类。Istio 有一组通用属性,列表可在 https://istio.io/docs/reference/config/policy-and-telemetry/attribute-vocabulary/ 查看。适配器只能理解编译在四个模板中的数据,每个模板有一组适配器可以捕获的属性。实例可定义为边车发送的属性到关联适配器模板的映射。获取可用模板列表的命令如下:
$ kubectl get crd -listio=mixer-instance
输出结果如下:
| NAME | CREATED AT |
| — | — |
| apikeys.config.istio.io | 2019-07-14T07:46:06Z |
| authorizations.config.istio.io | 2019-07-14T07:46:06Z |
| checknothings.config.istio.io | 2019-07-14T07:46:06Z |
| edges.config.istio.io | 2019-07-14T07:46:07Z |
| instances.config.istio.io | 2019-07-14T07:46:11Z |
| Kubernetes es.config.istio.io | 2019-07-14T07:46:06Z |
| listentries.config.istio.io | 2019-07-14T07:46:07Z |
| logentries.config.istio.io | 2019-07-14T07:46:07Z |
| metrics.config.istio.io | 2019-07-14T07:46:08Z |
| quotas.config.istio.io | 2019-07-14T07:46:08Z |
| reportnothings.config.istio.io | 2019-07-14T07:46:08Z |
| servicecontrolreports.config.istio.io | 2019-07-14T07:46:08Z |
| tracespans.config.istio.io | 2019-07-14T07:46:09Z |
查看现有实例的命令如下:
$ kubectl get logentries.config.istio.io --all-namespaces
输出结果如下:
| NAMESPACE | NAME | AGE |
| — | — | — |
| istio-system | accesslog | 41d |
| istio-system | tcpaccesslog | 41d |
查看 accesslog 定义的命令如下:
$ kubectl get logentries.config.istio.io accesslog -n istio-system -o yaml
输出结果如下:
apiVersion: config.istio.io/v1alpha2
kind: logentry
metadata:
// REMOVED FOR BREVITY
spec:
monitored_resource_type: '"global"'
severity: '"Info"'
timestamp: request.time
variables:
apiClaims: request.auth.raw_claims | ""
apiKey: request.api_key | request.headers["x-api-key"] | ""
.......
destinationApp: destination.labels["app"] | ""
destinationIp: destination.ip | ip("0.0.0.0")
destinationName: destination.name | ""
latency: response.duration | "0ms"
method: request.method | ""
protocol: request.scheme | context.protocol | "http"
receivedBytes: request.total_size | 0
// REMOVED for brevity
若预编译实例不可用,可使用以下 YAML 配置添加实例:
apiVersion: config.istio.io/v1alpha2
kind: instance
metadata:
name: myaccesslog
namespace: istio-system
spec:
compiledTemplate: logentry
params:
severity: '"info"'
timestamp: request.time
variables:
source: source.labels["app"] | source.workload.name | "unknown"
user: source.user | "unknown"
destination: destination.labels["app"] | destination.workload.name | "unknown"
responseCode: response.code | 0
responseSize: response.size | 0
latency: response.duration | "0ms"
monitored_resource_type: '"UNSPECIFIED"'
- Rules :规则将已部署的 Handler 与已部署的实例组合在一起。在调用关联实例之前,它会根据指定条件匹配请求。规则必须指定 Handler 和实例的完全限定名称。若它们都部署在同一命名空间中,则规则可以使用短名称。以下规则将
accesslog和myaccesslog日志发送到之前创建的fluentdHandler:
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: fluentdrule
namespace: istio-system
spec:
match: "true"
actions:
- handler: fluentdhandler
instances: [ myaccesslog, accesslog ]
部署所有组件的命令如下:
$ kubectl apply -f fluentd-adapter.yaml
使用 curl 命令访问服务,生成日志并发送到 ELK 实例,可在 Kibana 中验证。
3. Istio 安全策略
- Authentication :在分布式架构中,用户请求会跨越多个应用的子请求,每个子请求都需要验证用户身份,通常使用基于令牌的身份验证方式,如 SSO、OAuth 等。Istio 支持多种身份验证机制。
- Transport Authentication :微服务架构中的应用容易受到网络攻击,可通过实现 TLS 协议来保障通信安全。Istio 服务网格通过 Envoy 代理支持 TLS 交换,减轻了每个服务实现 TLS 通信的成本。TLS 协议基于公钥基础设施(PKI),Istio 通过 Citadel 和 Node-Agent 实现 PKI 逻辑。
证书颁发流程如下:
graph LR
A[Istio 节点代理生成私钥和 CSR] --> B[Istio 节点代理将 CSR 和密钥发送到 Citadel 签名]
B --> C[Citadel 验证 CSR 相关凭据并签名生成证书]
C --> D[节点代理将证书和私钥发送到 Envoy 代理]
TLS 通信步骤如下:
graph LR
A[客户端 Envoy 发起与服务器 Envoy 代理的相互 TLS 握手] --> B[客户端 Envoy 代理进行安全命名检查]
B --> C[客户端和服务器 Envoy 代理建立相互 TLS 连接,Istio 转发流量]
C --> D[服务器 Envoy 代理通过本地 TCP 连接将流量转发到服务器服务]
Istio 提供了严格模式和宽松模式,宽松模式允许服务同时接受明文流量和相互 TLS 流量,简化了服务网格的接入过程。Istio 相互 TLS 身份验证通过创建策略进行配置,策略可在网格、命名空间和服务级别创建。
查看网格策略的命令如下:
$ kubectl get meshpolicies.authentication.istio.io -o yaml
配置 STRICT 模式的示例如下:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "strict-policy"
spec:
targets:
- name: webservice
peers:
- mtls:
mode: null
部署策略后,执行 curl 命令会失败,因为 liveness 探测请求失败,可通过以下方式解决:
1. 在应用端口之外的端口进行检查,绕过 Envoy 代理。
2. 配置 ProbeRewrite,将检查请求发送到 Pilot-Agent,再由其发送到应用容器。
启用 ProbeRewrite 的命令如下:
$ kubectl get cm istio-sidecar-injector -n istio-system -o yaml | sed -e "s/ rewriteAppHTTPProbe: false/ rewriteAppHTTPProbe: true/" | kubectl apply -f -
配置 rewriteAppHTTPProbers 注解的示例如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment-6.0
// REMOVED FOR BREVITY
template:
metadata:
labels:
app: webapp
version: v6.0
annotations:
sidecar.istio.io/rewriteAppHTTPProbers: "true"
spec:
containers:
- name: webapp
// REMOVED FOR BREVITY
配置目标规则以指示客户端执行相互 TLS 握手的示例如下:
apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
name: "wb-rule"
namespace: "default"
spec:
host: webservice
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
4. 用户身份验证
Istio 提供基于 OAuth 令牌的身份验证。每个请求都需附带 OAuth 令牌,Envoy 代理会根据配置的 OpenID 提供商验证令牌,令牌以 JSON Web Token (JWT) 格式发送。
Istio 用户身份验证步骤如下:
1. 向授权服务器发起初始请求,交换凭证并生成令牌。生成的 JWT 与一组特定的用户角色和权限相关联。
2. 后续每个请求都必须指定令牌,使用户能够访问该令牌允许的授权路由、服务和资源。
Envoy 代理会验证令牌,并在每个子请求上复制该令牌。
JWT 是一种开放标准(RFC 7519),它以 JSON 对象的形式在各方之间安全地传输信息,该信息经过数字签名,可被验证和信任,常用于指定用户授权。
在进行用户身份验证之前,需要一个 OpenID 提供商,这里以 KeyCloak 为例。添加用户到 KeyCloak 的步骤如下:
1. 使用管理员账户登录 KeyCloak 管理控制台。
2. 在 Master 下拉菜单中点击“Add Realm”,创建一个名为 K8s - dev 的领域。
3. 选择 K8s - dev 领域,点击“Users”打开用户列表页面。
4. 打开“Add User”页面,输入用户名并点击“Save”。
5. 在用户页面,点击“Credentials”标签,为新用户设置临时密码。
配置完成后,会得到 OpenID 端点的详细信息,以下是一些重要的端点:
| 端点名称 | 端点地址 |
| — | — |
| issuer | “http://172.18.0.1:8181/auth/realms/k8s - dev” |
| authorization_endpoint | “http://172.18.0.1:8181/auth/realms/k8s - dev/protocol/OpenID - connect/auth” |
| token_endpoint | “http://172.18.0.1:8181/auth/realms/k8s - dev/protocol/OpenID - connect/token” |
| jwks_uri | “http://172.18.0.1:8181/auth/realms/k8s - dev/protocol/OpenID - connect/certs” |
配置 Istio 用户身份验证的策略示例如下:
apiVersion: "authentication.istio.io/v1alpha1"
kind: "Policy"
metadata:
name: "user - auth"
spec:
targets:
- name: webservice
origins:
- jwt:
issuer: http://172.18.0.1:8181/auth/realms/k8s - dev
jwksUri: http://172.18.0.1:8181/auth/realms/k8s - dev/protocol/OpenID - connect/certs
trigger_rules:
- excluded_paths:
- exact: /health
principalBinding: USE_ORIGIN
在上述配置中:
1. 配置 JWT 设置指向 K8s - dev 领域。
2. 当代理中可能存在两个安全主体(一个来自 mtls 配置,另一个来自用户身份令牌)时,配置绑定主体来自用户令牌。
3. 排除 /health URL 的身份验证,因为 Kubernetes 使用此路径进行存活检查。
测试配置时,执行以下 curl 命令:
$ curl -v http://10.152.183.230/
服务会返回 401 错误代码。要使其正常工作,需要在请求中添加 JWT。可以使用 Postman 生成 JWT,步骤如下:
1. 在 Postman 中选择“Authorization”标签,将类型设置为 OAuth 2.0。
2. 点击“Get New Access Token”,在新表单中填写 OpenID 配置的值。
3. 填写正确的值后,点击“Request Token”。
成功登录后,会返回一个令牌,将其复制并添加到认证头中,再次执行 curl 命令:
$ curl --header "Authorization: Bearer $TOKEN" -v http://10.152.183.230/
5. 总结
通过对 Istio 适配器配置和安全策略的详细介绍,我们了解到 Istio 在日志、追踪以及安全方面的强大功能。在适配器配置方面,通过 Handler、Instance 和 Rules 的组合,可以灵活地配置不同的适配器,满足各种应用场景的需求。在安全策略方面,Istio 提供了完善的身份验证机制,包括传输身份验证和用户身份验证,确保服务之间的通信安全。无论是在微服务架构中保障网络安全,还是实现用户的授权访问,Istio 都提供了有效的解决方案。合理利用 Istio 的这些功能,可以提升系统的可观测性和安全性,为企业的应用开发和部署带来便利。
超级会员免费看
17

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



