hugo-teek is loading...

1、Istio安装配置

最后更新于:

Istio安装配置

本节实战

实战名称
🚩 实战:istioctl 方式安装istio-2023.11.3(测试成功)
🚩 实战:手动注入 Envoy Sidecar-2023.11.3(测试成功)
🚩 实战:自动注入 Envoy Sidecar-2023.11.8(测试成功)
🚩 实战:BookInfo 示例应用-2023.11.5(测试成功)
🚩 实战:自定义一个端口访问应用-2023.11.6(测试成功)

目录

[toc]

前言

前面在服务网格基础章节我们和大家已经了解了 Istio 的基本概念以及架构,本章节我们将来快速了解 Istio 的基本使用方法,对 Istio 有一个最基本的认识。

img

1、安装

安装 Istio 之前,需要准备一个 Kubernetes 集群,我们可以使用任何支持的平台,例如 Minikube、Kind、Kubeadm 等,但是需要注意的是目前的 Istio 最新版本为 v1.19.3 版本,不同的版本支持的 Kubernetes 版本不同,可以参考下表进行对照:

img

我们这里选择最新的版本为 v1.19.3,Kubernetes 版本为 v1.27.6:

1$ kubectl get nodes
2NAME      STATUS   ROLES           AGE   VERSION
3master1   Ready    control-plane   43d   v1.27.6
4node1     Ready    <none>          43d   v1.27.6
5node2     Ready    <none>          43d   v1.27.6

安装方式

在 Kubernetes 集群上安装 Istio 的方法有很多方式,可以根据自己的需求选择不同的安装方式,我们可以先对比下每种方式的优缺点。

1.使用 istioctl install

具有高安全性、简单的安装和管理方法,这也是社区推荐的安装方法。

  • 优点:

    • 完整的配置和运行状态的验证。

    • 使用提供了扩展的配置、自定义选项的 IstioOperator API。

    • 不需要集群内的高权限 Pod,通过执行 istioctl 命令修改。

  • 缺点:

    • 需要维护多个 Istio 版本的二进制文件。

    • istioctl 命令可能根据你的运行环境设置诸如 JWT_POLICY 之类的值,从而在不同的 Kubernetes 环境中产生不同的安装结果。

整体来说,这里的缺点对我们可能影响不大。

2.使用 istioctl manifest generate 安装

生成 Kubernetes 的配置清单,并通过 kubectl apply --prune 命令应用到集群中。该方法适用于需要严格审查或者增加配置清单的情况。

  • 优点:

    • Chart 是由与 istioctl install 和 Operator 里使用的相同的 IstioOperator API 生成的。

    • 使用提供了扩展的配置、自定义选项的 IstioOperator API。

  • 缺点:

    • 一些在 istioctl install 和 Operator 中会进行的检查将不会执行。

    • istioctl install 相比,UX 不够简洁。

    • 错误反馈没有 istioctl install 的详细、全面。

3.使用 Helm 安装

使用 Helm 的 Chart 可以通过 Helm 的工作流轻松的完成,并在升级的过程中自动清理资源。

  • 优点:

    • 使用熟悉、常用的行业标准工具。

    • Helm 原生的版本、升级管理。

  • 缺点:

    • 相比于 istioctl install 和 Operator 相比,检查较少。

    • 一些管理任务需要更多步骤,具有更高的复杂性。

4.使用 Istio Operator 安装

不建议在新安装时使用 Operator,虽然 Operator 将继续得到支持,但新的功能特性不会被优先考虑。

Istio Operator 提供了一种安装路径,无需使用 istioctl 二进制文件。这可以用于简化升级工作流程,不必担心在集群中运行特权控制器的问题。此方法适用于不需要严格审计或增加输出清单的情况。

  • 优点:

    • istioctl install 相同的 API,但通过集群中的控制器 Pod 进行操作,实现了完全声明式操作。

    • IstioOperator API 提供了广泛的配置/定制选项。

    • 不需要管理多个 istioctl 二进制文件。

  • 缺点:

    • 集群中运行的高权限控制器存在安全风险。

安装 Istio

==🚩 实战:istioctl 方式安装istio-2023.11.3(测试成功)==

实验环境:

1k8s v1.25.4(containerd://1.6.10)
2
3[root@master1 ~]#istioctl version
4client version: 1.19.3
5control plane version: 1.19.3
6data plane version: 1.19.3 (8 proxies)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb 提取码:7yqb 2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功) (使用的是同一个软件包)

image-20231105111842627

上面我们对几种方式做了简单的对比,具体选择哪种方式安装需要结合自己的情况来决定。我们这里就选择社区推荐的 istioctl 方式进行安装。

首先前往 Istio Release 页面下载适合你操作系统的安装文件,或使用下面的命令自动下载并解压最新版本(Linux 或 macOS):

1curl -L https://istio.io/downloadIstio | sh -
  1#!/bin/sh
  2
  3# Copyright Istio Authors
  4#
  5# Licensed under the Apache License, Version 2.0 (the "License");
  6# you may not use this file except in compliance with the License.
  7# You may obtain a copy of the License at
  8#
  9#    http://www.apache.org/licenses/LICENSE-2.0
 10#
 11# Unless required by applicable law or agreed to in writing, software
 12# distributed under the License is distributed on an "AS IS" BASIS,
 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14# See the License for the specific language governing permissions and
 15# limitations under the License.
 16
 17#
 18# This file will be fetched as: curl -L https://git.io/getLatestIstio | sh -
 19# so it should be pure bourne shell, not bash (and not reference other scripts)
 20#
 21# The script fetches the latest Istio release candidate and untars it.
 22# You can pass variables on the command line to download a specific version
 23# or to override the processor architecture. For example, to download
 24# Istio 1.6.8 for the x86_64 architecture and linux OS,
 25# run curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.6.8 TARGET_ARCH=x86_64 TARGET_OS=Linux sh -.
 26
 27set -e
 28
 29# Determines the operating system.
 30OS="${TARGET_OS:-$(uname)}"
 31if [ "${OS}" = "Darwin" ] ; then
 32  OSEXT="osx"
 33else
 34  OSEXT="linux"
 35fi
 36
 37# Determine the latest Istio version by version number ignoring alpha, beta, and rc versions.
 38if [ "${ISTIO_VERSION}" = "" ] ; then
 39  ISTIO_VERSION="$(curl -sL https://github.com/istio/istio/releases | \
 40                  grep -o 'releases/[0-9]*.[0-9]*.[0-9]*/' | sort -V | \
 41                  tail -1 | awk -F'/' '{ print $2}')"
 42  ISTIO_VERSION="${ISTIO_VERSION##*/}"
 43fi
 44
 45LOCAL_ARCH=$(uname -m)
 46if [ "${TARGET_ARCH}" ]; then
 47    LOCAL_ARCH=${TARGET_ARCH}
 48fi
 49
 50case "${LOCAL_ARCH}" in
 51  x86_64|amd64)
 52    ISTIO_ARCH=amd64
 53    ;;
 54  armv8*|aarch64*|arm64)
 55    ISTIO_ARCH=arm64
 56    ;;
 57  armv*)
 58    ISTIO_ARCH=armv7
 59    ;;
 60  *)
 61    echo "This system's architecture, ${LOCAL_ARCH}, isn't supported"
 62    exit 1
 63    ;;
 64esac
 65
 66if [ "${ISTIO_VERSION}" = "" ] ; then
 67  printf "Unable to get latest Istio version. Set ISTIO_VERSION env var and re-run. For example: export ISTIO_VERSION=1.0.4"
 68  exit 1;
 69fi
 70
 71NAME="istio-$ISTIO_VERSION"
 72URL="https://github.com/istio/istio/releases/download/${ISTIO_VERSION}/istio-${ISTIO_VERSION}-${OSEXT}.tar.gz"
 73ARCH_URL="https://github.com/istio/istio/releases/download/${ISTIO_VERSION}/istio-${ISTIO_VERSION}-${OSEXT}-${ISTIO_ARCH}.tar.gz"
 74
 75with_arch() {
 76  printf "\nDownloading %s from %s ...\n" "$NAME" "$ARCH_URL"
 77  if ! curl -o /dev/null -sIf "$ARCH_URL"; then
 78    printf "\n%s is not found, please specify a valid ISTIO_VERSION and TARGET_ARCH\n" "$ARCH_URL"
 79    exit 1
 80  fi
 81  curl -fsLO "$ARCH_URL"
 82  filename="istio-${ISTIO_VERSION}-${OSEXT}-${ISTIO_ARCH}.tar.gz"
 83  tar -xzf "${filename}"
 84  rm "${filename}"
 85}
 86
 87without_arch() {
 88  printf "\nDownloading %s from %s ..." "$NAME" "$URL"
 89  if ! curl -o /dev/null -sIf "$URL"; then
 90    printf "\n%s is not found, please specify a valid ISTIO_VERSION\n" "$URL"
 91    exit 1
 92  fi
 93  curl -fsLO "$URL"
 94  filename="istio-${ISTIO_VERSION}-${OSEXT}.tar.gz"
 95  tar -xzf "${filename}"
 96  rm "${filename}"
 97}
 98
 99# Istio 1.6 and above support arch
