Kubernetes / Linux Note / Virtualization / 运维笔记

虚机网格(istio)管理实战篇

Einic Yeo · 11月17日 · 2023年 · · ·

为什么需要将虚机纳入网格管理

网格作为下一代的微服务整体解决方案,需要对容器和虚机都具有纳管治理的能力。尤其是对于传统应用上云的场景,用户业务很多是跑在虚机上。如果不具备虚机接入能力,无法适配用户业务部署场景。

虚机接入网格后上具有的功能

  1. DNS和服务发现能力:可以在虚机上通过k8s的svc dns名,直接访问一个网格中的服务;在k8s中可以直接通过虚机映射的服务名直接访问到虚机上的服务。
  2. 观测能力:可以在网格中看到虚机的流量、链路遥测信息
  3. 流量治理能力:流量双向加密mtls、限流熔断等

虚机接入网格整体架构图

接入准备

环境信息:

k8s: 两节点,master 10.253.17.27

节点IP角色
node110.253.17.27k8s master
node210.253.17.28k8s slave
node310.253.17.29虚机vm
svc网络pod网络
10.233.0.0/1810.233.64.0/18

通过以下命令可查容器网络 kubectl-n kube-systemgetcm kubeadm-co版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!nfig-oyaml|less

  • 根据虚机CPU架构类型X86 ARM,下载linux安装包: https://gcsweb.istio.io/gcs/istio-release/releases/1.11.3/

准备

参考istio官网

  • 设置环境变量
VM_APP="hello-service" #<将在这台虚机上运行的应用名> 
VM_NAMESPACE="vm" #"<您的服务所在的命名空间>" 
WORK_DIR="$HOME/vm" #"<证书工作目录>" 
SERVICE_ACCOUNT="vm-sa" #"<为这台虚机提供的 Kubernetes 的服务账号名称>" 
CLUSTER_NETWORK=""
VM_NETWORK=""
CLUSTER="Kubernetes"
  • 创建工作目录
mkdir -p "${WORK_DIR}"
cd ${WORK_DIR}

istio 控制面配置

  • 生成以下yaml,准备Istio的cr
cat <<EOF > ./vm‐cluster.yaml 
apiVersion: install.istio.io/v1alpha1 
kind: IstioOperator
metadata: 
     name: istio
spec:
    values: 
       global:
          meshID: mesh1 
          multiCluster:
               clusterName: "${CLUSTER}" 
          network: "${CLUSTER_NETWORK}"
EOF
  • 如果已经安装了istio,就执行执行patch。否则跳到下一步安装
kubectl -n istio-system patch istiooperators.install.istio.io istio  --type merge --patch "$(cat vm-cluster.yaml)"
  • 自动化创建workloadEntry。如果已经安装istio,需要编辑istio cr把这两个变量手动设置一下
istioctl install -f vm-cluster.yaml --set values.pilot.env.PILOT_ENABLE_WORKLOAD_ENTRY_AUTOREGISTRATION=true --set values.pilot.env.PILOT_ENABLE_WORKLOAD_ENTRY_HEALTHCHECKS=true
  • 部署东西向开关。如果加了一条路由通了,理论上也不需要东西向网关
samples/multicluster/gen‐eastwest‐gateway.sh ‐‐single‐cluster | istioctl install ‐y ‐f ‐
  • 使用东西向网关暴露集群内部服务:
kubectl ‐n istio‐system apply ‐f samples/multicluster/expose‐istiod.yaml

配置虚机命名空间及帐户

  • 创建虚机命名空间
kubectl create namespace "${VM_NAMESPACE}"
  • 为虚机创建serviceAccount
kubectl create serviceaccount "${SERVICE_ACCOUNT}" ‐n "${VM_NAMESPACE}"

虚拟机版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!相关配置

  • 创建workloadGroup模版
