为 Istio 准备应用程序

为 Istio 准备应用程序

Istio 是一个用于连接、保护和监控分布式应用程序的便捷工具。 Istio 使用各种技术来大规模运行和管理软件,包括用于打包应用程序代码和部署依赖项的容器,以及用于管理这些容器的 Kubernetes。 因此,要使用 Istio,您必须了解基于这些技术的具有多种服务的应用程序是如何工作的 伊斯蒂奥。 如果您已经熟悉这些工具和概念,请随意跳过本教程并直接进入参考资料部分 在 Google Kubernetes Engine (GKE) 上安装 Istio 或安装扩展 GKE 上的 Istio.

这是一个分步指南,我们将逐步介绍从源代码到 GKE 容器的整个过程,通过示例让您对这些技术有基本的了解。 您还将看到 Istio 如何利用这些技术的力量。 这假设您对容器、Kubernetes、服务网格或 Istio 一无所知。

任务

在本教程中,您将完成以下任务:

  1. 学习具有多种服务的简单 hello world 应用程序。
  2. 从源代码运行应用程序。
  3. 将应用程序打包在容器中。
  4. 创建 Kubernetes 集群。
  5. 将容器部署到集群中。

在你开始之前

按照说明启用 Kubernetes Engine API:

  1. 前往 Kubernetes 引擎页面 在 Google Cloud Platform 控制台中。
  2. 创建或选择一个项目。
  3. 等待API及相关服务启用。 这可能需要几分钟的时间。
  4. 确保为您的 Google Cloud Platform 项目设置结算信息。 了解如何启用计费.

在本教程中,您可以使用 Cloud Shell,它会准备虚拟机 Google 计算引擎中的 g1-small 使用基于 Debian 的 Linux,或者 Linux 或 macOS 计算机。

选项 A:使用 Cloud Shell

使用 Cloud Shell 的好处:

  • Python 2 和 Python 3 开发环境(包括 的virtualenv)已完全配置。
  • 命令行工具 , 搬运工人, 混帐 и Kubectl,我们将使用的已经安装。
  • 有几个可供选择 文本编辑器:
    1. 代码编辑器,它会打开并在 Cloud Shell 窗口顶部显示编辑图标。
    2. Emacs、Vim 或 Nano,从 Cloud Shell 中的命令行打开。

使用 云壳:

  1. 转到 GCP 控制台。
  2. 点击按钮 激活 Cloud Shell (激活 Cloud Shell)位于 GCP 控制台窗口顶部。

为 Istio 准备应用程序

在下部 GCP 控制台 带有命令行的 Cloud Shell 会话将在新窗口中打开。

为 Istio 准备应用程序

选项 B:在本地使用命令行工具

如果您将在运行 Linux 或 macOS 的计算机上工作,则需要配置和安装以下组件:

  1. 定制 Python 3 和 Python 2 开发环境.

  2. 安装云SDK 使用命令行工具 .

  3. Kubectl - 用于使用的命令行工具 Kubernetes.

    gcloud components install kubectl

  4. Docker 社区版 (CE)。 您将使用命令行工具 搬运工人为示例应用程序创建容器映像。

  5. 安装工具 Git 版本控制从 GitHub 获取示例应用程序。

下载示例代码

  1. 下载源代码 你好服务器:

    git clone https://github.com/GoogleCloudPlatform/istio-samples

  2. 进入示例代码目录:

    cd istio-samples/sample-apps/helloserver

探索具有多种服务的应用程序

示例应用程序是用 Python 编写的,由两个组件组成,这两个组件使用 REST的:

  • 服务器:具有一个端点的简单服务器 得到, /,它将“hello world”打印到控制台。
  • 负载生成器:将流量发送到的脚本 服务器,每秒的请求数是可配置的。

为 Istio 准备应用程序

从源代码运行应用程序