100# Istio 1.5 and below do not have arch support
101ARCH_SUPPORTED="1.6"
102# Istio 1.10 and above support arch for osx arm64
103ARCH_SUPPORTED_OSX="1.10"
104
105if [ "${OS}" = "Linux" ] ; then
106  # This checks if ISTIO_VERSION is less than ARCH_SUPPORTED (version-sort's before it)
107  if [ "$(printf '%s\n%s' "${ARCH_SUPPORTED}" "${ISTIO_VERSION}" | sort -V | head -n 1)" = "${ISTIO_VERSION}" ]; then
108    without_arch
109  else
110    with_arch
111  fi
112elif [ "${OS}" = "Darwin" ] ; then
113  # This checks if ISTIO_VERSION is less than ARCH_SUPPORTED_OSX (version-sort's before it) or ISTIO_ARCH not equal to arm64
114  if [ "$(printf '%s\n%s' "${ARCH_SUPPORTED_OSX}" "${ISTIO_VERSION}" | sort -V | head -n 1)" = "${ISTIO_VERSION}" ] || [ "${ISTIO_ARCH}" != "arm64" ]; then
115    without_arch
116  else
117    with_arch
118  fi
119else
120  printf "\n\n"
121  printf "Unable to download Istio %s at this moment!\n" "$ISTIO_VERSION"
122  printf "Please verify the version you are trying to download.\n\n"
123  exit 1
124fi
125
126printf ""
127printf "\nIstio %s Download Complete!\n" "$ISTIO_VERSION"
128printf "\n"
129printf "Istio has been successfully downloaded into the %s folder on your system.\n" "$NAME"
130printf "\n"
131BINDIR="$(cd "$NAME/bin" && pwd)"
132printf "Next Steps:\n"
133printf "See https://istio.io/latest/docs/setup/install/ to add Istio to your Kubernetes cluster.\n"
134printf "\n"
135printf "To configure the istioctl client tool for your workstation,\n"
136printf "add the %s directory to your environment path variable with:\n" "$BINDIR"
137printf "\t export PATH=\"\$PATH:%s\"\n" "$BINDIR"
138printf "\n"
139printf "Begin the Istio pre-installation check by running:\n"
140printf "\t istioctl x precheck \n"
141printf "\n"
142printf "Need more information? Visit https://istio.io/latest/docs/setup/install/ \n"

image-20231103072601834

🍀

但是上面方式默认也是走 github 下载,国内访问 github 速度比较慢(也可能根本下载不了),所有我们可以自己去下载安装文件包,下载完成后解压,将解压后的 istioctl 文件移动到 /usr/local/bin 目录下:

1# wget https://ghps.cc/https://github.com/istio/istio/releases/download/1.19.3/istio-1.19.3-linux-amd64.tar.gz
2$ wget https://github.com/istio/istio/releases/download/1.19.3/istio-1.19.3-linux-amd64.tar.gz
3$ tar -xvf istio-1.19.3-linux-amd64.tar.gz
4$ mv istio-1.19.3/bin/istioctl /usr/local/bin/
5$ istioctl version
6no ready Istio pods in "istio-system"
71.19.3

能执行 istioctl 命令说明安装成功,但是提示 no ready Istio pods in "istio-system",这是因为我们还没有安装 Istio,接下来我们就来安装 Istio。

image-20231103121417840

istioctl 工具中内置了一些安装配置文件,这些配置文件提供了对 Istio 控制平面和 Istio 数据平面 Sidecar 的定制内容。我们可以通过 istioctl profile list 命令查看:

 1$ istioctl profile list
 2Istio configuration profiles:
 3    ambient
 4    default
 5    demo
 6    empty
 7    external
 8    minimal
 9    openshift
10    preview
11    remote

我们可以从其中一个 Istio 内置配置文件开始入手, 然后根据特定需求进一步自定义配置文件。

  • default:根据 IstioOperator API 的默认配置启动组件。建议将此配置文件用于生产部署和多集群网格中的主集群,我们可以运行 istioctl profile dump 命令来查看默认设置,如下所示其实就是一个 IstioOperator 的配置文件:

注意:这里的IstioOperator和我们之前k8s里Operator不一样,这里没有直接的控制器,它是通过istioctl命令来做的一些解析。

istioctl 能够识别的一个安装配置文件,只是这个配置文件采用了类似于K8s CRD的方式来声明而已,并没有对应的控制器Pod。

  1#istioctl profile dump default
  2$ istioctl profile dump
  3apiVersion: install.istio.io/v1alpha1
  4kind: IstioOperator
  5spec:
  6  components:
  7    base:
  8      enabled: true
  9    cni:
 10      enabled: false
 11    egressGateways:
 12    - enabled: false
 13      name: istio-egressgateway
 14    ingressGateways:
 15    - enabled: true
 16      name: istio-ingressgateway
 17    istiodRemote:
 18      enabled: false
 19    pilot:
 20      enabled: true
 21  hub: docker.io/istio
 22  meshConfig:
 23    defaultConfig:
 24      proxyMetadata: {}
 25    enablePrometheusMerge: true
 26  profile: default
 27  tag: 1.19.3
 28  values:
 29    base:
 30      enableCRDTemplates: false
 31      validationURL: ""
 32    defaultRevision: ""
 33    gateways:
 34      istio-egressgateway:
 35        autoscaleEnabled: true
 36        env: {}
 37        name: istio-egressgateway
 38        secretVolumes:
 39        - mountPath: /etc/istio/egressgateway-certs
 40          name: egressgateway-certs
 41          secretName: istio-egressgateway-certs
 42        - mountPath: /etc/istio/egressgateway-ca-certs
 43          name: egressgateway-ca-certs
 44          secretName: istio-egressgateway-ca-certs
 45        type: ClusterIP
 46      istio-ingressgateway:
 47        autoscaleEnabled: true
 48        env: {}
 49        name: istio-ingressgateway
 50        secretVolumes:
 51        - mountPath: /etc/istio/ingressgateway-certs
 52          name: ingressgateway-certs
 53          secretName: istio-ingressgateway-certs
 54        - mountPath: /etc/istio/ingressgateway-ca-certs
 55          name: ingressgateway-ca-certs
 56          secretName: istio-ingressgateway-ca-certs
 57        type: LoadBalancer
 58    global:
 59      configValidation: true
 60      defaultNodeSelector: {}
 61      defaultPodDisruptionBudget:
 62        enabled: true
 63      defaultResources:
 64        requests:
 65          cpu: 10m
 66      imagePullPolicy: ""
 67      imagePullSecrets: []
 68      istioNamespace: istio-system
 69      istiod:
 70        enableAnalysis: false
 71      jwtPolicy: third-party-jwt
 72      logAsJson: false
 73      logging:
 74        level: default:info
 75      meshNetworks: {}
 76      mountMtlsCerts: false
 77      multiCluster:
 78        clusterName: ""
 79        enabled: false
 80      network: ""
 81      omitSidecarInjectorConfigMap: false
 82      oneNamespace: false
 83      operatorManageWebhooks: false
 84      pilotCertProvider: istiod
 85      priorityClassName: ""
 86      proxy:
 87        autoInject: enabled
 88        clusterDomain: cluster.local
 89        componentLogLevel: misc:error
 90        enableCoreDump: false
 91        excludeIPRanges: ""
 92        excludeInboundPorts: ""
 93        excludeOutboundPorts: ""
 94        image: proxyv2
 95        includeIPRanges: '*'
 96        logLevel: warning
 97        privileged: false
 98        readinessFailureThreshold: 30
 99        readinessInitialDelaySeconds: 1
