使用 Istioctl 在 Kubernetes 中安装 Istio

!版权声明:本博客内容均均为原创,每篇博文作为知识积累,写博不易,转载请注明出处


系统环境:

  • kubernetes 版本:1.6.6
  • istio 版本:1.4.3

参考地址:

机器分布:

IP地址 Hostname 备注
192.168.2.11 k8s-node-2-11 Master节点
192.168.2.12 k8s-node-2-12 工作节点
192.168.2.13 k8s-node-2-13 工作节点

一、下载 istio 与 istioctl 安装文件

下载安装文件:

如果因无法正常解析 github 而导致无法执行该命令,很可能是服务访问 Github 导致。所以,请更改 /etc/hosts 文件手动添加 Github DNS 映射关系,解决不能访问 Github 问题。

$ curl -L https://istio.io/downloadIstio | sh -

下载完成后,会看到 istio-1.4.3 文件夹,进入该文件夹可以看到如下内容:

.
├── bin             #istioctl 的二进制文件
├── install         #istio 的安装文件
├── LICENSE         #istio 许可声明文件
├── manifest.yaml   #istio 列表清单
├── README.md       #istio 介绍信息的 MD 文档
├── samples         #istio 学习的示例文件
└── tools           #istio 工具文件

二、安装配置 istioctl 工具

istioctl 是用于部署 istio 的命令行工具,可以灵活配置 istio 的安装参数然后进行安装 istio,下面介绍下如何安装配置 istioctl 工具。

1、配置 istioctl

将 istioctl 拷贝到 /usr/local/bin/ 中:

$ cp bin/istioctl /usr/local/bin/

2、开启 istioctl 自动补全

开启 istioctl 的自动补全功能:

## 将 tools 目录中的 istioctl.bash 拷贝到 $HOME 目录中:
$ cp tools/istioctl.bash ~/

##在 ~/.bashrc 中添加一行:
source ~/istioctl.bash

##使配置生效
$ source ~/.bashrc

三、查看与比较 istio 的多种安装配置方案

1、查看可用安装配置

istioctl 提供多种安装配置,使用不同的配置将安装不同的 istio 组件,来开启不同的功能,可以输入 istioctl profile list 命令查询可用的配置,例如:

$ istioctl profile list

Istio configuration profiles:
    minimal
    remote
    sds
    default
    demo
  • minimal: 使用Istio的流量管理功能所需的最少组件集。
  • remote: 用于配置共享控制平面的多集群服务网格 multicluster mesh。
  • sds: 类似于默认配置文件,但也启用 Istio 的 SDS(秘密发现服务)。此配置文件附带默认情况下启用的其他身份验证功能(严格双向TLS)。
  • demo: 旨在展示 Istio 功能且资源需求适中的配置。适合运行Bookinfo应用程序和相关任务。这是随快速入门说明一起安装的配置,但是,如果您想探索更高级的任务,则可以稍后自定义配置以启用其他功能。 此配置文件可实现高级别的跟踪和访问日志记录,因此不适合进行性能测试。
  • default: 根据 IstioControlPlaneAPI 的默认设置启用组件(建议用于生产部署)。您可以通过运行命令显示默认设置 istioctl profile dump。

2、配置间的区别

上面已经知道 istio 有很多套安装配置,它们不同配置间会影响在安装 istio 时,按照不同配置来安装不同组件,主要区别是:

  • 核心组件:
default demo minimal sds remote
istio-citadel
istio-egressgateway
istio-galley
istio-ingressgateway
istio-nodeagent
istio-pilot
istio-policy
istio-sidecar-injector
istio-telemetry
  • 附加组件:
default demo minimal sds remote
Grafana
istio-tracing
kiali
prometheus

3、查看不同配置的配置参数

可以输入 istioctl profile dump 命令查看不同配置中的配置参数的设置,例如查看 demo 配置的参数,可以输入下面命令:

$ istioctl profile dump demo

autoInjection:
  components:
    injector:
      enabled: true
      k8s:
        replicaCount: 1
        strategy:
          rollingUpdate:
            maxSurge: 100%
            maxUnavailable: 25%
  enabled: true
cni:
  enabled: false
configManagement:
  components:
    galley:
      enabled: true
      k8s:
        replicaCount: 1
......()

四、安装前注意问题

在安装前需要了解一些问题,便于知道安装过程中的一些知识点。

1、isito-ingressgateway Service 类型

istio 的 values.gateways.istio-ingressgateway.type 参数是设置 istio gateway 组件的 service 中类型,它的默认值是 LoadBalancer,由于很多平台不支持 LoadBalancer,所以这里将 values.gateways.istio-ingressgateway.type 设置为 ClusterIP。

2、CNI 插件

默认情况下,Istio 会在网格中部署的 pods 中注入一个 initContainer,即 Istio-init。Istio-init 容器是用于设置从 Istio sidecar 代理的 pod 网络流量重定向。这要求网格中的 pod 拥有有足够的 Kubernetes RBAC 权限来部署 NET_ADMIN 容器。 如果 pod 拥有一定的 RBAC 权限会导致一些潜在的安全问题。

Istio CNI 插件是 Istio-init 容器的替代品,它执行相同的网络功能,但是不需要 pod 拥有一定 Kubernetes RBAC 权限。Istio CNI 插件在 Kubernetes Pod 生命周期的网络设置阶段执行 Istio Mesh Pod 流量重定向,从而消除了将 Pod 部署到 Istio Mesh 中的用户的 NET_ADMIN 功能要求。

Istio CNI 插件取代了 istio-init 容器提供的功能,所以,我们安装时候选择应用 CNI 插件。

五、安装部署 istio

接下来将安装 istio,为了后续实践不同的 istio 功能,所以这里使用功能最全的 demo 配置进行安装。

1、创建 istio 自定义配置文件

创建 istio 自定义配置文件,这里面方便定制化配置 Istio 的安装选项,这里现在主要是为了开启 CNI 插件,如下配置:

istio-control-plane.yaml

apiVersion: install.istio.io/v1alpha2
kind: IstioControlPlane
spec:
  cni:                      #开启 CNI 插件,并且配置它所在的 Namespace
    enabled: true
    components:
      namespace: kube-system
  values:
    cni:
      excludeNamespaces:    #设置 CNI 插件忽略下面的 Namespace
       - istio-system
       - kube-system
  unvalidatedValues:
    cni:
      logLevel: info

2、安装 istio

使用 itsioctl 按照下面配置参数执行 istio 的安装部署:

$ istioctl manifest apply \
   --set profile=demo \
   --set values.gateways.istio-ingressgateway.type=ClusterIP \
   -f istio-control-plane.yaml 
  • profile=demo: 使用 demo 配置。
  • values.gateways.istio-ingressgateway.type=ClusterIP: 将 gateway 组件的 service 访问类型改为 ClusterIP。

3、查看安装的 istio 组件

查看 kubernetes 中部署的 istio 组件:

$ kubectl get pods -n istio-system

NAME                                      READY   STATUS    RESTARTS   AGE
grafana-6b65874977-n95sc                  1/1     Running   0          60s
istio-citadel-f78ff689-8h4lf              1/1     Running   0          60s
istio-egressgateway-7b6b69ddcd-xfzrq      1/1     Running   0          60s
istio-galley-69674cb559-dnl62             1/1     Running   0          60s
istio-ingressgateway-649f9646d4-d25kv     1/1     Running   0          114s
istio-pilot-7989874664-ldb47              1/1     Running   0          60s
istio-policy-5cdbc47674-wvkqg             1/1     Running   1          60s
istio-sidecar-injector-7dd87d7989-h77fz   1/1     Running   0          60s
istio-telemetry-6dccd56cf4-hpqdz          1/1     Running   1          60s
istio-tracing-c66d67cd9-scz24             1/1     Running   0          107s
kiali-8559969566-dn5h2                    1/1     Running   0          60s
prometheus-66c5887c86-dwcsr               1/1     Running   0          60s

查看 cni 插件配置:

$ cat /etc/cni/net.d/10-calico.conflist

{
    .....
    {
      "type": "istio-cni",          #istio cni 插件
      "log_level": "info",
      "kubernetes": {
        "kubeconfig": "/etc/cni/net.d/ZZZ-istio-cni-kubeconfig",
        "cni_bin_dir": "/opt/cni/bin",
        "exclude_namespaces": [
          "istio-system",
          "kube-system"
        ]
      }
    }
  ]
}

4、修改 istio-ingressgateway 组件

istio-ingressgateway 是 istio 中对外的入口,由于部署的机器非公网云环境,不支持 LoadBlances 模式,所以需要对网关进行一些修改。

(1)、为 istio-ingressgateway 添加 Node 亲和性

