2. 环境准备:Kubernetes集群搭建、Istio服务网格安装、示例微服务应用部署

本章是实战课程的基石。我们将完成三部分环境搭建:一个多节点Kubernetes集群、一套完整Istio服务网格,以及一个支持多租户隔离的示例微服务应用。所有后续的蓝绿部署、滚动升级与故障排查都将在此环境中进行。

2.1 环境拓扑概览

下图展示了本次实战环境的整体架构。集群包含1个控制平面节点和2个工作节点,Istio控制面独立部署,示例应用包含三个微服务,并通过Kubernetes Namespace实现租户隔离。

实战环境整体架构图 实战环境整体架构图 Kubernetes 集群边界 控制平面节点 kube-apiserver kube-scheduler kube-controller-manager etcd 工作节点 1 kubelet kube-proxy 容器运行时 租户A Pods 工作节点 2 kubelet kube-proxy 容器运行时 租户B Pods Istio 控制面 (istio-system Namespace) istiod (Pilot | Citadel | Galley) Ingress Gateway | Egress Gateway 租户A Namespace (tenant-a) frontend-v1 | backend-v1 | database Istio Sidecar (Envoy) 注入 租户B Namespace (tenant-b) frontend-v1 | backend-v1 | database Istio Sidecar (Envoy) 注入
环境说明:本课程使用 Kubernetes v1.28 和 Istio 1.20 进行演示。租户隔离通过 Kubernetes Namespace 实现,每个租户拥有独立的微服务实例和 Istio 配置。

2.2 Kubernetes集群搭建

我们使用 kubeadm 工具搭建一个包含1个控制平面节点和2个工作节点的集群。所有节点操作系统为 Ubuntu 22.04 LTS,容器运行时使用 containerd。

2.2.1 节点规格与网络规划

节点角色 主机名 IP地址 CPU 内存 磁盘
控制平面 k8s-master 192.168.1.10 4核 8GB 50GB
工作节点1 k8s-node1 192.168.1.11 4核 8GB 50GB
工作节点2 k8s-node2 192.168.1.12 4核 8GB 50GB

2.2.2 集群初始化步骤

  1. 所有节点基础配置:关闭swap、配置containerd、加载内核模块、设置iptables。
  2. 控制平面初始化:执行 kubeadm init,指定Pod网络CIDR为 10.244.0.0/16。
  3. 安装CNI插件:部署Flannel作为Pod网络插件。
  4. 工作节点加入:使用 kubeadm join 命令将两个工作节点加入集群。
  5. 验证集群状态:执行 kubectl get nodes 确认所有节点状态为 Ready。
关键命令示例:
# 控制平面初始化
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.10

# 配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 安装Flannel CNI
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

# 工作节点加入(在控制平面获取)
kubeadm join 192.168.1.10:6443 -- <> --discovery--ca-cert-hash sha256:<hash>

2.3 Istio服务网格安装

Istio 安装采用 istioctl 命令行工具,使用 demo 配置文件以启用完整的可观测性和流量管理功能。

2.3.1 安装步骤

  1. 下载Istio:从官方GitHub Release页面下载 istio-1.20.0-linux-amd64.tar.gz。
  2. 安装istioctl:将 istioctl 二进制文件复制到 /usr/local/bin。
  3. 执行安装:运行 istioctl install --set profile=demo -y。
  4. 注入Sidecar:为租户Namespace启用自动注入 kubectl label namespace tenant-a istio-injection=enabled。
  5. 验证安装:检查 istio-system Namespace下的Pod状态。
注意:生产环境应使用 default 或自定义Profile。本课程使用 demo Profile是为了方便演示流量管理和可观测性功能。

2.3.2 Istio核心组件清单

组件 Pod名称 功能描述
istiod istiod-xxxxx 控制面核心,包含Pilot、Citadel、Galley
Ingress Gateway istio-ingressgateway-xxxxx 南北向流量入口,接收外部请求
Egress Gateway istio-egressgateway-xxxxx 南北向流量出口,控制对外访问
Prometheus prometheus-xxxxx 指标收集与存储
Kiali kiali-xxxxx 服务网格可视化控制台

2.4 示例微服务应用部署

我们设计了一个模拟电商场景的微服务应用,包含三个服务:frontend(前端)、backend(后端API)和 database(数据库)。每个租户拥有独立的一套服务实例。

2.4.1 应用架构

示例微服务应用架构图 示例微服务应用架构图(单租户视角) 外部请求 Istio Ingress Gateway frontend Node.js / 端口8080 backend Go / 端口8080 database MySQL / 端口3306 每个租户独立部署一套 frontend + backend + database,通过 Namespace 隔离 服务间通信通过 Istio Sidecar (Envoy) 代理,支持灰度发布和流量管理

2.4.2 部署清单

以下为 tenant-a Namespace 下的部署清单示例。tenant-b 的部署结构相同,仅 Namespace 名称不同。

frontend 部署 (frontend-deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend-v1
  namespace: tenant-a
  labels:
    app: frontend
    version: v1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
      version: v1
  template:
    metadata:
      labels:
        app: frontend
        version: v1
    spec:
      containers:
      - name: frontend
        image: registry.example.com/frontend:v1
        ports:
        - containerPort: 8080
        env:
        - name: BACKEND_URL
          value: "http://backend.tenant-a.svc.cluster.local:8080"
---
apiVersion: v1
kind: Service
metadata:
  name: frontend
  namespace: tenant-a
spec:
  selector:
    app: frontend
  ports:
  - port: 8080
    targetPort: 8080
backend 部署 (backend-deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend-v1
  namespace: tenant-a
  labels:
    app: backend
    version: v1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: backend
      version: v1
  template:
    metadata:
      labels:
        app: backend
        version: v1
    spec:
      containers:
      - name: backend
        image: registry.example.com/backend:v1
        ports:
        - containerPort: 8080
        env:
        - name: DB_HOST
          value: "database.tenant-a.svc.cluster.local"
        - name: DB_PORT
          value: "3306"
---
apiVersion: v1
kind: Service
metadata:
  name: backend
  namespace: tenant-a
spec:
  selector:
    app: backend
  ports:
  - port: 8080
    targetPort: 8080

2.4.3 租户隔离验证

部署完成后,执行以下命令验证租户隔离效果:

# 查看租户A的Pod
kubectl get pods -n tenant-a

# 查看租户B的Pod
kubectl get pods -n tenant-b

# 验证服务间通信(在租户A的frontend Pod内)
kubectl exec -n tenant-a deploy/frontend-v1 -- curl -s http://backend.tenant-a.svc.cluster.local:8080/health

# 验证跨租户隔离(租户A无法访问租户B的服务)
kubectl exec -n tenant-a deploy/frontend-v1 -- curl -s --connect-timeout 3 http://backend.tenant-b.svc.cluster.local:8080/health
预期结果:租户A的frontend可以正常访问同租户的backend服务,但无法访问租户B的backend服务。跨Namespace的Service访问默认被Kubernetes网络策略和Istio的授权策略双重限制。

2.5 环境验证清单

在进入下一章之前,请确保以下所有项目均已通过验证:

验证项 验证命令 预期结果
集群节点状态 kubectl get nodes 3个节点均为 Ready 状态
Istio控制面 kubectl get pods -n istio-system istiod、ingressgateway等Pod均为 Running
租户A应用 kubectl get all -n tenant-a frontend、backend、database Pod运行正常
租户B应用 kubectl get all -n tenant-b frontend、backend、database Pod运行正常
Sidecar注入 kubectl get pods -n tenant-a -o jsonpath='{.items[*].spec.containers[*].name}' 每个Pod包含 istio-proxy 容器
租户隔离 跨Namespace访问测试 跨租户访问被拒绝
常见问题排查:
  • 如果Pod处于 Pending 状态,检查节点资源是否充足或PVC是否可用。
  • 如果Sidecar未注入,确认Namespace标签 istio-injection=enabled 已正确设置。
  • 如果跨租户访问未被拒绝,检查Istio的PeerAuthentication和AuthorizationPolicy配置。