100        readinessPeriodSeconds: 2
101        resources:
102          limits:
103            cpu: 2000m
104            memory: 1024Mi
105          requests:
106            cpu: 100m
107            memory: 128Mi
108        statusPort: 15020
109        tracer: zipkin
110      proxy_init:
111        image: proxyv2
112      sds:
113        token:
114          aud: istio-ca
115      sts:
116        servicePort: 0
117      tracer:
118        datadog: {}
119        lightstep: {}
120        stackdriver: {}
121        zipkin: {}
122      useMCP: false
123    istiodRemote:
124      injectionURL: ""
125    pilot:
126      autoscaleEnabled: true
127      autoscaleMax: 5
128      autoscaleMin: 1
129      configMap: true
130      cpu:
131        targetAverageUtilization: 80
132      env: {}
133      image: pilot
134      keepaliveMaxServerConnectionAge: 30m
135      nodeSelector: {}
136      podLabels: {}
137      replicaCount: 1
138      traceSampling: 1
139    telemetry:
140      enabled: true
141      v2:
142        enabled: true
143        metadataExchange:
144          wasmEnabled: false
145        prometheus:
146          enabled: true
147          wasmEnabled: false
148        stackdriver:
149          configOverride: {}
150          enabled: false
151          logging: false
152          monitoring: false
153          topology: false
  • demo:这个配置旨在展示 Istio 功能,具有适度的资源要求。它适合运行官方的 Bookinfo 示例应用和相关任务,比较适合用于快速入门的安装配置,比如我们这里就可以使用该配置。此配置文件启用了高级别的追踪和访问日志,因此不适合进行性能测试。我们也可以使用 istioctl profile dump demo 命令来查看该配置文件的具体配置资源对象。
  • minimal:与默认配置文件相同,但只安装了控制平面组件。这样我们就可以使用单独的配置文件来配置控制平面和数据平面组件(例如网关)。
  • remote:用于配置一个远程集群, 这个从集群由外部控制平面管理, 或者由多集群网格的主集群中的控制平面管理。
  • empty:不部署任何内容,可以作为自定义配置的基本配置文件。
  • preview:预览文件包含的功能都属于实验性阶段。该配置文件是为了探索 Istio 的新功能。确保稳定性、安全性和性能(使用风险需自负)。
  • ambient:Ambient 配置文件用于帮助开始使用 Ambient Mesh。需要注意的是 Ambient 目前处于 Alpha 状态。请勿在生产环境中使用 Ambient 模式。
  • openshift:用于在 OpenShift 上安装 Istio。

标注 的组件安装在每个配置文件中:

img

除了安装 Istio 内置的配置之外,istioctl install 还提供了一套完整的用于定制配置的 API - IstioOperator API

此 API 中的配置参数可以使用命令行选项 --set 进行独立设置,比如要在 default 配置中启动 debug 的日志特性,我们可以使用下面的命令:

1$ istioctl install --set values.global.logging.level=debug

或者,可以在 YAML 文件中指定 IstioOperator 的配置,然后用 -f 选项传递给 istioctl 即可:

1$ istioctl install -f samples/operator/pilot-k8s.yaml

IstioOperator API 定义主要包括如下几个组件:

  • base
  • pilot
  • ingressGateways
  • egressGateways
  • cni
  • istiodRemote

针对每一个组件的配置内容通过 components.<component name> 下的 API 中提供。例如,要用 API 更改 pilot 组件的 enabled 设置, 可以使用 --set components.pilot.enabled=false 命令,或在 IstioOperator 资源中设置:

1apiVersion: install.istio.io/v1alpha1
2kind: IstioOperator
3spec:
4  components:
5    pilot:
6      enabled: false

这样安装后就不会启动 pilot 组件了。

所有的组件共享一个通用 API,用来修改 Kubernetes 特定的设置,它在 components.<component name>.k8s 路径下,它允许修改如下设置:

  • Resources
  • Readiness probes
  • Replica count
  • HorizontalPodAutoscaler
  • PodDisruptionBudget
  • Pod annotations
  • Service annotations
  • ImagePullPolicy
  • Priority class name
  • Node selector
  • Affinity and anti-affinity
  • Service
  • Toleration
  • Strategy
  • Env
  • Pod security context

所有这些 Kubernetes 设置也就是平时我们使用的 Kubernetes API 定义,配置方式完全一样。比如我们要调整 Pilot 组件的资源限制和 Pod 水平伸缩,可以用如下所示的配置:

 1apiVersion: install.istio.io/v1alpha1
 2kind: IstioOperator
 3spec:
 4  components:
 5    pilot:
 6      k8s:
 7        resources:
 8          requests:
 9            cpu: 1000m # 覆盖默认的 500m
10            memory: 4096Mi # ... 默认 2048Mi
11        hpaSpec:
12          maxReplicas: 10 # ... 默认 5
13          minReplicas: 2 # ... 默认 1

然后我们就可以直接使用 istioctl install 把改变的设置应用到集群:

1$ istioctl install -f samples/operator/pilot-k8s.yaml

🍀

了解了 Istio 安装的基本概念之后,我们就可以开始安装 Istio 了,我们这里选择 demo 配置文件进行安装,选择它是因为它包含了一组专为测试准备的功能集合,另外还有用于生产或性能测试的配置组合。

执行下面的命令即可:

1$ istioctl install --set profile=demo -y
2✔ Istio core installed
3✔ Istiod installed
4✔ Egress gateways installed
5✔ Ingress gateways installed
6✔ Installation complete
7Made this installation the default for injection and validation.

可以看到上面的 demo 配置应用后,启用了 Istio coreIstiodEgress gatewaysIngress gateways 几个组件,这些组件都是通过 IstioOperator API 进行配置的。

🍀

安装完成后会自动创建一个 istio-system 命名空间,包含如下几个 Pod,分别对应上面的几个组件:

1[root@master1 ~]#kubectl get po -nistio-system

image-20231103183034166

这其实也和 Istio 架构中的组件是一一对应的,我们可以再看下 Istio 架构图:

img

  • istio-egressgateway:出口网关,用于处理出站流量。
  • istio-ingressgateway:入口网关,用于处理入站流量,接收传入的 HTTP/TCP 连接。
  • istiod:Istio 控制平面,用于管理和配置数据平面,提供服务网格的核心功能。

当然安装后并没有出现架构图上面的数据平面相关组件,这是因为数据平面的 Envoy Sidecar 代理是伴随应用 Pod 一起的,所以需要部署应用后才会出现。

安装成功。😘

2、注入 Envoy Sidecar

要为应用注入 Envoy Sidecar 代理有几种方法:

1.手动注入 Sidecar

==🚩 实战:手动注入 Envoy Sidecar-2023.11.3(测试成功)==

实验环境:

1k8s v1.25.4(containerd://1.6.10)
2
3[root@master1 ~]#istioctl version
4client version: 1.19.3
5control plane version: 1.19.3
6data plane version: 1.19.3 (8 proxies)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb 提取码:7yqb 2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功) (使用的是同一个软件包)

image-20231105111842627

默认的测试demo如下位置:

 1[root@master1 ~]#cat istio-1.19.3/samples/sleep/sleep.yaml
 2# Copyright Istio Authors
 3#
 4#   Licensed under the Apache License, Version 2.0 (the "License");
 5#   you may not use this file except in compliance with the License.
 6#   You may obtain a copy of the License at
 7#
 8#       http://www.apache.org/licenses/LICENSE-2.0
 9#
