一.模块概览

在本模块中,我们将了解如何将运行在虚拟机上的工作负载纳入istio服务网格。

向istio服务网格中引入虚拟机的前提是已经安装好了istio,关于istio的安装部署,请查看博客《Istio(二):在Kubernetes(k8s)集群上安装部署istio1.14》https://www.cnblogs.com/renshengdezheli/p/16836404.html

二.系统环境

服务器版本 docker软件版本 Kubernetes(k8s)集群版本 Istio软件版本 CPU架构
CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 Istio1.14 x86_64

Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点

服务器 操作系统版本 CPU架构 进程 功能描述
k8scloude1/192.168.110.130 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kube-apiserver,etcd,kube-scheduler,kube-controller-manager,kubelet,kube-proxy,coredns,calico k8s master节点
k8scloude2/192.168.110.129 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点
k8scloude3/192.168.110.128 CentOS Linux release 7.4.1708 (Core) x86_64 docker,kubelet,kube-proxy,calico k8s worker节点

三.虚拟机负载

3.1 虚拟机负载

如果我们有在虚拟机上运行的工作负载,我们可以将它们连接到 Istio 服务网格,使其成为网格的一部分

带有虚拟机的 Istio 服务网格有两种架构:单网络架构和多网络架构

3.2 单网络架构

在这种情况下,有一个单一的网络。Kubernetes 集群和在虚拟机上运行的工作负载都在同一个网络中,它们可以直接相互通信。

控制平面的流量(配置更新、证书签署)是通过 Gateway 发送的

虚拟机被配置了网关地址,所以它们在启动时可以连接到控制平面

3.3 多网络架构

多网络架构横跨多个网络。Kubernetes 集群在一个网络内,而虚拟机则在另一个网络内。这使得 Kubernetes 集群中的 Pod 和虚拟机上的工作负载无法直接相互通信。

所有的流量,控制平面和 pod 到工作负载的流量都流经网关,网关作为两个网络之间的桥梁。

3.4 Istio 中如何表示虚拟机工作负载?

在 Istio 服务网格中,有两种方式来表示虚拟机工作负载

工作负载组(WorkloadGroup 资源)类似于 Kubernetes 中的部署(Deployment),它代表了共享共同属性的虚拟机工作负载的逻辑组。

描述虚拟机工作负载的第二种方法是使用工作负载条目(WorkloadEntry 资源)。工作负载条目类似于 Pod,它代表了一个虚拟机工作负载的单一实例。

请注意,创建上述资源将不会提供或运行任何虚拟机工作负载实例。这些资源只是用来引用或指向虚拟机工作负载的。Istio 使用它们来了解如何适当地配置网格,将哪些服务添加到内部服务注册表中,等等。

为了将虚拟机添加到网格中,我们需要创建一个工作负载组,作为模板。然后,当我们配置并将虚拟机添加到网格中时,控制平面会自动创建一个相应的 WorkloadEntry。

我们已经提到,WorkloadEntry 的作用类似于 Pod。在添加虚拟机时,会创建 WorkloadEntry 资源,而当虚拟机的工作负载从网格中移除时,该资源会被自动删除。

除了 WorkloadEntry 资源外,我们还需要创建一个 Kubernetes 服务。创建一个 Kubernetes 服务给了我们一个稳定的主机名和 IP 地址,以便使用选择器字段访问虚拟机工作负载和 pod。这也使我们能够通过 DestinationRule 和 VirtualService 资源使用 Istio 的路由功能

四.实战:向istio Mesh中引入虚拟机

4.1 将虚拟机引入到 Istio Mesh

在这个实验中,我们将学习如何将虚拟机上运行的工作负载连接到 Kubernetes 集群上运行的 Istio 服务网格。Kubernetes 集群和虚拟机都将在谷歌云平台(GCP)上运行。我们将使用单一网络架构

在我们创建了一个 Kubernetes 集群后,我们可以下载、安装和配置 Istio。

4.2 在 Kubernetes 集群上安装 Istio

让我们下载 Istio 1.10.3。

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

下载了 Istio 后,我们可以使用 IstioOperator 来安装它,它可以设置网格 ID、集群名称和网络名称。网络名称将是空的,因为我们要用单一网络架构

