Istio与vm融合

栏目: 后端 · 发布时间: 5年前

内容简介:最近在搞ISTIO与VM集成的方案,官网上有一些文档,按照流程部署下去发现问题不少;下面对在遇到的问题和经验都整理了一下。为了使VM与已经部署了ISTIO的K8S集群连通,我们需要先把VM加入到k8s集群,这样会自动部署flannel网络,保障POD网络可通。这块如果使用kubeadm来部署的k8s的话,比较简单,直接为了让VM的应用可以直接使用服务名称来通信,需要修改vm的域名解析服务的配置文件 (从k8s的任意一个pod上拷贝

最近在搞ISTIO与VM集成的方案,官网上有一些文档,按照流程部署下去发现问题不少;下面对在遇到的问题和经验都整理了一下。

部署

接下来的实验的拓扑图如下所示:

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

效果展示

调用链

Istio与vm融合 Istio与vm融合

Granfana

Istio与vm融合

调试经验

查看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与vm融合 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融合》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Sprint

Sprint

Jake Knapp、John Zeratsky、Braden Kowitz / Simon & Schuster / 2016-3-8 / GBP 14.60

媒体推荐 “Every business leader I know worries about the same thing: Are we moving fast enough? The genius of Jake Knapp’s Sprint is its step-by-step breakdown of what it takes to solve big problems an......一起来看看 《Sprint》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具