10#   Unless required by applicable law or agreed to in writing, software
11#   distributed under the License is distributed on an "AS IS" BASIS,
12#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13#   See the License for the specific language governing permissions and
14#   limitations under the License.
15
16##################################################################################################
17# Sleep service
18##################################################################################################
19apiVersion: v1
20kind: ServiceAccount
21metadata:
22  name: sleep
23---
24apiVersion: v1
25kind: Service
26metadata:
27  name: sleep
28  labels:
29    app: sleep
30    service: sleep
31spec:
32  ports:
33  - port: 80
34    name: http
35  selector:
36    app: sleep
37---
38apiVersion: apps/v1
39kind: Deployment
40metadata:
41  name: sleep
42spec:
43  replicas: 1
44  selector:
45    matchLabels:
46      app: sleep
47  template:
48    metadata:
49      labels:
50        app: sleep
51    spec:
52      terminationGracePeriodSeconds: 0
53      serviceAccountName: sleep
54      containers:
55      - name: sleep
56        image: curlimages/curl
57        command: ["/bin/sleep", "infinity"]
58        imagePullPolicy: IfNotPresent
59        volumeMounts:
60        - mountPath: /etc/sleep/tls
61          name: secret-volume
62      volumes:
63      - name: secret-volume
64        secret:
65          secretName: sleep-secret
66          optional: true
67---
68[root@master1 ~]#

🍀

先来部署这个应用

1[root@master1 ~]#kubectl  apply -f istio-1.19.3/samples/sleep/sleep.yaml
2serviceaccount/sleep created
3service/sleep created
4deployment.apps/sleep created
5
6[root@master1 ~]#kubectl get po -l app=sleep
7NAME                     READY   STATUS    RESTARTS   AGE
8sleep-78ff5975c6-ftlzx   1/1     Running   0          46s

这是一个正常应用的状态。

🍀

比如我们为一个 Deployment 手动注入 Sidecar,可以使用下面的方法:

1# istio-1.19.3 目录下
2$ istioctl kube-inject -f samples/sleep/sleep.yaml | kubectl apply -f -
3serviceaccount/sleep created
4service/sleep created
5deployment.apps/sleep created

image-20231103191345481

image-20231103191442827

默认情况下 Pod 的注入是基于 Sidecar 注入模板,在 istio-sidecar-injector Configmap 中配置,我们可以将配置导出到本地,然后手动指定注入也可以:

1$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.config}' > inject-config.yaml
2$ kubectl -n istio-system get configmap istio-sidecar-injector -o=jsonpath='{.data.values}' > inject-values.yaml
3$ kubectl -n istio-system get configmap istio -o=jsonpath='{.data.mesh}' > mesh-config.yaml

然后指定输入文件,运行 kube-inject 并部署应用即可:

1$ istioctl kube-inject \
2    --injectConfigFile inject-config.yaml \
3    --meshConfigFile mesh-config.yaml \
4    --valuesFile inject-values.yaml \
5    --filename samples/sleep/sleep.yaml \
6    | kubectl apply -f -

🍀

正常部署后我们的应用 Pod 中会多出一个 Sidecar 容器:

1[root@master1 istio-1.19.3]#kubectl get po -l app=sleep
2NAME                     READY   STATUS    RESTARTS   AGE
3sleep-7cbcd885cf-6j4bt   2/2     Running   0          2m8s
4[root@master1 istio-1.19.3]#

这个容器就是 Envoy Sidecar 代理。

image-20231103191947765

这个 Envoy Sidecar 代理,它会和应用 Pod 一起运行,用来代理整个应用的流量,当然整体控制都是由 Istio 控制平面来决定的。而 Istio 控制平面实现了 Envoy 的控制平面接口,可以动态下发修改 Envoy 的配置,这样我们就可以去操控这些 Envoy Sidecar 了,这是不是和我们前面讲解的 Envoy 基于 API 的动态配置部分就关联起来了,所以我们说需要先熟悉 Envoy,然后再来学习 Istio 效果会更好。

image-20231103193705213

🍀

image-20231103193003472

image-20231103193236133

测试完成。😘

2.自定义注入

上面我们了解到 Pod 的注入是基于 istio-sidecar-injector 这个 Configmap 模板的,同样的我们也可以自行定义注入 Sidecar 代理。我们可以通过在 Pod 中手动添加一个 istio-proxy 容器来完成,Sidecar 注入将会把自定义的任何配置视为默认注入模板的覆盖。

自定义这些设置时,需格外小心,因为允许完全自定义生成的 Pod,包括进行一些更改而导致 Sidecar 容器无法正常运行。

例如,以下配置可自定义各种设置,包括降低 CPU 请求,添加 Volume 挂载,和添加 preStop Hook:

 1apiVersion: v1
 2kind: Pod
 3metadata:
 4  name: example
 5spec:
 6  containers:
 7    - name: hello
 8      image: alpine
 9    - name: istio-proxy # 这个容器名需要叫 istio-proxy
10      image: auto # 设置为 auto,自动选择要使用的 Image
11      resources:
12        requests:
13          cpu: "100m"
14      volumeMounts:
15        - mountPath: /etc/certs
16          name: certs
17      lifecycle:
18        preStop:
19          exec:
20            command: ["sleep", "10"]
21  volumes:
22    - name: certs
23      secret:
24        secretName: istio-certs

一般来说 Pod 中的任何字段我们都可以配置,但是必须注意某些字段:

  • Kubernetes 要求在注入运行之前配置 image,虽然可以可以设置一个指定的 Image 来覆盖默认的 image 配置,但建议将 image 设置为 auto,可使 Sidecar 注入自动选择要使用的 Image。
  • Pod 中一些字段取决于相关设置。例如,CPU 请求必须小于 CPU 限制。

3.自动注入 Sidecar

==🚩 实战:自动注入 Envoy Sidecar-2023.11.8(测试成功)==

实验环境:

1k8s v1.27.6(containerd://1.6.20)
2
3[root@master1 ~]#istioctl version
4client version: 1.19.3
5control plane version: 1.19.3
6data plane version: 1.19.3 (8 proxies)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb 提取码:7yqb 2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功) (使用的是同一个软件包)

image-20231105111842627

上面我们介绍了手动注入和自定义注入两种方式,这些都是需要我们手动去操作的,此外我们也可以通过配置实现自动注入,这样我们就不需要手动去注入了,Istio 提供了一个 Kubernetes 准入控制器,它可以自动注入 Sidecar 代理,我们只需要为命名空间设置 istio-injection=enabled 标签即可启用自动注入。

🍀

比如我们先在集群中部署 sleep 应用:(测试之前记得先删除先前的测试demo)

 1#在目录istio-1.19.3下
 2[root@master1 istio-1.19.3]#kubectl apply -f samples/sleep/sleep.yaml
 3serviceaccount/sleep unchanged
 4service/sleep unchanged
 5deployment.apps/sleep created
 6[root@master1 istio-1.19.3]#kubectl get deploy
 7NAME    READY   UP-TO-DATE   AVAILABLE   AGE
 8sleep   1/1     1            1           22s
 9web     1/1     1            1           6d4h
10[root@master1 istio-1.19.3]#kubectl get pod -l app=sleep
11NAME                     READY   STATUS    RESTARTS   AGE
12sleep-78ff5975c6-v62sv   1/1     Running   0          31s

目前我们的 sleep 应用是没有注入 Sidecar 的,只有 1 个容器。

🍀

现在我们可以为 default 命名空间打上 istio-injection=enabled 标签:

 1[root@master1 istio-1.19.3]#kubectl label namespace default istio-injection=enabled --overwrite
 2namespace/default labeled
 3[root@master1 istio-1.19.3]#kubectl get namespace -L istio-injection
 4NAME                   STATUS   AGE    ISTIO-INJECTION
 5default                Active   6d4h   enabled
 6istio-system           Active   8h     
 7kube-flannel           Active   6d4h   
 8kube-node-lease        Active   6d4h   
 9kube-public            Active   6d4h   
10kube-system            Active   6d4h   
11kubernetes-dashboard   Active   6d4h   
12[root@master1 istio-1.19.3]#kubectl get pod -l app=sleep
13NAME                     READY   STATUS    RESTARTS   AGE
14sleep-78ff5975c6-v62sv   1/1     Running   0          108s

🍀

现在我们为命名空间打上了自动注入标签,但是已经部署了的应用并不会主动注入,这是因为注入的动作发生着 Pod 创建时。我们可以杀掉正在运行的 Pod 来验证新创建的 Pod 是否注入 Sidecar。

1$ kubectl delete pod -l app=sleep
2$ kubectl get pod -l app=sleep
3NAME                    READY   STATUS    RESTARTS   AGE
4sleep-9454cc476-kmbzz   2/2     Running   0          5s

