在华为云CCE中使用Kmesh
Kmesh是一个基于eBPF和可编程内核实现的高性能服务网格(Service Mesh)数据平面软件。通过将流量管理卸载到内核,Kmesh允许在网格内进行服务通信,而不需要经过代理软件,大大减少了流量转发路径,有效提升了服务访问的转发性能。
Kmesh的双引擎模式使用eBPF来拦截内核空间的流量,并部署Waypoint Proxy来处理复杂的L7流量管理,从而在内核空间(eBPF)和用户空间(Waypoint)之间分离L4和L7治理。与Istio的Ambient Mesh相比,它将延迟降低了30%。与内核原生模式相比,双引擎模式不需要内核增强,适用性更广。
本文档详细描述了在CCE集群上部署Kmesh双引擎模式的操作指导,满足用户在CCE上使用Kmesh的需求。
前提条件
- 创建v1.28及以上版本的CCE集群并添加节点,具体操作步骤请参考购买Standard/Turbo集群和创建节点。
在本文中使用的是VPC网络模型或容器隧道网络模型的CCE Standard集群。且在选择节点时,请注意新创建节点的内核版本必须为5.10及以上,因此本文使用的节点操作系统为Ubuntu 22.04。
- 准备一台可访问公网的虚拟机,使用kubectl连接集群并安装Helm。
步骤一:安装Service Mesh控制平面
Kmesh作为Service Mesh的数据面,与Service Mesh的控制面通过xDS协议进行通信。本文使用的是Istiod作为Kmesh的控制平面。理论上,任何支持xDS协议的控制平面都可以作为Kmesh的控制平面。具体操作请参见Kmesh快速入门。
- 登录安装kubectl的虚拟机,添加istio仓库。
helm repo add istio https://istio-release.storage.googleapis.com/charts helm repo update
- 安装istio-base模板:
kubectl create namespace istio-system helm install istio-base istio/base -n istio-system
- 安装istiod模板:
helm install istiod istio/istiod --namespace istio-system --set pilot.env.PILOT_ENABLE_AMBIENT=true
必须设置pilot.env.PILOT_ENABLE_AMBIENT=true参数,否则Kmesh将无法与istiod建立grpc连接。
执行以下命令查看结果。kubectl get svc -n istio-system | grep istiod
回显如下:istiod ClusterIP 10.247.51.34 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 4h8m
- 安装Kubernetes Gateway API CRD。
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \ { kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=444631bfe06f3bcca5d0eadf1857eac1d369421d" | kubectl apply -f -; }
步骤二:安装Kmesh
- 执行以下命令,将Kmesh的Helm包和kmeshctl工具下载到本地。
# download helm package curl -L -o kmesh-pakcage.tgz https://github.com/kmesh-net/kmesh/releases/download/v1.0.0/kmesh-helm-v1.0.0.tgz tar -zxvf kmesh-pakcage.tgz # download kmeshctl curl -L -o kmeshctl https://github.com/kmesh-net/kmesh/releases/download/v1.0.0/kmeshctl-linux-amd64
- 使用Helm安装Kmesh。
helm install kmesh ./kmesh-helm -n kmesh-system --create-namespace
- 执行安装命令后,执行以下命令查看Kmesh启动状态。
kubectl get pod -A | grep kmesh
回显如下:
kmesh-system kmesh-dc5l8 1/1 Running 0 4h25m
- 执行以下命令,查看Kmesh运行状态。
kubectl logs -n kmesh-system kmesh-dc5l8
回显如下:
time="2025-04-15T13:17:12Z" level=info msg="FLAG: --bpf-fs-path=\"/sys/fs/bpf\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --cgroup2-path=\"/mnt/kmesh_cgroup2\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --cni-etc-path=\"/etc/cni/net.d\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --conflist-name=\"\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --enable-bypass=\"false\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --enable-ipsec=\"false\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --enable-mda=\"false\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --enable-secret-manager=\"false\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --help=\"false\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --mode=\"dual-engine\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --monitoring=\"true\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --plugin-cni-chained=\"true\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="FLAG: --profiling=\"false\"" subsys=manager time="2025-04-15T13:17:12Z" level=info msg="kmesh start with Normal" subsys=bpf time="2025-04-15T13:17:14Z" level=info msg="bpf loader start successfully" subsys=manager time="2025-04-15T13:17:14Z" level=info msg="start kmesh manage controller successfully" subsys=controller time="2025-04-15T13:17:14Z" level=info msg="proxy ztunnel~192.168.1.174~kmesh-dc5l8.kmesh-system~kmesh-system.svc.cluster.local connect to discovery address istiod.istio-system.svc:15012" subsys=controller/config time="2025-04-15T13:17:14Z" level=info msg="controller start successfully" subsys=manager time="2025-04-15T13:17:14Z" level=info msg="start write CNI config" subsys="cni installer" time="2025-04-15T13:17:14Z" level=info msg="kmesh cni use chained\n" subsys="cni installer" time="2025-04-15T13:17:14Z" level=info msg="reload authz config from last epoch" subsys=workload_controller time="2025-04-15T13:17:14Z" level=info msg="Copied /usr/bin/kmesh-cni to /opt/cni/bin." subsys="cni installer" time="2025-04-15T13:17:14Z" level=info msg="wrote kubeconfig file /etc/cni/net.d/kmesh-cni-kubeconfig" subsys="cni installer" time="2025-04-15T13:17:14Z" level=info msg="cni config file: /etc/cni/net.d/10-kindnet.conflist" subsys="cni installer" time="2025-04-15T13:17:14Z" level=info msg="start cni successfully" subsys=manager time="2025-04-15T13:17:14Z" level=info msg="start watching file /var/run/secrets/kubernetes.io/serviceaccount/token" subsys="cni installer"
步骤三:使用Kmesh
- 使用Kmesh管理命名空间,即为default命名空间添加istio.io/dataplane-mode=Kmesh标签。
kubectl label namespace default istio.io/dataplane-mode=Kmesh
- 查看Kmesh管理的命名空间。
kubectl get namespace -L istio.io/dataplane-mode
回显如下:
NAME STATUS AGE DATAPLANE-MODE default Active 92d Kmesh ...
- 部署Bookinfo示例应用。
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/bookinfo/platform/kube/bookinfo.yaml
- 部署sleep应用作为curl客户端。
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.21/samples/sleep/sleep.yaml
- 安装Waypoint。Waypoint可以在命名空间、服务和Pod维度使用,还可以在一个命名空间内安装不同粒度的多个Waypoint。使用Waypoint时需要添加istio.io/use-waypoint标签,标签值为Waypoint名称。您还可以使用--image指定自定义的Waypoint镜像,默认情况下为ghcr.io/kmesh-net/waypoint:{VERSION}。在本文示例中为命名空间配置Waypoint。更多详情可以参考安装Waypoint。
kmeshctl waypoint apply -n default --enroll-namespace --image ghcr.io/kmesh-net/waypoint:latest
回显如下:
waypoint default/waypoint applied namespace default labels with "istio.io/use-waypoint: waypoint"
- 查看Pod:
kubectl get pod
回显如下:
NAME READY STATUS RESTARTS AGE details-v1-86545f5dfb-p6kgw 1/1 Running 0 22m productpage-v1-7c74cbdbcc-tnk7w 1/1 Running 0 22m ratings-v1-57544668d4-vx9h2 1/1 Running 0 22m reviews-v1-5f58978c56-xqjtz 1/1 Running 0 22m reviews-v2-7bd564ffc6-pdskr 1/1 Running 0 22m reviews-v3-7dfb7c4b64-bzjm8 1/1 Running 0 22m sleep-5fcd8fd6c8-9wj7l 1/1 Running 0 18m waypoint-75686498f6-ksrnh 1/1 Running 0 9m15s
- 测试bookinfo按预期工作。
kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o "<title>.*</title>"
回显如下:
<title>Simple Bookstore App</title>
步骤四:使用基于权重的路由
- 配置基于权重的路由,将流量路由配置为将90%的请求发送到reviews-v1,将10%的请求发送到reviews-v2:
kubectl apply -f -<<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 90 - destination: host: reviews subset: v2 weight: 10 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews trafficPolicy: loadBalancer: simple: RANDOM subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 - name: v3 labels: version: v3 EOF
- 确认大约90%的流量都会进入reviews-v1。
kubectl exec deploy/sleep -- sh -c "for i in \$(seq 1 100); do curl -s http://productpage:9080/productpage | grep reviews-v.-; done"
回显如下:
<u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v2-7bd564ffc6-pdskr</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v2-7bd564ffc6-pdskr</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u> <u>reviews-v1-5f58978c56-xqjtz</u>
由于默认命名空间已经由Kmesh管理,并且为默认命名空间部署了一个Waypoint代理,因此所有发送到reviews服务的流量都将由Kmesh转发到Waypoint。Waypoint会根据我们设置的路由规则,将90%的请求发送到reviews-v1,10%的请求发送到reviews-v2。