ISTIO 學習筆記(三)之 管理kubernetes集群外的vm服務流量


一、背景

   Istio 是基於 kubernetes 進行實現,因此其與 kubernetes 是強耦合的。它使用的根本場景是對雲上的微服務進行治理。但實際的多數場景是產品均部署在虛擬機或物理機上,針對這種 istio 實際上是不適用的。 雲上場景中,也存在基礎組件安裝在 vm (虛擬機或物理機)上,雲上的微服務需要使用  vm 上的微服務,此時就需要將 vm 加入到 istio mesh,本文介紹,如何將 vm 上的微服務加入到 istio mesh 中。

二、部署架構

    

三、實操

 環境信息:

# 使用 的kubernets 版本為 1.19.2

[root@k8s-1 certs]# kubectl version --short
Client Version: v1.19.2
Server Version: v1.19.2

# 准備安裝的istio版本為 1.7.3
[root@k8s-1 certs]# istioctl version --short
client version: 1.7.3
control plane version: 1.7.3
data plane version: 1.7.3 (4 proxies), 1.7.0 (1 proxies)

 1、常規安裝操作

PS:在 kubernetes 安裝 istio 之前就 創建 istio-system,並將證書准備好(生成根證書、根key、中間CA證書、中間CA key),將證書導入到 istio,供 istio 使用。

(1) 在 安裝 kubernets 的 Node 結點上操作(可以直接是 master node)

  a) 生成證書

cd /home/opt/istio-1.7.3/tools/certs

# 在當前目錄下生成 root 根證書;root-ca.conf\root-cert.csr\root-cert.pem\root-key.pem

#可以將這幾個文件備份下

make root-ca

#由於准備將虛擬機上的所有服務添加到vm命名空間下,所以為vm創建證書

#會發現之前在當前目錄生成的4個根證書文件消失,多了一個vm目錄,在vm目錄中存在如下文件:root-cert.pem、selfSigned-ca-cert-chain.pem、selfSigned-ca-cert.pem、selfSigned-ca-key.pem

# 執行 make 命令可以看到 相關生成證書的方式

make vm-cacerts-selfSigned    (其中的vm 可以換成對應的命名空間名稱)

 生成的根證書

 b)  生成 vm 命名空間 、istio-system命名空間,並導入證書

將 vm 目錄下剛剛生成的4個文件,更改成如下名字:

kubectl create ns vm

kubectl create ns istio-system

# 在 istio-system中生成 secret,該 secret 名稱必須是 cacerts,否則 istio無法正常加載該證書

kubectl create secret generic cacerts -n istio-system \

--from-file=vm/root-cert.pem \

--from-file=vm/cert-chain.pem \

--from-file=vm/ca-cert.pem \

--from-file=vm/ca-key.pem

# 查看 secret 是否創建成功

kubectl get secret -n istio-system

 c) 安裝 istio

istioctl manifest generate --set profile=demo --set components.cni.enabled=true --set values.global.meshExpansion.enabled=true --set addonComponents.istiocoredns.enabled=true

d) 安裝 第三方監控軟件及配置可瀏覽器訪問 kiali

kubectl apply -f /home/opt/istio-1.7.3/samples/addon

# 查看 istio-system 命名空間中已安裝的 istio 相關服務,找到 istio-ingressgateway 80/15012 映射到宿主機上的端口

kubectl get svc -n istio-system

# kiali-virtualservice.yaml 文件中配置了 網關(和 istio 的 istio-ingressgateway服務掛鈎) 和 虛擬服務,網關將 80 的流量經過路由轉發給kiali服務

kubectl apply -f kubectl apply -f /home/opt/istio-1.7.3/samples/addons/kiali-virtualservice.yaml skubectl apply -f /

 其中 kiali-virtualservice.yaml 內容如下

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: kiali
  namespace: istio-system
spec:
  gateways:
  - kiali-gateway
  hosts:
  - "*"
  http:
  - match:
    - uri:
        prefix: /
    route:
    - destination:
        host: kiali
        port:
          number: 20001
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: kiali-gateway
  namespace: istio-system
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

 根據以上配置,31654 端口上接收的請求會轉給 istio-ingressgateway 的 80 ,然后該請求根據 路由會轉給 kiali;

