内容简介:最近在搞ISTIO与VM集成的方案,官网上有一些文档,按照流程部署下去发现问题不少;下面对在遇到的问题和经验都整理了一下。为了使VM与已经部署了ISTIO的K8S集群连通,我们需要先把VM加入到k8s集群,这样会自动部署flannel网络,保障POD网络可通。这块如果使用kubeadm来部署的k8s的话,比较简单,直接为了让VM的应用可以直接使用服务名称来通信,需要修改vm的域名解析服务的配置文件 (从k8s的任意一个pod上拷贝
最近在搞ISTIO与VM集成的方案,官网上有一些文档,按照流程部署下去发现问题不少;下面对在遇到的问题和经验都整理了一下。
部署
接下来的实验的拓扑图如下所示:
基础网络准备
为了使VM与已经部署了ISTIO的K8S集群连通,我们需要先把VM加入到k8s集群,这样会自动部署flannel网络,保障POD网络可通。这块如果使用kubeadm来部署的k8s的话,比较简单,直接 kubeadm join
就可以加入一个新的集群了。
为了让VM的应用可以直接使用服务名称来通信,需要修改vm的域名解析服务的配置文件 (从k8s的任意一个pod上拷贝 /etc/resolv.conf
)
cat /etc/resolv.conf # Your system has been configured with 'manage-resolv-conf' set to true. # As a result, cloud-init has written this file with configuration data # that it has been provided. Cloud-init, by default, will write this file # a single time (PER_ONCE). # #nameserver 183.60.83.19 #nameserver 183.60.82.98 nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5
预安装
kubectl create namespace istio-system helm template install/kubernetes/helm/istio-init --name istio-init --namespace istio-system | kubectl apply -f -
安装istio
主要是需要指定 meshExpansion 扩展:
helm install --set global.meshExpansion.enabled=true install/kubernetes/helm/istio --name istio --namespace istio-system --values install/kubernetes/helm/istio/values-istio-demo.yaml # 或者安装istio(带meshExpansion-认证) helm install --set global.meshExpansion.enabled=true install/kubernetes/helm/istio --name istio --namespace istio-system --values install/kubernetes/helm/istio/values-istio-demo-auth.yaml
cluster.env
cat << EOF > cluster.env ISTIO_CP_AUTH=MUTUAL_TLS # 需要使用这个值,很重要 ISTIO_SERVICE_CIDR=10.244.0.0/16 # Pod子网CIDR ISTIO_INBOUND_PORTS=3306,9080 # VM上对外提供服务的端口号 POD_NAME=details # 似乎作用不大,可以随意 EOF sudo cp cluster.env /var/lib/istio/envoy
准备证书
kubectl -n istio-system get secret istio.default -o jsonpath='{.data.root-cert\.pem}' |base64 --decode > root-cert.pem kubectl -n istio-system get secret istio.default -o jsonpath='{.data.key\.pem}' |base64 --decode > key.pem kubectl -n istio-system get secret istio.default -o jsonpath='{.data.cert-chain\.pem}' |base64 --decode > cert-chain.pem sudo mkdir -p /etc/certs sudo cp {root-cert.pem,cert-chain.pem,key.pem} /etc/certs
安装sidecar
Debian包
针对Ubuntu,可以直接从官方下载安装包:
curl -L https://storage.googleapis.com/istio-release/releases/1.1.6/deb/istio-sidecar.deb > istio-sidecar.deb sudo dpkg -i istio-sidecar.deb
RPM包
针对CentOS系统,需要自己编译安装包:
-
编译
在本地的GOPATH目录下克隆istio,然后在istio的根目录执行
cd /go/src/github.com/istio/istio make rpm/builder-image make rpm/proxy
-
安装
然后在/go/src/out/目录下可以找到对应的rpm包。
在安装rpm包的时候,会发现没有GLIBC_2.18,解决方法如下:
下载:wget http://mirrors.ustc.edu.cn/gnu/libc/glibc-2.18.tar.gz
解压:tar -zxvf glibc-2.18.tar.gz
进入解压文件夹,创建文件夹build, 运行configure配置:
mkdir build cd build ../configure --prefix=/usr make -j4 sudo make install
准备用户
sudo useradd istio-proxy sudo chown -R istio-proxy /etc/certs /var/lib/istio/envoy
启动服务
sudo systemctl start istio-auth-node-agent sudo systemctl start istio
sidecar.env
内容如下
## cat sidecar.env | grep -v '#' ISTIO_SERVICE=details ISTIO_SVC_IP=10.244.3.0 ENVOY_USER=istio-proxy ISTIO_AGENT_FLAGS="--zipkinAddress zipkin.istio-system:9411 --proxyLogLevel debug"
重启ISTIO服务
systemctl restart istio
部署业务
首先使用bookinfo中的示例来部署整个调用链中的服务和workload。
kubectl apply -f istio-1.1.6/samples/bookinfo/platform/kube/bookinfo.yaml
等k8s中所有服务都起来之后,删除details这个deployment以及其对应的services。然后在github上找到details的 ruby代码文件 ,拷贝到VM上保存为 ruby_server.rb
。
在VM上需要直接使用ubuntu用户来运行该服务:
ruby ./ruby_server.rb 9080
在k8s集群里面,重新创建details服务:
istioctl -n default register details 10.244.3.0 http:9080 # 这里的 10.244.3.0 是VM的IP地址,http为通信协议,9080为details服务对外暴露的端口号
部署istio转发规则
kubectl apply -f istio-1.1.6/samples/bookinfo/networking/destination-rule-all.yaml kubectl apply -f istio-1.1.6/samples/bookinfo/networking/virtual-service-all-v1.yaml
待解决问题
VM网络转发
到当前,bookinfo的流量转发应该能够正常,但是还存在一个问题:
如果直接在vm上通过service名称来访问k8s中的其他服务,将无法经过sidecar。其主要原因是iptables,通过查看配置可以看到:
# iptables -t nat -nvL OUTPUT Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 744K 82M KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ 2285 137K ISTIO_OUTPUT tcp -- * * 0.0.0.0/0 0.0.0.0/0
由于我们在VM上部署了k8s,kube-proxy的KUBE-SERVICES链要优先于ISTIO_OUTPUT导致上面的问题。
Prometheus监控vm-envoy
由于prometheus对所有sidecar的envoy监控是通过k8s来做服务发现的,而VM的envoy并没有在k8s中体现出来。这块需要我们手动配置prometheus的target。
具体通过修改istio-system命令空间下prometheus configmap的配置, 添加 vm-envoy-stats
任务。
global: scrape_interval: 15s scrape_timeout: 10s evaluation_interval: 1m scrape_configs: - job_name: vm-envoy-stats scrape_interval: 15s scrape_timeout: 10s metrics_path: /stats/prometheus scheme: http static_configs: - targets: - 10.244.3.0:15090
效果展示
调用链
Granfana
调试经验
查看envoy的配置信息
对于pod的sidecar,直接通过nsenter进入到pid的net namespace下(对于VM直接在VM上)执行以下命令:
# curl localhost:15000/help admin commands are: /: Admin home page /certs: print certs on machine /clusters: upstream cluster status /config_dump: dump current Envoy configs (experimental) /contention: dump current Envoy mutex contention stats (if enabled) /cpuprofiler: enable/disable the CPU profiler /healthcheck/fail: cause the server to fail health checks /healthcheck/ok: cause the server to pass health checks /heapprofiler: enable/disable the heap profiler /help: print out list of admin commands /hot_restart_version: print the hot restart compatibility version /listeners: print listener addresses /logging: query/change logging levels /memory: print current allocation/heap usage /quitquitquit: exit the server /reset_counters: reset all counters to zero /runtime: print runtime values /runtime_modify: modify runtime values /server_info: print server version/status information /stats: print server stats /stats/prometheus: print server stats in prometheus format
当然, 对于pod如果是指查看xds的配置,可以直接执行
# istioctl ps NAME CDS LDS EDS RDS PILOT VERSION details.default SYNCED SYNCED SYNCED (50%) SYNCED istio-pilot-59954cff67-wxgnr 1.1.3 istio-egressgateway-7dbbb87698-ds9j2.istio-system SYNCED SYNCED SYNCED (100%) NOT SENT istio-pilot-59954cff67-wxgnr 1.1.3 istio-ingressgateway-565b894b5f-rn2l2.istio-system SYNCED SYNCED SYNCED (100%) NOT SENT istio-pilot-59954cff67-wxgnr 1.1.3 productpage-v1-79458795bc-jdvg6.default SYNCED SYNCED SYNCED (50%) SYNCED istio-pilot-59954cff67-wxgnr 1.1.3 ratings-v1-5b7cd6c58f-559nb.default SYNCED SYNCED SYNCED (50%) SYNCED istio-pilot-59954cff67-wxgnr 1.1.3 ratings-v2-mysql-vm-74978d9b97-mlv8r.default SYNCED SYNCED SYNCED (50%) SYNCED istio-pilot-59954cff67-wxgnr 1.1.3 reviews-v1-54c7c79486-wrw6f.default SYNCED SYNCED SYNCED (50%) SYNCED istio-pilot-59954cff67-wxgnr 1.1.3 reviews-v2-7dc5785684-zccst.default SYNCED SYNCED SYNCED (50%) SYNCED istio-pilot-59954cff67-wxgnr 1.1.3 reviews-v3-6c464d7bf4-5px2m.default SYNCED SYNCED SYNCED (50%) SYNCED istio-pilot-59954cff67-wxgnr 1.1.3 # istioctl pc listeners productpage-v1-79458795bc-jdvg6.default ADDRESS PORT TYPE 10.244.1.130 9080 HTTP 10.103.241.209 31400 TCP 10.103.241.209 8060 TCP 10.107.214.136 16686 TCP .... # 通过指定-o json可以查看到更详细的配置信息
查看envoy是否GRPC上报telemetry到mixer
需要先打开envoy的日志模块,具体如下:
curl -X POST localhost:15000/logging?level=info curl -X POST localhost:15000/logging?grpc=trace tailf /var/log/istio/istio.err.log
可以看到如下信息:
strings { key: 3 value: -8 } strings { key: 17 value: -11 } ... } default_words: "kubernetes://details.default" default_words: "details.default.svc.cluster.local" default_words: "istio-envoy" default_words: "Wed, 29 May 2019 07:33:10 GMT" default_words: "178" default_words: "origin.ip" default_words: "default" default_words: "kubernetes://productpage-v1-79458795bc-jdvg6.default" default_words: "istio://default/services/details" ... global_word_count: 221
这里就是envoy的mixer filter上报到mixer的attribute信息。每一个key都对应着mixer中内置的attribute关键字的index,每一个value对应default_workds索引。具体参考 这篇 文章。
之前遇到一个问题,发现envoy有通过grpc Report到mixer;同时在mixer的accessLog也能够看到logentry生成到stdio的访问日志。但是prometheus始终无法从istio-telemetry采集到istio_requests_total的指标。后来调查发现是手动通过istioctl register注册服务的时候,没有指定其协议类型导致的。
查看envoy的业务流量访问日志
istio默认是不看业务流量访问日志的,因为日志量太大。如果需要调试,需要手动修改istio-system中的configmap的配置。
kubectl -n istio-system edit cm istio # apiVersion: v1 data: mesh: "# Set the following variable to true to disable policy checks by the Mixer.\n# Note that metrics will still be reported to the Mixer.\ndisablePolicyChecks: true\n\n# Set enableTracing to false to disable request tracing.\nenableTracing: true\n\n# Set accessLogFile to empty string to disable access log.\naccessLogFile: \"/dev/stdout\"\n\n#
修改最后一行为 /dev/stdout
,这样通过查看业务pod的istio-proxy container的日志就可以看到流量的access-log了。
当然,对于VM可以直接修改这个值为一个目录,然后在VM上重启istio服务就可以在日志文件中看到流量信息。
# kc logs --tail=5 -f productpage-v1-79458795bc-jdvg6 -c istio-proxy [2019-05-29T07:57:21.444Z] "GET /productpage?u=normal HTTP/1.1" 200 - "-" 0 4083 5034 5034 "-" "curl/7.47.0" "9d5d739a-9fbd-9659-ab58-2619a6792936" "productpage.default.svc.cluster.local:9080" "127.0.0.1:9080" inbound|9080|http|productpage.default.svc.cluster.local - 10.244.1.130:9080 10.244.3.0:51704 - [2019-05-29T07:57:29.495Z] "GET /details/0 HTTP/1.1" 200 - "-" 0 178 2 2 "-" "curl/7.47.0" "366fc77a-d9d5-9971-9a3b-60576e1ca230" "details:9080" "10.244.3.0:9080" outbound|9080||details.default.svc.cluster.local - 10.102.237.154:9080 10.244.1.130:35582 - [2019-05-29T07:57:29.500Z] "GET /reviews/0 HTTP/1.1" 500 - "-" 0 3926 2510 2509 "-" "curl/7.47.0" "366fc77a-d9d5-9971-9a3b-60576e1ca230" "reviews:9080" "10.244.1.155:9080" outbound|9080|v3|reviews.default.svc.cluster.local - 10.109.123.127:9080 10.244.1.130:35202 - [2019-05-29T07:57:32.012Z] "GET /reviews/0 HTTP/1.1" 500 - "-" 0 3926 2510 2509 "-" "curl/7.47.0" "366fc77a-d9d5-9971-9a3b-60576e1ca230" "reviews:9080" "10.244.1.155:9080" outbound|9080|v3|reviews.default.svc.cluster.local - 10.109.123.127:9080 10.244.1.130:35258 -
查看流表转发流程
istio中流量的转发流程可以参考jimmy的这张图, 下面要说的是具体chain中的规则。
- inbound流量
# iptables -t nat -nvL PREROUTING Chain PREROUTING (policy ACCEPT 15 packets, 900 bytes) pkts bytes target prot opt in out source destination 1969K 174M KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ 162K 9707K ISTIO_INBOUND tcp -- * * 0.0.0.0/0 0.0.0.0/0
首先查看PREROUTING chain,可以看到,流量被送到ISTIO_INBOUND。
# iptables -t nat -nvL ISTIO_INBOUND Chain ISTIO_INBOUND (1 references) pkts bytes target prot opt in out source destination 2536 152K ISTIO_IN_REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 343 20580 ISTIO_IN_REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:9080
在ISTIO_INBOUND中,VM提供对外服务的端口3306和9080的流量被转发到 ISTIO_IN_REDIRECT。这里如果VM上面有新添加服务端口,需要修改了cluster.env之后重启istio服务。
# iptables -t nat -nvL ISTIO_IN_REDIRECT Chain ISTIO_IN_REDIRECT (2 references) pkts bytes target prot opt in out source destination 2962 178K REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15001
在 ISTIO_IN_REDIRECT中,流量被送到了envoy处理。
- outbound流量
同理,这里只给出对应的链表规则:
# iptables -t nat -nvL OUTPUT Chain OUTPUT (policy ACCEPT 24 packets, 2927 bytes) pkts bytes target prot opt in out source destination 782K 86M KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */ 5033 302K ISTIO_OUTPUT tcp -- * * 0.0.0.0/0 0.0.0.0/0
# iptables -t nat -nvL ISTIO_OUTPUT Chain ISTIO_OUTPUT (1 references) pkts bytes target prot opt in out source destination 0 0 ISTIO_REDIRECT all -- * lo 0.0.0.0/0 !127.0.0.1 790 47400 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 1000 4387 263K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner UID match 0 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner GID match 1000 0 0 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0 owner GID match 0 0 0 RETURN all -- * * 0.0.0.0/0 127.0.0.1 0 0 ISTIO_REDIRECT all -- * * 0.0.0.0/0 10.244.0.0/16 2 120 RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
这里的uid 1000其实就是envoy进程的uid,而0是root。之所以这样设置,是因为如果将root的流量都干掉了,将导致ssh无法连接主机。继续查看ISTIO_REDIRECT链的规则:
# iptables -t nat -nvL ISTIO_REDIRECT Chain ISTIO_REDIRECT (2 references) pkts bytes target prot opt in out source destination 0 0 REDIRECT tcp -- * * 0.0.0.0/0 0.0.0.0/0 redir ports 15001
这样就基本明白了inbound和outbound流量被送进envoy之前的转发过程了。
以上所述就是小编给大家介绍的《Istio与vm融合》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。