让我们来设置几个环境变量,我们将在本实验中使用这些变量。

 export SERVICE_ACCOUNT="vm-sa"
export VM_APP="hello-vm"
export VM_NAMESPACE="vm-namespace"
export WORK_DIR="${HOME}/vmfiles"
export CLUSTER_NETWORK=""
export VM_NETWORK=""
export CLUSTER="Kubernetes"

我们还可以创建 $WORK_DIR,在这里我们将存储证书和其他我们必须复制到虚拟机上的文件。

 mkdir -p $WORK_DIR

接下来,我们将初始化 Istio Operator 并安装 Istio:

 getmesh istioctl operator init

一旦 Operator 被初始化,我们就可以创建 IstioOperator 资源,指定网格 ID、集群名称和网络,并安装 Istio

 cat <<EOF | kubectl apply -f -
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio
namespace: istio-system
spec:
values:
global:
meshID: mesh1
multiCluster:
clusterName: "${CLUSTER}"
network: "${CLUSTER_NETWORK}"
EOF

我们可以使用 kubectl get iop -n istio-system 命令来检查 Istio 安装状态何时变为健康

在下一步,我们将安装东西向网关。这是控制平面用来与虚拟机工作负载对话的网关,反之亦然。

gen-eastwest-gateway.sh 脚本是我们之前下载的 Istio 包的一部分。将文件夹改为 istio-1.10.3(或你解压 Istio 的文件夹)并运行以下命令:

 samples/multicluster/gen-eastwest-gateway.sh --single-cluster | istioctl install -y -f -

gen-eastwest-gateway.sh 脚本使用一个 IstioOperator 来部署一个额外的网关,名为 istio-eastwestgateway,并配置了服务端口。

我们可以通过查看 istio-system 命名空间中的 Kubernetes 服务来检查新网关。

最后,我们还需要配置网关,通过它来暴露控制平面(istiod)。我们可以通过部署 expose-istiod.yaml 文件来做到这一点:

 $ kubectl apply -n istio-system -f samples/multicluster/expose-istiod.yaml
gateway.networking.istio.io/istiod-gateway created
virtualservice.networking.istio.io/istiod-vs created

4.3 准备虚拟机命名空间和文件

对于虚拟机工作负载,我们必须创建一个单独的命名空间来存储 WorkloadEntry 资源和任何其他虚拟机工作负载相关的资源。此外,我们还必须导出集群环境文件、令牌、证书和其他我们必须转移到虚拟机上的文件

我们将把所有文件存放在我们在实验开始时创建的 $WORK_DIR 中。

让我们在同一命名空间中创建虚拟机命名空间和我们将用于虚拟机工作负载的服务账户

 $ kubectl create ns "${VM_NAMESPACE}"
namespace/vm-namespace created $ kubectl create serviceaccount "${SERVICE_ACCOUNT}" -n "${VM_NAMESPACE}"
serviceaccount/vm-sa created

现在我们可以创建一个 WorkloadGroup 资源并将其保存到 workloadgroup.yaml 中:

 cat <<EOF > workloadgroup.yaml
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadGroup
metadata:
name: "${VM_APP}"
namespace: "${VM_NAMESPACE}"
spec:
metadata:
labels:
app: "${VM_APP}"
template:
serviceAccount: "${SERVICE_ACCOUNT}"
network: "${VM_NETWORK}"
EOF

虚拟机需要关于集群和 Istio 的控制平面的信息来连接到它。为了生成所需文件,我们可以运行 getmesh istioctl x workload entry 命令。我们将所有生成的文件保存到 $WORK_DIR 中:

 $ getmesh istioctl x workload entry configure -f workloadgroup.yaml -o "${WORK_DIR}" --clusterID "${CLUSTER}"
Warning: a security token for namespace "vm-namespace" and service account "vm-sa" has been generated and stored at "/vmfiles/istio-token"
configuration generation into directory /vmfiles was successful

4.4 配置虚拟机