cat <<EOF > workloadgroup.yaml 
apiVersion: networking.istio.io/v1alpha3 
kind: WorkloadGroup
metadata:
     name:  "${VM_APP}" 
     namespace: "${VM_NAMESPACE}"
spec:
    metadata: 
          labels:
             app: "${VM_APP}"
     template:
         serviceAccount: "${SERVICE_ACCOUNT}" 
         network: "${VM_NETWORK}"
EOF
  • 将 WorkLoadGroup 应用到集群中
kubectl ‐‐namespace "${VM_NAMESPACE}" apply ‐f workloadgroup.yaml
  • 配置探针【非必须】 workloadGroup可以设置探针,类似k8s的探针。w版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!orkloadEntry通过检查后会标记为Ready
cat <<EOF > workloadgroup.yaml 
apiVersion: networking.istio.io/v1alpha3 
kind: WorkloadGroup
metadata:
     name:  "${VM_APP}" 
     namespace: "${VM_NAMESPACE}"
spec:
    metadata: 
         labels:
            app: "${VM_APP}" 
    template:
        serviceAccount: "${SERVICE_ACCOUNT}" 
        network: "${NETWORK}"
     probe:
         periodSeconds: 5
         initialDelaySeconds: 1 
         httpGet:
            port: 8080
            path: /ready
EOF
  • 生成配置文件
istioctl x workload entry configure ‐f workloadgroup.yaml ‐o "${WORK_DIR}" ‐‐clusterID "${CLUSTER}" --autoregister

在实际环境中,需要先把eastwest改成NodePort

# 先获取eastWeast的nodePort地址,在生成的mesh.yaml中把15012换成这个nodePort
kubectl -n istio-system get svc istio-eastwestgateway -ojson | jq -r '.spec.ports[] | select(.port == 15012) | .nodePort'
vi mesh.yaml  # 第一行的15012端口改成上述端口

生成的文件如下:

[root@istio-1 cert]# ls
cluster.env # 包含用来识别名称空间、服务帐户、网络 CIDR、和入站端口(可选)的元数据。
hosts #  /etc/hosts 的补充,代理将使用该补充从 Istiod 获取 xDS.*。
istio-token # 用来从 CA 获取证书的 Kubernetes 令牌。
mesh.yaml # 提供 ProxyConfig 来配置 discoveryAddress, 健康检查, 以及一些认证操作。
root-cert.pem # 用于认证的根证书。

注意:hosts检查下,如果为空,需要手动设置下host 在设置host时有两种方式,一种是使用eastwest网关,此时使用node的IP,另外还需要修改istiod地址,使用NodePort,见下文**10.253.17.27istiod.istio-system.svc# ip为NodeIP**另一种是使用istiod的svc dns及默认port,此时的配置需要设置为容器服务网络,查看istiod svc的ip后,配置:

$ kubectl -n istio-system get svc istiod
istiod   ClusterIP      10.233.61.18   <none>     15010/TCP,15012/TCP,443/TCP,15014/TCP   69d
# host设置:
10.233.61.18  istiod.istio-system.svc

虚拟机配置

虚拟机上操作

  • 配置虚机加入k8s网络

虚机的网络需要跟k8s node节点在同一网络,相互能通。此时配置一条路由,当访问k8s的容器网络(svc网络和pod网络)时,将k8s的node节点当作虚机的网关:

ip r add 10.233.0.0/18 via 10.253.17.27
ip r add 10.233.64.0/18 via 10.253.17.27

其实这两条路由合并为一条路由:

ip r add 10.233.0.0/16 via 10.253.17.27

将文件从 ${WORK_DIR}安全上传到虚拟机。如何安全的传输这些文件,这需要考虑到您的信息安全策略。本指南为方便起见,将所有必备文件上传到虚拟机中的 "${HOME}" 目录。

scp-r ${WORK_DIR}node3:/root/vm

  • 将根证书安装到目录 /etc/certs:
mkdir -p /etc/certs
cp root-cert.pem /etc/certs/root-cert.pem
  • 将令牌安装到目录 /var/run/secrets/tokens:
mkdir -p /var/run/secrets/tokens
cp istio-token /var/run/secrets/tokens/istio-token
  • 安装rpm包到vm
curl -LO https://storage.googleapis.com/istio-release/releases/1.11.4/rpm/istio-sidecar.rpm
rpm -i istio-sidecar.rpm
  • 将 cluster.env 安装到目录 /var/lib/istio/envoy/ 中:
cp cluster.env /var/lib/istio/envoy/cluster.env
  • 将网格配置文件 Mesh Config 安装到目录 /etc/istio/config/mesh:
cp mesh.yaml /etc/istio/config/mesh
  • 将 istiod 主机添加到 /etc/hosts:
sh -c 'cat hosts >> /etc/hosts'
  • 把文件 /etc/certs/ 和 /var/lib/istio/envoy/ 的所有权转移给 Istio proxy:
mkdir -p /etc/istio/proxy
chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem

Istio 虚拟机启动

在虚拟机中启动 Istio 代理:

systemctl start istio

验证 Istio 是否成功工作

检查 /var/log/istio/istio.log 中的日志,您应该能看到类似于以下的内容:

# tail -f /var/log/istio/istio.log
2023 - 11 - 17T07 : 09 : 12.386073Z info ads XDS :Incremental Pushing : 0 ConnectedEndpoints : 2 Version :
2023 - 11 - 17T07 : 09 : 12.386232Z info cache returned workload trust anchor from cache ttl = 23h59m59.613786138s
2023 - 11 - 17T07 : 09 : 12.386336Z info cache returned workload certificate from cache ttl = 23h59m59.613671788s
2023 - 11 - 17T07 : 09 : 12.386470Z info cache returned workload trust anchor from cache ttl = 23h59m59.613537165s
2023 - 11 - 17T07 : 09 : 12.387102Z info ads SDS : PUSH request for node : istio - 3.vm resources : 1 size : 1.1kB resource : ROOTCA
2023 - 11 - 17T07 : 09 : 12.387141Z info ads SDS : PUSH request for node : istio - 3.vm resources : 1 size : 4.0kB resource : default
2023 - 11 - 17T07 : 09 : 12.387178Z info cache returned workload trust anchor from cache ttl = 23h59m59.612842363s
2023 - 11 - 17T07 : 09 : 12.387317Z info ads SDS : PUSH for node : istio - 3.vm resources : 1 size : 1.1kB resource : ROOTCA
2023 - 11 - 17T07 : 09 : 13.162849Z info Initialization took 1.04593278s
2023 - 11 - 17T07 : 09 : 13.163122Z info healthcheck failure threshold hit , marking as unhealthy : Get "http://10.253.17.29:8080/ready" : dial tcp 127.0 . 0.6 : 0 -> 10.253 . 17.29 : 8080 : connect : connection refused

上述日志中,由于vm上的这个端口没有启动,所以在报这个端口的服务不正常。其实已经正常通信。

检查istiod日志,可以看到vm正常注册到了注册中心:

│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.175302Z info wle auto - registered WorkloadEntry vm / hello - service - 10.253 . 17.29
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.175366Z warn kube getProxyServiceInstancesFromMetadata for istio - 3.vm failed : no instances found for
│ istio - 3.vm : <nil>
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.175504Z info ads ADS : new connection for node : istio - 3.vm - 1774
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.178898Z info ads CDS : PUSH request for node : istio - 3.vm resources : 94 size : 101.0kB
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.219917Z info ads EDS : PUSH request for node : istio - 3.vm resources : 88 size : 22.5kB empty : 0 cached : 88 / 88
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.392344Z info ads LDS : PUSH request for node : istio - 3.vm resources : 41 size : 82.9kB
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.392496Z info ads NDS : PUSH request for node : istio - 3.vm resources : 1 size : 2.6kB
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 41.459858Z info ads RDS : PUSH request for node : istio - 3.vm resources : 11 size : 21.8kB
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 46.652042Z info ads ADS : "10.233.81.42:47656" istio - 3.vm - 1774 terminated rpc error : code = Canceled desc
│= context canceled
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 08 : 56.671317Z info wle cleaned up auto - registered WorkloadEntry vm / hello - service - 10.253 . 17.29
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.232517Z warn kube error on get hello - service - 10.253 . 17.29 / vm : workloadentries . networking . istio . io "he
│ llo-service-10.253.17.29" not found
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.241471Z info wle auto - registered WorkloadEntry vm / hello - service - 10.253 . 17.29 with health checking ena
│ bled
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.241541Z warn kube getProxyServiceInstancesFromMetadata for istio - 3.vm failed : no instances found for
│ istio - 3.vm : <nil>
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.241665Z info ads ADS : new connection for node : istio - 3.vm - 1775
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.244716Z info ads CDS : PUSH request for node : istio - 3.vm resources : 94 size : 101.0kB
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.288325Z info ads EDS : PUSH request for node : istio - 3.vm resources : 88 size : 22.5kB empty : 0 cached : 88 / 88
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.406812Z info ads LDS : PUSH request for node : istio - 3.vm resources : 41 size : 82.9kB
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.407042Z info ads NDS : PUSH request for node : istio - 3.vm resources : 1 size : 2.6kB
│ istiod - 59d9856d79 - knml9 2023 - 11 - 17T07 : 09 : 12.463787Z info ads RDS : PUSH request for node : istio - 3.vm resources : 11 size : 21.8kB

看k8s上面的workloadEntry及workloadGroup已经成功创建

[ root@istio-1 vm ]# k get se - n vm
No resources found in vm namespace .
[ root@istio - 1 vm ]# k - n vm get we
NAME                                           AGE                          ADDRESS
hello-service-10.253.17.29           40m                          10.253.17.29
[ root@istio-1 vm ]# k - n vm get wg
NAME                                           AGE
hello-service                                 46h

相关故障处理

如果有报错,会在err.log中发现。如:

2023 - 11 - 15T17 : 43 : 19.400532Z warning envoy config StreamAggregatedResources gRPC config stream closed : 14 , connection error : desc ="transport: Error while dialing dial tcp 10.253.17.27:15012: connect: connection refused"

修改istiod的连接端口

vi /etc/istio/envoy/sidecar.env #CA_ADDR=istiod.istio-system.svc:31885
vi mesh.yaml

如果修改配置后,要重启

systemctl stop istio
killall envoy istio
systemctl start istio
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!

从虚机上访问k8s 上 mesh 的svc不通

# 虚机上访问 mesh svc
[ root@istio-3 ~]# curl - v test-mesh-01-canary-1.infvie.svc/ip
* Trying 10.233.63.207 ...
* TCP_NODELAY set
^C

# 可以看到已经成功实现dns解析到了mesh的svc上。
[ root@istio-1 vm ]# k get svc - A | grep 10.233.63.207
infvie      test-mesh-01-canary-1       ClusterIP       10.233.63.207           <none>            80/TCP, 8081/TCP, 443/TCP, 3306/TCP

虽然dns成功解析到了mesh的svc上,但是由于虚机的网络无法访问通k8s的容器网络,所以还是不通。此时需要增加一条路由:

# 首先要找出svc ip 网络。master节点上过滤
ps - ef | grep 10.233
ip r add 10.233.0.0/18 via 10.253.17.27 #注意,这样配了之后,只有svc能通,需要把pod网络也配通,把子网改成/16就成功了

参考文献

https://istio.io/latest/zh/docs/setup/install/virtual-machine/

https://www.cnblogs.com/renshengdezheli/p/16840972.html

https://wiki.cestc.cn/pages/viewpage.action?pageId=131659773

版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!
0 条回应