30492 端口上接收的請求會轉給 istio-ingressgateway的 15012,該端口上的請求會被轉給 istiod 的 15012 端口。

在瀏覽器上輸入 http://x.x.x.x:31654 可以看到 kiali 的界面,選擇 istio Config ,在右側可以看到 30492 對應的 gateway 及 virtualservice(這兩個顯然是 istio 內置的)

  e) 生成 vm 虛擬機加入到 istio Mesh需要的配置

# 設置 vm 命名空間自動注入sidecar

kubectl label n vm istio-injection=enabled

# 將 vm 命名空間 設置成需要 mtls 雙向認證

kubectl apply -n vm -f - <<EOF
apiVersion: "security.istio.io/v1beta1"
kind: "PeerAuthentication"
metadata:
  name: "default"
spec:
  mtls:
    mode: STRICT
EOF

# 查看 vm 命名空間的 secret,此時只有默認的 secret

kubectl get sercet -n vm

# 將 默認的 secret 中的 token 取出並放到 當前目錄的 istio-token文件中

kubectl -n vm get secret default-token-bdhs7 \
    -o jsonpath='{.data.token}' |base64 --decode > istio-token

# 生成 cluster.env 文件內容

ISTIO_SERVICE_CIDR=$(echo '{"apiVersion":"v1","kind":"Service","metadata":{"name":"tst"},"spec":{"clusterIP":"1.1.1.1","ports":[{"port":443}]}}' | kubectl apply -f - 2>&1 | sed 's/.*valid IPs is //')

touch cluster.env

echo ISTIO_SERVICE_CIDR=$ISTIO_SERVICE_CIDR > cluster.env

# 設置 vm 中的 sidecar 需要將指定端口流出的請求發送給 istio

echo "ISTIO_INBOUND_PORTS=3306,8080" >> cluster.env

# 在當前目錄中生成 hosts-addendum文件,該文件中存放 istio 安裝所屬服務器 IP 與 istiod 服務域名的映射

echo "x.x.x.x istiod.istio-system.svc" > hosts-addendum

 (2) 在 VM 虛擬機上操作

  a) 在 VM 虛擬機上 安裝 istio-sidecar

   下載 地址:https://storage.googleapis.com/istio-release/releases/1.7.3/rpm/istio-sidecar.rpm

  使用 rpm 命令進行安裝

  b) 將 之前准備的文件放到 vm 對應目錄

  將 istio 所屬服務器准備的 hosts-addendum、clsuter.env、root-cert.pem、ca-cert.pem、ca-key.pem、cert-chain.pem 、istio-token 拷貝到 vm 服務器上的 /home/certs 目錄下

cd /home/certs

mkdir -p /var/run/secrets/istio

# 拷貝證書到指定目錄

cp root-cert.pem ca-cert.pem ca-key.pem cert-chain.pem /var/run/secrets/istio

mkdir -p /var/run/secrets/tokens

# 拷貝token 到指定位置

cp istio-token /var/run/secrets/tokens/istio-token

# 拷貝集群相關信息到指定位置

cp cluster.env /var/lib/istio/envoy/cluster.env

# 編輯 sidecar.env

vi /var/lib/istio/envoy/sidecar.env

# 將istiod.istio-system.svc 域名與IP的映射關系寫入到 hosts文件中

 

cat hosts-addendum >>/etc/hosts

# 授權

chown -R istio-proxy /var/run/secrets /var/lib/istio/envoy

sidecar.env 編輯之后的內容如下,紅色部分表示修改的:

# Environment variables used to configure istio startup

# Comma separated list of CIDRs used for services. If set, iptables will be run to allow istio
# sidecar to intercept outbound calls to configured addresses. If not set, outbound istio sidecar
# will not be used via iptables.
# ISTIO_SERVICE_CIDR=

# Name of the service exposed by the machine.
ISTIO_SERVICE=vm

