建议参考官方文档 https://istio.io/latest/zh/docs/setup/install/virtual-machine/ ,这里提醒大家对于命令中文版部分命令与英文版不一致,请以 英文版 为准。
对于istio在vm上的安装教程主要分为三部分。首先是在k8s的master节点生成vm连接主节点的一些配置信息,其实是在vm上应用这些配置信息,最后也就是验证连接是否成功。
本篇主要介绍“单网络”的情况, 对于”多网络“请自行参考官方文档。
vm环境准备
生成vm通讯配置信息
这里主要介绍一些新手迷惑的部分。如环境变量设置及vm注册的方式
设置环境变量
在设置变量时,对于”单网络“来讲 CLUSTER_NETWORK 和 VM_NETWORK 保留空值即可。如我这里设置如下
$ VM_APP="myapp" $ VM_NAMESPACE="vm" $ WORK_DIR="/root/myapp" $ SERVICE_ACCOUNT="vm-sa" $ CLUSTER_NETWORK="" $ VM_NETWORK="" $ CLUSTER="Kubernetes"
每个环境变量的解释:VM_APP
表示vm上应用的名称VM_NAMESPACE
表示应用所在的namespaceWORK_DIR
生成vm配置信息保留的目录,任何位置即可SERVICE_ACCOUNT
服务运行的账号 ,即yaml文件中的 ServiceAccount 字段CLUSTER
集群名称,默认为 Kubernetes 即可。
安装 Istio 控制平面
1 为安装创建 IstioOperator 空间
cat <<EOF > ./vm-cluster.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator metadata: name: istio spec: meshConfig: accessLogFile: /dev/stdout enableTracing: true enableEnvoyAccessLogService: true defaultConfig.envoyAccessLogService.address: skywalking-oap.istio-system:11800 values: global: meshID: mesh1 multiCluster: clusterName: "${CLUSTER}" network: "${CLUSTER_NETWORK}" EOF
spec.meshConfig.accessLogFile
表示启用日志功能,这样流量经过envoy 时将在日志 /var/log/istio/istio.log
中输出;其余三个是启用skywaling
链路追踪服务所需要的配置,如果不启用将其删除即可;第四个是链路追踪服务的地址。如果仅仅是想输出日志没有启用流量追踪服务的话,则只配置前两项即可。
2 安装 Istio
对于vm要注册到集群中的方法,分为”手动注册”和”自动注册”两种。其中”自动注册”方式目前还处于实验阶段,这里为了方便我们使用自动注册方式。
$ 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
如果想调整日志等级,从默认的 info 级别调整到 debug 的话,可以在命令行后面添加 –set values.global.logging.level=debug
3 部署东西向网关:(单网络)
$ samples/multicluster/gen-eastwest-gateway.sh --single-cluster | istioctl install -y -f -
4 使用东西向网关暴露集群内部服务:(单网络)
$ kubectl apply -n istio-system -f samples/multicluster/expose-istiod.yaml
5 配置虚拟主机的 namespace 和 ServiceAccount
$ kubectl create namespace "${VM_NAMESPACE}" $ kubectl create serviceaccount "${SERVICE_ACCOUNT}" -n "${VM_NAMESPACE}"
创建vm运行配置文件
对于vm要注册到集群中,分手动注册和自动注册。其中自动注册目前还处于实验阶段,这里为了方便我们使用自动注册。当虚拟机连接到 Istiod 时,会自动创建一个 workloadEntry。 这使得虚拟机成为 service 的一部分,类似于 Kubernetes 中的 endpoint。
这里的 WorkloadEntry
和 WorkloadGroup
他们分别对应的是k8s中的 POD 和 Deployment。
1 创建 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
2 将 WorkloadGroup 信息注册到集群中
$ kubectl --namespace "${VM_NAMESPACE}" apply -f workloadgroup.yaml
注意在配置 WorkloadGroup 的时候,不要使用探针这个例子,否则会导致通讯连接失败。
3 生成vm配置信息
$ istioctl x workload entry configure -f workloadgroup.yaml -o "${WORK_DIR}" --clusterID "${CLUSTER}" --autoregister
此时生成的vm配置信息将保存到环境变量 WORK_DIR 设置的目录。
建议了解一下生成的每一个配置文件内容,最好先看一下他们的内容,官方已对它们做了介绍。
这里需要提醒一下,你当前k8s集群没有使用 LoadBalancer 的话,则生成的 hosts 文件内容可能为空值,否则就需要手动添加一条域名解析记录。
$ cat /root/myapp/hosts 192.168.111.201 istiod.istio-system.svc $ kubectl get svc -A
域名 istiod.istio-system.svc
中的 istiod 为服务名称, istio-system 是服务所属的namespace, 后面的 svc 代表服务类型。如果对k8s比较熟悉的话,这个很容易理解。
不过我们仍然可用kubectl 进行端口映射,以向外提供服务.
先找到 istiod 对应的pod,然后再将pod的端口遇到外面,参考 https://istio.io/latest/zh/docs/setup/getting-started/
$ kubectl get -n istio-system pod -l app=istiod NAME READY STATUS RESTARTS AGE istiod-6445d59578-g6m45 1/1 Running 15 7d3h
为了允许vm与master通讯,以获取证书信息(安全传输使用),需要将master中的 15012 端口暴露出去。一般云厂商都提供了 LB 的方法,这时我们只讨论非 云厂商的情况。
这里有两种方法,一种是使用 kubectl 命令,适合线下测试使用。第二种方法是专业的裸机解决方案,那就是安装 Metallb,安装教程参考 https://blog.haohtml.com/archives/30956。
我们这里为了方便,采用第一种方法
$ kubectl port-forward -n istio-system pod/istiod-6445d59578-g6m45 --address=0.0.0.0 15012:15012 Forwarding from 0.0.0.0:15012 -> 15012
4 将生成的vm配置信息通过scp命令上传到vm
$ scp -r myapp sxf@192.168.111.133:/home/sxf/ sxf@192.168.111.133's password:
虚拟机配置
刚刚我们已经将生成的配置信息上传到了虚拟机vm,存储目录为 /home/sxf/myapp
,下面我们开始应用配置信息。
1 进入存储目录
cd /home/sxf/myapp
2 将根证书安装到目录 /etc/certs:
sudo mkdir -p /etc/certs sudo cp root-cert.pem /etc/certs/root-cert.pem
3 将令牌安装到目录 /var/run/secrets/tokens:
sudo mkdir -p /var/run/secrets/tokens sudo cp istio-token /var/run/secrets/tokens/istio-token
4 安装包含 Istio 虚拟机集成运行时(runtime)的包:
ubuntu:
$ curl -LO https://storage.googleapis.com/istio-release/releases/1.11.1/deb/istio-sidecar.deb $ sudo dpkg -i istio-sidecar.deb 正在选中未选择的软件包 istio-sidecar。 (正在读取数据库 ... 系统当前共安装有 213866 个文件和目录。) 正准备解包 istio-sidecar.deb ... 正在解包 istio-sidecar (1.11.2) ... 正在设置 istio-sidecar (1.11.2) ...
centos:
$ curl -LO https://storage.googleapis.com/istio-release/releases/1.11.2/rpm/istio-sidecar.rpm $ sudo rpm -i istio-sidecar.rpm
对于centos系统,目前官方声称只运行centos8(截止istio1.11.2),但经过测试发现 centos7.6 .1801 也可以支持,只是需要安装一个glibc 扩展包即可。
如果重复安装的话,会提示以下信息
$ sudo dpkg -i istio-sidecar.deb
Selecting previously unselected package istio-sidecar.
(Reading database ... 192947 files and directories currently installed.)
Preparing to unpack istio-sidecar.deb ...
Unpacking istio-sidecar (1.11.1) ...
Setting up istio-sidecar (1.11.1) ...
Adding group `istio-proxy' (GID 134) ...
Done.
Warning: The home dir /var/lib/istio you specified already exists.
Adding system user `istio-proxy' (UID 128) ...
Adding new user `istio-proxy' (UID 128) with group `istio-proxy' ...
The home directory `/var/lib/istio' already exists. Not copying from `/etc/skel'.
adduser: Warning: The home directory `/var/lib/istio' does not belong to the user you are currently creating.
此时会创建一个 istio-proxy 用户,和一些配置目录,如 /var/lib/istio
。
查看生成的目录结构
$ tree /var/lib/istio /var/lib/istio ├── config │ └── mesh ├── envoy │ ├── envoy_bootstrap_tmpl.json │ └── sidecar.env ├── extensions │ ├── metadata-exchange-filter.compiled.wasm │ ├── metadata-exchange-filter.wasm │ ├── stats-filter.compiled.wasm │ └── stats-filter.wasm └── proxy
5 将 cluster.env 安装到目录 /var/lib/istio/envoy/ 中
sudo cp cluster.env /var/lib/istio/envoy/cluster.env
6 将网格配置文件 Mesh Config 安装到目录 /etc/istio/config/mesh
sudo cp mesh.yaml /etc/istio/config/mesh
7 将 istiod 主机添加到 /etc/hosts
$ sudo sh -c 'cat hosts >> /etc/hosts' $ cat /etc/hosts 192.168.111.201 istiod.istio-system.svc
这时会将一个域名解析记录写入本机hosts文件,此域名至关重要,它是实现一切服务发现 xDS 的地址
8 把文件 /etc/certs/ 和 /var/lib/istio/envoy/ 的所有权转移给 Istio proxy
sudo mkdir -p /etc/istio/proxy sudo chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem
此时我们再看一下相关目录结构
$ 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 ├── extensions │ ├── metadata-exchange-filter.compiled.wasm │ ├── metadata-exchange-filter.wasm │ ├── stats-filter.compiled.wasm │ └── stats-filter.wasm └── proxy /etc/certs └── root-cert.pem /etc/istio/proxy /etc/istio/config └── mesh /var/run/secrets └── tokens └── istio-token 5 directories, 11 files
启动 istio 服务
1 在vm虚拟机上启用服务
$ systemctl start istio
2 查看istio日志
root@vm1:/home/sxf/myapp# tail -f /var/log/istio/istio.log 2021-09-06T07:27:43.891160Z info cache generated new workload certificate latency=969.387861ms ttl=23h59m59.108862154s 2021-09-06T07:27:43.891238Z info cache Root cert has changed, start rotating root cert 2021-09-06T07:27:43.891265Z info ads XDS: Incremental Pushing:0 ConnectedEndpoints:0 Version: 2021-09-06T07:27:43.892535Z info cache returned workload trust anchor from cache ttl=23h59m59.107482619s 2021-09-06T07:27:46.875262Z info ads ADS: new connection for node:vm1.vm-1 2021-09-06T07:27:46.875301Z info ads ADS: new connection for node:vm1.vm-2 2021-09-06T07:27:46.875490Z info cache returned workload trust anchor from cache ttl=23h59m56.124527456s 2021-09-06T07:27:46.875722Z info cache returned workload certificate from cache ttl=23h59m56.124293167s 2021-09-06T07:27:46.876267Z info ads SDS: PUSH for node:vm1.vm resources:1 size:1.1kB resource:ROOTCA 2021-09-06T07:27:46.876305Z info ads SDS: PUSH for node:vm1.vm resources:1 size:4.0kB resource:default
如果看到类似的输出,则表示服务成功。 其中 node:vm1.vm 中的vm1表示当前主机名,vm表示命名空间
也可以查看错误日志
$ tail -f /var/log/istio/istio.err.log
为了防止服务器重启导致的 istio 服务无法自动重启的问题,建议设置为随机启动。
$ systemctl enable istio
可以通过 systemctl is-enabled istio.service 查看服务是否为随机启动状态。
验证vm是否联机成功
在k8s控制面 master 节点执行查看命令
$ istioctl proxy-status vm1.vm SYNCED SYNCED SYNCED SYNCED istiod-6445d59578-g6m45 1.11.0
当看到类似信息即表示通讯成功!更多用法通过命令 istioctl --help
查看
另外我们也可以查看前面注册的 WorkloadGroup 和 WorkloadEntry
$ kubectl get wg -A $ kubectl get we -A
常见问题
- 如果遇到 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 日志文件
2021-09-09T01: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服务
4. 如果按照istio官方文档的istio步骤,会发现通过 vm 请求服务时
$ curl helloworld.sample.svc:5000/hello
是无法正常通讯的。
此时需要先检查一下域名路由问题,使用 traceroute 或 ping 命令均可。
$ traceroute helloworld.sample.svc
此时需要手动添加一条路由规则才可以。
$ route add -net 10.244.0.0 gw 192.168.3.58 netmask 255.255.0.0
这里向所以来自ip段 10.244.0.0 的请求通过网关 192.168.3.58 进行转发。这里的 10.244.0.0 是指安装k8s时指定的 Pod CIDR网格段(参考), 192.168.3.58 是指安装k8s master 节点的IP地址。
5. 如果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内容共一行,如果在终端复制的话可能变为多行。
# 停止服务 systemctl stop istio killall envoy # 清理旧内容 rm -rf /etc/certs/ unlink /var/lib/istio/proxy/XDS unlink /var/lib/istio/proxy/SDS unlink /etc/istio/proxy/SDS unlink /etc/istio/proxy/XDS # 复制新生成的 istio-token sudo mkdir -p /etc/certs sudo cp root-cert.pem /etc/certs/root-cert.pem sudo mkdir -p /var/run/secrets/tokens sudo cp istio-token /var/run/secrets/tokens/istio-token # 当前目录结构 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 ├── extensions │ ├── metadata-exchange-filter.compiled.wasm │ ├── metadata-exchange-filter.wasm │ ├── stats-filter.compiled.wasm │ └── stats-filter.wasm └── proxy /etc/certs └── root-cert.pem /etc/istio/proxy └── envoy-rev0.json /etc/istio/config └── mesh /var/run/secrets └── tokens └── istio-token # 重启服务验证 systemctl start istio tail -f /var/log/istio/istio.log