Skip to content

Kubernetes 下安装和使用 Istio

中文文档:https://istio.io/latest/zh/docs/

下载 Istio

bash
# 最新版本
curl -L https://istio.io/downloadIstio | sh -

# 指定版本
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.9.3 TARGET_ARCH=x86_64 sh -

# 由于国内网络原因,下载不下来,可以手动从 github 下载 istio-1.9.3-linux-amd64.tar.gz
# https://github.com/istio/istio/releases/tag/1.9.3

cd istio-1.9.3

# 将 istioctl 客户端加入系统环境变量(root 用户)
vi /etc/profile
# 在最下面加入下面两行:
export ISTIO_HOME=/usr/local/istio-1.9.3/bin
export PATH=$ISTIO_HOME:$PATH
# 使环境变量立马生效
source /etc/profile

# 下面切换回普通用户,检查环境变量
echo $PATH

安装 Istio

bash
# 查看 istioctl 安装的 profile 列表,有以下七种配置档可选
istioctl profile list
# 七种配置档如下:
Istio configuration profiles:
    default
    demo
    empty
    minimal
    openshift
    preview
    remote

前四种配置档的安装差异:https://istio.io/latest/zh/docs/setup/additional-setup/config-profiles/

bash
# 默认安装,生成环境推荐使用默认安装(不设置profile的情况下: --set profile=default)
istioctl install -y

# 也可以换成上面四种配置档之一
istioctl install --set profile=demo -y

# 给命名空间添加标签,指示 Istio 在部署应用的时候,自动的注入 Envoy 边车代理:
kubectl label namespace default istio-injection=enabled
# kubectl label namespace default istio-injection-

# 检查安装了什么
kubectl -n istio-system get deploy

# 查看安装时的配置参数
kubectl -n istio-system get IstioOperator installed-state -o yaml

# 内容太多,可以导出到一个 yaml 中
kubectl -n istio-system get IstioOperator installed-state -o yaml > installed-state.yaml

# 浏览一个配置档的配置信息
istioctl profile dump default

# 验证安装是否成功
istioctl verify-install

ingressgateway 的默认网络类型是 LoadBanlancer,在没有外部负载均衡的情况下可以修改为 NodePort。

bash
# 将 LoadBanlancer 修改为 NodePort
kubectl get services -n istio-system
kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'

# 或者 直接编辑,打开后,找到LB,修改为NodePort
kubectl edit svc istio-ingressgateway -n istio-system

修改配置也可以通过执行一个 patch 文件:https://istio.io/latest/zh/docs/setup/install/istioctl/

部署应用并对外开放应用程序 istio.yaml

要开放访问,你需要创建 Istio 入站网关(Ingress Gateway), 它会在网格边缘把一个路径映射到路由。

kubectl apply -f istio.yaml

yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-quickboot-mybatis-plus
  labels:
    app: sample-quickboot-mybatis-plus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-quickboot-mybatis-plus
  template:
    metadata:
      labels:
        app: sample-quickboot-mybatis-plus
    spec:
      containers:
        - name: sample-quickboot-mybatis-plus
          image: registry.cn-hangzhou.aliyuncs.com/mengweijin/sample-quickboot-mybatis-plus:0.0.1-SNAPSHOT
          # IfNotPresent, Always, Never
          imagePullPolicy: IfNotPresent
          args: ["--server.ssl.enabled=false"]
          ports:
            - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: sample-quickboot-mybatis-plus
spec:
  # type: NodePort
  selector:
    app: sample-quickboot-mybatis-plus
  ports:
    # 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
    - port: 8080
      targetPort: 8080
      # 在 Istio Gateway 中必须配置,并且格式为:"<protocol>[-<suffix>]"
      name: http
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: sample-quickboot-mybatis-plus
spec:
  selector:
    # use Istio default gateway implementation
    istio: ingressgateway
  servers:
    - port:
        # 需要指定一个公开的端口,80、443
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sample-quickboot-mybatis-plus
spec:
  # 使用 hosts 字段列举虚拟服务的主机——即用户指定的目标或是路由规则设定的目标。这是客户端向服务发送请求时使用的一个或多个地址。
  hosts:
    - "*"
  gateways:
    - sample-quickboot-mybatis-plus
  http:
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            port:
              number: 8080
            # 这里应该时服务名(Service 的名称)
            host: sample-quickboot-mybatis-plus

执行命令: kubectl get all 会显示 pod READY=2,尽管 pod 在 dashboard 中显示的只有一个。这是由于原来的 pod 具有 READY 为 1/1 的容器,注入 sidecar 后的 pod 则具有 READY 为 2/2 的容器。

部署完成后,需要检查配置文件有没有问题

bash
istioctl analyze

# 如果有问题,参考
[mengweijin@mengweijin ~]$ istioctl analyze
Error [IST0101] (VirtualService sample-quickboot-mybatis-plus.default) Referenced host not found: "mengweijin.com"
Warning [IST0104] (Gateway sample-quickboot-mybatis-plus.default) The gateway refers to a port that is not exposed on the workload (pod selector istio=ingressgateway; port 8080)
Info [IST0118] (Service sample-quickboot-mybatis-plus.default) Port name  (port: 8080, targetPort: 8080) doesn't follow the naming convention of Istio port.
Error: Analyzers found issues when analyzing namespace: default.
See https://istio.io/v1.9/docs/reference/config/analysis for more information about causes and resolutions.

