部署ASM-PROXY
为了兼容不同虚拟机操作系统的版本差异,ASM-PROXY以Docker镜像的方式进行部署。部署流程如图1所示。
准备工作
- 已购买CCE集群,已在集群中创建虚拟机服务使用的命名空间(假设为vmns),已在该命名空间创建容器服务。具体操作请参见购买CCE集群。
- 已购买企业版网格,并添加集群到网格,虚拟机服务使用的命名空间已开启sidecar注入。具体操作请参购买网格、添加集群和sidecar管理。
- 准备两台已安装Docker的ECS虚拟机,并满足以下要求:
要求
操作方法
创建相应目录及文件
在ECS虚拟机上执行以下命令:
mkdir -p /opt/asm_proxy/certs/
touch /opt/asm_proxy/asm_proxy.env
备份虚拟机iptables规则
在ECS虚拟机上执行以下命令:
iptables-save > ~/iptables.backup
请确保网络三层连通性:
- 为了保证虚拟机与CCE集群的Pod互通,准备的虚拟机需要与CCE集群处于同一VPC内。
- 虚拟机需放通安全组,入方向需添加到<cluster-name>-cce-control安全组的规则,否则ping不通Pod IP。
获取根证书
- 通过kubectl访问CCE集群。
- 登录云容器引擎控制台,在“集群管理”页面单击集群名称,进入集群详情页。
- 在“连接信息”区域找到kubectl,单击查看后,按照教程为您的客户端机器配置kubectl,并访问CCE集群。
假设配置了kubectl的客户端机器称为kubectl节点,下文将一律使用kubectl节点进行描述。
- 在kubectl节点执行以下命令,创建临时工作目录。
export VM1_DIR="<a working directory for vm1>"
mkdir -p ${VM1_DIR}
- 在kubectl节点执行以下命令,创建服务账号。
export NS=<vmns>
export SERVICE_ACCOUNT=<vmsa>
kubectl create serviceaccount "${SERVICE_ACCOUNT}" -n "${NS}"
其中,NS为虚拟机要加入的命名空间,SERVICE_ACCOUNT为虚拟机使用的服务账号。
- 获取证书密钥文件。
- 在kubectl节点执行以下命令,确认集群是否已开启TokenRequest API。
kubectl get --raw /api/v1 | grep "serviceaccounts/token"
如果没有返回,则需要参考Service Account Token Volume Projection开启该API。
- 在kubectl节点执行以下命令,获取证书密钥文件。
export tokenexpiretime=$((3600*24*365))
1、echo '{"kind":"TokenRequest","apiVersion":"authentication.k8s.io/v1","spec":{"audiences":["istio-ca"],"expirationSeconds":'$tokenexpiretime'}}' | kubectl create --raw /api/v1/namespaces/vmns/serviceaccounts/vmsa/token -f -
其中,3600*24*365表示1年有效期,31536000s。
3.复制token字段的值,在kubectl节点执行以下命令,将密钥保存在istio-token文件中。
echo -n "{token字段的值}" > ${VM1_DIR}/istio-token
- 在kubectl节点执行以下命令,确认集群是否已开启TokenRequest API。
- 在kubectl节点执行以下命令,获取根证书文件。
kubectl get secret -n istio-system cacerts -o yaml |grep "root-cert.pem" | head -1 | cut -d ":" -f 2 | sed s/[[:space:]]//g | base64 -d > ${VM1_DIR}/root-cert.pem
设置启动参数
- 在kubectl节点执行以下命令,获取相关参数并写入${VM1_DIR}目录下的asm_proxy.env文件中。
- 获取ASM控制面通信地址
ISTIO_PILOT_ADDR=$(kubectl get pod -n istio-system -o jsonpath='{.items[2].status.podIP}') echo "ISTIO_PILOT_ADDR=${ISTIO_PILOT_ADDR}" > ${VM1_DIR}/asm_proxy.env
- 获取集群ID
ASM_CLUSTER_ID=$(kubectl get deploy -n istio-system -o yaml | grep -A1 "ISTIO_META_CLUSTER_ID" | tail -1 | awk -F':' '{print $NF}' | awk '$1=$1') echo "ISTIO_META_CLUSTER_ID=${ASM_CLUSTER_ID}" >> ${VM1_DIR}/asm_proxy.env
- 获取网格ID
ASM_MESH_ID=$(kubectl get deploy -n istio-system -o yaml | grep -A1 "ISTIO_META_ASM_MESH_ID" | tail -1 | awk -F':' '{print $NF}' | awk '$1=$1') echo "ISTIO_META_MESH_ID=${ASM_MESH_ID}" >> ${VM1_DIR}/asm_proxy.env
- 获取监控服务端地址
ZIPKIN_ADDRESS=$(kubectl get iop -n istio-system -o yaml | grep -A1 "zipkin" | sed -n '2p') TRACING_ZIPKIN_ADDRESS=$(echo ${ZIPKIN_ADDRESS#*:}) echo "TRACING_ZIPKIN_ADDRESS=${TRACING_ZIPKIN_ADDRESS}" >> ${VM1_DIR}/asm_proxy.env
- 获取虚拟机要加入的命名空间
echo "NS=${NS}" >> ${VM1_DIR}/asm_proxy.env
- 获取虚拟机使用的服务账号
echo "SERVICE_ACCOUNT=${SERVICE_ACCOUNT}" >> ${VM1_DIR}/asm_proxy.env
- 获取ASM控制面通信地址
- 打开kubectl节点的${VM1_DIR}/asm_proxy.env文件,填写以下变量,保存文件。
# 集群服务网段,从ASM控制台“网格配置 > 基本信息”页面集群列表中获取 ISTIO_SERVICE_CIDR=x.x.x.x/x # 虚拟机使用的Pod名称,自定义 POD_NAME=<vmapp1> # 不指定代理云平台 CLOUD_PLATFORM=none
- 执行以下命令检查文件内容。
cat ${VM1_DIR}/asm_proxy.env
正常回显如下:
ISTIO_PILOT_ADDR=10.252.2.36 ISTIO_META_CLUSTER_ID=cluster-vm ISTIO_META_MESH_ID=e256c79c-8b13-11ec-94e9-0255ac10069a TRACING_ZIPKIN_ADDRESS=otel-collector.monitoring.svc.cluster.local:9411 NS=vmns SERVICE_ACCOUNT=vmsa ISTIO_SERVICE_CIDR=10.233.0.0/16 POD_NAME=vmapp1
- 将kubectl节点${VM1_DIR}目录下的asm_proxy.env文件上传到虚拟机/opt/asm_proxy/目录下。
在root下执行:
scp ${VM1_DIR}/asm_proxy.env root@${虚拟机ip}:/opt/asm_proxy/
- 将kubectl节点${VM1_DIR}目录下的istio-token、root-cert.pem文件上传到虚拟机/opt/asm_proxy/certs目录下。
在root下执行:
scp ${VM1_DIR}/istio-token root@${虚拟机ip}:/opt/asm_proxy/certs
scp ${VM1_DIR}/root-cert.pem root@${虚拟机ip}:/opt/asm_proxy/certs
获取镜像包
- 以root用户登录虚拟机。
- 获取asm-proxy-1.8.4镜像包。
asm-proxy-1.8.4镜像包存放在SWR镜像仓库中,使用如下命令拉取镜像(x86和arm架构的命令相同)。
docker pull SWR镜像仓库地址/istio/asm-proxy:1.8.4
SWR镜像仓库地址的获取方式如下:
在容器镜像服务控制台“总览”页面单击右上角的“登录指令”,弹出“登录指令”对话框,指令末尾的域名即为SWR镜像仓库地址,形式为swr.***.com。
启动前检查
- 以root用户登录虚拟机。
- 检查证书文件信息。
ls -l /opt/asm_proxy/certs/
以下为预期结果:
-rw------- 1 root root 757 Jan 24 10:41 istio-token -rw------- 1 root root 1789 Jan 24 10:41 root-cert.pem
- 检查启动参数文件信息。
cat /opt/asm_proxy/asm_proxy.env
以下为预期结果(具体值会不同,确保不为空):
ISTIO_PILOT_ADDR=10.252.2.36 ISTIO_META_CLUSTER_ID=cluster-vm ISTIO_META_MESH_ID=e256c79c-8b13-11ec-94e9-0255ac10069a TRACING_ZIPKIN_ADDRESS=otel-collector.monitoring.svc.cluster.local:9411 NS=vmns SERVICE_ACCOUNT=vmsa ISTIO_SERVICE_CIDR=10.233.0.0/16 POD_NAME=vmapp1
启动asm-proxy
- 执行以下命令,启动asm-proxy容器。
docker run -d \ --name=asm-proxy \ --network=host \ --restart=always \ --env-file /opt/asm_proxy/asm_proxy.env \ --cap-add=NET_ADMIN \ --volume=/opt/asm_proxy/certs:/opt/istio/certs \ SWR镜像仓库地址/istio/asm-proxy:1.8.4
其中,“SWR镜像仓库地址/istio/asm-proxy:1.8.4”为asm-proxy镜像包地址,请参考获取镜像包获取。
- 若虚拟机为arm架构,还需要执行以下步骤:
- 执行docker ps | grep asm-proxy,查看asm-proxy容器的ID。
返回示例如下:
fad1ab9530fc asm-proxy:1.8.4 "/usr/bin/bash /usr/…" 24 h
- 执行如下命令从容器中拷贝二进制文件。
docker cp fad1ab9530fc:/usr/local/bin/pilot-agent /usr/local/bin
其中,fad1ab9530fc为上一步获取的容器ID。
- 为二进制文件赋予可执行权限。
- 定义环境变量并赋值。
export ISTIO_SERVICE_CIDR=x.x.x.x/x
其中,x.x.x.x/x为集群服务网段,从ASM控制台“网格配置 > 基本信息”页面集群列表中获取。
- 设置虚拟机的iptables。
pilot-agent istio-clean-iptables -m REDIRECT
pilot-agent istio-iptables -p 15001 -z 15006 -u 1337 -m REDIRECT -i ${ISTIO_SERVICE_CIDR} -x "" -b "*" -d 15020
- 执行docker ps | grep asm-proxy,查看asm-proxy容器的ID。
启动后检查
- 在虚拟机上执行以下命令,检查istio的envoy进程是否正常。
ps -ef | grep istio
正常回显信息类似如下,envoy进程运行正常。
root 27254 27139 0 14:37 ? 00:00:00 su -s /bin/bash -c INSTANCE_IP=10.66.6.88 POD_NAME=vmapp1 POD_NAMESPACE=vmns exec /usr/local/bin/pilot-agent proxy --serviceCluster vmapp1 2> /var/log/istio/istio.err.log > /var/log/istio/istio.log istio-proxy systemd+ 27714 27707 0 14:40 ? 00:00:00 /usr/local/bin/envoy -c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster vmapp1 --service-node sidecar~10.66.6.88~vmapp1.vmns~vmns.svc.cluster.local --local-address-ip-version v4 --bootstrap-version 3 --log-format-prefix-with-location 0 --log-format %Y-%m-%dT%T.%fZ?%l?envoy %n?%v -l warning --component-log-level misc:error root 27745 3521 0 14:50 pts/0 00:00:00 grep --color=auto istio
- 检查asm-proxy容器状态正常。
docker ps | grep asm-proxy
如果第5列没有提示Restarting,说明asm-proxy容器启动正常。
2bc3ee448c6d asm-proxy:1.8.4 "/usr/bin/bash /usr/..." 52 seconds ago Up 51 seconds asm-proxy
启动异常显示如下:
- 检查istio启动正常。
- 执行以下命令进入asm-proxy容器。
- 执行以下命令查看istio启动日志。
正常启动日志如下:
2022-02-07T09:23:31.651059Z info xdsproxy Envoy ADS stream established 2022-02-07T09:23:31.651156Z info xdsproxy connecting to upstream XDS server: istiod.istio-system.svc:15012 2022-02-07T09:23:31.962409Z info sds resource:ROOTCA new connection 2022-02-07T09:23:31.962484Z info sds Skipping waiting for gateway secret 2022-02-07T09:23:31.962547Z info sds resource:default new connection 2022-02-07T09:23:31.962592Z info sds Skipping waiting for gateway secret 2022-02-07T09:23:31.962706Z info cache adding watcher for file ./etc/certs/root-cert.pem 2022-02-07T09:23:31.962785Z info cache GenerateSecret from file ROOTCA 2022-02-07T09:23:31.963252Z info sds resource:ROOTCA pushed root cert to proxy 2022-02-07T09:23:32.041052Z error cache cannot load key pair from /etc/certs: open /etc/certs/cert-chain.pem: no such file or directory 2022-02-07T09:23:32.055631Z info cache GenerateSecret default 2022-02-07T09:23:32.056570Z info sds resource:default pushed key/cert pair to proxy
- 在虚拟机上执行以下命令,确认iptables规则正确配置。
iptables -t nat -L -v
如果回显信息类似如下,说明iptables规则配置成功。
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 106 4240 ISTIO_INBOUND tcp -- any any anywhere anywhere Chain INPUT (policy ACCEPT 106 packets, 4240 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 207 packets, 16621 bytes) pkts bytes target prot opt in out source destination 50 3000 ISTIO_OUTPUT tcp -- any any anywhere anywhere Chain POSTROUTING (policy ACCEPT 207 packets, 16621 bytes) pkts bytes target prot opt in out source destination Chain ISTIO_INBOUND (1 references) pkts bytes target prot opt in out source destination 0 0 RETURN tcp -- any any anywhere anywhere tcp dpt:15008 0 0 RETURN tcp -- any any anywhere anywhere tcp dpt:ssh 0 0 RETURN tcp -- any any anywhere anywhere tcp dpt:15020 106 4240 ISTIO_IN_REDIRECT tcp -- any any anywhere anywhere Chain ISTIO_IN_REDIRECT (3 references) pkts bytes target prot opt in out source destination 106 4240 REDIRECT tcp -- any any anywhere anywhere redir ports 15006 Chain ISTIO_OUTPUT (1 references) pkts bytes target prot opt in out source destination 0 +++++++++++++++++++++++++++++++++++++++++++ 0 RETURN all -- any lo 127.0.0.6 anywhere 0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner UID match 1337 0 0 RETURN all -- any lo anywhere anywhere ! owner UID match 1337 0 0 RETURN all -- any any anywhere anywhere owner UID match 1337 0 0 ISTIO_IN_REDIRECT all -- any lo anywhere !localhost owner GID match 1337 0 0 RETURN all -- any lo anywhere anywhere ! owner GID match 1337 0 0 RETURN all -- any any anywhere anywhere owner GID match 1337 0 0 RETURN all -- any any anywhere localhost 0 0 ISTIO_REDIRECT all -- any any anywhere 10.228.0.0/16 50 3000 RETURN all -- any any anywhere anywhere Chain ISTIO_REDIRECT (1 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT tcp -- any any anywhere anywhere redir ports 15001
其中,10.228.0.0/16为集群服务网段。