暴露kiali服务



前提工作:

方式一:安装 openelb,编辑 istio-ingressgateway 的 svc 资源,添加如下内容来获取 EXTERNAL-IP。

apiVersion: v1
kind: Service
metadata:
  annotations:
    eip.openelb.kubesphere.io/v1alpha2: eip-pool
    lb.kubesphere.io/v1alpha1: openelb
    protocol.openelb.kubesphere.io/v1alpha1: layer2

方式二:给 istio 的 ingressgateway 配置 EXTERNAL-IP:

        默认情况下在本地搭建的k8s服务没有外网IP,istio安装后 istio-ingressgateway 也是获取不到EXTERNAL-IP 的,现在手动配置一个IP作为外网IP。

~]# cp ifcfg-eth0 ifcfg-eth0:1

临时修改:

~]# ip addr add 192.168.0.88/24 dev eth0 label eth0:1

永久修改:修改IP和设备名DEVICE,修改后重启主机,仅重启网卡有点问题。

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
NAME=eth0
DEVICE=eth0:1 # 修改网卡别名
ONBOOT=yes
IPADDR=192.168.0.88 # 修改IP地址
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=114.114.114.114

修改配置:

~]# kubectl edit svc -n istio-system istio-ingressgateway
spec:
  externalIPs:
  - 192.168.199.88
  ports:
  # 如果 virtualService 资源里面使用的是端口模式 spec.http.match.port,则需要加上下面 http-kiali 这段配置,访问时需要加端口
  # 如果 virtualService 里使用的是 spec.http.match.uri.prefix 时,则不需要如下这段配置,访问时不需要加端口
  - name: http-kiali
    nodePort: 32159
    port: 20001
    protocol: TCP
    targetPort: 20001

效果如下:有EXTERNAL-IP即可

~]# kubectl get svc -n istio-system | grep istio-ingressgateway
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)
istio-ingressgateway   LoadBalancer   10.103.23.83     192.168.0.88  ........


注意下面几个命令的使用:

istioctl proxy-status
istioctl proxy-config listeners # 查看端口
istioctl proxy-config routes # 查看路由信息
istioctl proxy-config clusters # 查看集群信息
istioctl proxy-config endpoints # 端点信息


暴露服务:

gateway文件:这里演示的kiali暴露方式是指定的端口,如果用80端口看下面暴露grafana服务的流程。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata: 
  name: kiali-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway # 后端服务的标签
  servers:
  - port:
#      number: 20001 # 指定端口方式,访问域名加端口:kiali.ops.net:20001
      number: 80 # 使用默认80端口方式,直接访问域名:kiali.ops.net
      name: http-kiali # 这样的格式代表七层http代理,否者是四层代理
      protocol: HTTP # 跟上面的意义一样
    hosts:
    - "kiali.ops.net"

查看配置是否下发:

在istio-ingressgateway这个条目中没有出现 非SYNCED 的状态,说明已经下发成功。

~]# istioctl proxy-status
NAME                                                   CDS        LDS        EDS        RDS          ISTIOD                      VERSION
istio-egressgateway-c9cbbd99f-7c6px.istio-system       SYNCED     SYNCED     SYNCED     NOT SENT     istiod-765596f7ff-vk6b5     1.12.2
istio-ingressgateway-7c8bc47b49-2xcpt.istio-system     SYNCED     SYNCED     SYNCED     SYNCED       istiod-765596f7ff-vk6b5     1.12.2

查看监听的端口:

~]# istioctl proxy-config listeners istio-ingressgateway-7c8bc47b49-2xcpt -n istio-system
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 20001 ALL   Route: http.20001
0.0.0.0 15021 ALL   Inline Route: /healthz/ready*
0.0.0.0 15090 ALL   Inline Route: /stats/prometheus*

查看路由信息:

~]# istioctl proxy-config routes istio-ingressgateway-7c8bc47b49-2xcpt.istio-system
NAME          DOMAINS     MATCH                  VIRTUAL SERVICE
http.20001    *           /*                     404 # 可以看到404,说明路由还未完成
              *           /stats/prometheus*     
              *           /healthz/ready*

部署virtualService:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: kiali-virtualservice
  namespace: istio-system
spec:
  hosts:
  - "kiali.ops.net"
  gateways:
  - kiali-gateway # 如果和gateway资源不在同一个名称空间则使用<namespace>/<virtualService>格式
  http:
#  - match:
#    - port: 20001 # 这里用的是端口方式,访问域名加端口:kiali.ops.net:20001
  - match:
    - uri: # 此处用的是uri,上面用的是port,直接访问域名:kiali.ops.net
        prefix: /
    route:
    - destination:
        host: kiali # 如果有DestinationRule就路由到ds,没有就路由到svc
        port: 
          number: 20001

查看路由:可以看出404已经变成具体的服务了

]# istioctl proxy-config routes istio-ingressgateway-7c8bc47b49-2xcpt.istio-system
NAME           DOMAINS           MATCH                  VIRTUAL SERVICE
http.20001     kiali.ops.net     /*                     kiali-virtualservice.istio-system
               *                 /stats/prometheus*     
               *                 /healthz/ready*

查看vs:

]# kubectl get vs -n istio-system 
NAME                   GATEWAYS            HOSTS               AGE
kiali-virtualservice   ["kiali-gateway"]   ["kiali.ops.net"]   21m

查看clusters:可以看到outbound已经正常工作了(这里演示的是端口类型)。

]# istioctl proxy-config clusters istio-ingressgateway-7c8bc47b49-2xcpt.istio-system | grep kiali
kiali.istio-system.svc.cluster.local                                   9090      -          outbound      EDS            
kiali.istio-system.svc.cluster.local                                   20001     -          outbound      EDS

如果用端口访问:kiali.ops.net:20001

如果用uri访问:kiali.ops.net


快速配置:

Uri方式:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: kiali-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "kiali.ops.net"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: kiali-virtualservice
  namespace: istio-system
spec:
  hosts:
  - "kiali.ops.net"
  gateways:
  - kiali-gateway
  http:
  - match:
    - uri: # 此处用的是uri,上面用的是port
        prefix: /
    route:
    - destination:
        host: kiali
        port:
          number: 20001

端口方式:

步骤一:

~]# kubectl edit svc -n istio-system istio-ingressgateway
spec:
- name: http-kiali
    nodePort: 32159
    port: 20001
    protocol: TCP
    targetPort: 20001

步骤二:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata: 
  name: kiali-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port:
      number: 20001
      name: http-kiali
      protocol: HTTP
    hosts:
    - "kiali.ops.net"
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: kiali-virtualservice
  namespace: istio-system
spec:
  hosts:
  - "kiali.ops.net"
  gateways:
  - kiali-gateway
  http:
  - match:
    - port: 20001
    route:
    - destination:
        host: kiali
        port: 
          number: 20001


其他方面:

DestionationRule:dr一般不需要配置,除非应用的服务中使用了一些高级路由

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: kiali
  namespace: istio-system
spec:
  host: kiali
  trafficPolicy:
    tls:
      mode: DISABLE

查看规则:

]# kubectl get dr -n istio-system 
NAME    HOST    AGE
kiali   kiali   9s

查看集群规则:后面的 DESTINATION RULE 就多个个dr的规则。

]# istioctl proxy-config clusters istio-ingressgateway-7c8bc47b49-2xcpt.istio-system | grep kiali
kiali.istio-system.svc.cluster.local                                   9090      -          outbound      EDS            kiali.istio-system
kiali.istio-system.svc.cluster.local                                   20001     -          outbound      EDS            kiali.istio-system


查看Pod的listeners、clusters、routes、endpoints:只有跑了sidecar的服务才能看到。

istioctl proxy-config listeners httpbin-575d9fdcf-gbn6z.default
istioctl proxy-config clusters httpbin-575d9fdcf-gbn6z.default
istioctl proxy-config routes httpbin-575d9fdcf-gbn6z.default
istioctl proxy-config endpoints httpbin-575d9fdcf-gbn6z.default

查看端口:

]# istioctl proxy-config listeners httpbin-575d9fdcf-gbn6z.default --port 20001
ADDRESS PORT  MATCH                        DESTINATION
0.0.0.0 20001 Trans: raw_buffer; App: HTTP Route: 20001
0.0.0.0 20001 ALL                          PassthroughCluster

问题:

grafana URL is not set in Kiali configuration

kiali.png

解决:

~]# kubectl edit configmaps -n istio-system kiali

添加如下:

    external_services:
      grafana:
        url: grafana.istio-system.cluster.svc.local:3000

重启kiali服务:

~]# kubectl delete pods -n istio-system kiali-cc67f8648-lzq6v



暴露grafana服务


配置文件对应关系如图:

image.png

gateway文件:

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: grafana-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway
  servers:
  - port: 
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "grafana.ops.net"

查看监听端口:

]# istioctl proxy-config listeners istio-ingressgateway-7c8bc47b49-2xcpt.istio-system
ADDRESS PORT  MATCH DESTINATION
0.0.0.0 8080  ALL   Route: http.8080 # 这里使用的是8080,因为80端口有特殊作用
0.0.0.0 15021 ALL   Inline Route: /healthz/ready*
0.0.0.0 15090 ALL   Inline Route: /stats/prometheus*
0.0.0.0 20001 ALL   Route: http.20001

查看路由:可以看到8080的端口的VIRTUAL SERVICE是404,下面需要配置virtualService。

]# istioctl proxy-config routes istio-ingressgateway-7c8bc47b49-2xcpt.istio-system
NAME           DOMAINS           MATCH                  VIRTUAL SERVICE
http.20001     kiali.ops.net     /*                     kiali-virtualservice.istio-system
http.8080      *                 /*                     404
               *                 /stats/prometheus*     
               *                 /healthz/ready*

部署vs文件:

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: grafana-virtualservice
  namespace: istio-system
spec:
  hosts:
  - "grafana.ops.net"
  gateways:
  - grafana-gateway
  http:
  - match:
    - uri: # 此处用的是uri,上面用的是port
        prefix: /
    route:
    - destination:
        host: grafana
        port:
          number: 3000

查看路由:这时候VIRTUAL SERVICE 已近有vs的配置了

]# istioctl proxy-config routes istio-ingressgateway-7c8bc47b49-2xcpt.istio-system
NAME           DOMAINS             MATCH                  VIRTUAL SERVICE
http.20001     kiali.ops.net       /*                     kiali-virtualservice.istio-system
http.8080      grafana.ops.net     /*                     grafana-virtualservice.istio-system
               *                   /stats/prometheus*     
               *                   /healthz/ready*

查看集群:此时的集群是看不到 DESTINATION RULE 的信息的,因为还没有配置。

]# istioctl proxy-config clusters istio-ingressgateway-7c8bc47b49-2xcpt.istio-system
SERVICE FQDN                                                           PORT      SUBSET     DIRECTION     TYPE           DESTINATION RULE
BlackHoleCluster                                                       -         -          -             STATIC         
agent                                                                  -         -          -             STATIC         
grafana.istio-system.svc.cluster.local                                 3000      -          outbound      EDS

这时就已近可以访问了。


TLS


1. SIMPLE(单向 TLS)

含义:启用 TLS 加密,并采用单向认证(服务器向客户端提供证书,客户端验证服务器身份)。

用途:用于标准的 HTTPS 场景,服务端需配置证书和私钥,客户端无需提供证书。

配置要求:需通过 credentialName 指定包含服务器证书和私钥的 Kubernetes Secret。


2. MUTUAL(双向 TLS)

含义:启用 TLS 加密,并采用双向认证(客户端和服务器互相验证证书)。

用途:适用于高安全要求的场景,如内部服务间通信,客户端和服务端均需验证对方身份。

配置要求:除服务器证书外,还需配置客户端 CA 证书(用于验证客户端证书),通过 credentialName 引用相关 Secret。


3. PASSTHROUGH(透传 TLS 流量)

含义:Istio 不会终止 TLS 连接,而是将加密的流量直接透传给后端服务。

用途:当后端服务自行处理 TLS 终止时使用,Istio 仅负责基于 SNI(Server Name Indication)路由流量。

配置要求:无需证书配置,但需在 hosts 字段中明确指定支持的 SNI 主机名。

示例:暴露argocd服务时,后端的服务是https,这时候只需要把流量透传给后端服务即可,不用在ingressgateway中处理。

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: argocd-dashboard-gateway
  namespace: istio-system
spec:
  selector:
    app: istio-ingressgateway
  servers:
    - hosts:
        - "argocd.ops.net"
      port:
        number: 80
        name: http
        protocol: HTTP
      tls:
        httpsRedirect: true
    - hosts:
        - "argocd.ops.net"
      port:
        number: 443
        name: https
        protocol: HTTPS
      tls:
        mode: PASSTHROUGH
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: argocd-dashboard-virtualservice
  namespace: argocd
spec:
  hosts:
  - "argocd.ops.net"
  gateways:
  - istio-system/argocd-dashboard-gateway
  tls:
  - match:
    - port: 443
      sniHosts:
      - argocd.ops.net
    route:
    - destination:
        host: argocd-server
        port:
          number: 443


4. AUTO_PASSTHROUGH(自动透传)

含义:透传 TLS 流量,但自动根据 SNI 信息路由,无需预先定义所有主机名。

用途:适用于动态路由场景,如处理大量未知主机名的请求,Istio 自动将流量转发到对应后端。

配置要求:无需证书或显式配置主机名,流量完全由后端服务处理。


其他相关模式(非 Gateway 资源)

ISTIO_MUTUAL:

此模式通常出现在 DestinationRule 中,用于服务间通信的双向 TLS。由 Istio 自动管理证书(通过 Citadel 或 Istiod),无需手动配置证书,简化了 mTLS 的启用流程。