官方数据:https://istio.io/latest/zh/docs/setup/install/virtual-machine/
一、背景¶
将虚拟机工作负载纳入 Istio 服务网格的主要原因之一是实现 混合云 环境下的 统一 治理和管理。在许多互联网公司,部分应用程序可能仍然运行在传统的虚拟机环境中,而其他应用程序可能已经迁移到了容器化的环境中。
为了实现整个系统的一致性和可操作性,将虚拟机工作负载纳入 Istio 服务网格具有以下背景和优势:
-
统一的治理平台:通过将虚拟机工作负载纳入 Istio 服务网格,可以在同一个平台上 进行统一的治理和管理。无论是容器化的应用还是虚拟机应用,都可以享受到 Istio 提供的流量管理、安全性增强、监控和策略等功能。这简化了管理和操作的复杂性,并提供了一致的开发和运维体验。
-
流量管理和控制:通过将虚拟机工作负载纳入 Istio,可以利用其流量管理功能进行精确的流量控制和路由。无论是虚拟机还是容器,都可以通过 Istio 的智能代理 (Envoy)进行流量的管控,实现灵活的流量路由、负载均衡和故障恢复等功能。这样可以提高系统的弹性和可靠性,确保流量在不同环境之间的无缝切换。
-
安全性增强:将虚拟机工作负载纳入 Istio 服务网格可以提供一致的安全性增强策略。通过使用 Istio 的安全功能,如服务间的身份认证、流量加密和访问控制,可以在混合云环境中实现统一和集中的安全管理。无论是容器还是虚拟机,都可以受益于这些安全性增强策略,确保敏感数据的安全传输和访问控制。
-
观测和监控:Istio 提供了强大的观测和监控能力,可以对流量进行跟踪、指标收集和日志记录等。将虚拟机工作负载纳入 Istio 后,可以方便地集成和统一监控整个系统,包括虚拟机和容器化应用程序。这有助于实时监控工作负载的性能和健康状态,加快故障排查和性能调优的速度。
综上所述,将虚拟机工作负载纳入 Istio 服务网格可以实现混合云环境的统一治理和管理,提供流量管理、安全性增强、观测和监控等功能,并简化了整个系统的管理和操作。这样可以在混合云环境中提供一致的开发和运维体验,提高系统的可靠性、弹性和安全性。
二、虚机负载¶
我们可以将在虚拟机上运行的工作负载连接到 Istio 服务网格,使其成为网格的一部分。 虚拟机可以通过安装和配置 Istio 的智能代理(例如 Envoy)来实现与网格的集成。
下面是虚拟机与 Kubernetes 中负载的资源抽象层级对比:
| 对比项 | Kubernetes | 虚拟机 |
|---|---|---|
| 基础运行单位 | Pod | WorkloadEntry |
| 编排组合 | Deployment | WorkloadGroup |
| 服务注册与发现 | Service | ServiceEntry |
从上面的图表中我们可以看到,对于虚拟机工作负载是可以与 Kubernetes 中的负载一 一对对应的。
此时看似一切都比较完美了,但是直接将 Kubernetes 集群中的 DNS server 暴露出来会 带来很大的安全风险,因此我们一般手动将虚拟机需要访问的服务的域名和 Cluster IP 对写到本机的 /etc/hosts 中,但是对于一个节点数量庞大的分布式集群来说,这种做法又有些不现实,因此本节课的目标也比较明确了。
上节课咱么也讲了虚拟机的 Istio 服务网格有两种架构:单网络架构和多网络架构,今天咱们就来看下基于这些数据,如何将独立的服务网格外的虚机成功加入到Istio的服务网格内。
2.1 单网络架构¶
上节课,咱们讲到但控制层面及多控制层面,那么针对多个集群使用一个控制层面的时候, Remote Cluster中的svc通过东西向网关加入到集群,接受istio控制层面的管控及调度。
今天咱们的集群架构依旧是,有一个单一的网络。Kubernetes 集群和在虚拟机上运行 的工作负载都在同一个网络中,它们仅可以基于网络层面进行一些服务层面的相互通信,但是对于使用kubernetes的内网通讯是不行的。
通过这张图大家也能看得出来,这个时候我们就需要通过一个特殊的配置 “东西向网关”,然后在虚机层面配置Istio服务及 Envoy 就可以通过这样一个网关进行kubernetes 内网层面的交互了。