要探索示例应用程序,请在 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 是一个文本文件,定义了用于将应用程序的源代码及其依赖项构建到的命令 Docker 镜像。 构建完成后,您可以将映像上传到容器注册表,例如 Docker Hub 或 集装箱登记处.

例子已经有 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

容器化服务器

  1. 进入示例所在目录 服务器:

    cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/

  2. 使用组装图​​像 Dockerfile 以及您之前定义的环境变量:

    docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .

参数 -t 代表 Docker 标签。 这是部署容器时使用的映像的名称。

  1. 将镜像上传到容器镜像仓库:
    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 是一个容器编排平台,可将虚拟机聚合到集群中。 每个虚拟机称为一个节点。 GKE集群基于开源Kubernetes集群管理系统。 Kubernetes 提供了与集群交互的机制。

创建 GKE 集群:

1)创建集群:

gcloud container clusters create istioready 
  --cluster-version latest 
  --machine-type=n1-standard-2 
  --num-nodes 4

团队 在您指定的 GCP 项目和默认区域中创建 istioready 集群。 要运行 Istio,我们建议至少有 4 个节点和一个虚拟机 n1-标准-2.

该团队在几分钟内创建了集群。 当集群准备就绪时,命令输出如下所示 сообщение.

2) 在命令行工具中提供凭据 Kubectl使用它来管理集群:

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 上的一个应用程序:

为 Istio 准备应用程序

在 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 使用 声明式模型。 这意味着我们并不是告诉 Kubernetes 到底要做什么,而是描述所需的状态。 例如,Kubernetes 根据需要启动和停止 pod,以保持系统的实际状态与期望状态一致。

您在清单或文件中指示所需的状态 Yaml。 YAML 文件包含一个或多个 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 代理拦截应用程序容器的所有传入和传出流量。 代表着 服务器 и 负载生成器 通过 sidecar 代理 Envoy 接收,以及来自的所有流量 负载生成器 к 服务器 通过 Envoy 代理。

Envoy 代理之间的连接形成服务网格。 服务网格架构在 Kubernetes 之上提供了一个控制层。

为 Istio 准备应用程序

由于 Envoy 代理在自己的容器中运行,因此 Istio 可以安装在 GKE 集群之上,几乎无需更改应用程序代码。 但是您已经做了一些工作来让您的应用程序准备好由 Istio 管理:

  • 适用于所有集装箱的服务。 至部署 服务器 и 负载生成器 与 Kubernetes 服务绑定。 甚至 负载生成器,不接收传入请求,有服务。
  • 服务中的端口必须有名称。 尽管服务端口可以在 GKE 中保留未命名,但 Istio 要求您指定 端口名称 按照他的协议。 在 YAML 文件中的端口 服务器 被称为 HTTP因为服务器使用协议 HTTP。 如果 服务远程过程调用,您可以将端口命名为 gpc.
  • 部署已标记。 因此,您可以使用 Istio 的流量管理功能,例如在同一服务的版本之间拆分流量。

安装 Istio

有两种方法安装 Istio。 能 在 GKE 扩展上启用 Istio или 安装 Istio 的开源版本 在集群上。 借助 GKE 上的 Istio,您可以在整个 GKE 集群生命周期中轻松管理 Istio 安装和升级。 如果您想要最新版本的 Istio 或对 Istio 控制面板配置有更多控制权,请安装开源版本而不是 Istio on GKE 扩展。 要决定方法,请阅读文章 GKE 上是否需要 Istio?.

选择一个选项,查看相应的指南,然后按照说明在集群上安装 Istio。 如果您想将 Istio 与新部署的应用程序一起使用, 启用边车实施 对于命名空间 默认.

清洁的

为了避免向您的 Google Cloud Platform 帐户收取本教程中使用的资源费用,请在安装 Istio 并使用示例应用程序后删除容器集群。 这将删除所有集群资源,例如计算实例、磁盘和网络资源。

接下来是什么?

来源: habr.com

添加评论