可以看到现在我们的应用有 2 个容器了。查看已注入 Pod 的详细状态,应该可以看到被注入的 istio-proxy 容器:

 1$ kubectl describe pod -l app=sleep
 2...
 3Events:
 4  Type    Reason     Age   From               Message
 5  ----    ------     ----  ----               -------
 6  Normal  Scheduled  91s   default-scheduler  Successfully assigned default/sleep-9454cc476-kmbzz to node2
 7  Normal  Pulled     90s   kubelet            Container image "docker.io/istio/proxyv2:1.19.3" already present on machine
 8  Normal  Created    90s   kubelet            Created container istio-init
 9  Normal  Started    90s   kubelet            Started container istio-init
10  Normal  Pulled     90s   kubelet            Container image "curlimages/curl" already present on machine
11  Normal  Created    90s   kubelet            Created container sleep
12  Normal  Started    90s   kubelet            Started container sleep
13  Normal  Pulled     90s   kubelet            Container image "docker.io/istio/proxyv2:1.19.3" already present on machine
14  Normal  Created    89s   kubelet            Created container istio-proxy
15  Normal  Started    89s   kubelet            Started container istio-proxy

这样我们就实现了 Pod 应用自动注入 Envoy Sidecar 代理,以后 default 命名空间中的应用部署后都会自动注入了。当然要取消自动注入功能,只需要将 istio-injection 标签去掉即可:

1$ kubectl label namespace default istio-injection-

当然除了在命名空间级别启用和禁用注入功能之外,注入也可以通过配置 Pod 上的 sidecar.istio.io/inject: "true" 标签,在每个 Pod 的基础上进行控制。

自动注入 Envoy Sidecar 的原理其实很简单,如果你对 Kubernetes 比较熟悉的话,肯定听过准入控制器的,其中就有两个对象 validatingwebhookconfigurationsmutatingwebhookconfigurations,前面是用来校验资源是否合法的,后面是用来修改资源对象的,那么要实现自动注入功能,也就相当于去为 Pod 自动添加一个容器,所以就需要用到 mutate 功能了,我们可以查看下系统中是否包含一个 istio-sidecar-injector 的准入控制器:

1$ kubectl get mutatingwebhookconfigurations
2NAME                                             WEBHOOKS   AGE
3istio-sidecar-injector                           4          63m

而实现准入控制器逻辑的也正是 istiod 这个组件了。

image-20231103194848038


⚠️

==但是特别注意:我这里在做测试时出现了问题。。。排查了好多次,有点浪费时间。。。==

  • 但是,我这里出现问题了。。。提示:创建pod失败,内部错误发生,失败调用webhook……
 1[root@master1 istio-1.19.3]#kubectl get po
 2No resources found in default namespace.
 3[root@master1 istio-1.19.3]#kubectl get deploy sleep 
 4NAME    READY   UP-TO-DATE   AVAILABLE   AGE
 5sleep   0/1     0            0           8m32s
 6[root@master1 istio-1.19.3]#kubectl describe deployments.apps sleep 
 7Name:                   sleep
 8Namespace:              default
 9CreationTimestamp:      Fri, 03 Nov 2023 21:50:31 +0800
10Labels:                 <none>
11Annotations:            deployment.kubernetes.io/revision: 1
12Selector:               app=sleep
13Replicas:               1 desired | 0 updated | 0 total | 0 available | 1 unavailable
14StrategyType:           RollingUpdate
15MinReadySeconds:        0
16RollingUpdateStrategy:  25% max unavailable, 25% max surge
17Pod Template:
18  Labels:           app=sleep
19  Service Account:  sleep
20  Containers:
21   sleep:
22    Image:      curlimages/curl
23    Port:       <none>
24    Host Port:  <none>
25    Command:
26      /bin/sleep
27      infinity
28    Environment:  <none>
29    Mounts:
30      /etc/sleep/tls from secret-volume (rw)
31  Volumes:
32   secret-volume:
33    Type:        Secret (a volume populated by a Secret)
34    SecretName:  sleep-secret
35    Optional:    true
36Conditions:
37  Type             Status  Reason
38  ----             ------  ------
39  Progressing      True    NewReplicaSetAvailable
40  Available        False   MinimumReplicasUnavailable
41  ReplicaFailure   True    FailedCreate
42OldReplicaSets:    <none>
43NewReplicaSet:     sleep-78ff5975c6 (0/1 replicas created)
44Events:
45  Type    Reason             Age    From                   Message
46  ----    ------             ----   ----                   -------
47  Normal  ScalingReplicaSet  8m39s  deployment-controller  Scaled up replica set sleep-78ff5975c6 to 1
48[root@master1 istio-1.19.3]#

image-20231103220001099

 1[root@master1 istio-1.19.3]#kubectl get rs sleep-78ff5975c6
 2NAME               DESIRED   CURRENT   READY   AGE
 3sleep-78ff5975c6   1         0         0       10m
 4[root@master1 istio-1.19.3]#kubectl describe rs sleep-78ff5975c6
 5Name:           sleep-78ff5975c6
 6Namespace:      default
 7Selector:       app=sleep,pod-template-hash=78ff5975c6
 8Labels:         app=sleep
 9                pod-template-hash=78ff5975c6
10Annotations:    deployment.kubernetes.io/desired-replicas: 1
11                deployment.kubernetes.io/max-replicas: 2
12                deployment.kubernetes.io/revision: 1
13Controlled By:  Deployment/sleep
14Replicas:       0 current / 1 desired
15Pods Status:    0 Running / 0 Waiting / 0 Succeeded / 0 Failed
16Pod Template:
17  Labels:           app=sleep
18                    pod-template-hash=78ff5975c6
19  Service Account:  sleep
20  Containers:
21   sleep:
22    Image:      curlimages/curl
23    Port:       <none>
24    Host Port:  <none>
25    Command:
26      /bin/sleep
27      infinity
28    Environment:  <none>
29    Mounts:
30      /etc/sleep/tls from secret-volume (rw)
31  Volumes:
32   secret-volume:
33    Type:        Secret (a volume populated by a Secret)
34    SecretName:  sleep-secret
35    Optional:    true
36Conditions:
37  Type             Status  Reason
38  ----             ------  ------
39  ReplicaFailure   True    FailedCreate
40Events:
41  Type     Reason            Age                    From                   Message
42  ----     ------            ----                   ----                   -------
43  Normal   SuccessfulCreate  10m                    replicaset-controller  Created pod: sleep-78ff5975c6-9tpms
44  Warning  FailedCreate      6m58s (x4 over 8m58s)  replicaset-controller  Error creating: Internal error occurred: failed calling webhook "namespace.sidecar-injector.istio.io": failed to call webhook: Post "https://istiod.istio-system.svc:443/inject?timeout=10s": dial tcp 10.108.70.31:443: i/o timeout
45  Warning  FailedCreate      101s (x13 over 9m8s)   replicaset-controller  Error creating: Internal error occurred: failed calling webhook "namespace.sidecar-injector.istio.io": failed to call webhook: Post "https://istiod.istio-system.svc:443/inject?timeout=10s": context deadline exceeded
46[root@master1 istio-1.19.3]#

image-20231103220111397

提示:创建pod失败,内部错误发生,失败调用webhook……

image-20231103220207796

image-20231103220301942

image-20231103220503270

奇怪。。。。

老师的都没问题。。。

重启istio组件测试(失败)

重启k8s集群(失败)

  • istiod日志

image-20231103221342362

  • 个人判断是自己的k8s集群版与老师集群版本不一致或需要开启什么webhook等……

很大程度是这个问题导致的。。。

老师环境:

image-20231125084909818

自己环境:

image-20231104161014770

image-20231104161251139

  • 删除istiod,重装还是有问题。。。

  • 后期重新搭建了v1.27.6版本k8s集群测试,containerd v1.6.20,但是还是不行。。。

重装完成k8s后,还是无法自动注入哇。。。。

image-20231107202156806

image-20231107202221241

istiod-644f5d55fc-gs96f日志

image-20231107202311255

api-server日志:

image-20231107202413251

kubelet信息:

image-20231107202504022

image-20231107202657228

再次测试:2023年11月8日,升级cni flanel版本

  • 自己当前flannel版本

image-20231107202657228

  • 老师测试成功的flannel版本:docker.io/flannel/flannel:v0.22.2

image-20231108212637806

  • 这里到flannel github下载v0.22.2版本,进行安装再测试

