重要
本文介绍如何识别 OSM 加载项配置,并将其转换为等效的 Istio 加载项配置。 这并不是一份完整的生产环境迁移操作手册。
本文将 OSM 加载项策略映射到等效的 Istio 加载项策略。 本文中的源和目标均为 Azure Kubernetes 服务 (AKS) 托管加载项。 它不涵盖从上游 Open Service Mesh 迁移到自我管理或开源 Istio 安装的情形。 它以 OSM Bookstore 示例应用程序 作为当前使用 OSM 加载项的用户的参考。 本文有两个独立的部分:
- 将 OSM Bookstore 示例迁移到 Istio 加载项:针对运行 OSM 加载项的现有群集的原地迁移过程。
- Bookstore 策略转换参考:基于干净示例的演练,演示如何在全新集群上将 OSM SMI 策略转换为对应的 Istio 策略。
如果不使用 OSM 并且不熟悉托管的 Istio 加载项,请从 安装 Istio 加载项开始。 如果您当前正在使用 OSM,请先查阅 OSM Bookstore 示例应用程序演练指南,然后再继续。 以下演练内容不会重复 OSM 文档中的内容,并会在相关情况下引用特定主题。 在继续操作之前,请确保了解 Bookstore 应用程序体系结构。
先决条件
具有运行 OSM 加载项的现有 AKS 群集的 Azure 订阅。
对 AKS 群集的访问权限,可在其中启用或禁用托管加载项。
kubectl对群集的访问。OSM Bookstore 示例已部署在
bookbuyer、bookthief、bookstore和bookwarehouse命名空间中。选择要安装的 Istio 修订版。 将
LOCATION设置为 AKS 集群所在的 Azure 区域,然后使用az aks mesh get-revisions命令查找受支持的 Istio 修订版本:export LOCATION=<location>az aks mesh get-revisions --location ${LOCATION} -o table设置本文中使用的变量。 将
REVISION设置为由az aks mesh get-revisions命令返回的修订版本:export RESOURCE_GROUP=<resource-group-name> export CLUSTER=<cluster-name> export REVISION=<revision> export BOOKSTORE_NAMESPACES="bookbuyer bookthief bookstore bookwarehouse"
将 OSM Bookstore 示例迁移到 Istio 附加组件
OSM 加载项和 Istio 加载项不能在同一 AKS 群集上同时运行。 此过程迁移 OSM Bookstore 示例,而无需删除群集、命名空间、服务或工作负荷控制器。 正在运行的 Pod 不会被原地修改。 现有 Pod 会保留其 OSM sidecar,直到其控制器在为托管 Istio 修订版标记命名空间后创建替换 Pod。
Warning
此迁移会导致服务中断。 禁用 OSM 加载项会立即删除 SMI 流量策略强制实施:即使现有 Pod 仍在运行,mTLS 和访问控制也会停止应用。 禁用 OSM 和完成 Istio 推出之间的窗口会让工作负载没有网格级安全或路由策略。 在此期间发生的任何 Pod 替换(滚动重启、扩缩容事件、节点逐出或崩溃循环)都会创建出既不带 OSM 边车代理也不带 Istio 边车代理的 Pod,直到为命名空间添加标签并再次重新创建该 Pod 之后才会恢复正常。 为生产工作负荷规划应用程序停机时间或减少可用性窗口,并首先验证非生产群集中的完整过程。 AKS 计划内维护设置不会计划或控制此手动迁移。
以下迁移使用以下清理顺序:
- 在禁用 OSM 加载项之前保存 SMI 资源。
- 在启用托管 Istio 加载项之前禁用 OSM 加载项。
- 在重新标记命名空间或重启工作负载之前,请删除过时的 OSM 准入 Webhook。
- 除非你自己的验证表明这些 CRD 会阻碍启用、准入或发布,否则在托管式 Istio 启用和工作负载滚动发布过程中,请保留 OSM 和 SMI CRD 不动。
- 在标签交换期间删除过时
openservicemesh.io/*的命名空间标记。 - 使用
istio.io/rev=<revision>.. 标记工作负荷命名空间 - 应用并验证已转换的 Istio 资源,这些资源对于现有工作负荷名称和选择器是安全的。
- 滚动现有工作负荷控制器,以便使用 Istio sidecars 创建替换 Pod。
- 仅在已迁移的 Pod 准备就绪后,才删除残留的 OSM 和 SMI CRD。
验证 OSM Bookstore 状态
验证 OSM 加载项已启用,且受管理的 Istio 加载项未启用:
az aks show \
--resource-group ${RESOURCE_GROUP} \
--name ${CLUSTER} \
--query "{openServiceMesh:addonProfiles.openServiceMesh.enabled, serviceMeshProfile:serviceMeshProfile}"
该值 openServiceMesh.enabled 应为 true.
serviceMeshProfile 的值应为 null,或者在迁移开始前显示 mode: disabled。
验证 OSM 控制平面是否已准备就绪:
kubectl wait -n kube-system --for=condition=Ready pod -l app=osm-controller --timeout=10m
kubectl wait -n kube-system --for=condition=Ready pod -l app=osm-injector --timeout=10m
kubectl wait -n kube-system --for=condition=Ready pod -l app=osm-bootstrap --timeout=10m
验证 Bookstore Pod 是否正在运行,并且包含多个处于就绪状态的容器。 OSM 注入的 Pod 包括 osm-init 初始化容器和 envoy 边车容器。
kubectl get pods -A -o wide | grep -E '^(bookbuyer|bookstore|bookthief|bookwarehouse)'
以下精简示例展示了包含多个容器且已就绪的 Bookstore Pod:
bookbuyer bookbuyer-58c7699cb7-fxzvz 2/2 Running 0 51s 10.224.0.20 aks-nodepool1-32739176-vmss000002 <none> <none>
bookstore bookstore-7696584686-6zdkn 2/2 Running 0 50s 10.224.0.71 aks-nodepool1-32739176-vmss000001 <none> <none>
bookthief bookthief-77bf8c9b76-vswxz 2/2 Running 0 50s 10.224.0.15 aks-nodepool1-32739176-vmss000002 <none> <none>
bookwarehouse bookwarehouse-6b94d668f7-vksf4 2/2 Running 0 49s 10.224.0.82 aks-nodepool1-32739176-vmss000001 <none> <none>
bookwarehouse mysql-0 3/3 Running 0 48s 10.224.0.17 aks-nodepool1-32739176-vmss000002 <none> <none>
确认注入的 Pod 包含 OSM 容器:
for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
kubectl get pods -n ${NAMESPACE} \
-o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\tinit="}{range .spec.initContainers[*]}{.name}{","}{end}{"\tcontainers="}{range .spec.containers[*]}{.name}{","}{end}{"\n"}{end}'
done
验证示例使用的 SMI 资源:
kubectl get traffictargets.access.smi-spec.io,httproutegroups.specs.smi-spec.io,tcproutes.specs.smi-spec.io,trafficsplits.split.smi-spec.io -A
更改网格之前,先检查 Bookbuyer 日志:
kubectl logs -n bookbuyer deploy/bookbuyer -c bookbuyer --tail=20
(可选)启动连续 Bookbuyer 日志流来监视应用程序可用性。 如果你希望日志覆盖整个迁移窗口期,请让该流在命名空间重新标记和工作负载发布期间持续运行。
BOOKBUYER_LOG=bookbuyer-migration.log
kubectl logs -n bookbuyer deploy/bookbuyer -c bookbuyer --timestamps --since=10s -f > ${BOOKBUYER_LOG} 2>&1 &
BOOKBUYER_LOG_PID=$!
保存 SMI 策略配置
在对 OSM 和 SMI API 进行最终清理之前,保存 SMI 资源。 使用这些文件来计划翻译和回滚。
mkdir -p osm-smi-backup
kubectl get traffictargets.access.smi-spec.io -A -o yaml > osm-smi-backup/traffic-targets.yaml
kubectl get httproutegroups.specs.smi-spec.io -A -o yaml > osm-smi-backup/http-route-groups.yaml
kubectl get tcproutes.specs.smi-spec.io -A -o yaml > osm-smi-backup/tcp-routes.yaml
kubectl get trafficsplits.split.smi-spec.io -A -o yaml > osm-smi-backup/traffic-splits.yaml
禁用加载项后,不要依赖剩余 OSM Webhook、CRD、标签或批注作为回滚状态。
使用本文后面的策略示例将保存的 SMI 资源转换为 Istio 资源:
| OSM 资源或行为 | Istio 替代方案 |
|---|---|
| OSM 命名空间载入 |
istio.io/rev=<revision> 命名空间标签 |
| OSM Sidecar 注入 | 为所选修订版本注入 Istio sidecar |
TrafficTarget、 HTTPRouteGroup和 TCPRoute |
AuthorizationPolicy |
TrafficSplit |
VirtualService 和 DestinationRule |
| OSM 宽容流量策略和 mTLS 设置 |
PeerAuthentication 和 AuthorizationPolicy |
在将迁移视为完成之前,请为工作负荷应用并验证已翻译的 Istio 资源。 本节中的 Bookstore 就地步骤用于验证控制平面的变更以及 sidecar 的滚动更新。 它们不会自动应用参考部分中的策略示例,本文后面的干净示例清单必须经过调整,然后才能将其应用到现有命名空间。
禁用 OSM 加载项
禁用 OSM 加载项:
az aks disable-addons \
--resource-group ${RESOURCE_GROUP} \
--name ${CLUSTER} \
--addons open-service-mesh
验证 OSM 加载项是否已禁用:
az aks show \
--resource-group ${RESOURCE_GROUP} \
--name ${CLUSTER} \
--query "{openServiceMesh:addonProfiles.openServiceMesh.enabled, serviceMeshProfile:serviceMeshProfile}"
该值 openServiceMesh.enabled 应为 false 或 null。 在启用托管 Istio 之前,该值 serviceMeshProfile 应保持不变。
确认现有的 Bookstore Pod 是否仍在运行:
kubectl get pods -n bookbuyer
kubectl get pods -n bookthief
kubectl get pods -n bookstore
kubectl get pods -n bookwarehouse
OSM 禁用后,现有 Pod 仍可能包含 OSM 边车容器。 这是预期的。 它们会在该流程的后续步骤中其控制器轮换时被替换。
删除残留的 OSM 准入阻碍项
检查残留的 OSM 准入配置是否仍然影响工作负载命名空间:
kubectl run osm-admission-probe \
--namespace bookbuyer \
--image mcr.azk8s.cn/oss/nginx/nginx:1.25.5 \
--restart Never \
--dry-run=server \
-o yaml
删除 AKS OSM 附加 Webhook 配置。 如果试运行失败是因为 Kubernetes 无法调用 osm-injector 服务,则此清理操作会清除准入阻碍。
kubectl delete mutatingwebhookconfiguration aks-osm-webhook-osm --ignore-not-found
kubectl delete validatingwebhookconfiguration aks-osm-validator-mesh-osm --ignore-not-found
在重新标记命名空间或重启工作负载之前删除这些 Webhook 配置。 损坏的残差 OSM Webhook 可以阻止 Pod 创建,以便进行验证、工作负荷推出或回滚测试。
确认在清理 Webhook 后服务器端 Pod 准入成功:
kubectl run osm-admission-probe \
--namespace bookbuyer \
--image mcr.azk8s.cn/oss/nginx/nginx:1.25.5 \
--restart Never \
--dry-run=server \
-o yaml
确认不再有任何 OSM 准入 Webhook 存在:
kubectl get mutatingwebhookconfiguration,validatingwebhookconfiguration | grep -i osm || true
在启用托管 Istio 之前,盘点所有剩余的 OSM 和 SMI CRD。 除非验证表明这些 CRD 会阻碍启用、准入或发布,否则请保留这些 CRD。
kubectl get crd | grep -E 'openservicemesh.io|smi-spec.io' || true
启用 Istio 插件并迁移工作负载
启用托管的 Istio 加载项:
az aks mesh enable \
--resource-group ${RESOURCE_GROUP} \
--name ${CLUSTER} \
--revision ${REVISION}
验证托管 Istio 加载项状态:
az aks show \
--resource-group ${RESOURCE_GROUP} \
--name ${CLUSTER} \
--query "{mode:serviceMeshProfile.mode, revisions:serviceMeshProfile.istio.revisions}"
该值 mode 应为 Istio,修订列表应包含所选修订。
等待 Istio 控制平面和注入器 Webhook:
kubectl wait -n aks-istio-system --for=condition=Ready pod -l app=istiod --timeout=10m
kubectl get mutatingwebhookconfiguration | grep istio-sidecar-injector
删除过时的 OSM 命名空间标记,并使用托管 Istio 修订版标记 Bookstore 命名空间。 请勿与 AKS 托管的 Istio 加载项一起使用 istio-injection=enabled 。
for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
kubectl label namespace ${NAMESPACE} openservicemesh.io/monitored-by- --overwrite
kubectl annotate namespace ${NAMESPACE} openservicemesh.io/sidecar-injection- --overwrite
kubectl label namespace ${NAMESPACE} istio.io/rev=${REVISION} --overwrite
done
在滚动控制器之前,应用并验证已转换的 Istio 资源,这些资源对于现有工作负荷名称和选择器是安全的。 具体是哪些文件,取决于您保存并翻译的 SMI 资源。
kubectl apply -f translated-istio-resources.yaml
kubectl get peerauthentication,authorizationpolicy,destinationrule,virtualservice -A
在针对工作负荷验证等效的 Istio 策略和路由行为之前,请勿删除 OSM 或 SMI API。
滚动现有控制器,以便 Kubernetes 使用 Istio sidecars 创建替换 Pod。 以下顺序与示例验证流匹配:
kubectl rollout restart -n bookwarehouse deployment/bookwarehouse
kubectl rollout status -n bookwarehouse deployment/bookwarehouse --timeout=10m
kubectl rollout restart -n bookwarehouse statefulset/mysql
kubectl rollout status -n bookwarehouse statefulset/mysql --timeout=10m
kubectl rollout restart -n bookstore deployment/bookstore
kubectl rollout status -n bookstore deployment/bookstore --timeout=10m
kubectl rollout restart -n bookthief deployment/bookthief
kubectl rollout status -n bookthief deployment/bookthief --timeout=10m
kubectl rollout restart -n bookbuyer deployment/bookbuyer
kubectl rollout status -n bookbuyer deployment/bookbuyer --timeout=10m
验证更换用 Pod 是否包含 istio-proxy:
for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
kubectl get pods -n ${NAMESPACE} \
-o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{"\tinit="}{range .spec.initContainers[*]}{.name}{","}{end}{"\tcontainers="}{range .spec.containers[*]}{.name}{","}{end}{"\n"}{end}'
done
上线后检查 Bookbuyer:
kubectl logs -n bookbuyer deploy/bookbuyer -c bookbuyer --tail=20
如果启动 Bookbuyer 日志流,请停止它并检查收集的样本。 在将日志用作可用性证据之前,请确认时间戳涵盖重新标记和发布窗口。
kill ${BOOKBUYER_LOG_PID}
wait ${BOOKBUYER_LOG_PID} 2>/dev/null || true
grep "MAESTRO! THIS TEST FAILED!" ${BOOKBUYER_LOG} || true
grep "MAESTRO! THIS TEST SUCCEEDED!" ${BOOKBUYER_LOG} | tail
迁移后的 Pod 就绪后,请检查 CRD 清单,并删除残留的 OSM 和 SMI CRD,作为最后的清理步骤。 删除 CRD 会删除群集中该 CRD 的所有自定义资源,而不仅仅是 Bookstore 示例。 在确认没有剩余工作负荷依赖于 OSM 或 SMI 资源之前,请不要运行此清理。
kubectl delete crd \
egresses.policy.openservicemesh.io \
httproutegroups.specs.smi-spec.io \
ingressbackends.policy.openservicemesh.io \
meshconfigs.config.openservicemesh.io \
meshrootcertificates.config.openservicemesh.io \
retries.policy.openservicemesh.io \
tcproutes.specs.smi-spec.io \
trafficsplits.split.smi-spec.io \
traffictargets.access.smi-spec.io \
upstreamtrafficsettings.policy.openservicemesh.io \
--ignore-not-found
验证最终附加组件和剩余 OSM 状态:
az aks show \
--resource-group ${RESOURCE_GROUP} \
--name ${CLUSTER} \
--query "{openServiceMesh:addonProfiles.openServiceMesh.enabled, serviceMeshProfile:serviceMeshProfile}"
kubectl get mutatingwebhookconfiguration,validatingwebhookconfiguration | grep -i osm || true
kubectl get crd | grep -E 'openservicemesh.io|smi-spec.io' || true
最终的 AKS 状态应为 OSM 处于禁用状态,且托管 Istio 处于启用状态。 如果删除了剩余 OSM 和 SMI CRD,则剩余 OSM 资源检查不应返回任何资源。
书店政策翻译参考
本文的其余部分使用干净的 Bookstore 示例部署来演示如何将 OSM SMI 资源和工作负荷清单转换为 Istio 资源。 在迁移过程中,对现有清单文件应用相同类型的更改,并对现有工作负载控制器执行原地滚动更新,而不是删除后再重新创建应用程序。
注释
在单独的群集中运行策略转换引用,或者在运行示例部署命令之前删除现有的 Bookstore 命名空间。 如果命名空间已存在,命令 kubectl create namespace 将失败。 目标群集必须已启用托管的 Istio 加载项。
若要允许 Istio 管理 OSM Bookstore 应用程序,请更新现有的 Bookstore 和 MySQL 服务清单。
书店修改
在转换 OSM 流量策略之前,请查看 Istio 如何处理 流量管理。
Istio 使用 VirtualService 和 DestinationRule 的组合进行流量路由。 在继续操作之前,请查看虚拟服务和目标规则的概念。
Istio 虚拟服务为请求主机(即服务名称)的客户端定义路由规则。 目标规则定义该服务的流量策略。
对 Istio Bookstore 服务和部署所做的更改,使 Bookstore 应用程序继续位于 bookstore 服务之后。 OSM traffic-access-v1.yaml 清单的 Istio 版本显示在 “创建 Pod”、“服务和服务帐户”中。
MySQL 的修改
只需在服务配置中更改 MySQL StatefulSet。 根据服务规范,OSM 需要该 targetPort 属性和 appProtocol 属性。 Istio 不需要这些属性。 保留服务名称, mysql 因为 Bookstore 示例和 MySQL StatefulSet 使用该名称。 以下更新的服务如以下示例所示:
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: bookwarehouse
labels:
app: mysql
service: mysql
spec:
ports:
- port: 3306
name: tcp
selector:
app: mysql
clusterIP: None
部署修改后的 Bookstore 应用程序
与 OSM Bookstore 演练类似,该示例从书店应用程序的新安装开始。 此示例部署演示策略转换流。 对于现有工作负载,请使用本文前面的就地迁移模式。
创建命名空间
kubectl create namespace bookstore
kubectl create namespace bookbuyer
kubectl create namespace bookthief
kubectl create namespace bookwarehouse
为 Istio sidecar 注入添加命名空间标签
对于 OSM,使用命令 osm namespace add <namespace> 为 OSM 控制器创建了命名空间所需的批注,以添加自动 sidecar 注入。 使用托管的 Istio 加载项,使用已安装的 Istio 修订版标记命名空间,以允许 Istio 控制器注入 Envoy sidecar 代理。 默认的 istio-injection=enabled 标签不会为 Istio 附加组件启用边车注入。
for NAMESPACE in ${BOOKSTORE_NAMESPACES}; do
kubectl label namespace ${NAMESPACE} istio.io/rev=${REVISION}
done
为 Bookstore 部署 Istio 虚拟服务
为 bookstore 服务部署虚拟服务。
kubectl apply -f - <<EOF
# Create bookstore virtual service
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookstore-virtualservice
namespace: bookstore
spec:
hosts:
- bookstore
http:
- route:
- destination:
host: bookstore
EOF
创建 Pod、服务和服务帐户
使用包含前面演练中讨论的修改的单个清单文件来部署bookbuyer、bookthief、bookstore和bookwarehousemysql应用程序。
kubectl apply -f - <<EOF
##################################################################################################
# bookbuyer service
##################################################################################################
---
# Create bookbuyer Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookbuyer
namespace: bookbuyer
---
# Create bookbuyer Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookbuyer
namespace: bookbuyer
spec:
replicas: 1
selector:
matchLabels:
app: bookbuyer
version: v1
template:
metadata:
labels:
app: bookbuyer
version: v1
spec:
serviceAccountName: bookbuyer
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookbuyer
image: openservicemesh/bookbuyer:latest-main
imagePullPolicy: Always
command: ["/bookbuyer"]
env:
- name: "BOOKSTORE_NAMESPACE"
value: bookstore
- name: "BOOKSTORE_SVC"
value: bookstore
---
##################################################################################################
# bookthief service
##################################################################################################
---
# Create bookthief ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookthief
namespace: bookthief
---
# Create bookthief Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookthief
namespace: bookthief
spec:
replicas: 1
selector:
matchLabels:
app: bookthief
template:
metadata:
labels:
app: bookthief
version: v1
spec:
serviceAccountName: bookthief
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookthief
image: openservicemesh/bookthief:latest-main
imagePullPolicy: Always
command: ["/bookthief"]
env:
- name: "BOOKSTORE_NAMESPACE"
value: bookstore
- name: "BOOKSTORE_SVC"
value: bookstore
- name: "BOOKTHIEF_EXPECTED_RESPONSE_CODE"
value: "503"
---
##################################################################################################
# bookstore service version 1 & 2
##################################################################################################
---
# Create bookstore Service
apiVersion: v1
kind: Service
metadata:
name: bookstore
namespace: bookstore
labels:
app: bookstore
spec:
ports:
- port: 14001
name: bookstore-port
selector:
app: bookstore
---
# Create bookstore Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookstore
namespace: bookstore
---
# Create bookstore-v1 Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookstore-v1
namespace: bookstore
spec:
replicas: 1
selector:
matchLabels:
app: bookstore
version: v1
template:
metadata:
labels:
app: bookstore
version: v1
spec:
serviceAccountName: bookstore
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookstore
image: openservicemesh/bookstore:latest-main
imagePullPolicy: Always
ports:
- containerPort: 14001
name: web
command: ["/bookstore"]
args: ["--port", "14001"]
env:
- name: BOOKWAREHOUSE_NAMESPACE
value: bookwarehouse
- name: IDENTITY
value: bookstore-v1
##################################################################################################
# bookwarehouse service
##################################################################################################
---
# Create bookwarehouse Service Account
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookwarehouse
namespace: bookwarehouse
---
# Create bookwarehouse Service
apiVersion: v1
kind: Service
metadata:
name: bookwarehouse
namespace: bookwarehouse
labels:
app: bookwarehouse
spec:
ports:
- port: 14001
name: bookwarehouse-port
selector:
app: bookwarehouse
---
# Create bookwarehouse Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: bookwarehouse
namespace: bookwarehouse
spec:
replicas: 1
selector:
matchLabels:
app: bookwarehouse
template:
metadata:
labels:
app: bookwarehouse
version: v1
spec:
serviceAccountName: bookwarehouse
nodeSelector:
kubernetes.io/arch: amd64
kubernetes.io/os: linux
containers:
- name: bookwarehouse
image: openservicemesh/bookwarehouse:latest-main
imagePullPolicy: Always
command: ["/bookwarehouse"]
##################################################################################################
# mysql service
##################################################################################################
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: mysql
namespace: bookwarehouse
---
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: bookwarehouse
labels:
app: mysql
service: mysql
spec:
ports:
- port: 3306
name: tcp
selector:
app: mysql
clusterIP: None
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
namespace: bookwarehouse
spec:
serviceName: mysql
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
serviceAccountName: mysql
nodeSelector:
kubernetes.io/os: linux
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: mypassword
- name: MYSQL_DATABASE
value: booksdemo
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- mountPath: /mysql-data
name: data
readinessProbe:
tcpSocket:
port: 3306
initialDelaySeconds: 15
periodSeconds: 10
volumes:
- name: data
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 250M
EOF
若要查看群集上的这些资源,请运行以下命令:
kubectl get pods,deployments,serviceaccounts -n bookbuyer
kubectl get pods,deployments,serviceaccounts -n bookthief
kubectl get pods,deployments,serviceaccounts,services,endpoints -n bookstore
kubectl get pods,deployments,serviceaccounts,services,endpoints -n bookwarehouse
查看应用程序 UI
与原始 OSM 演练类似,如果克隆了 OSM 存储库,则可以使用端口转发脚本查看应用程序 UI。 有关详细信息,请参阅 查看应用程序 UI。 目前,仅查看 bookbuyer 和 bookthief 界面。
cp .env.example .env
bash <<EOF
./scripts/port-forward-bookbuyer-ui.sh &
./scripts/port-forward-bookthief-ui.sh &
wait
EOF
在浏览器中,打开以下 URL:
http://localhost:8080 - 购书者
配置 Istio 的流量策略
为了使 Istio 译文与原始 OSM Bookstore 演练指南保持一致,请先从 OSM 的宽松流量策略模式开始。 在未部署特定SMI 流量访问控制规则时,OSM 的宽松流量策略模式会允许或拒绝网格中的流量。 此模式允许用户将应用程序加入网格,并在定义显式允许规则之前获取 mTLS 加密。 可以通过 OSM 的 MeshConfig 将此值设置为 true 或 false。
Istio 以不同的方式处理 mTLS 的实施。 与 OSM 不同,Istio 的宽松模式会自动将 sidecar 代理配置为使用 mTLS,并允许服务同时接受纯文本和 mTLS 流量。 使用 Istio PeerAuthentication 设置等效于 OSM 的宽松模式配置。 可以为命名空间或整个网格配置 PeerAuthentication 。 有关详细信息,请阅读 Istio Mutual TLS 迁移文章。
在 Bookstore 命名空间上强制实施 Istio 严格模式
请记住,与 OSM 的宽松模式一样,Istio 的配置 PeerAuthentication 仅适用于 mTLS 强制实施。 Istio 使用 AuthorizationPolicy 配置来处理七层策略,例如 OSM 的 HTTPRouteGroups 中使用的策略。
将 bookbuyer、bookthief、bookstore 和 bookwarehouse 命名空间置于 Istio 的 mTLS 严格模式下。
kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: bookbuyer
namespace: bookbuyer
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: bookthief
namespace: bookthief
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: bookstore
namespace: bookstore
spec:
mtls:
mode: STRICT
---
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: bookwarehouse
namespace: bookwarehouse
spec:
mtls:
mode: STRICT
EOF
部署 Istio 访问控制策略
OSM 使用 SMI 流量目标和 SMI 流量规范资源来定义应用程序通信的访问控制和路由策略。 Istio 通过 AuthorizationPolicy 配置提供类似的细粒度控制。
以下示例展示了如何转换 bookstore TrafficTarget 策略,该策略允许 bookbuyer 使用特定的第 7 层路径、标头和方法与 bookstore 通信。 此内容是 traffic-access-v1.yaml 清单的一部分。
kind: TrafficTarget
apiVersion: access.smi-spec.io/v1alpha3
metadata:
name: bookstore
namespace: bookstore
spec:
destination:
kind: ServiceAccount
name: bookstore
namespace: bookstore
rules:
- kind: HTTPRouteGroup
name: bookstore-service-routes
matches:
- buy-a-book
- books-bought
sources:
- kind: ServiceAccount
name: bookbuyer
namespace: bookbuyer
---
apiVersion: specs.smi-spec.io/v1alpha4
kind: HTTPRouteGroup
metadata:
name: bookstore-service-routes
namespace: bookstore
spec:
matches:
- name: books-bought
pathRegex: /books-bought
methods:
- GET
headers:
- "user-agent": ".*-http-client/*.*"
- "client-app": "bookbuyer"
- name: buy-a-book
pathRegex: ".*a-book.*new"
methods:
- GET
在 TrafficTarget 策略中, spec.destination 定义目标服务并 spec.sources 定义授权的源服务。 在此示例中, bookbuyer 可以与书店通信。 等效的 Istio AuthorizationPolicy 如以下示例所示:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: bookstore
namespace: bookstore
spec:
selector:
matchLabels:
app: bookstore
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookbuyer/bookbuyer"]
在 Istio AuthorizationPolicy中,OSM TrafficTarget 目标服务映射到策略命名空间和选择器标签匹配。 源服务映射到 source.serviceAccounts 下的 rules.from 属性。
除了 OSM TrafficTarget 中的源配置和目标配置外,OSM 还绑定 HTTPRouteGroup 以定义源的第 7 层授权。 以下 HTTPRouteGroup 包含两个用于允许的源服务的 matches。
apiVersion: specs.smi-spec.io/v1alpha4
kind: HTTPRouteGroup
metadata:
name: bookstore-service-routes
namespace: bookstore
spec:
matches:
- name: books-bought
pathRegex: /books-bought
methods:
- GET
headers:
- "user-agent": ".*-http-client/*.*"
- "client-app": "bookbuyer"
- name: buy-a-book
pathRegex: ".*a-book.*new"
methods:
- GET
此books-bought匹配允许源通过使用带有 user-agent 和 client-app 标头信息的/books-bought方法访问GET路径。 该buy-a-book匹配项使用正则表达式来匹配包含.*a-book.*new且使用GET方法的路径。
在 Istio AuthorizationPolicy的规则部分中定义这些 OSM HTTPRouteGroup 配置。 将源、操作和请求头条件保留在同一条规则中,以免它们各自单独允许请求。 Istio AuthorizationPolicy 字符串字段支持精确、前缀、后缀和状态匹配,而不是任意 SMI 正则表达式。 以下示例使用与 Bookstore 示例匹配的确切路径和 Go HTTP 客户端用户代理前缀。 对于工作负荷,请将每个 SMI pathRegex 和标头正则表达式转换为显式 Istio 匹配,以保留预期访问。
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "bookstore"
namespace: bookstore
spec:
selector:
matchLabels:
app: bookstore
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookbuyer/bookbuyer"]
to:
- operation:
methods: ["GET"]
paths: ["/books-bought"]
when:
- key: request.headers[user-agent]
values: ["Go-http-client/*"]
- key: request.headers[client-app]
values: ["bookbuyer"]
- from:
- source:
serviceAccounts: ["bookbuyer/bookbuyer"]
to:
- operation:
methods: ["GET"]
paths: ["/buy-a-book/new"]
将由 OSM 迁移而来的 traffic-access-v1.yaml 清单部署为 Istio AuthorizationPolicy。 bookthief 没有对应的 AuthorizationPolicy,因此 bookthief UI 不应再从 bookstore v1 累加图书数量:
kubectl apply -f - <<EOF
##################################################################################################
# bookstore policy
##################################################################################################
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "bookstore"
namespace: bookstore
spec:
selector:
matchLabels:
app: bookstore
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookbuyer/bookbuyer"]
to:
- operation:
methods: ["GET"]
paths: ["/books-bought"]
when:
- key: request.headers[user-agent]
values: ["Go-http-client/*"]
- key: request.headers[client-app]
values: ["bookbuyer"]
- from:
- source:
serviceAccounts: ["bookbuyer/bookbuyer"]
to:
- operation:
methods: ["GET"]
paths: ["/buy-a-book/new"]
---
##################################################################################################
# bookwarehouse policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "bookwarehouse"
namespace: bookwarehouse
spec:
selector:
matchLabels:
app: bookwarehouse
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookstore/bookstore"]
to:
- operation:
methods: ["POST"]
---
##################################################################################################
# mysql policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "mysql"
namespace: bookwarehouse
spec:
selector:
matchLabels:
app: mysql
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookwarehouse/bookwarehouse"]
to:
- operation:
ports: ["3306"]
EOF
允许 Bookthief 应用程序访问 Bookstore
目前没有 AuthorizationPolicy 允许 bookthief 与书店通信。 部署以下内容 AuthorizationPolicy 以允许 bookthief 与书店通信。 请注意书店政策中新增的允许 bookthief 访问的规则。
kubectl apply -f - <<EOF
##################################################################################################
# bookstore policy
##################################################################################################
apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
name: "bookstore"
namespace: bookstore
spec:
selector:
matchLabels:
app: bookstore
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookbuyer/bookbuyer", "bookthief/bookthief"]
to:
- operation:
methods: ["GET"]
paths: ["/books-bought"]
when:
- key: request.headers[user-agent]
values: ["Go-http-client/*"]
- key: request.headers[client-app]
values: ["bookbuyer"]
- from:
- source:
serviceAccounts: ["bookbuyer/bookbuyer", "bookthief/bookthief"]
to:
- operation:
methods: ["GET"]
paths: ["/buy-a-book/new"]
---
##################################################################################################
# bookwarehouse policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "bookwarehouse"
namespace: bookwarehouse
spec:
selector:
matchLabels:
app: bookwarehouse
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookstore/bookstore"]
to:
- operation:
methods: ["POST"]
---
##################################################################################################
# mysql policy
##################################################################################################
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: "mysql"
namespace: bookwarehouse
spec:
selector:
matchLabels:
app: mysql
action: ALLOW
rules:
- from:
- source:
serviceAccounts: ["bookwarehouse/bookwarehouse"]
to:
- operation:
ports: ["3306"]
EOF
Bookthief UI 现在应能够从 bookstore 中增加图书数量。
概要
本演练演示如何将 OSM 策略迁移到 Istio 策略。 若要了解如何在 AKS 上部署和操作托管 的 Istio 加载项,请参阅安装 Istio 加载项。 如果需要有关 Istio API 和流量管理行为的背景信息,请查看上游 Istio 概念 。