# The mode used to redirect inbound connections to Envoy. This setting
# has no effect on outbound traffic: iptables REDIRECT is always used for
# outbound connections.
# If "REDIRECT", use iptables REDIRECT to NAT and redirect to Envoy.
# The "REDIRECT" mode loses source addresses during redirection.
# If "TPROXY", use iptables TPROXY to redirect to Envoy.
# The "TPROXY" mode preserves both the source and destination IP
# addresses and ports, so that they can be used for advanced filtering
# and manipulation.
# The "TPROXY" mode also configures the sidecar to run with the
# CAP_NET_ADMIN capability, which is required to use TPROXY.
# If not set, defaults to "REDIRECT".
# ISTIO_INBOUND_INTERCEPTION_MODE=REDIRECT

# When the interception mode is "TPROXY", the iptables skb mark that is set on
# every inbound packet to be redirected to Envoy.
# If not set, defaults to "1337".
# ISTIO_INBOUND_TPROXY_MARK=1337

# When the interception mode is "TPROXY", the number of the routing table that
# is configured and used to route inbound connections to the loopback interface
# in order to be redirected to Envoy.
# If not set, defaults to "133".
# ISTIO_INBOUND_TPROXY_ROUTE_TABLE=133

# Comma separated list of local ports that will use Istio sidecar for inbound services.
# If set, iptables rules will be configured to intercept inbound traffic and redirect to sidecar.
# If not set, no rules will be enabled
# ISTIO_INBOUND_PORTS=

# List of ports to exclude from inbound interception, if ISTIO_INBOUND_PORTS is set to *
# Port 22 is automatically excluded
# ISTIO_INBOUND_EXCLUDE_PORTS=

# Namespace of the cluster.
ISTIO_NAMESPACE=vm

# Specify the IP address used in endpoints. If not set, 'hostname --ip-address' will be used.
# Needed if the host has multiple IP.
# ISTIO_SVC_IP=

# If istio-pilot is configured with mTLS authentication (--controlPlaneAuthPolicy MUTUAL_TLS ) you must
# also configure the mesh expansion machines:
ISTIO_PILOT_PORT=30492    // 值為 istio-ingressgateway 15012 端口映射到宿主機上的端口 ISTIO_CP_AUTH=MUTUAL_TLS

# Fine tunning - useful if installing/building binaries instead of using the .deb file, or running
# multiple instances.

# Port used by Envoy. Defaults to 15001, used in the autogenerated config
# ENVOY_PORT=15001

# User running Envoy. For testing you can use a regular user ID - however running iptables requires
# root or netadmin capability. The debian file creates user istio.
# ENVOY_USER=istio-proxy

# Uncomment to enable debugging
 ISTIO_AGENT_FLAGS="--proxyLogLevel debug --log_output_level default:debug --proxyComponentLogLevel misc:debug"

# Directory for stdout redirection. The redirection is required because envoy attempts to open
# /dev/stdout - must be a real file. Will be used for access logs. Additional config for logsaver
# needs to be made, envoy reopens the file on SIGUSR1
# ISTIO_LOG_DIR=/var/log/istio

# Installation directory for istio binaries, customize in case you're using a binary.
# This is likely to change - current path matches the docker layout in 0.1
# ISTIO_BIN_BASE=/usr/local/bin

# Location of istio configs.
# ISTIO_CFG=/var/lib/istio

# Ignore Istio iptables custom rules
# Enable this flag if you would like to manage iptables yourself. Default to false (true/false)
# ISTIO_CUSTOM_IP_TABLES=false

# Location of provisioning certificates. VM provisioning tools must generate a certificate with
# the expected SAN. Istio-agent will use it to connect to istiod and get fresh certificates.
PROV_CERT=/var/run/secrets/istio