wget https://raw.githubusercontent.com/flannel-io/flannel/v0.20.1/Documentation/kube-flannel.yml

wget https://raw.githubusercontent.com/flannel-io/flannel/v0.20.1/Documentation/kube-flannel.yml

https://github.com/flannel-io/flannel/releases/download/v0.22.2/kube-flannel.yml

https://ghps.cc/https://github.com/flannel-io/flannel/releases/download/v0.22.2/kube-flannel.yml

1wget https://ghps.cc/https://github.com/flannel-io/flannel/releases/download/v0.22.2/kube-flannel.yml

先卸载原来版本的kube-falnnel:

1[root@master1 ~]#kubectl delete -f kube-flannel.yml 
2namespace "kube-flannel" deleted
3clusterrole.rbac.authorization.k8s.io "flannel" deleted
4clusterrolebinding.rbac.authorization.k8s.io "flannel" deleted
5serviceaccount "flannel" deleted
6configmap "kube-flannel-cfg" deleted
7daemonset.apps "kube-flannel-ds" deleted

下载好后直接安装:

1[root@master1 install-flannel]#kubectl apply -f kube-flannel.yml 
2namespace/kube-flannel created
3serviceaccount/flannel created
4clusterrole.rbac.authorization.k8s.io/flannel created
5clusterrolebinding.rbac.authorization.k8s.io/flannel created
6configmap/kube-flannel-cfg created
7daemonset.apps/kube-flannel-ds created
8[root@master1 install-flannel]#
  • 查看安装好的新版本flannel

image-20231108213612352

image-20231108213627145

1[root@master1 install-flannel]#kubectl get ds kube-flannel-ds  -nkube-flannel -oyaml|grep image
2       image: docker.io/flannel/flannel:v0.22.2
3        imagePullPolicy: IfNotPresent
4        image: docker.io/flannel/flannel-cni-plugin:v1.2.0
5        imagePullPolicy: IfNotPresent
6        image: docker.io/flannel/flannel:v0.22.2
7        imagePullPolicy: IfNotPresent

终于可以了:==。。。==

  • 再次部署istio sidecar测试

image-20231108214129991

结束。😘

3、BookInfo 示例应用

Bookinfo 是一个非常经典的微服务示例项目,它由四个独立的微服务组成,每个微服务都是用不同的语言编写的,可以用于演示多种 Istio 特性的应用。这个应用模仿在线书店的一个分类,显示一本书的信息,页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。

Bookinfo 应用分为以下四个单独的微服务:

  • productpage:这个微服务会调用 detailsreviews 两个微服务,用来生成页面。
  • details:这个微服务中包含了书籍的信息。
  • reviews:这个微服务中包含了书籍相关的评论,它还会调用 ratings 微服务。
  • ratings:这个微服务中包含了由书籍评价组成的评级信息。

reviews 微服务有 3 个版本:

  • v1 版本不会调用 ratings 服务。
  • v2 版本会调用 ratings 服务,并使用 1 到 5 个黑色星形图标来显示评分信息。
  • v3 版本会调用 ratings 服务,并使用 1 到 5 个红色星形图标来显示评分信息。

下图展示了这个应用的端到端架构。

img

现在我们来为 Bookinfo 应用提供 Istio 支持,无需对应用自身做出任何改变。只要简单的在 Istio 环境中对服务进行配置和运行即可,其实就是把 Envoy Sidecar 注入到每个服务之中。最终的部署结果将如下图所示:

img

所有的微服务都和 Envoy Sidecar 集成在一起,服务所有的出入流量都被 Sidecar 所劫持,然后我们就可以利用 Istio 控制平面为应用提供服务路由、遥测数据收集以及策略实施等服务治理功能了。

==🚩 实战:BookInfo 示例应用-2023.11.5(测试成功)==

实验环境:

1k8s v1.25.4(containerd://1.6.10)
2
3[root@master1 ~]#istioctl version
4client version: 1.19.3
5control plane version: 1.19.3
6data plane version: 1.19.3 (8 proxies)

实验软件:

链接:https://pan.baidu.com/s/1pMnJxgL63oTlGFlhrfnXsA?pwd=7yqb 提取码:7yqb 2023.11.5-实战:BookInfo 示例应用-2023.11.5(测试成功)

image-20231105111842627

实验步骤:

1graph LR
2	A[实战步骤] -->B(1️⃣ 部署示例应用)
3	A[实战步骤] -->C(2️⃣ 对外暴露应用)
4    A[实战步骤] -->D(3️⃣ 查看 Dashboard)

==1.部署示例应用==

🍀

我们首先进入 Istio 安装目录,该目录中的 samples 目录中就包含了 Bookinfo 部署到 Kubernetes 集群中的配置文件,我们只需要为这些资源注入 Sidecar。这里我们为 default 命名空间打上标签 istio-injection=enabled,开启自动注入功能即可:

1kubectl label namespace default istio-injection=enabled --overwrite

image-20231105072837083

🍀

然后只需要使用 kubectl 正常部署应用即可:

 1$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml
 2service/details created
 3serviceaccount/bookinfo-details created
 4deployment.apps/details-v1 created
 5service/ratings created
 6serviceaccount/bookinfo-ratings created
 7deployment.apps/ratings-v1 created
 8service/reviews created
 9serviceaccount/bookinfo-reviews created
10deployment.apps/reviews-v1 created
11deployment.apps/reviews-v2 created
12deployment.apps/reviews-v3 created
13service/productpage created
14serviceaccount/bookinfo-productpage created
15deployment.apps/productpage-v1 created

注意:

如果在安装过程中禁用了 Sidecar 自动注入功能而选择手动注入 Sidecar,可以使用 istioctl kube-inject 命令来手动注入:

1$ kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)

自己本次手动注入:(我的自动注入有点问题,这里使用手动注入方式)

 1[root@master1 istio-1.19.3]#kubectl apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
 2service/details created
 3serviceaccount/bookinfo-details created
 4deployment.apps/details-v1 created
 5service/ratings created
 6serviceaccount/bookinfo-ratings created
 7deployment.apps/ratings-v1 created
 8service/reviews created
 9serviceaccount/bookinfo-reviews created
10deployment.apps/reviews-v1 created
11deployment.apps/reviews-v2 created
12deployment.apps/reviews-v3 created
13service/productpage created
14serviceaccount/bookinfo-productpage created
15deployment.apps/productpage-v1 created

🍀

上面的命令会启动全部的四个服务,其中也包括了 reviews 服务的三个版本(v1、v2 以及 v3)。

隔一会儿,我们可以查看下 Pod 的状态:

 1$ kubectl get pods
 2NAME                                     READY   STATUS    RESTARTS         AGE
 3details-v1-5f4d584748-97stc              2/2     Running   0                12m
 4productpage-v1-564d4686f-z7fwn           2/2     Running   0                12m
 5ratings-v1-686ccfb5d8-cvlcq              2/2     Running   0                12m
 6reviews-v1-86896b7648-rrjxv              2/2     Running   0                12m
 7reviews-v2-b7dcd98fb-kk8fv               2/2     Running   0                12m
 8reviews-v3-5c5cc7b6d-c4wf5               2/2     Running   0                12m
 9$ kubectl get svc
10NAME                           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
11details                        ClusterIP   10.98.49.69      <none>        9080/TCP            13m
12kubernetes                     ClusterIP   10.96.0.1        <none>        443/TCP             44d
13productpage                    ClusterIP   10.101.255.202   <none>        9080/TCP            13m
14ratings                        ClusterIP   10.101.210.142   <none>        9080/TCP            13m
15reviews                        ClusterIP   10.106.93.80     <none>        9080/TCP            13m
 1[root@master1 istio-1.19.3]#kubectl get po
 2NAME                            READY   STATUS    RESTARTS   AGE
 3details-v1-76bdcd6b59-9p5gh     2/2     Running   0          18m
 4productpage-v1-d594c998-x8s6k   2/2     Running   0          18m
 5ratings-v1-64694b479f-qcbcm     2/2     Running   0          18m
 6reviews-v1-68f98444cd-szhrv     2/2     Running   0          18m
 7reviews-v2-6c9b87bd47-t4l9c     2/2     Running   0          18m
 8reviews-v3-9569b895b-jr29m      2/2     Running   0          18m
 9[root@master1 istio-1.19.3]#kubectl get svc
10NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
11details       ClusterIP   10.107.100.41    <none>        9080/TCP   19m
12kubernetes    ClusterIP   10.96.0.1        <none>        443/TCP    7d17h
13productpage   ClusterIP   10.110.115.123   <none>        9080/TCP   19m
14ratings       ClusterIP   10.101.72.27     <none>        9080/TCP   19m
15reviews       ClusterIP   10.111.206.146   <none>        9080/TCP   19m

当每个 Pod 准备就绪时,Istio Sidecar 将伴随应用一起部署。

🍀

要确认 Bookinfo 应用是否正在运行,我们可以在某个 Pod 中用 curl 命令对应用发送请求来验证,例如 ratings

1$ kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"
2<title>Simple Bookstore App</title>

如果能够正常数据,说明应用已经部署成功了,而且已经被 Istio 管控起来了。

==2.对外暴露应用==

上面我们已经将 Bookinfo 应用部署成功了,但是还不能被外界访问,如果没有 Istio 的情况下我们可以直接通过 NodePort 或者 Ingress 的方式来对外进行暴露,但是现在我们使用了 Istio,需要创建 ==Istio 入站网关(Ingress Gateway)==来对外暴露应用了。

🍀

samples 目录下面有一个 Bookinfo 对外暴露的配置文件 bookinfo-gateway.yaml,这个配置文件中定义了一个 Gateway 和一个 VirtualService 对象,Gateway 定义了入站流量的端口和协议,VirtualService 定义了流量的路由规则,内容如下所示:

 1# samples/bookinfo/networking/bookinfo-gateway.yaml
 2apiVersion: networking.istio.io/v1alpha3
 3kind: Gateway
 4metadata:
 5  name: bookinfo-gateway
 6spec:
 7  selector: # 如果使用的是 Helm 方式安装,则默认应该是 istio=ingress 标签
 8    istio: ingressgateway # 匹配 ingress gateway pod 的标签(kubectl get pods -l istio=ingressgateway -n istio-system)
 9  servers:
10    - port:
11        number: 8080
12        name: http
13        protocol: HTTP
14      hosts:
15        - "*"
16---
17apiVersion: networking.istio.io/v1alpha3
18kind: VirtualService
19metadata:
20  name: bookinfo
21spec:
22  hosts:
23    - "*"
24  gateways:
25    - bookinfo-gateway
26  http:
27    - match:
28        - uri:
29            exact: /productpage
30        - uri:
31            prefix: /static
32        - uri:
33            exact: /login
34        - uri:
35            exact: /logout
36        - uri:
37            prefix: /api/v1/products
38      route:
39        - destination:
40            host: productpage
41            port:
42              number: 9080

这两个资源对象我们后面还会详细讲解的,现在我们只需要知道这两个资源对象是用来定义入站流量的端口和协议以及流量的路由规则的即可。如果你联想到前面我们讲解的 Envoy 配置,那么你就会发现这两个资源对象其实分别对应着 Envoy 配置中的 Listener 和 VirtualHosts(包括 Cluster),只不过这里是用我们更熟悉的 Kubernetes CRD 的方式来进行配置的,当我们创建了这两个资源对象后,Istio 控制平面会自动把这些配置下发到 Envoy Sidecar 中,然后 Envoy Sidecar 就会根据这些配置来进行流量的路由了。

🍀

接下来我们执行下面的命令来把应用关联到 Istio 网关:

1$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml
2gateway.networking.istio.io/bookinfo-gateway created
3virtualservice.networking.istio.io/bookinfo created

🍀

然后我们就可以通过 istio-ingressgateway 这个统一的入口来访问应用了,我们可以通过 kubectl get svc -n istio-system 命令来查看下 istio-ingressgateway 的地址:

1$ kubectl get svc istio-ingressgateway -n istio-system
2NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                      AGE
3istio-ingressgateway   LoadBalancer   10.103.227.57   <pending>     15021:32459/TCP,80:31896/TCP,443:30808/TCP,31400:31535/TCP,15443:30761/TCP   155m
1[root@master1 istio-1.19.3]#kubectl get svc istio-ingressgateway -n istio-system
2NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE
3istio-ingressgateway   LoadBalancer   10.104.174.171   <pending>     15021:32479/TCP,80:31814/TCP,443:31263/TCP,31400:32543/TCP,15443:30806/TCP   13h

由于我们这里没有负载均衡器,所以 EXTERNAL-IP 的值一直是 <pending> 状态,这种情况下我们可以用 NodePort 来访问网关。可以通过如下命令获取 HTTP 和 HTTPS 的访问端口:

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

然后获取集群中任意一个节点的 IP 地址:

1export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')

设置环境变量 GATEWAY_URL:

1export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

确保 IP 地址和端口均成功地赋值给了环境变量:

1$ echo "$GATEWAY_URL"
2192.168.0.20:31896
3
4[root@master1 istio-1.19.3]#echo "$GATEWAY_URL"
5172.29.9.62:31814

这样我们就得到了 Istio 入口网关的访问地址,然后我们只需要在浏览器中通过 http://$GATEWAY_URL/productpage 即可访问到 Bookinfo 应用了。

img

注意:

image-20231105074411915

image-20231105074425584

image-20231105074458472

image-20231105074512207

image-20231105102632050

image-20231105102656887

image-20231105102713002

image-20231105102721943

==3.查看 Dashboard==

Istio 和几个遥测应用做了集成。遥测能帮我们了解服务网格的结构、展示网络的拓扑结构、分析网格的健康状态。

🍀

我们可以使用下面的方式来安装 Kiali,包括 Prometheus、Grafana 以及 jaeger。

 1$ kubectl apply -f samples/addons
 2$ kubectl rollout status deployment/kiali -n istio-system
 3Waiting for deployment "kiali" rollout to finish: 0 of 1 updated replicas are available...
 4deployment "kiali" successfully rolled out
 5$ kubectl get pods -n istio-system
 6NAME                                   READY   STATUS    RESTARTS   AGE
 7grafana-5f9b8c6c5d-jv65v               1/1     Running   0          6m23s
 8istio-egressgateway-556f6f58f4-hkzdd   1/1     Running   0          177m
 9istio-ingressgateway-9c8b9b586-s6s48   1/1     Running   0          177m
10istiod-644f5d55fc-zz2zh                1/1     Running   0          179m
11jaeger-db6bdfcb4-qpmmv                 1/1     Running   0          6m23s
12kiali-7c9d5f9f96-cp4mb                 1/1     Running   0          6m23s
13prometheus-5d5d6d6fc-2gtxm             2/2     Running   0          6m22s

如果在安装插件时出错,再运行一次命令。有一些和时间相关的问题,再次运行就能解决。

🍀

安装完成后我们可以使用 istioctl dashboard 命令来开启访问 Kiali 面板。

1$ istioctl dashboard kiali --address 0.0.0.0
2http://0.0.0.0:20001/kiali
3
4# http://172.29.9.61:20001/kiali/

image-20231105103618874

🍀

在左侧的导航菜单,选择 Graph ,然后在 Namespace 下拉列表中,选择 default

img

丢失图片

🍀

要查看链路追踪数据,必须向服务发送请求。请求的数量取决于 Istio 的采样率,采样率在安装 Istio 时设置,默认采样速率为 1%。也就是说在第一个 tracing 可见之前,需要发送至少 100 个请求:

1$ for i in $(seq 1 100); do curl -s -o /dev/null "http://$GATEWAY_URL/productpage"; done

image-20231105075227351

img

丢失图片

🍀

Kiali 的仪表板展示了网格的概览以及 Bookinfo 示例应用的各个服务之间的关系。 它还提供过滤器来可视化流量的流动。

img

丢失图片

到这里我们就完成了 Bookinfo 示例应用的部署,以及对外暴露应用的配置,接下来我们就可以开始学习 Istio 的核心功能了。

⚠️ 注意:这里的pod要依赖pvc

本次这里就暂不安装nfs了,记录下即可。

image-20231105112159229

image-20231105112143810

4、istioctl如何卸载istiod

🍀

官方删除istiod

image-20231104205800313

卸载 Istio

要从集群中完整卸载 Istio,运行下面命令:

1$ istioctl uninstall --purge

