Istio 是一个用于连接、保护和监控分布式应用程序的便捷工具。 Istio 使用各种技术来大规模运行和管理软件,包括用于打包应用程序代码和部署依赖项的容器,以及用于管理这些容器的 Kubernetes。 因此,要使用 Istio,您必须了解基于这些技术的具有多种服务的应用程序是如何工作的 无 伊斯蒂奥。 如果您已经熟悉这些工具和概念,请随意跳过本教程并直接进入参考资料部分
这是一个分步指南,我们将逐步介绍从源代码到 GKE 容器的整个过程,通过示例让您对这些技术有基本的了解。 您还将看到 Istio 如何利用这些技术的力量。 这假设您对容器、Kubernetes、服务网格或 Istio 一无所知。
任务
在本教程中,您将完成以下任务:
- 学习具有多种服务的简单 hello world 应用程序。
- 从源代码运行应用程序。
- 将应用程序打包在容器中。
- 创建 Kubernetes 集群。
- 将容器部署到集群中。
在你开始之前
按照说明启用 Kubernetes Engine API:
- 前往
Kubernetes 引擎页面 在 Google Cloud Platform 控制台中。 - 创建或选择一个项目。
- 等待API及相关服务启用。 这可能需要几分钟的时间。
- 确保为您的 Google Cloud Platform 项目设置结算信息。
了解如何启用计费 .
在本教程中,您可以使用 Cloud Shell,它会准备虚拟机
选项 A:使用 Cloud Shell
使用 Cloud Shell 的好处:
- Python 2 和 Python 3 开发环境(包括 的virtualenv)已完全配置。
- 命令行工具 云, 搬运工人, 混帐 и Kubectl,我们将使用的已经安装。
- 有几个可供选择
文本编辑器 :代码编辑器 ,它会打开并在 Cloud Shell 窗口顶部显示编辑图标。- Emacs、Vim 或 Nano,从 Cloud Shell 中的命令行打开。
使用
- 转到 GCP 控制台。
- 点击按钮 激活 Cloud Shell (激活 Cloud Shell)位于 GCP 控制台窗口顶部。
在下部
选项 B:在本地使用命令行工具
如果您将在运行 Linux 或 macOS 的计算机上工作,则需要配置和安装以下组件:
-
-
安装云SDK 使用命令行工具 云. -
集 Kubectl - 用于使用的命令行工具
Kubernetes .gcloud components install kubectl
-
集
Docker 社区版 (CE) 。 您将使用命令行工具 搬运工人为示例应用程序创建容器映像。 -
安装工具
Git 版本控制 从 GitHub 获取示例应用程序。
下载示例代码
-
下载源代码 你好服务器:
git clone https://github.com/GoogleCloudPlatform/istio-samples
-
进入示例代码目录:
cd istio-samples/sample-apps/helloserver
探索具有多种服务的应用程序
示例应用程序是用 Python 编写的,由两个组件组成,这两个组件使用
- 服务器:具有一个端点的简单服务器 得到, /,它将“hello world”打印到控制台。
- 负载生成器:将流量发送到的脚本 服务器,每秒的请求数是可配置的。
从源代码运行应用程序
要探索示例应用程序,请在 Cloud Shell 或您的计算机上运行它。
1) 在目录中 istio-samples/sample-apps/helloserver 跑 服务器:
python3 server/server.py
当您运行 服务器 显示如下:
INFO:root:Starting server...
2)打开另一个终端窗口来发送请求到 服务器。 如果您使用的是 Cloud Shell,请单击添加图标以打开另一个会话。
3) 发送请求至 服务器:
curl http://localhost:8080
服务器回复:
Hello World!
4) 从您下载示例代码的目录中,转到包含以下内容的目录 负载生成器:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/loadgen
5)创建以下环境变量:
export SERVER_ADDR=http://localhost:8080
export REQUESTS_PER_SECOND=5
6)运行 的virtualenv:
virtualenv --python python3 env
7)激活虚拟环境:
source env/bin/activate
8) 设定要求 负载生成器:
pip3 install -r requirements.txt
9)运行 负载生成器:
python3 loadgen.py
当您运行 负载生成器 显示类似以下消息的内容:
Starting loadgen: 2019-05-20 10:44:12.448415
5 request(s) complete to http://localhost:8080
在另一个终端窗口中 服务器 将以下消息输出到控制台:
127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 -
INFO:root:GET request,
Path: /
Headers:
Host: localhost:8080
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*
从网络角度来看,整个应用程序在单个主机(本地计算机或 Cloud Shell 虚拟机)上运行。 因此你可以使用 本地将请求发送至 服务器.
10) 停止 负载生成器 и 服务器, 进入 Ctrl-c 在每个终端窗口中。
11) 在终端窗口中 负载生成器 停用虚拟环境:
deactivate
将应用程序打包到容器中
要在 GKE 上运行应用程序,您需要打包示例应用程序 - 服务器 и 负载生成器 - 在
要将应用程序打包到容器中,您需要 Dockerfile. Dockerfile 是一个文本文件,定义了用于将应用程序的源代码及其依赖项构建到的命令
例子已经有 Dockerfile 为 服务器 и 负载生成器 以及收集图像所需的所有命令。 以下 - Dockerfile 为 服务器:
FROM python:3-slim as base
FROM base as builder
RUN apt-get -qq update
&& apt-get install -y --no-install-recommends
g++
&& rm -rf /var/lib/apt/lists/*
# Enable unbuffered logging
FROM base as final
ENV PYTHONUNBUFFERED=1
RUN apt-get -qq update
&& apt-get install -y --no-install-recommends
wget
WORKDIR /helloserver
# Grab packages from builder
COPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/
# Add the application
COPY . .
EXPOSE 8080
ENTRYPOINT [ "python", "server.py" ]
- 团队 FROM python:3-slim 作为基础 告诉 Docker 使用最新的
Python 3 图像 作为基础。 - 团队 复制。 。 将源文件复制到当前工作目录(在我们的例子中仅 服务器.py) 到容器的文件系统。
- 入口点 定义用于启动容器的命令。 在我们的例子中,该命令与您以前运行的命令几乎相同 服务器.py 来自源代码。
- 团队 暴露 表示 服务器 等待通过端口的数据 8080。 这支球队不是
提供端口 。 这是打开端口所需的某种文档 8080 启动容器时。
准备容器化您的应用程序
1) 设置以下环境变量。 代替 项目ID 添加到您的 GCP 项目 ID。
export PROJECT_ID="PROJECT_ID"
export GCR_REPO="preparing-istio"
使用价值观 项目ID и GCR_REPO 您在构建 Docker 映像时对其进行标记并将其推送到私有容器注册表。
2)为命令行工具设置默认GCP项目 云.
gcloud config set project $PROJECT_ID
3)设置命令行工具的默认区域 云.
gcloud config set compute/zone us-central1-b
4) 确保GCP项目中启用了ContainerRegistry服务。
gcloud services enable containerregistry.googleapis.com
容器化服务器
-
进入示例所在目录 服务器:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/
-
使用组装图像 Dockerfile 以及您之前定义的环境变量:
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .
参数 -t 代表 Docker 标签。 这是部署容器时使用的映像的名称。
- 将镜像上传到容器镜像仓库:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1
loadgen的容器化
1)进入示例所在目录 负载生成器:
cd ../loadgen
2)采集图像:
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 .
3)将镜像上传到容器镜像仓库:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1
查看图像列表
查看存储库中的图像列表并验证图像是否已上传:
gcloud container images list --repository gcr.io/$PROJECT_ID/preparing-istio
该命令显示新上传的图像的名称:
NAME
gcr.io/PROJECT_ID/preparing-istio/helloserver
gcr.io/PROJECT_ID/preparing-istio/loadgen
创建 GKE 集群。
这些容器可以在 Cloud Shell 虚拟机或使用以下命令的计算机上运行 码头运行。 但在生产环境中,您需要一种集中编排容器的方法。 例如,您需要一个确保容器始终运行的系统,并且您需要一种在流量增加时扩展和启动其他容器实例的方法。
要运行容器化应用程序,您可以使用
创建 GKE 集群:
1)创建集群:
gcloud container clusters create istioready
--cluster-version latest
--machine-type=n1-standard-2
--num-nodes 4
团队 云 在您指定的 GCP 项目和默认区域中创建 istioready 集群。 要运行 Istio,我们建议至少有 4 个节点和一个虚拟机
该团队在几分钟内创建了集群。 当集群准备就绪时,命令输出如下所示
2) 在命令行工具中提供凭据
gcloud container clusters get-credentials istioready
3)现在您可以通过以下方式与 Kubernetes 通信 Kubectl。 例如,以下命令可以查看节点的状态:
kubectl get nodes
该命令生成节点列表:
NAME STATUS ROLES AGE VERSION
gke-istoready-default-pool-dbeb23dc-1vg0 Ready <none> 99s v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-36z5 Ready <none> 100s v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-fj7s Ready <none> 99s v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-wbjw Ready <none> 99s v1.13.6-gke.13
Kubernetes 关键概念
该图显示了 GKE 上的一个应用程序:
在 GKE 中部署容器之前,请先了解 Kubernetes 的关键概念。 如果您想了解更多信息,最后有链接。
- 节点和集群。 在 GKE 中,节点就是虚拟机。 在其他 Kubernetes 平台上,节点可以是计算机或虚拟机。 集群是节点的集合,可以将其视为部署容器化应用程序的单个单元。
- 豆荚。 在 Kubernetes 中,容器在 Pod 中运行。 Kubernetes 中的 Pod 是一个不可分割的单元。 一个 Pod 包含一个或多个容器。 您部署服务器容器并 负载生成器 在单独的豆荚中。 当一个 pod 中有多个容器时(例如应用程序服务器和
代理服务器 ),容器作为单个实体进行管理并共享 Pod 资源。 - 部署。 在 Kubernetes 中,部署是一个对象,它是相同 Pod 的集合。 部署会启动分布在集群节点上的多个 Pod 副本。 部署会自动替换失败或无响应的 Pod。
- 库伯内特服务。 在 GKE 中运行应用程序代码时,之间的连接 负载生成器 и 服务器。 当您在 Cloud Shell 虚拟机或桌面上启动服务时,您将请求发送到 服务器 поадресу 本地主机:8080。 部署到 GKE 后,Pod 将在可用节点上执行。 默认情况下,您无法控制 pod 运行在哪个节点上,因此您
豆荚 没有永久的IP地址。
获取 IP 地址 服务器,您需要在 Pod 之上定义一个网络抽象。 就是这样库伯内特服务 。 Kubernetes 服务为一组 Pod 提供持久端点。 有几个服务类型 . 服务器 使用 负载均衡器,提供外部 IP 地址进行联系 服务器 来自集群外部。
Kubernetes 还有一个内置的 DNS 系统,用于分配 DNS 名称(例如, helloserver.default.cluster.local) 服务。 因此,集群内的 Pod 可以通过固定地址与集群中的其他 Pod 进行通信。 DNS 名称不能在集群外部使用,例如在 Cloud Shell 中或在计算机上。
Kubernetes 清单
当您从源代码运行应用程序时,您使用了命令式命令 python3
服务器.py
命令式意味着一个动词:“做这个”。
Kubernetes 使用
您在清单或文件中指示所需的状态
该示例包含一个 YAML 文件 服务器 и 负载生成器。 每个 YAML 文件指定部署对象和 Kubernetes 服务的所需状态。
服务器.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloserver
spec:
selector:
matchLabels:
app: helloserver
replicas: 1
template:
metadata:
labels:
app: helloserver
spec:
terminationGracePeriodSeconds: 5
restartPolicy: Always
containers:
- name: main
image: gcr.io/google-samples/istio/helloserver:v0.0.1
imagePullPolicy: Always
- 样 表示对象的类型。
- 元数据.名称 指定部署名称。
- 第一场 规格 包含所需状态的描述。
- 规格复制品 指示所需的 Pod 数量。
- 部分 规格模板 定义一个 Pod 模板。 Pod规范中有一个字段 图片,指定需要从容器注册表中提取的镜像的名称。
该服务定义如下:
apiVersion: v1
kind: Service
metadata:
name: hellosvc
spec:
type: LoadBalancer
selector:
app: helloserver
ports:
- name: http
port: 80
targetPort: 8080
- 负载均衡器:客户端将请求发送到负载均衡器的 IP 地址,该负载均衡器具有持久 IP 地址并且可从集群外部访问。
- 目标端口: 正如你所记得的,团队 曝光 8080 в Dockerfile 没有提供端口。 您提供端口 8080以便您可以联系容器 服务器 集群外。 在我们的例子中 hellosvc.default.cluster.local:80 (简称: 你好) 对应端口 8080 Pod IP 地址 你好服务器.
- 端口:这是集群中其他服务将发送请求的端口号。
loadgen.yaml
部署对象到 loadgen.yaml 看起来像 服务器.yaml。 不同之处在于部署对象包含一个部分 ENV。 它定义了所需的环境变量 负载生成器 以及您在从源代码运行应用程序时安装的。
apiVersion: apps/v1
kind: Deployment
metadata:
name: loadgenerator
spec:
selector:
matchLabels:
app: loadgenerator
replicas: 1
template:
metadata:
labels:
app: loadgenerator
spec:
terminationGracePeriodSeconds: 5
restartPolicy: Always
containers:
- name: main
image: gcr.io/google-samples/istio/loadgen:v0.0.1
imagePullPolicy: Always
env:
- name: SERVER_ADDR
value: "http://hellosvc:80/"
- name: REQUESTS_PER_SECOND
value: "10"
resources:
requests:
cpu: 300m
memory: 256Mi
limits:
cpu: 500m
memory: 512Mi
时间 负载生成器 不接受该字段的传入请求 类型 不明 集群IP。 此类型提供集群中的服务可以使用的持久 IP 地址,但此 IP 地址不会暴露给外部客户端。
apiVersion: v1
kind: Service
metadata:
name: loadgensvc
spec:
type: ClusterIP
selector:
app: loadgenerator
ports:
- name: http
port: 80
targetPort: 8080
在 GKE 中部署容器
1)进入示例所在目录 服务器:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/
2) 打开 服务器.yaml 在文本编辑器中。
3) 替换字段中的名称 图片 添加到您的 Docker 镜像的名称。
image: gcr.io/PROJECT_ID/preparing-istio/helloserver:v0.0.1
代替 项目ID 添加到您的 GCP 项目 ID。
4)保存并关闭 服务器.yaml.
5)将YAML文件部署到Kubernetes:
kubectl apply -f server.yaml
成功完成后,该命令会生成以下代码:
deployment.apps/helloserver created
service/hellosvc created
6)进入所在目录 负载生成器:
cd ../loadgen
7) 打开 loadgen.yaml 在文本编辑器中。
8) 替换字段中的名称 图片 添加到您的 Docker 镜像的名称。
image: gcr.io/PROJECT_ID/preparing-istio/loadgenv0.0.1
代替 项目ID 添加到您的 GCP 项目 ID。
9)保存并关闭 loadgen.yaml,关闭文本编辑器。
10)将YAML文件部署到Kubernetes:
kubectl apply -f loadgen.yaml
成功完成后,该命令会生成以下代码:
deployment.apps/loadgenerator created
service/loadgensvc created
11) 检查 Pod 的状态:
kubectl get pods
该命令显示状态:
NAME READY STATUS RESTARTS AGE
helloserver-69b9576d96-mwtcj 1/1 Running 0 58s
loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
12) 从pod中提取应用程序日志 负载生成器. 代替 POD_ID 到上一个答案中的标识符。
kubectl logs loadgenerator-POD_ID
13) 获取外部IP地址 你好:
kubectl get service
命令响应看起来像这样:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m
kubernetes ClusterIP 10.81.0.1 <none> 443/TCP 93m
loadgensvc ClusterIP 10.81.15.155 <none> 80/TCP 4m52s
14) 发送请求至 你好: 代替 外部IP 到外部IP地址 你好.
curl http://EXTERNAL_IP
让我们来挑战 Istio
您已经将应用程序部署到 GKE。 负载生成器 可以使用 Kubernetes DNS(你好:80) 将请求发送至 服务器您可以将请求发送至 服务器 通过外部 IP 地址。 尽管 Kubernetes 有很多功能,但缺少一些有关服务的信息:
- 服务如何交互? 服务之间有哪些关系? 服务之间的流量如何流动? 你知道吗 负载生成器 发送请求至 服务器,但假设您对应用程序一无所知。 为了回答这些问题,我们来看看 GKE 中正在运行的 pod 列表。
- 指标。 多久 服务器 响应传入的请求? 服务器每秒接收多少个请求? 它会给出错误信息吗?
- 安全信息。 之间的交通 负载生成器 и 服务器 刚刚经过 HTTP 或者
传输层安全协议 ?
Istio 回答了所有这些问题。 为此,Istio 放置了一个 sidecar 代理
Envoy 代理之间的连接形成服务网格。 服务网格架构在 Kubernetes 之上提供了一个控制层。
由于 Envoy 代理在自己的容器中运行,因此 Istio 可以安装在 GKE 集群之上,几乎无需更改应用程序代码。 但是您已经做了一些工作来让您的应用程序准备好由 Istio 管理:
- 适用于所有集装箱的服务。 至部署 服务器 и 负载生成器 与 Kubernetes 服务绑定。 甚至 负载生成器,不接收传入请求,有服务。
- 服务中的端口必须有名称。 尽管服务端口可以在 GKE 中保留未命名,但 Istio 要求您指定
端口名称 按照他的协议。 在 YAML 文件中的端口 服务器 被称为 HTTP因为服务器使用协议 HTTP。 如果 服务 旧 远程过程调用,您可以将端口命名为 gpc. - 部署已标记。 因此,您可以使用 Istio 的流量管理功能,例如在同一服务的版本之间拆分流量。
安装 Istio
有两种方法安装 Istio。 能
选择一个选项,查看相应的指南,然后按照说明在集群上安装 Istio。 如果您想将 Istio 与新部署的应用程序一起使用,
清洁的
为了避免向您的 Google Cloud Platform 帐户收取本教程中使用的资源费用,请在安装 Istio 并使用示例应用程序后删除容器集群。 这将删除所有集群资源,例如计算实例、磁盘和网络资源。
接下来是什么?
-
探索以下技术:
-
探索以下工具:
-
学习 Kubernetes 概念:
来源: habr.com