# Location to save the certificates from the CA. Setting this to the same location with PROV_CERT
# allows rotation of the secrets. Users may also use longer-lived PROV_CERT, rotated under the control
# of the provisioning tool.
# Istiod may return a certificate with additional information and shorter lived, to be used for
# workload communication. In order to use the certificate with applications not supporting SDS, set this
# environment variable. If the value is different from PROV_CERTS the workload certs will be saved, but
# the provisioning cert will remain under control of the VM provisioning tools.
OUTPUT_CERTS=/var/run/secrets/istio
# OUTPUT_CERTS=/etc/certs

# Address of the CA. The CA must implement the Istio protocol, accepting the provisioning certificate
# and returning workload certificates. Istiod is implementing the protocol, and is the default value
# if CA_ADDR is not set.
# CA_ADDR
# set CA_ADDR if your istiod.istio-system.svc is on port other than 15012 CA_ADDR=istiod.istio-system.svc:30492

 c) 啟動 istio

systemctl start istio

 打開日志,若日志內容為下面,則表示成功

2020-10-24T07:37:37.697566Z    info    sds    SDS gRPC server for workload UDS starts, listening on "./etc/istio/proxy/SDS" 

2020-10-24T07:37:37.697603Z    info    Starting proxy agent
2020-10-24T07:37:37.697810Z    warn    citadelclient    cannot load key pair, using token instead : open /var/run/secrets/istio/key.pem: no such file or directory
2020-10-24T07:37:37.698209Z    info    sds    Start SDS grpc server
2020-10-24T07:37:37.698304Z    info    Received new config, creating new Envoy epoch 0
2020-10-24T07:37:37.698311Z    info    Epoch 0 starting
2020-10-24T07:37:37.699122Z    info    Opening status port 15020

2020-10-24T07:37:37.708289Z    warn    failed to read pod labels: open ./etc/istio/pod/labels: no such file or directory
2020-10-24T07:37:37.709351Z    info    Envoy command: [-c etc/istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster istio-proxy --service-node sidecar~192.168.149.131~192.vm~vm.svc.cluster.local --local-address-ip-version v4 --log-format-prefix-with-location 0 --log-format %Y-%m-%dT%T.%fZ    %l    envoy %n    %v -l debug --component-log-level misc:debug]
2020-10-24T07:37:37.804099Z    info    sds    resource:default new connection
2020-10-24T07:37:37.804157Z    info    sds    Skipping waiting for gateway secret
2020-10-24T07:37:38.397953Z    error    cache    cannot load key pair from /var/run/secrets/istio: open /var/run/secrets/istio/key.pem: no such file or directory
2020-10-24T07:37:38.421423Z    info    cache    Root cert has changed, start rotating root cert for SDS clients
2020-10-24T07:37:38.421468Z    info    cache    GenerateSecret default
2020-10-24T07:37:38.422145Z    info    sds    resource:default pushed key/cert pair to proxy
2020-10-24T07:37:39.507809Z    info    sds    resource:ROOTCA new connection
2020-10-24T07:37:39.507965Z    info    sds    Skipping waiting for gateway secret
2020-10-24T07:37:39.508055Z    info    cache    Loaded root cert from certificate ROOTCA
2020-10-24T07:37:39.508347Z    info    sds    resource:ROOTCA pushed root cert to proxy

(3) 虛擬 vm 上安裝的服務添加到 istio mesh 中

 a) vm 上通過 python 啟動一個占用 8080 的 進程

 b) 進程模擬的 服務放到 kubernetes 的 vm 命名空間中

# 將 python 對應的進程程序模擬成一個服務添加vm中

cat <<EOF | kubectl -n vm apply -f -
apiVersion: v1
kind: Service
metadata:
  name: python-vm
  labels:
    app: python-vm
spec:
  ports:
  - port: 8080    # 端口號
    name: python-vm
    targetPort: 8080
  selector:
    app: python-vm
EOF

# 將 python 對應的進程程序模擬成一個負載實例添加到vm中

cat <<EOF | kubectl -n vm apply -f -
apiVersion: networking.istio.io/v1beta1
kind: WorkloadEntry
metadata:
  name: "python-vm"
  namespace: "vm"