可选的 --purge 参数将移除所有 Istio 资源,包括可能被其他 Istio 控制平面共享的、集群范围的资源。

或者,只移除指定的 Istio 控制平面,运行以下命令:

1$ istioctl uninstall <your original installation options>

1$ istioctl manifest generate <your original installation options> | kubectl delete --ignore-not-found=true -f -

控制平面的命名空间(例如:istio-system)默认不会被移除。 如果确认不再需要,用下面命令移除该命名空间:

1$ kubectl delete namespace istio-system

🍀

gpt回答:

istioctl如何卸载istiod ?

要卸载 Istio 中的 istiod,您可以使用 Istio 的命令行工具 istioctl 来执行卸载操作。请注意,卸载 istiod 会从集群中删除 Istio 控制平面的组件。

以下是卸载 istiod 的基本步骤:

  1. 打开终端并使用 istioctl 连接到您的 Kubernetes 集群。确保已经安装 Istio 并配置好 istioctl
  2. 运行以下命令卸载 istiod
1istioctl  uninstall istiod

这将删除 istiod 及其关联的组件,例如 Pilot、Galley 和 Mixer。

  1. 确认卸载操作完成。这可能需要一些时间,具体时间取决于您的集群规模和网络状况。

请注意,卸载 istiod 后,您的 Istio 控制平面将不再运行,这可能会影响已部署的应用程序。如果需要重新安装 Istio 或者只是想卸载 Istio 控制平面而保留 sidecar 代理(Envoy)在应用程序中,可以根据需要重新安装 Istio 控制平面的特定组件。

在执行任何卸载操作之前,请务必备份您的配置和数据,以免丢失重要信息。根据您的需求和集群配置,还可能需要对卸载过程进行适当的自定义。

🍀

自己测试过程:

 1[root@master1 ~]#istioctl uninstall --purge
 2All Istio resources will be pruned from the cluster
 3Proceed? (y/N) Y
 4  Removed IstioOperator:istio-system:installed-state.
 5  Removed Deployment:istio-system:istio-egressgateway.
 6  Removed Deployment:istio-system:istio-ingressgateway.
 7  Removed Deployment:istio-system:istiod.
 8  Removed Service:istio-system:istio-egressgateway.
 9  Removed Service:istio-system:istio-ingressgateway.
10  Removed Service:istio-system:istiod.
11  Removed ConfigMap:istio-system:istio.
12  Removed ConfigMap:istio-system:istio-sidecar-injector.
13  Removed Pod:istio-system:istio-egressgateway-8477dd44c4-9q8d4.
14  Removed Pod:istio-system:istio-ingressgateway-5c58fcb646-jk4fh.
15  Removed Pod:istio-system:istiod-5d9595449c-b2pmc.
16  Removed ServiceAccount:istio-system:istio-egressgateway-service-account.
17  Removed ServiceAccount:istio-system:istio-ingressgateway-service-account.
18  Removed ServiceAccount:istio-system:istio-reader-service-account.
19  Removed ServiceAccount:istio-system:istiod.
20  Removed RoleBinding:istio-system:istio-egressgateway-sds.
21  Removed RoleBinding:istio-system:istio-ingressgateway-sds.
22  Removed RoleBinding:istio-system:istiod.
23  Removed Role:istio-system:istio-egressgateway-sds.
24  Removed Role:istio-system:istio-ingressgateway-sds.
25  Removed Role:istio-system:istiod.
26  Removed PodDisruptionBudget:istio-system:istio-egressgateway.
27  Removed PodDisruptionBudget:istio-system:istio-ingressgateway.
28  Removed PodDisruptionBudget:istio-system:istiod.
29  Removed MutatingWebhookConfiguration::istio-revision-tag-default.
30  Removed MutatingWebhookConfiguration::istio-sidecar-injector.
31  Removed ValidatingWebhookConfiguration::istio-validator-istio-system.
32  Removed ValidatingWebhookConfiguration::istiod-default-validator.
33  Removed ClusterRole::istio-reader-clusterrole-istio-system.
34  Removed ClusterRole::istiod-clusterrole-istio-system.
35  Removed ClusterRole::istiod-gateway-controller-istio-system.
36  Removed ClusterRoleBinding::istio-reader-clusterrole-istio-system.
37  Removed ClusterRoleBinding::istiod-clusterrole-istio-system.
38  Removed ClusterRoleBinding::istiod-gateway-controller-istio-system.
39  Removed CustomResourceDefinition::authorizationpolicies.security.istio.io.
40  Removed CustomResourceDefinition::destinationrules.networking.istio.io.
41  Removed CustomResourceDefinition::envoyfilters.networking.istio.io.
42  Removed CustomResourceDefinition::gateways.networking.istio.io.
43  Removed CustomResourceDefinition::istiooperators.install.istio.io.
44  Removed CustomResourceDefinition::peerauthentications.security.istio.io.
45  Removed CustomResourceDefinition::proxyconfigs.networking.istio.io.
46  Removed CustomResourceDefinition::requestauthentications.security.istio.io.
47  Removed CustomResourceDefinition::serviceentries.networking.istio.io.
48  Removed CustomResourceDefinition::sidecars.networking.istio.io.
49  Removed CustomResourceDefinition::telemetries.telemetry.istio.io.
50  Removed CustomResourceDefinition::virtualservices.networking.istio.io.
51  Removed CustomResourceDefinition::wasmplugins.extensions.istio.io.
52  Removed CustomResourceDefinition::workloadentries.networking.istio.io.
53  Removed CustomResourceDefinition::workloadgroups.networking.istio.io.
54? Uninstall complete                                                                                                                                                                              [root@master1 ~]#
55[root@master1 ~]#kubectl get po -A
56NAMESPACE              NAME                                         READY   STATUS    RESTARTS      AGE
57kube-flannel           kube-flannel-ds-pjfww                        1/1     Running   1 (22h ago)   7d4h
58kube-flannel           kube-flannel-ds-pzt57                        1/1     Running   1 (22h ago)   7d4h
59kube-flannel           kube-flannel-ds-slqjx                        1/1     Running   1 (22h ago)   7d4h
60kube-system            coredns-7b884d5cb7-nvg5b                     1/1     Running   1 (22h ago)   7d4h
61kube-system            coredns-7b884d5cb7-zg9x6                     1/1     Running   1 (22h ago)   7d4h
62kube-system            etcd-master1                                 1/1     Running   1 (22h ago)   7d4h
63kube-system            kube-apiserver-master1                       1/1     Running   1 (22h ago)   7d4h
64kube-system            kube-controller-manager-master1              1/1     Running   1 (22h ago)   7d4h
65kube-system            kube-proxy-dqzq4                             1/1     Running   1 (22h ago)   7d4h
66kube-system            kube-proxy-jf46d                             1/1     Running   1 (22h ago)   7d4h
67kube-system            kube-proxy-xvmdd                             1/1     Running   1 (22h ago)   7d4h
68kube-system            kube-scheduler-master1                       1/1     Running   1 (22h ago)   7d4h
69kubernetes-dashboard   dashboard-metrics-scraper-64bcc67c9c-tm42j   1/1     Running   1 (22h ago)   7d4h
70kubernetes-dashboard   kubernetes-dashboard-5c8bd6b59-stxgx         1/1     Running   1 (22h ago)   7d4h
71[root@master1 ~]#

可以看到istio相关的3个pod资源被清除掉了。

清除istio-system

 1[root@master1 ~]#kubectl get ns
 2NAME                   STATUS   AGE
 3default                Active   7d4h
 4istio-system           Active   31h
 5kube-flannel           Active   7d4h
 6kube-node-lease        Active   7d4h
 7kube-public            Active   7d4h
 8kube-system            Active   7d4h
 9kubernetes-dashboard   Active   7d4h
10
11[root@master1 ~]#kubectl delete ns istio-system
12namespace "istio-system" deleted
13[root@master1 ~]#kubectl get ns
14NAME                   STATUS   AGE
15default                Active   7d4h
16kube-flannel           Active   7d4h
17kube-node-lease        Active   7d4h
18kube-public            Active   7d4h
19kube-system            Active   7d4h
20kubernetes-dashboard   Active   7d4h
21[root@master1 ~]#

1

推荐使用微信支付
微信支付二维码
推荐使用支付宝
支付宝二维码
最新文章

文档导航