在这个页面就能根据 [IST0101] [IST0104] [IST0118] 找到错误原因:https://istio.io/v1.9/docs/reference/config/analysis

改正后,重启部署有问题的应用组件。

bash
# 再次检查
[mengweijin@mengweijin ~]$ istioctl analyze
# 返回如下,就是没有问题了
 No validation issues found when analyzing namespace: default.

验证外部访问(minikube)

bash
# 查看访问的 ip
minikube ip
# 查看访问的端口
echo $(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
# 也可以通过如下命令查看80端口映射的端口,就是我们要的访问的端口
kubectl -n istio-system get service istio-ingressgateway

# 组合起来就是下面的命令(打印出访问URL的IP和port):
echo $(minikube ip):$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
# 打印出:
192.168.49.2:31811

# 偷懒方式,输出整个命令
echo curl $(minikube ip):$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')/user/get

# VMware 中虚拟机中访问 url
# 部署文件中配置的hosts 为:- "*" 时访问 URL:
curl 192.168.49.2:31811/user/get
# 部署文件中配置的hosts 为:- "mengweijin.com" 时访问 URL(已经配置了域名在 /etc/hosts 文件):
curl mengweijin.com:31811/user/get

# kube-proxy 端口转发(在新的 ssh 窗口下运行),转发端口:8001
kubectl proxy --address=0.0.0.0 --disable-filter=true
# Windows 下访问:
http://192.168.171.134:8001/api/v1/namespaces/istio-system/services/http:istio-ingressgateway:80/proxy/user/get

打开 Istio Dashboard

bash
# 安装,需要联网拉镜像,耐心等待
# 这条命令如果执行报错了,请再次执行一遍就好了。比如出现错误:no matches for kind "MonitoringDashboard" in version "monitoring.kiali.io/v1alpha1"
kubectl apply -f /usr/local/istio-1.9.3/samples/addons

# 等上面镜像拉完运行成功后,再执行下面这条命令执行时间很长
kubectl rollout status deployment/kiali -n istio-system

# kube-proxy 端口转发(在新的 ssh 窗口下运行),转发端口:8001
kubectl proxy --address=0.0.0.0 --disable-filter=true

# 打开 dashboard(在新的 ssh 窗口下运行)
istioctl dashboard kiali
# 控制台输出如下,记住下面的端口和 url 后缀
http://localhost:20001/kiali

# 在 Windows 下的浏览器中访问URL 即可打开 dashboard: 格式为:
http://<CentOS虚拟机的IP>:<端口为上面proxy中显示的端口,默认8001>/api/v1/namespaces/<服务的namespace>/services/http:<服务名称>:<服务端口>/proxy/<原始 url 的后>
# 示例 URL:
http://192.168.171.134:8001/api/v1/namespaces/istio-system/services/http:kiali:20001/proxy/kiali

验证外部访问(官方文档)

确定入站 IP 和端口(minikube)

其他平台参考:https://istio.io/latest/zh/docs/setup/getting-started/

bash
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
export SECURE_INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="https")].nodePort}')

# 确认端口被成功的赋值给了每一个环境变量:
[mengweijin@mengweijin ~]$ echo "$INGRESS_PORT"
32391
[mengweijin@mengweijin ~]$ echo "$SECURE_INGRESS_PORT"
30557

# 设置入站 IP:
export INGRESS_HOST=$(minikube ip)

# 确认 IP 地址被成功的赋值给了环境变量:
[mengweijin@mengweijin ~]$ echo "$INGRESS_HOST"
192.168.49.2


# 在一个新的终端窗口中执行此命令,启动一个 Minikube tunnel,它将把流量发送到你 Istio 入站网关:
minikube tunnel

# 设置环境变量 GATEWAY_URL:
export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

# 确保 IP 地址和端口均成功的赋值给了环境变量:
[mengweijin@mengweijin ~]$ echo "$GATEWAY_URL"
192.168.49.2:32391

访问 API URL

bash
# 运行下面命令,获取应用的外部访问地址(原始地址:http://localhost:8080/user/get)
[mengweijin@mengweijin ~]$ echo "http://$GATEWAY_URL/user/get"
http://192.168.49.2:32391/user/get

# 把上面命令的输出地址复制粘贴到 curl 并访问,发现成功访问到了数据
curl http://192.168.49.2:32391/user/get

卸载

安装和卸载:https://istio.io/latest/zh/docs/setup/install/istioctl/

bash
# 移除命名空间上的标签
kubectl label namespace default istio-injection-

# 要从集群中完整卸载 Istio,运行下面命令:可选的 --purge 参数将删除所有 Istio 资源,包括可能被其他 Istio 控制平面共享的、集群范围的资源。
istioctl x uninstall --purge
kubectl delete namespace istio-system

minikube

minikube enable addons istio

setup on minikube: https://istio.io/latest/zh/docs/setup/platform-setup/minikube/