Istio与vm融合

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

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

查看所有标签

猜你喜欢:

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

游戏化实战

游戏化实战

[美]Yu-kai Chou / 杨国庆 / 华中科技大学出版社 / 2017-1 / 59.00

TED演讲人作品,罗辑思维、华为首席用户体验架构师、思科网络体验CTO推荐。 随书附有TED演讲中文视频及作者开设的游戏化初学者课程。作者为Google、乐高、华为、思科、斯坦福大学、丹麦创新中心等多家企业、机构提供高层培训与合作。 ********************** “我长期以来都在密切关注Yu-kai的研究成果。任何想要让工作、生活变美好的人都应该阅读这本书。” ......一起来看看 《游戏化实战》 这本书的介绍吧!

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

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具