下面使用 kubectlpatch 命令来修改 istio-ingressgateway 配置,添加 Node 亲和性,让其只能部署在特定的节点上。

本人这里设置 istio-ingressgateway 组件启动在 192.168.2.12 节点上,该节点的 hostnamek8s-node-2-12,所以需要按下面配置:

{
  "spec": {
    "template": {
      "spec": {
        "affinity": {
          "nodeAffinity": {
            "requiredDuringSchedulingIgnoredDuringExecution": {
              "nodeSelectorTerms": [
                {
                  "matchExpressions": [
                    {
                      "key": "kubernetes.io/hostname",
                      "operator": "In",
                      "values": [
                        "k8s-node-2-12" 
                      ]
                    }
                  ]
                }
              ]
            }
          }
        }
      }
    }
  }
}

执行 kubectl patch 命令进行修改:

$ kubectl patch deployment istio-ingressgateway -p '{"spec":{"template":{"spec":{"affinity":{"nodeAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":{"nodeSelectorTerms":[{"matchExpressions":[{"key":"kubernetes.io/hostname","operator":"In","values":["k8s-node-2-12"]}]}]}}}}}}}' -n istio-system

(2)、修改 istio-ingressgateway 对外端口

修改 istio-ingressgateway 端口配置,添加 hostPort 端口,这样会将容器所在节点服务器的 hostPort 设置的值的端口绑定,每次访问该节点 IP + hostPort 端口就能将对应的流量代理进入 gateway 中,方便后续 istio 对访问流量执行对应访问策略。

  • 修改 istio-ingressgateway 中的 containerPort":80 端口添加 hostPort: 80 端口。
  • 修改 istio-ingressgateway 中的 containerPort":443 端口添加 hostPort: 443 端口。
  • 修改 istio-ingressgateway 中的 dnsPolicy 策略为 ClusterFirstWithHostNet

    $ kubectl patch deployment istio-ingressgateway -p '{"spec":{"template":{"spec":{"containers":[{"name":"istio-proxy","ports":[{"containerPort":80,"hostPort":80},{"containerPort":443,"hostPort":443}]}],"dnsPolicy":"ClusterFirstWithHostNet"}}}}' -n istio-system

六、运行应用进行测试

1、部署测试应用

下面将部署测试用例,需要注意的是部署的测试用例,需要按照 istio 部署规定,应用的 Service 端口 name 参数必须指定网络协议,例如 http、http2、grpc 等等。

helloworld.yaml

apiVersion: v1
kind: Service
metadata:
  name: helloworld
  labels:
    app: helloworld
spec:
  type: ClusterIP
  ports:
  - port: 5000
    name: http          #告知istio使用http协议
  selector:
    app: helloworld
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: helloworld-v1
  labels:
    version: v1
spec:
  replicas: 1
  selector:         
    matchLabels:        
      app: helloworld   
      version: v1       
  template:
    metadata:
      labels:           #根据规则,需要设置两个标签 app 与
        app: helloworld #- app 标签设置为应用名称 version
        version: v1     #- version标签设置为应用版本号
    spec:
      containers:
      - name: helloworld
        image: docker.io/istio/examples-helloworld-v1
        ports:
        - containerPort: 5000

在 kubernetes 中部署应用:

$ kubectl apply -f helloworld.yaml

2、部署测试应用的 itio gateway 路由规则

接下来讲配置上面示例项目的 istio 网关路由规则,方面我们进行测试。

helloworld-gateway.yaml

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: helloworld-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"       #指定为*则匹配全部域名
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: helloworld
spec:
  hosts:
  - "*"
  gateways:
  - helloworld-gateway
  http:
  - match:
    - uri:
        exact: /hello
    route:
    - destination:
        host: helloworld
        port:
          number: 5000

在 kubernetes 中部署 istio gateway 路由规则:

$ kubectl apply -f helloworld-gateway.yaml

3、输入

上面配置的网关 istio-ingressgateway 组件在 192.168.2.11 服务器上,且上面配置的 gateway 路由规则是 * 所以这里输入 网关 IP 地址与 api 路径: http://192.168.2.12/hello 进行测试示例服务是否正常运行,显示如下:

img

七、卸载 istio

如果想卸载 istio,则可以使用下面命令:

$ istioctl manifest generate --set profile=demo | kubectl delete -f -

—END—

这些信息有用吗?
Do you have any suggestions for improvement?

Thanks for your feedback!