现在是时候创建和配置一个虚拟机了。我在 GCP 中运行这个虚拟机,就像 Kubernetes 集群一样。虚拟机使用的是 Debian GNU/Linux 10(Buster)镜像。确保你在防火墙部分勾选了 "允许 HTTP 流量",并且你有 SSH 访问该实例的权限。

在这个例子中,我们在 80 端口运行一个简单的 Python HTTP 服务器。你可以在不同的端口上配置任何其他服务。只要确保你配置了相应的安全和防火墙规则

  1. $WORK_DIR 中的文件复制到实例的主文件夹中。相应地替换 USERNAMEINSTANCE_IP
 $ scp $WORK_DIR/* [USERNAME]@[INSTANCE_IP]:~
Enter passphrase for key '/Users/peterj/.ssh/id_rsa':
bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
cluster.env 100% 589 12.6KB/s 00:00
hosts 100% 38 0.8KB/s 00:00
istio-token 100% 906 19.4KB/s 00:00
mesh.yaml 100% 667 14.4KB/s 00:00
root-cert.pem 100% 1094 23.5KB/s 00:00

或者,你可以使用 gcloud 命令和实例名称: gcloud compute scp --zone=us-west1-b ${WORK_DIR}/* [INSTANCE_NAME]:~

  1. SSH 进入实例,将根证书复制到 /etc/certs
 sudo mkdir -p /etc/certs
sudo cp root-cert.pem /etc/certs/root-cert.pem
  1. 拷贝 istio-token 文件到 /var/run/secrets/tokens 目录:
 sudo mkdir -p /var/run/secrets/tokens
sudo cp istio-token /var/run/secrets/tokens/istio-token
  1. 下载和安装 Istio sidecar 包:
 curl -LO https://storage.googleapis.com/istio-release/releases/1.10.3/deb/istio-sidecar.deb
sudo dpkg -i istio-sidecar.deb
  1. 拷贝 cluster.env/var/lib/istio/envoy/
 sudo cp cluster.env /var/lib/istio/envoy/cluster.env
  1. 将 Mesh 配置(mesh.yaml)添加到 /etc/istio/config/mesh
 sudo cp mesh.yaml /etc/istio/config/mesh
  1. 将 istiod host 添加到 /etc/hosts 文件中:
 sudo sh -c 'cat $(eval echo ~$SUDO_USER)/hosts >> /etc/hosts'
  1. /etc/certs/var/lib/istio/envoy 的所有者修改为 Istio proxy:
 sudo mkdir -p /etc/istio/proxy
sudo chown -R istio-proxy /var/lib/istio /etc/certs /etc/istio/proxy /etc/istio/config /var/run/secrets /etc/certs/root-cert.pem

以上都就绪后,就可以在虚拟机中启动 Istio:

 sudo systemctl start istio

此刻,虚拟机被配置为与 Kubernetes 集群中 Istio 的控制平面通信。

4.5 从虚拟机访问服务

让我们在 Kubernetes 集群中部署一个 Hello world 应用程序。首先,我们需要在 default 命名空间中启用自动 sidecar 注入:

 $ kubectl label namespace default istio-injection=enabled
namespace/default labeled

接下来,创建 Hello world 的部署和服务。

 apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
labels:
app: hello-world
spec:
replicas: 1
selector:
matchLabels:
app: hello-world
template:
metadata:
labels:
app: hello-world
spec:
containers:
- image: gcr.io/tetratelabs/hello-world:1.0.0
imagePullPolicy: Always
name: svc
ports:
- containerPort: 3000
---
kind: Service
apiVersion: v1
metadata:
name: hello-world
labels:
app: hello-world
spec:
selector:
app: hello-world
ports:
- port: 80
name: http
targetPort: 3000

将上述文件保存为 hello-world.yaml,并使用 kubectl apply -f hello-world.yaml 进行部署。

等待 Pod 准备好,然后回到虚拟机上,尝试访问 Kubernetes 服务:

 $ curl http://hello-world.default
Hello World

你可以从虚拟机上访问在你的 Kubernetes 集群内运行的任何服务。

4.6 在虚拟机上运行服务

我们也可以在虚拟机上运行一个工作负载。切换到实例上,运行一个简单的 Python HTTP 服务器:

 $ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

如果你试图直接 curl 到实例 IP,你会得到一个响应(目录列表)。:

 $ curl [INSTANCE_IP]
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dt
d">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
...

但我们要做的是将工作负载(Python HTTP 服务)添加到网格中。出于这个原因,我们在前面创建了虚拟机命名空间。所以让我们创建一个代表虚拟机工作负载的 Kubernetes 服务。注意,名称和标签值等于我们之前设置的 VM_APP 环境变量的值。不要忘记将服务部署到 VM_NAMESPACE

 apiVersion: v1
kind: Service
metadata:
name: hello-vm
labels:
app: hello-vm
spec:
ports:
- port: 80
name: http-vm
targetPort: 80
selector:
app: hello-vm

将上述文件保存为 hello-vm-service.yaml,并使用 kubectl apply -f hello-vm-service.yaml -n vm-namespace 将其部署到 VM 命名空间。

因为我们没有使用实验性的虚拟机自动注册,它将自动创建 WorkloadEntry 资源,我们需要手动创建它们

我们需要一个代表虚拟机工作负载的 WorkloadEntry 资源——该资源使用虚拟机服务账户(SERVICE_ACCOUNT)和标签中的应用程序名称(VM_APP)。

请注意,我们还需要获得虚拟机的内部 IP 地址,这样 Istio 就知道在哪里可以到达虚拟机。让我们把它存储在另一个环境变量中(确保用你的值替换 INSTANCE_NAMEZONE)。

 export VM_IP=$(gcloud compute instances describe [INSTANCE_NAME] --format='get(networkInterfaces[0].networkIP)' --zone=[ZONE])

我们现在可以创建 WorkloadEntry 资源:

 cat <<EOF > workloadentry.yaml
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadEntry
metadata:
name: ${VM_APP}
namespace: ${VM_NAMESPACE}
spec:
serviceAccount: ${SERVICE_ACCOUNT}
address: ${VM_IP}
labels:
app: ${VM_APP}
instance-id: vm1
EOF

将上述文件保存为 workloadentry.yaml,然后在 $VM_NAMESPACE 命名空间创建资源:

 kubectl apply -n ${VM_NAMESPACE} -f workloadentry.yaml

为了把虚拟机的工作负载加入到网格内,我们还需要定义 ServiceEntry:

 cat <<EOF > serviceentry.yaml
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: ${VM_APP}
spec:
hosts:
- ${VM_APP}
location: MESH_INTERNAL
ports:
- number: 80
name: http
protocol: HTTP
targetPort: 80
resolution: STATIC
workloadSelector:
labels:
app: ${VM_APP}

请注意,WorkloadEntry 和 ServiceEntry 在未来最终将自动创建。

$VM_NAMESPACE 中创建服务条目资源。

 kubectl apply -n ${VM_NAMESPACE} -f serviceentry.yaml

我们现在可以使用 Kubernetes 服务名称 hello-vm.vm-namespace 来访问虚拟机上的工作负载。让我们在集群内运行一个 Pod,并尝试从那里访问该服务:

 $ kubectl run curl --image=radial/busyboxplus:curl -i --tty
If you don't see a command prompt, try pressing enter.
[ root@curl:/ ]$

在你得到 Pod 中的命令提示后,你可以运行 curl 并访问工作负载。你应该看到一个目录列表的响应。同样地,你会注意到在 HTTP 服务器运行的实例上有一个日志条目:

 [ root@curl:/ ]$ curl hello-vm.vm-namespace
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dt
d">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
<body>
<h1>Directory listing for /</h1>
<hr>
...

Istio(十一):向istio服务网格中引入虚拟机的更多相关文章

  1. Istio(五):使用服务网格Istio进行流量路由

    目录 一.模块概览 二.系统环境 三.简单路由 3.1 简单路由 四.Subset和DestinationRule 4.1 Subset 和 DestinationRule 4.2 Destinati ...

  2. Lind.DDD.IoC(大叔推荐)~在服务定位器中引入IoC容器~容器的适配器

    回到目录 关于依赖倒置(DIP) 高层模块不依赖于低层模块的实现,而低层模块依赖于高层模块定义的接口,通俗的讲,就是高层模块定义接口,低层模块负责实现,这在我们实际开发中经常被用到,层与层之间引用,经 ...

  3. Service Mesh服务网格新生代--Istio(转)

    万字解读:Service Mesh服务网格新生代--Istio  官网地址:https://preliminary.istio.io/zh/docs/concepts/security/ Servic ...

  4. 【译文连载】 理解Istio服务网格(第一章 概述)

    书籍英文版下载链接为 https://developers.redhat.com/books/introducing-istio-service-mesh-microservices/,作者 Burr ...

  5. 【译文连载】 理解Istio服务网格(第三章 流控)

    第3章 流控.............................................................................................. ...

  6. 【译文连载】 理解Istio服务网格(第六章 可观测性)

    全书目录 第一章 概述 第二章 安装 第三章 流控 第四章 服务弹性 第五章 混沌测试 ​本文目录 第6章 可观测性 6.1 分布式调用链跟踪(tracing) 6.1.1 基本概念 6.1.2 Ja ...

  7. Service Mesh服务网格新生代——Istio

    Istio 是什么?使用云平台可以为组织提供丰富的好处.然而,不可否认的是,采用云可能会给 DevOps 团队带来压力.开发人员必须使用微服务已满足应用的可移植性,同时运营商管理了极其庞大的混合和多云 ...

  8. 服务网格Istio初探

    1. 服务网格Istio初探 1.1. 什么是Istio 它是一个完全开源的服务网格.什么是服务网格? 这个术语通常用于描述构成这些应用程序的微服务网络以及应用之间的交互.随着规模和复杂性的增长,服务 ...

  9. 【译文连载】 理解Istio服务网格(第七章 安全)

    全书目录 第一章 概述 第二章 安装 第三章 流控 第四章 服务弹性 第五章 混沌测试 第六章 可观测性 本文目录 第7章 安全 7.1 身份认证 7.1.1 Kubernetes上的Istio的身份 ...

随机推荐

  1. MyBatis-Plus 代码生成

    MyBatis-Plus官网的代码生成器配置不是特别全,在此整理了较为完整的配置,供自己和大家查阅学习. // 代码生成器 AutoGenerator mpg = new AutoGenerator( ...

  2. 浅谈MySQL的sql_mode

    SQL mode 今天我们来分享一下MySQL的SQL mode , 这也是我们比较容易忽略的一点,我们在一开始安装数据库的时候其实就要先考虑要保留哪些SQL mode,去除哪些,合理的配置能够减少很 ...

  3. matery添加加载动画

    1.在主题 /layout/_partial/目录新建一个loading-pages.ejs 内容如下: <style type="text/css" lang=" ...

  4. 2019 CSP-S Ⅱ 游记

    day0(试机) 第零天,重新打了一遍头文件和读优,熟悉了一下就匆匆走了. day1 T1一看到先把二分打了,然后发现long long要爆,好慌 主要是基础知识不够扎实,不知道unsigned lo ...

  5. HTML初学者小知识2

    网页内嵌 代码以及演示如下 代码 <div id="tab_1"> <iframe src="div.html" height="5 ...

  6. ubuntu下安装python

    一.安装python3.6 sudo add-apt-repository ppa:jonathonf/python-3.6 如显示不能添加"'ppa:~jonathonf/ubuntu/p ...

  7. std::atomic和std::mutex区别

    ​ ​std::atomic介绍​ ​模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.​在多线程调用下,利用std::atomic可实 ...

  8. PostgreSQL 大对象导出报错问题分析

    1.前言 在处理用户问题过程遇到一个问题.用户通过pg_dump导出 bytea 对象时,当行的大小超过 1G时,会报错: [v8r6c5b41@dbhost01 ~]$ sys_dump -t t1 ...

  9. KingbaseES 绑定变量与游标共享

    对于重复执行的SQL,需要使用绑定变量,避免SQL的重复解析.但是,并不是说使用了绑定变量,就一定能避免硬解析.具体可以参见:https://www.cnblogs.com/kingbase/p/16 ...

  10. logstash接受checkpoint防火墙日志并用ruby分词

    直接上logstahs配置文件 input{ syslog{ type => "syslog" port => 514 } } filter { grok { matc ...