控制平面的流量(配置更新、证书签署)是通过 Gateway 发送的。虚拟机被配置了网关地址,所以它们在启动时可以连接到控制平面。
2.2 多网络架构¶
那我们再来看下,多网络架构,多网络架构横跨多个网络。Kubernetes 集群在一个网络内,而虚拟机则在另一个网络内。这样 Kubernetes 集群中的 Pod 和虚拟机上的工作负载无法直接相互通信。
那么如何通过istio的这种解决方案来实现呢?

仍然是可以巧妙的借助 东西向网关(istio-eastwestgateway),控制平面和 pod 到 工作负载的流量都流经网关,网关作为两个网络之间的桥梁。
2.3 Istio 中如何标识虚拟机工作负载?¶
在 Istio 中,虚拟机工作负载可以通过 Kubernetes 的虚拟机集群(Virtual Machine Cluster)资源来标识。虚拟机集群是 Istio 扩展了的 Kubernetes 资源之一,它用于表示运行在虚拟机或裸金属服务器上的工作负载。
在 Istio 服务网格中,有两种方式来表示虚拟机工作负载:
工作负载组( WorkloadGroup 资源)类似于 Kubernetes 中的部署 (Deployment),它代表了共享共同属性的虚拟机工作负载的逻辑组。
描述虚拟机工作负载的 第二种方法是使用工作负载条目( WorkloadEntry资源)。工 作负载条目类似于Pod,它代表了一个虚拟机工作负载的单一实例。
请注意,创建上述资源将不会提供或运行任何虚拟机工作负载实例。这些资源只是用来 引用或指向虚拟机工作负载的。Istio 使用它们来了解如何适当地配置网格,将哪些服务添加到内部服务注册表中,等等。
为了将虚拟机添加到网格中,我们需要创建一个工作负载组,作为模板。然后,当我们 配置并将虚拟机添加到网格中时,控制平面会自动创建一个相应的 WorkloadEntry。
我们已经提到,WorkloadEntry 的作用类似于 Pod。在添加虚拟机时,会创建 WorkloadEntry 资源,而当虚拟机的工作负载从网格中移除时,该资源会被自动删除。
除了 WorkloadEntry 资源外,我们还需要创建一个 Kubernetes 服务。创建一个 Kubernetes 服务给了我们一个稳定的主机名和 IP 地址,以便使用选择器字段访问虚拟 机工作负载和 pod。这也使我们能够通过 DestinationRule 和 VirtualService 资源使用 Istio 的路由功能。
三、实战:向Istio Mesh中引入虚拟机¶
3.1 将虚拟机引入到 Istio Mesh¶
在这个实验中,我们将学习 如何将虚拟机上运行的工作负载连接到 Kubernetes 集群上 运行的 Istio 服务网格。我们将 使用单一网络架构。
下载了 Istio 后,我们可以使用 IstioOperator 来安装它,它 可以设置网格 ID、集群名 称和网络名称。网络名称将是空的,因为我们要用单一网络架构。
让我们来设置几个环境变量,我们将在本实验中使用这些变量。
export SERVICE_ACCOUNT="vm-sa"
export VM_APP="hello-vm"
export VM_NAMESPACE="vm-namespace"
export WORK_DIR="${HOME}/vmfiles"
export CLUSTER_NETWORK=""
export VM_NETWORK=""
export CLUSTER="Kubernetes"
我们还可以创建 $WORK_DIR,在这里我们将存储证书和其他我们必须复制到虚拟机上的文件
[root@master01 istioyaml]# mkdir -p $WORK_DIR
一旦 Operator 被初始化,我们就可以创建 IstioOperator 资源,指定网格 ID、集群名称和网络,并安装 Istio:
[root@master01 ~]# cd /root/10/istioyaml/
[root@master01 istioyaml]#
cat <<EOF | kubectl apply -f -
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio
namespace: istio-system
spec:
values:
global:
meshID: mesh1
multiCluster:
clusterName: "${CLUSTER}"
network: "${CLUSTER_NETWORK}"
EOF
我们可以 使用 kubect l get iop - n istio-system 命令来检查 Istio 安装状态何时变为健康。
[root@master01 istioyaml]# kubectl get iop -n istio-system
demo-istio-install HEALTHY 35h
installed-state-eastwest 9h
在下一步,我们将安装东西向网关。这是控制平面用来与虚拟机工作负载对话的网关, 反之亦然。
gen-eastwest-gateway.sh 脚本是我们之前下载的 Istio 包的一部分。运行以下命令:
#安装
[root@master01 ~]# cd /root/10/istio-1.20.8/samples/multicluster/
[root@master01 multicluster]# ./gen-eastwest-gateway.sh --single-cluster | istioctl install -y -f -
WARNING: Istio 1.20.0 may be out of support (EOL) already: see https://istio.io/latest/docs/releases/supported-releases/ for supported releases
✔ Ingress gateways installed
✔ Installation complete
#验证
[root@master01 istioyaml]# kubectl get iop -n istio-system
NAME REVISION STATUS AGE
demo-istio-install HEALTHY 35h
installed-state-eastwest 9h
istio 9h
gen-eastwest-gateway.sh 脚本 使用一个 IstioOperator 来部署一个额外的网关, 名为 istio-eastwestgateway ,并配置了服务端口。
我们稍后可以通过查看 istio-system 命名空间中的 Kubernetes 服务来检查新网关。 最后,我们还需要配置网关,通过它来暴露控制平面(istiod)。我们可以通过部署expose-istiod.yaml 文件来做到这一点:
[root@master01 ~]# cd /root/10/istio-1.20.8/samples/multicluster/
[root@master01 multicluster]# kubectl apply -n istio-system -f expose-istiod.yaml
3.2 准备虚拟机命名空间和文件¶
对于虚拟机工作负载,我们必须创建一个单独的命名空间来存储 WorkloadEntry 资源 和任何其他虚拟机工作负载相关的资源。
此外,我们还必须导出集群环境文件、令牌、证书和其他我们必须转移到虚拟机上的文件。
我们刚刚已经将所有文件存放在我们在实验开始时创建的 $WORK_DIR 中。
让我们在同一命名空间中创建虚拟机命名空间和我们将用于虚拟机工作负载的服务账户:
[root@master01 istioyaml]# kubectl create ns "${VM_NAMESPACE}"
[root@master01 istioyaml]# kubectl create serviceaccount "${SERVICE_ACCOUNT}" -n "${VM_NAMESPACE}"
现在我们可以创建一个 WorkloadGroup 资源并将其保存到 workloadgroup.yaml中:
[root@master01 istioyaml]#
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
虚拟机需要关于集群和 Istio 的控制平面的信息来连接到它。 为了生成所需文件,我们可以运行 getmesh istioctl x workload entry 命令。 我们将所有生成的文件保存到$WORK_DIR 中:
# 生成所需文件
[root@master01 istioyaml]# istioctl x workload entry configure -f workloadgroup.yaml -o "${WORK_DIR}" --clusterID "${CLUSTER}"
#查看生成的文件
[root@master01 istioyaml]# ls /root/vmfiles
cluster.env hosts istio-token mesh.yaml root-cert.pem
3.3 配置虚拟机¶
虚拟机:确保你在防火墙部分勾选了 "允许 HTTP 流量",并且你有 SSH 访问该实例的权限。
在这个例子中,我们在 80 端口运行一个简单的 Python HTTP 服务器。你可以在不同的端口上配置任何其他服务。只要确保你配置了相应的安全和防火墙规则。
虚机10.0.0.51准备工作:
[root@jenkins-01 ~]# mkdir -p /usr/local/src/istio
1. 在master01节点上将 $WORK_DIR 中的文件复制到实例的主文件夹中。相应地替换 USERNAME 和 INSTANCE_IP 。
[root@master01 istioyaml]# scp $WORK_DIR/* root@10.0.0.51:/usr/local/src/istio
cluster.env 100% 584 1.0MB/s 00:00
hosts 100% 34 41.3KB/s 00:00
istio-token 100% 830 997.9KB/s 00:00
mesh.yaml 100% 605 974.4KB/s 00:00
root-cert.pem 100% 1094 1.4MB/s 00:00
SSH 进入实例,将根证书复制到 /etc/certs :
# 虚机10.0.0.51上操作
[root@jenkins-01 ~]# mkdir -p /etc/certs
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# cp root-cert.pem /etc/certs/root-cert.pem
拷贝 istio-token 文件到 /var/run/secrets/tokens 目录:
# 虚机10.0.0.51上操作
[root@jenkins-01 ~]# mkdir -p /var/run/secrets/tokens
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# cp istio-token /var/run/secrets/tokens/istio-token
下载和安装 Istio sidecar 包:
# 虚机10.0.0.51上操作
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# curl -LO https://storage.googleapis.com/istio-release/releases/1.20.8/rpm/istio-sidecar.rpm
# 虚机安装istio-sidecar
[root@jenkins-01 istio]# yum install istio-sidecar.rpm -y
拷贝 cluster.env 到 /var/lib/istio/envoy/ :
# 虚机10.0.0.51上操作
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# cp cluster.env /var/lib/istio/envoy/cluster.env
将 Mesh 配置( mesh.yaml )添加到 /etc/istio/config/mesh
# 虚机10.0.0.51上操作
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# cp mesh.yaml /etc/istio/config/mesh
将 istiod host 添加到 /etc/hosts 文件中:
# 虚机10.0.0.51上操作
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# sh -c 'cat hosts >> /etc/hosts'
将 /etc/certs 和 /var/lib/istio/envoy 的所有者修改为 Istio proxy:
# 虚机10.0.0.51上操作
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# mkdir -p /etc/istio/proxy
[root@jenkins-01 istio]# chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem
升级make
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# wget http://ftp.gnu.org/gnu/make/make-4.2.tar.gz
[root@jenkins-01 istio]# tar xf make-4.2.tar.gz
[root@jenkins-01 istio]# cd make-4.2/
[root@jenkins-01 make-4.2]# ./configure
[root@jenkins-01 make-4.2]# sudo make
[root@jenkins-01 make-4.2]# sudo make install
[root@jenkins-01 make-4.2]# sudo rm -rf /usr/bin/make
[root@jenkins-01 make-4.2]# sudo cp ./make /usr/bin/
[root@jenkins-01 make-4.2]# make -v
GNU Make 4.2
Built for x86_64-pc-linux-gnu
...
...
升级GCC编译器为8.3.1
# 需要提前新增repo源,repo源地址:https://vault.centos.org/7.9.2009/sclo/x86_64/rh/
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-51 istio]# yum -y install centos-release-scl
[root@jenkins-51 ~]# cd /etc/yum.repos.d/
[root@jenkins-51 yum.repos.d]# rm -f CentOS-SCLo-scl.repo
[root@jenkins-51 yum.repos.d]# > CentOS-SCLo-scl-rh.repo
[root@jenkins-51 yum.repos.d]# vim CentOS-SCLo-scl-rh.repo
[centos-sclo-rh]
name=CentOS-7 - SCLo rh
#baseurl=http://mirror.centos.org/centos/7/sclo/$basearch/rh/
baseurl=https://vault.centos.org/7.9.2009/sclo/x86_64/rh/
mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=7&repo=sclo-rh
gpgcheck=0
enabled=1
[centos-sclo-rh-testing]
name=CentOS-7 - SCLo rh Testing
baseurl=http://buildlogs.centos.org/centos/7/sclo/$basearch/rh/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
[centos-sclo-rh-source]
name=CentOS-7 - SCLo rh Sources
baseurl=http://vault.centos.org/centos/7/sclo/Source/rh/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
[centos-sclo-rh-debuginfo]
name=CentOS-7 - SCLo rh Debuginfo
baseurl=http://debuginfo.centos.org/centos/7/sclo/$basearch/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
# yum源生效
[root@jenkins-51 yum.repos.d]# sudo yum clean all
[root@jenkins-51 yum.repos.d]# sudo rm -rf /var/cache/yum
[root@jenkins-51 yum.repos.d]# sudo yum makecache
# 安装升级gcc
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-51 istio]# yum -y install devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-binutils
[root@jenkins-51 istio]# scl enable devtoolset-8 bash
# yum安装完,原来的gcc不覆盖,需要执行enable脚本更新环境变量
[root@jenkins-51 istio]# source /opt/rh/devtoolset-8/enable
# 想保持覆盖,可将其写入~/.bashrc或/etc/profile
[root@jenkins-51 istio]# echo "source /opt/rh/devtoolset-8/enable" >>/etc/profile
[root@jenkins-51 istio]# source /etc/profile
# 查看gcc版本
[root@jenkins-51 istio]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-8/root/usr --mandir=/opt/rh/devtoolset-8/root/usr/share/man --infodir=/opt/rh/devtoolset-8/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-8.3.1-20190311/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)
升级glibc-2.28
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-51 istio]# wget https://mirror.bjtu.edu.cn/gnu/libc/glibc-2.28.tar.xz
# 解压
[root@jenkins-51 istio]# tar -xf glibc-2.28.tar.xz -C /usr/local
# 进入编译目录
[root@jenkins-51 istio]# cd /usr/local/glibc-2.28/
# 编译
[root@jenkins-51 glibc-2.28]# mkdir build
[root@jenkins-51 glibc-2.28]# cd build/
[root@jenkins-51 build]#
sudo ../configure \
--prefix=/opt/glibc-2.28 \
--disable-profile \
--enable-add-ons \
--with-headers=/usr/include \
--with-binutils=/usr/bin
# 编译,步骤很长
[root@jenkins-51 build]# make
# 生成/opt/glibc-2.28/etc/ld.so.conf文件
[root@jenkins-51 istio]# cd /usr/local/glibc-2.28/build
[root@jenkins-51 build]# sudo mkdir -p /opt/glibc-2.28/etc
[root@jenkins-51 build]# echo "/opt/glibc-2.28/lib" | sudo tee /opt/glibc-2.28/etc/ld.so.conf
# 安装
[root@jenkins-51 build]# make install
# 这一步正常不需要做
# 如make没有运行成功,解决error后需要先运行make clean,清除之前make的内容,才能再次执行make
[root@jenkins-51 build]# make clean
[root@jenkins-51 build]# make
通过strings /lib64/libc.so.6 |grep GLIBC查询是否存在glibc-2.28版本
[root@jenkins-51 build]# strings /lib64/libc.so.6 |grep GLIBC_2.28
GLIBC_2.28
GLIBC_2.28
以上都就绪后,就可以在虚拟机中启动 Istio:
[root@jenkins-01 istio]# systemctl start istio && systemctl status istio && systemctl enable istio
验证 Istio 是否成功工作
[root@jenkins-51 ~]# systemctl status istio
● istio.service - istio-sidecar: The Istio sidecar
Loaded: loaded (/usr/lib/systemd/system/istio.service; disabled; vendor preset: disabled)
Active: active (running) since Fri 2025-04-18 20:42:19 CST; 1min 30s ago
Docs: http://istio.io/
Main PID: 66084 (sudo)
CGroup: /system.slice/istio.service
‣ 66084 sudo -E -u istio-proxy -s /bin/bash -c ulimit -n 1024; INSTANCE_IP=...
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: -A ISTIO_OUTPUT -o lo -p tcp -m tcp...N
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: -A ISTIO_OUTPUT -m owner --gid-owne...N
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: -A ISTIO_OUTPUT -d 223.5.5.5/32 -p ...3
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: -A ISTIO_OUTPUT -d 223.6.6.6/32 -p ...3
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: -A ISTIO_OUTPUT -d 127.0.0.1/32 -j ...N
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: -A ISTIO_OUTPUT -j ISTIO_REDIRECT
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: -A ISTIO_REDIRECT -p tcp -j REDIREC...1
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: COMMIT
Apr 18 20:42:20 jenkins-51 istio-start.sh[66084]: # Completed on Fri Apr 18 20:42:20 2025
Apr 18 20:42:20 jenkins-51 sudo[66084]: root : TTY=unknown ; PWD=/ ; USER=istio-...og
Hint: Some lines were ellipsized, use -l to show in full.
检查 /var/log/istio/istio.log 中的日志,应该能看到类似于以下的内容:
# tail -f /var/log/istio/istio.log
验证VM是否联机成功:
# istioctl proxy-status
此刻,虚拟机被配置为与 Kubernetes 集群中 Istio 的控制平面通信。
当在 vm 中安装代理后,这时会监听一些监听, https://github.com/istio/istio/blob/1.14.3/pilot/cmd/pilot-agent/options/options.go
| 端口 | 协议 | 描述 | 使用 |
|---|---|---|---|
| 15000 | HTTP | envoy Admin 管理地 址 | localhost:15000 |
| 15001 | TCP | Envoy Engress | 流量流出端口 |
| 15004 | HTTP | 策略/遥测 – mTLS | XDS DEBUG AGENT |
| 15006 | TCP | Envoy Ingress | 流量流入端口 |
| 15020 | pilot-agent 进程 | Ingress Gateway | |
| 15021 | HTTP | envoy 状态检测 | localhost:15021/healthz/ready |
| 15024 | pilot-agent 进程 | ||
| 15053 | TCP | DNS 服务 pilot-agent 进程 | |
| 15090 | HTTP | envoy prometheus 端口 |
3.4 从虚拟机访问服务¶
让我们在 Kubernetes 集群中部署一个 Hello world 应用程序。首先,我们需要在default 命名空间中启用自动 sidecar 注入:
[root@master01 ~]# kubectl label namespace default istio-injection=enabled
接下来,创建 Hello world 的部署和服务。
[root@master01 ~]# cd /root/10/istio-1.20.8/
[root@master01 istio-1.20.8]# kubectl apply -f samples/helloworld/helloworld.yaml
等待 Pod 准备好,然后回到虚拟机上,尝试访问 Kubernetes 服务:
# 10.0.0.51主机上操作
[root@jenkins-51 ~]# curl helloworld.default.svc:5000/hello
一旦可以从虚拟机上访问 Kubernetes 集群内运行的任何服务,即代表着实验的成功! 这个时候虚机就已经成功加入了Istio网络。
3.5 自己部署遇到的问题¶
3.5.1 启动istio异常¶
问题一:启动istio失败
# 启动
[root@jenkins-01 istio]# systemctl start istio && systemctl status istio && systemctl enable istio
# 查看istio服务
[root@jenkins-01 istio]# systemctl status istio
● istio.service - istio-sidecar: The Istio sidecar
Loaded: loaded (/usr/lib/systemd/system/istio.service; enabled; vendor preset: disabled)
Active: activating (auto-restart) since Fri 2025-04-18 08:46:11 CST; 3s ago
Docs: http://istio.io/
Process: 15986 ExecStopPost=/usr/local/bin/istio-start.sh clean (code=exited, status=0/SUCCESS)
Process: 15866 ExecStart=/usr/local/bin/istio-start.sh (code=exited, status=0/SUCCESS)
Main PID: 15866 (code=exited, status=0/SUCCESS)
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: COMMIT
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: # Completed on Fri Apr 18 08:46:11 2025
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: # Generated by ip6tables-save v1.4.21 on Fri A...025
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: *nat
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: :PREROUTING ACCEPT [0:0]
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: :INPUT ACCEPT [0:0]
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: :OUTPUT ACCEPT [0:0]
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: :POSTROUTING ACCEPT [0:0]
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: COMMIT
Apr 18 08:46:11 jenkins-01 istio-start.sh[15986]: # Completed on Fri Apr 18 08:46:11 2025
Hint: Some lines were ellipsized, use -l to show in full.
解决方法:
查看日志信息
[root@jenkins-01 istio]# tail -f /var/log/istio/istio.err.log
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libm.so.6: version `GLIBC_2.27' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.25' not found (required by /usr/local/bin/envoy)
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.27' not found (required by /usr/local/bin/envoy)
升级glibc
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# wget https://mirror.bjtu.edu.cn/gnu/libc/glibc-2.28.tar.xz
[root@jenkins-01 istio]# tar -xf glibc-2.28.tar.xz -C /usr/local/
[root@jenkins-01 istio]# cd /usr/local/glibc-2.28/
[root@jenkins-01 glibc-2.28]# mkdir build
[root@jenkins-01 glibc-2.28]# cd build
[root@jenkins-01 build]# ../configure --prefix=/usr/local/glibc-2.28
在configure这一步骤会遇到如下报错:
configure: error:
*** These critical programs are missing or too old: make compiler
*** Check the INSTALL file for required versions.
针对这一报错,是因为make太过老旧,参照下文升级make
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-01 istio]# wget http://ftp.gnu.org/gnu/make/make-4.2.tar.gz
[root@jenkins-01 istio]# tar xf make-4.2.tar.gz
[root@jenkins-01 istio]# cd make-4.2/
[root@jenkins-01 make-4.2]# ./configure
[root@jenkins-01 make-4.2]# sudo make
[root@jenkins-01 make-4.2]# sudo make install
[root@jenkins-01 make-4.2]# sudo rm -rf /usr/bin/make
[root@jenkins-01 make-4.2]# sudo cp ./make /usr/bin/
[root@jenkins-01 make-4.2]# make -v
GNU Make 4.2
Built for x86_64-pc-linux-gnu
...
...
再次尝试configure
[root@jenkins-01 istio]# cd /usr/local/glibc-2.28/
[root@jenkins-01 glibc-2.28]# ./configure --prefix=/usr/local/glibc-2.28
又发生如下报错,原因是因为gcc版本太旧
configure: error:
*** These critical programs are missing or too old: compiler
*** Check the INSTALL file for required versions.
参照下文升级gcc centos 升级GCC编译器为8.3.1
# 需要提前新增repo源,repo源地址:https://vault.centos.org/7.9.2009/sclo/x86_64/rh/
[root@jenkins-51 istio]# yum -y install centos-release-scl
[root@jenkins-51 ~]# cd /etc/yum.repos.d/
[root@jenkins-51 yum.repos.d]# rm -f CentOS-SCLo-scl.repo
[root@jenkins-51 yum.repos.d]# vim CentOS-SCLo-scl-rh.repo
[centos-sclo-rh]
name=CentOS-7 - SCLo rh
#baseurl=http://mirror.centos.org/centos/7/sclo/$basearch/rh/
baseurl=https://vault.centos.org/7.9.2009/sclo/x86_64/rh/
mirrorlist=http://mirrorlist.centos.org?arch=$basearch&release=7&repo=sclo-rh
gpgcheck=0
enabled=1
[centos-sclo-rh-testing]
name=CentOS-7 - SCLo rh Testing
baseurl=http://buildlogs.centos.org/centos/7/sclo/$basearch/rh/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
[centos-sclo-rh-source]
name=CentOS-7 - SCLo rh Sources
baseurl=http://vault.centos.org/centos/7/sclo/Source/rh/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
[centos-sclo-rh-debuginfo]
name=CentOS-7 - SCLo rh Debuginfo
baseurl=http://debuginfo.centos.org/centos/7/sclo/$basearch/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
# yum源生效
[root@jenkins-51 yum.repos.d]# sudo yum clean all
[root@jenkins-51 yum.repos.d]# sudo rm -rf /var/cache/yum
[root@jenkins-51 yum.repos.d]# sudo yum makecache
# 安装升级gcc
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-51 istio]# yum -y install devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-binutils
[root@jenkins-51 istio]# scl enable devtoolset-8 bash
# yum安装完,原来的gcc不覆盖,需要执行enable脚本更新环境变量
[root@jenkins-51 istio]# source /opt/rh/devtoolset-8/enable
# 想保持覆盖,可将其写入~/.bashrc或/etc/profile
[root@jenkins-51 istio]# echo "source /opt/rh/devtoolset-8/enable" >>/etc/profile
[root@jenkins-51 istio]# source /etc/profile
# 查看gcc版本
[root@jenkins-51 istio]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-8/root/usr --mandir=/opt/rh/devtoolset-8/root/usr/share/man --infodir=/opt/rh/devtoolset-8/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-8.3.1-20190311/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)
升级glibc-2.28
[root@jenkins-01 ~]# cd /usr/local/src/istio/
[root@jenkins-51 istio]# wget https://mirror.bjtu.edu.cn/gnu/libc/glibc-2.28.tar.xz
# 解压
[root@jenkins-51 istio]# tar -xf glibc-2.28.tar.xz -C /usr/local
# 进入编译目录
[root@jenkins-51 istio]# cd /usr/local/glibc-2.28/
# 编译
[root@jenkins-51 istio]# mkdir build
[root@jenkins-51 glibc-2.28]# cd build/
[root@jenkins-51 build]# sudo ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
# 编译安装
[root@jenkins-51 build]# make
[root@jenkins-51 build]# make install
# 如make没有运行成功,解决error后需要先运行make clean,清除之前make的内容,才能再次执行make
[root@jenkins-51 build]# make clean
[root@jenkins-51 build]# make
通过strings /lib64/libc.so.6 |grep GLIBC查询是否存在glibc-2.28版本
[root@jenkins-51 build]# strings /lib64/libc.so.6 |grep GLIBC_2.28
GLIBC_2.28
GLIBC_2.28
四、异常处理¶
4.1 启动istio异常¶
# tail -f /var/log/istio/istio.err.log
/usr/local/bin/envoy: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /usr/local/bin/envoy)
解决方案:
wget https://mirror.bjtu.edu.cn/gnu/libc/glibc-2.28.tar.xz
tar -xf glibc-2.28.tar.xz -C /usr/local/
cd /usr/local/glibc-2.28/
mkdir build
cd build
../configure --prefix=/usr/local/glibc-2.28
运行到./configure --prefix=/usr/local/glibc-2.28时报错
报错1:
configure: error: in `/root/test/glibc-2.28/build’:
configure: error: no acceptable C compiler found in $PATH
报错1解决方法:
yum install gcc -y
报错2:
These critical programs are missing or too old: make
Check the INSTALL file for required versions.
报错2解决方法: make太过老旧,参照下文升级make
报错3:
These critical programs are missing or too old: compiler
Check the INSTALL file for required versions.
报错3解决方法:
gcc版本太旧,参照下文升级gcccentos 升级GCC编译器
Centos升级GCC编译器
yum -y install centos-release-scl
yum -y install devtoolset-8-gcc devtoolset-8-gcc-c++ devtoolset-8-binutils
scl enable devtoolset-8 bash
###yum安装完,原来的gcc不覆盖,需要执行enable脚本更新环境变量
source /opt/rh/devtoolset-8/enable
###想保持覆盖,可将其写入~/.bashrc或/etc/profile
echo "source /opt/rh/devtoolset-8/enable" >>/etc/profile
###查看gcc版本
gcc -v
升级make
wget http://ftp.gnu.org/gnu/make/make-4.2.tar.gz
tar xf make-4.2.tar.gz
cd make-4.2
sudo ./configure
sudo make
sudo make install
sudo rm -rf /usr/bin/make
sudo cp ./make /usr/bin/
make -v
升级glibc-2.28
wget https://mirror.bjtu.edu.cn/gnu/libc/glibc-2.28.tar.xz
tar -xf glibc-2.28.tar.xz -C /usr/local
cd /usr/local/glibc-2.28/
mkdir build
cd build/
yum install -y bison
sudo ../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
make //make 运行时间较长,可能会有半小时
make install
-----------------------
###如make没有运行成功,解决error后需要先运行make clean,清除之前make的内容,才能再次执行make
make clean
make
通过strings /lib64/libc.so.6 |grep GLIBC查询是否存在glibc-2.28版本
strings /lib64/libc.so.6 |grep GLIBC
ref:
centos /lib64/libc.so.6: version ‘GLIBC_2.28’ not found (required by
4.2 其他问题¶
如果遇到 failed to warm certificate 之类的错误,一般是由于token 失效引起 的,此时可以通过在master 节点重新生成vm配置信息,并将 token 的内容复制过来再重试。如果遇到一些ca之类的信息,可以试着执行以下命令:
$ sudo unlink /etc/istio/proxy/SDS && sudo unlink /etc/istio/proxy/XDS
有时候服务停止后,存在envoy未退出的情况,虽然官方声称解决了这个问题,但在不同的版本中仍出现此问题。这个错误信息出现在 /var/log/istio/istio.err.log 日志文件
2023-07-29T01:34:29.634762Z critical envoy main error initializing configuration 'etc/istio/proxy/envoy-rev0.json':
cannot bind '127.0.0.1:15000': Address already **in** use
此时可能需要手动 kill -9 PID 将envoy进程结束掉,再重启istio服务
如果按照istio官方文档的istio步骤,会发现通过 vm 请求服务时是无法正常通讯的。
$ curl helloworld.default.svc:5000/hello
此时需要先检查一下域名路由问题,使用 traceroute 或 ping 命令均可。
$ traceroute helloworld.default.svc
此时需要手动添加一条路由规则才可以。
$ route add -net 10.240.0.0 gw 192.10.192.158 netmask 255.255.0.0
这里向所以来自ip段 10.240.0.0 的请求通过网关 192.10.192.158 进行转发。这里的 10.240.0.0 是指安装k8s时指定的 Pod CIDR网格段(参考),192.10.192.158是指安装 k8s master 节点的IP地址。
4.3 异常¶
如果vm重启的话,会发现 /var/run/secrets/tokens/istio-token 自动丢失,如果只是短 暂断开的话,则需要先删除目录 /etc/certs/ 下自动生成的 .pem 文件,再将原来的配置 文件重新复制过去, 再次启用istio即可。
如果是长时间断开的话,就没有好的解决办法了,只有重新生成vm连接配置( istioctl x workload entry configure -f workloadgroup.yaml -o “${WORK_DIR}” –clusterID “${CLUSTER}” –autoregister),将生成的istio-token复制到vm上(issue)。这一点感觉不太好,虽然token是用来引导vm连接,为了安 全性,但维护成本有些大,毕竟vm断开的情况是无法避免的。注意token内容共一行,如果在终端复制的话可能变为多行。
[root@jenkins-51 ~]# tree /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets
/var/lib/istio
├── config
│ └── mesh
├── envoy
│ ├── cluster.env
│ ├── envoy_bootstrap_tmpl.json
│ └── sidecar.env
└── proxy
/etc/certs
└── root-cert.pem
/etc/istio/proxy
/etc/istio/config
└── mesh
/var/run/secrets
└── tokens
└── istio-token
4 directories, 7 files