spec:
  address: "192.168.149.131"  # 實際的external-ip 地址,即程序運行的實際IP地址
  labels:
    app: python-vm
  serviceAccount: "default"    # 這里需要填寫 之前添加vm 到 istio mesh時, 獲取的 token 對應的 serviceaccount 賬號
EOF

 c) 在 kubernetes 的 sleep 容器中訪問 python 模擬的服務進程

#部署 sleep 到 vm 命名空間中

kubectl apply -f /home/opt/istio-1.7.3/samples/sleep/sleep.yaml -n vm

# 其中 python-vm.vm.svc.cluster.local 是之前將 python 進程模擬服務添加到 kubernetes 中,服務對應的域名,默認域名格式為:服務名+命名空間名+svc.cluster.local

kubectl exec -it sleep-854565cb79-8wx9n -c sleep -n vm -- curl python-vm.vm.svc.cluster.local:8080

 進入 sleep 容器進行訪問 vm 上的服務,效果如下圖:

打開 vm 服務器上 istio-sidecar 對應的日志(var/log/istio/istio.log),可以看到如下內容,表示 進入 vm 8080 端口的流量 被 iptables 轉發給 sidecar,其進行了處理

d) 在 vm 上訪問 istio-mesh 中的 httpbin 服務(目前還沒有調通,待補充)

 

五、遇到的問題

(1) 設置 vm 命名空間中 vm serviceaccount 中關聯secrect 的 token 失敗

 解決辦法:

    直接使用如下命令,獲取 已有 secret 中的 token

kubectl -n vm get secret default-token-bdhs7 \
    -o jsonpath='{.data.token}' |base64 --decode > istio-token

 (2) 在虛擬機中安裝 istio-sidecar.deb 包

該包在centos上不支持安裝,基於此,需要在 https://gcsweb.istio.io/gcs/istio-release/releases 地址上下載對應的 rpm 包進行安裝

該網頁上列舉出了所有成果物

(3) systemctl start istio 啟動失敗

  日志路徑在 /var/log/istio,打開日志查看錯誤

  a) Invalid path: /etc/certs/root-cert.pem

2020-10-22T16:12:48.688987Z    critical    envoy main    error initializing configuration 'etc/istio/proxy/envoy-rev0.json': Invalid path: /etc/certs/root-cert.pem
Invalid path: /etc/certs/root-cert.pem

 將證書拷貝到 /etc/certs/root-cert.pem

b) 日志顯示訪問 istio 不通

2020-10-22T17:17:54.418797Z    warning    envoy config    StreamSecrets gRPC config stream closed: 14, connection error: desc = "transport: Error while dialing dial tcp: lookup istiod.istio-system.svc on 192.168.149.2:53: no such host"
  • 將 x.x.x.x  istiod.istio-system.svc 寫到 /etc/hosts 中
  • 將 istiod 端口對外開放,將 istio-ingressgateway 中的 15012 對應的宿主機端口 填寫到 sidecar.env中
  • 修改 vm 上 /var/lib/istio/envoy/sidecar.env 文件
CA_ADDR=istiod.istio-system.svc:30431
OUTPUT_CERTS=/var/run/secrets/istio
PROV_CERT=/var/run/secrets/istio
ISTIO_PILOT_PORT=30492
ISTIO_CP_AUTH=MUTUAL_TL

同時,k8s 上的 vm 要設置開啟 mtls 雙向認證。

 (3) 在 vm 上通過 python 啟動一個進程啟動不了

解決辦法:

   換成 python3 -m http.server 8080   (python3 與 python2 的該命令不一樣)

(4) 在 sleep 容器中訪問 vm 中的服務訪問不了

 

 產生原因:

    sleep 容器中未自動注入 sidecar (若注入,ready 值應該是 2/2);

解決辦法:

    卸載 sleep,將 vm 命名空間 加入 istio-injection=enabled 標簽,再安裝 sleep 到 vm 命名空間,最后再次進入 sleep 容器調用 vm 上的服務

 

 

 

 

 

 

 參開資料:

https://copr.fedorainfracloud.org/coprs/g/maistra/istio/

https://www.cnblogs.com/charlieroro/p/13299942.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM