Docker-Kubenetes-微服务教程-四-

75 阅读48分钟

Docker Kubenetes 微服务教程(四)

原文:Kubernetes Microservices with Docker

协议:CC BY-NC-SA 4.0

十一、使用 Apache Solr

Apache Solr 是一个基于 Apache Lucene 的企业搜索平台,提供诸如全文搜索、近实时索引和数据库集成等功能。Apache Solr 在 servlet 容器中作为全文搜索服务器运行,缺省情况下是 Jetty,它包含在 Solr 安装中。在本章中,我们将讨论在 Apache Solr 中使用 Kubernetes 集群管理器。我们将只使用利用定义文件的声明性方法来创建和管理 Solr 集群。本章包括以下几节。

  • 设置环境
  • 创建服务
  • 列出服务端点
  • 描述服务
  • 创建复制控制器
  • 列出 POD
  • 描述一个 Pod
  • 列出日志
  • 启动交互式 Shell
  • 创建 Solr 核心
  • 添加文档
  • 使用 REST 客户端在命令行上访问 Solr
  • 设置端口转发
  • 在管理控制台中访问 Solr
  • 扩展集群

设置环境

本章需要以下软件。

  • -Docker 引擎(最新版本)
  • -Kubernetes(1.01 版)
  • -Kubernetes(1.01 版)
  • Apache Solr 的 Docker 映像(最新版本)

我们在其他章节中使用了相同的 Amazon EC2 实例 AMI。从本地机器 SSH 登录到 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@54.152.82.142

按照第一章所述安装所需软件。启动 Docker 并验证其状态。

sudo service docker start
sudo service docker status

如图 11-1 所示 Docker 机应该正在运行。

A418863_1_En_11_Fig1_HTML.gif

图 11-1。

Starting Docker and Verifying Status

列出服务。

kubectl get services

如图 11-2 所示,Kubernetes 服务应该正在运行。

A418863_1_En_11_Fig2_HTML.gif

图 11-2。

Listing the “kubernetes” Service

要列出节点,请运行以下命令。

kubectl get nodes

127.0.0.1 节点被列出,如图 11-3 所示。

A418863_1_En_11_Fig3_HTML.gif

图 11-3。

Listing a Single Node

使用以下命令列出端点。

kubectl get endpoints

最初只列出了 kubernetes 的终点,如图 11-4 所示。

A418863_1_En_11_Fig4_HTML.gif

图 11-4。

Listing “kubernetes” Endpoint

创建服务

创建一个定义文件solr-service.yaml并将以下(表 11-1 )字段添加到定义文件中。

表 11-1。

Service Definition File for Apache Solr

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 服务 | | 元数据 | 服务元数据。 |   | | 元数据->标签 | 服务标签。不需要。 | 应用程式:太阳能板 | | 元数据->名称 | 服务名称。必选。 | 太阳能服务 | | 投机 | 服务规范。 |   | | 规格->端口 | 服务公开的端口。 |   | | 规格->端口->端口 | 服务公开的端口。 | Eight thousand nine hundred and eighty-three | | 规格>连接埠>目标连接埠 | 目标端口。 | Eight thousand nine hundred and eighty-three | | 规格->选择器 | 吊舱选择器。服务将流量路由到标签与选择器表达式匹配的 pod。 | 应用程式:太阳能板 |

solr-service.yaml已列出。

apiVersion: v1
kind: Service
metadata:
  labels:
    app: solrApp
  name: solr-service
spec:
  ports:
    -
      port: 8983
      targetPort: 8983
  selector:
    app: solrApp

solr-service.yaml可以在 vi 编辑器中编辑,并用:wq 保存,如图 11-5 所示。

A418863_1_En_11_Fig5_HTML.gif

图 11-5。

Service Definition File in vi Editor

使用以下命令从定义文件创建服务。

kubectl create -f solr-service.yaml  

随后列出服务。

kubectl get services

如图 11-6 所示的“服务/solr-service”输出表明服务已经创建。随后solr-service被列出。服务有标签app=solrApp和选择器app=solrApp

A418863_1_En_11_Fig6_HTML.gif

图 11-6。

Creating a Service from Definition File

列出服务端点

要列出端点,请运行以下命令。

kubectl get endpoints

由于solr-service最初没有管理任何 pod,因此没有列出端点,如图 11-7 所示。

A418863_1_En_11_Fig7_HTML.gif

图 11-7。

Listing the Endpoint for the Solr Service

描述服务

要描述solr-service,运行以下命令。

kubectl describe service solr-service

服务名称、名称空间、标签、选择器、类型、IP、端口、端点和事件被列出,如图 11-8 所示。

A418863_1_En_11_Fig8_HTML.gif

图 11-8。

Describing the Apache Solr Service

创建复制控制器

为复制控制器创建一个定义文件solr-rc.yaml,并将以下(表 11-2 )字段添加到定义文件中。

表 11-2。

Replication Controller Definition File Fields

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 复制控制器 | | 元数据 | 复制控制器元数据。 |   | | 元数据->标签 | 复制控制器标签。 | 应用程式:太阳能板 | | 元数据->名称 | 复制控制器的名称。 | 索尔-rc | | 投机 | 复制控制器规范。 |   | | 规格->副本 | Pod 副本的数量。 | Two | | 规格->选择器 | key:用于选择要管理的窗格的值表达式。标签与选择器表达式相同的窗格由复制控制器管理。对于单个标签/选择器表达式窗格/复制控制器组合,选择器表达式必须与规格->模板->元数据->标签表达式相同。选择器默认为规范->模板->元数据->未指定标签。app: solrApp 设置转换为 app=solrApp。 | 应用程式:太阳能板 | | 规格->模板 | Pod 模板。 |   | | 规格->模板->元数据 | Pod 模板元数据。 |   | | 规格->模板->元数据->标签 | Pod 模板标签。 | 应用程式:太阳能板 | | 规格->模板->规格 | Pod 模板规范。 |   | | 规格->模板->规格->容器 | Pod 模板的容器配置。 |   | | 规格->模板->规格->容器->映像 | Docker 的形象。 | 使用 | | 规格->模板->规格->容器->名称 | 容器名称。 | 使用 | | 规格->模板->规格->容器->端口 | 容器港口。 |   | | 规格->模板->规格->容器->端口->容器端口 | Solr 服务器的容器端口。 | Eight thousand nine hundred and eighty-three | | 规格->模板->规格->容器->端口->名称 | Solr 端口名称。 | 索拉普 |

solr-rc.yaml已列出。

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    app: solrApp
  name: solr-rc
spec:
  replicas: 2
  selector:
    app: solrApp
  template:
    metadata:
      labels:
        app: solrApp
    spec:
      containers:
        -
          image: solr
          name: solr
          ports:
            -
              containerPort: 8983
              name: solrApp

可以在 vi 编辑器中创建并保存solr-rc.yaml定义文件,如图 11-9 所示。

A418863_1_En_11_Fig9_HTML.gif

图 11-9。

Replication Controller Definition File in vi Editor

运行以下命令,从定义文件创建复制控制器。

kubectl create -f solr-rc.yaml  

solr-rc复制控制器被创建,如图 11-10 所示。随后列出复制控制器。

A418863_1_En_11_Fig10_HTML.gif

图 11-10。

Creating a Replication Controller from Definition File

kubectl get rc

solr-rc复制控制器列表如图 11-10 所示。

列出 POD

使用以下命令列出 pod。

kubectl get pods

由复制控制器创建的两个 pod 被列出,如图 11-11 所示。最初,一些 pod 可能没有运行,也没有准备好。

A418863_1_En_11_Fig11_HTML.gif

图 11-11。

Listing the Pods, all of them not yet Ready

几秒钟后再次运行相同的命令,再次列出 pod。

kubectl get pods

如图 11-12 所示,pod 应列出状态“运行”和就绪状态 1/1。

A418863_1_En_11_Fig12_HTML.gif

图 11-12。

Listing the Pods as Ready

要描述solr-service,运行以下命令。

kubectl describe svc solr-service

服务描述被列出,如图 11-13 所示。还列出了两个 pod 的服务端点。服务在其端点被访问。如前所述,在创建复制控制器之前,没有列出服务端点,如图 11-8 所示。

A418863_1_En_11_Fig13_HTML.gif

图 11-13。

Describing the Solr Service including the Service Endpoints

端点也可以单独列出。

kubectl get endpoints

端点列表如图 11-14 所示。

A418863_1_En_11_Fig14_HTML.gif

图 11-14。

Listing the Endpoints for Solr Service

描述复制控制器

要描述复制控制器solr-rc,运行以下命令。

kubectl describe rc solr-rc

复制控制器描述被列出,如图 11-15 所示。

A418863_1_En_11_Fig15_HTML.gif

图 11-15。

Describing the Replication Controller

列出日志

要列出特定命令的日志,运行kubectl logs命令。例如,使用以下命令列出了solr-rc-s82ip Pod 的日志。

kubectl logs solr-rc-s82ip

在日志输出中,Solr 服务器正在启动,如图 11-16 所示。

A418863_1_En_11_Fig16_HTML.gif

图 11-16。

Listing Logs for the Pod

服务器启动后,输出“服务器启动”得到如图 11-17 所示的输出。

A418863_1_En_11_Fig17_HTML.gif

图 11-17。

Listing the Solr Server as started

启动交互式 Shell

由于“Solr”Docker 映像继承自“Java:open JDK-8-JRE”Docker 映像,而“Java:open JDK-8-JRE”Docker 映像又继承自“buildpack-deps:jessie-curl”映像,而“jessie-curl”映像又继承自 Linux 的 Docker 映像“debian ”,因此可以启动一个交互式 bash shell 来访问基于“Solr”Docker 映像的 Docker 容器。要访问 Solr 软件,我们需要为运行 Solr 的 Docker 容器启动一个交互式 bash shell。对于运行 Solr 的 Docker 容器,使用以下命令获取容器 if。

sudo docker ps

Docker 容器如图 11-18 所示。

A418863_1_En_11_Fig18_HTML.gif

图 11-18。

Listing the Docker Container for Apache Solr

复制容器并启动一个交互式 shell。

sudo docker exec -it 2d4d7d02c05f bash

交互外壳启动,如图 11-19 所示。要列出 Solr 服务器的状态,请运行以下命令。

A418863_1_En_11_Fig19_HTML.gif

图 11-19。

Listing the Solr Status in an Interactive Shell for the Docker Container

bin/solr status

找到一个 Solr 节点,如图 11-19 所示。

Solr 5.x 引入配置集。configsets 目录由示例配置组成,可用作创建新 Solr 核心或集合的基础。configsets 将 Solr 4.x. Cd(更改目录)中的collection1示例核心配置替换为configsets目录。

cd /opt/solr/server/solr/configsets

列出configsets目录中的文件和目录。

ls –l

如图 11-20 所示,列出了三种示例配置。

A418863_1_En_11_Fig20_HTML.gif

图 11-20。

Listing the Example Configurations

当我们在本章后面创建 Solr 核心时,我们将使用 basic_configs 配置。列出//configsets/ basic_configs/conf目录中的文件。

cd conf
ls –l

basic_configs示例的配置文件被列出,包括schema.xml和 solrconfig.xml,如图 11-21 所示。

A418863_1_En_11_Fig21_HTML.gif

图 11-21。

Listing the Configuration Files in the basic_configs Example Configuration

创建 Solr 核心

也可以从命令行创建一个新的 Solr 内核。solr create命令用于创建一个新的核心或集合。例如,用solr create_core命令创建一个名为wlslog的内核。使用带有–d选项的配置集basic_configs。如果没有指定(使用–d选项),使用的默认配置集是data_driven_schema_configs。Cd 到/opt/solr目录,并运行下面的命令。

bin/solr create_core -c wlslog -d /opt/solr/server/solr/configsets/basic_configs

一个名为wlslog的 Solr 内核被创建,如图 11-22 所示。

A418863_1_En_11_Fig22_HTML.gif

图 11-22。

Creating a Solr Core called wlslog

索引文档

Apache Solr 提供了从命令行索引文档的post工具。post工具支持不同的输入文件格式,如 XML、CSV 和 JSON。我们将索引一个 XML 格式的文档,并将下面的 XML 文档保存到wlslog.xml文件中。

<add>
<doc>
<field name="id">wlslog1</field>
  <field name="time_stamp_s">Apr-8-2014-7:06:16-PM-PDT</field>
  <field name="category_s">Notice</field>
  <field name="type_s">WebLogicServer</field>
  <field name="servername_s">AdminServer</field>
  <field name="code_s">BEA-000365</field>
  <field name="msg_s">Server state changed to STANDBY</field>

</doc>

<doc>
<field name="id">wlslog2</field>

  <field name="time_stamp_s">Apr-8-2014-7:06:17-PM-PDT</field>
  <field name="category_s">Notice</field>
  <field name="type_s">WebLogicServer</field>

  <field name="servername_s">AdminServer</field>
  <field name="code">BEA-000365</field>
  <field name="msg_s">Server state changed to STARTING</field>

</doc>

<doc>
<field name="id">wlslog3</field>

  <field name="time_stamp_s">Apr-8-2014-7:06:18-PM-PDT</field>
  <field name="category_s">Notice</field>
  <field name="type_s">WebLogicServer</field>

  <field name="servername_s">AdminServer</field>
  <field name="code">BEA-000365</field>
  <field name="msg_s">Server state changed to ADMIN</field>
</doc>
<doc>
<field name="id">wlslog4</field>
  <field name="time_stamp_s">Apr-8-2014-7:06:19-PM-PDT</field>
  <field name="category_s">Notice</field>
  <field name="type_s">WebLogicServer</field>
  <field name="servername_s">AdminServer</field>
  <field name="code">BEA-000365</field>
  <field name="msg_s">Server state changed to RESUMING</field>

</doc>

<doc>
<field name="id">wlslog5</field>

  <field name="time_stamp_s">Apr-8-2014-7:06:20-PM-PDT</field>
  <field name="category_s">Notice</field>
  <field name="type_s">WebLogicServer</field>
  <field name="servername_s">AdminServer</field>
  <field name="code">BEA-000331</field>
  <field name="msg_s">Started WebLogic AdminServer</field>
</doc>
<doc>
<field name="id">wlslog6</field>

  <field name="time_stamp_s">Apr-8-2014-7:06:21-PM-PDT</field>
  <field name="category_s">Notice</field>

  <field name="type_s">WebLogicServer</field>
  <field name="servername_s">AdminServer</field>
  <field name="code">BEA-000365</field>
  <field name="msg_s">Server state changed to RUNNING</field>
</doc>
<doc>
<field name="id">wlslog7</field>
  <field name="time_stamp_s">Apr-8-2014-7:06:22-PM-PDT</field>
  <field name="category_s">Notice</field>
  <field name="type_s">WebLogicServer</field>
  <field name="servername_s">AdminServer</field>
  <field name="code">BEA-000360</field>
  <field name="msg_s">Server started in RUNNING mode</field>
</doc>
</add>

可以在 vi 编辑器中创建wlslog.xml文件,并用:wq 命令保存,如图 11-23 所示。

A418863_1_En_11_Fig23_HTML.gif

图 11-23。

The wlslog.xml File

Cd 到/opt/solr目录,并运行 post 工具将wlslog.xml文件中的文档添加到 Solr 服务器。

bin/post -c wlslog ./wlslog.xml

一个文件被编入索引,如图 11-24 所示。

A418863_1_En_11_Fig24_HTML.gif

图 11-24。

Posting the wlslog.xml File to the Solr Index

使用 REST 客户端在命令行上访问 Solr

Solr 请求处理器命令如/update/select可以使用 REST 客户端如 curl 和 wget 运行。在这一节中,我们将使用 curl 工具运行一些/select请求处理程序命令。例如,使用下面的 curl 命令查询所有文档。

curl http://localhost:8983/solr/wlslog/select?q=*%3A*&wt=json&indent=true

卷曲命令如图 11-25 所示。

A418863_1_En_11_Fig25_HTML.gif

图 11-25。

Using curl to send a Request to Solr Server with Request Handler /select

添加的 7 个文件列表如图 11-26 所示。

A418863_1_En_11_Fig26_HTML.gif

图 11-26。

Listing the Documents returned by the /select Request Handler

作为另一个例子,运行/select请求处理程序来查询 id 为wlslog7的文档。

curl http://localhost:8983/solr/wlslog/select?q=id:wlslog7&wt=json&indent=true

id 为wlslog7的文件被列出,如图 11-27 所示。

A418863_1_En_11_Fig27_HTML.gif

图 11-27。

Querying for a Single Document with id wlslog7 using /select Request Handler and curl

可用post工具删除文件。例如,使用下面的命令删除 id 为wlslog1的文档。

bin/post -c wlslog -d "<delete><id>wlslog1</id></delete>"

id 为wlslog1的文档被删除,如图 11-28 所示。

A418863_1_En_11_Fig28_HTML.gif

图 11-28。

Deleting a Document using post Tool

随后运行下面的 curl 命令,列出wlslog索引中的文档。

curl http://localhost:8983/solr/wlslog/select?q=*%3A*&wt=json&indent=true

id 为wlslog1的文件未被列出,如图 11-29 所示。

A418863_1_En_11_Fig29_HTML.gif

图 11-29。

Querying after Deleting a Document

/update请求处理程序可以用来删除文档,如下面的 curl 命令,它删除了wlslog核心中的所有文档。

curl http://localhost:8983/solr/wlslog/update --data '<delete><query>*:*</query></delete>' -H 'Content-type:text/xml; charset=utf-8'

如果尚未配置自动提交,则必须运行以下 curl 命令来提交更改。

curl http://localhost:8983/solr/wlslog/update --data '<commit/>' -H 'Content-type:text/xml; charset=utf-8'

随后运行 curl 命令来调用/select请求处理程序。

curl http://localhost:8983/solr/wlslog/select?q=*%3A*&wt=json&indent=true

如图 11-30 所示,所有文件都被删除,没有列出任何文件。

A418863_1_En_11_Fig30_HTML.gif

图 11-30。

Deleting all Documents in Solr Index with /update

设置端口转发

如果我们在本地机器上运行 Kubernetes,我们可以使用 url http://localhost:8983打开 Solr 管理控制台,但是因为我们使用的是 Amazon EC2 实例,所以我们需要在本地机器上使用 web 浏览器从 localhost:8983 到 172.17.0.2:8983 设置端口转发。从本地机器运行以下命令,从localhost端口 8983 设置端口转发。

ssh -i key-pair-file -f -nNT -L 8983:172.17.0.2:8983 ubuntu@ec2-54-152-82-142.compute-1.amazonaws.com

前面的命令将localhost:8983 URL to endpoint 172.17.0.2:8983向前,如图 11-31 所示。

A418863_1_En_11_Fig31_HTML.gif

图 11-31。

Setting Port Forwarding to localhost

在管理控制台中访问 Solr

在端口转发之后,Solr 管理控制台可以使用 url http://localhost:8983从本地机器访问,如图 11-32 所示。在型芯选择器中选择wlslog型芯,如图 11-32 所示。

A418863_1_En_11_Fig32_HTML.gif

图 11-32。

Displaying the Solr Admin Console

选择文档选项卡,将/update请求处理器的文档类型设置为 XML,如图 11-33 所示。复制并粘贴前面在文档字段中列出的 XML 文档 wlslog.xml,然后单击提交文档。

A418863_1_En_11_Fig33_HTML.jpg

图 11-33。

Adding Document to the wlslog Core

如图 11-34 所示的“成功”输出表示文档已被索引。

A418863_1_En_11_Fig34_HTML.gif

图 11-34。

Response from adding Documents

接下来,我们将查询wlslog索引。选择查询选项卡,如图 11-35 所示。

A418863_1_En_11_Fig35_HTML.gif

图 11-35。

Selecting the Query Tab

请求处理程序为/select时,查询默认为“:”,如图 11-36 所示。

A418863_1_En_11_Fig36_HTML.gif

图 11-36。

Using the Request Handler /select to Query Solr index wlslog

点击执行查询,如图 11-37 所示。

A418863_1_En_11_Fig37_HTML.gif

图 11-37。

Submitting a Query to select all Documents in the wlslog Index

因为我们没有设置自动提交,所以添加的文档还没有被索引。因此,没有文件被列出,如图 11-38 所示。

A418863_1_En_11_Fig38_HTML.gif

图 11-38。

Response from the Query

我们需要重新加载核心,以便为添加的文档建立索引。或者,我们可以重启 Solr 服务器,但是重新加载内核是一个更快的选择。选择核心管理员并点击重新加载,如图 11-39 所示。

A418863_1_En_11_Fig39_HTML.gif

图 11-39。

Reloading the Core

再次运行查询,如图 11-40 所示,添加的 7 个文档被列出。

A418863_1_En_11_Fig40_HTML.gif

图 11-40。

Query Response with 7 Documents

Solr 服务器已经自动将_version_字段添加到每个文档中,如图 11-41 所示。

A418863_1_En_11_Fig41_HTML.gif

图 11-41。

The version Field is added to each Document stored in Solr Index Automatically by the Solr Server

扩展集群

要缩放 Solr pod 集群,运行kubectl scale命令。例如,要扩展到 4 个单元,请将副本设置为 4。

kubectl scale rc solr-rc --replicas=4

输出“scaled”表示 Solr 集群已经被缩放。随后运行以下命令来列出窗格。

kubectl get pods

如图 11-42 所示,列出的吊舱数量为 4 个,而不是开始时的 2 个。一些 pod 可能没有运行或最初没有准备好。

A418863_1_En_11_Fig42_HTML.gif

图 11-42。

Scaling the Apache Solr Cluster to 4 Pods

摘要

Apache Solr 是一个索引和搜索引擎,它利用本地文件系统来存储数据。在本章中,我们使用 Docker 映像“solr”和 Kubernetes 集群管理来创建和管理 Solr 实例集群。我们演示了如何从 Docker 容器的交互式 shell 访问 Solr 实例,以及如何使用管理控制台。在下一章中,我们将使用库伯涅特斯和 ApacheKafka。

十二、使用 ApacheKafka

Apache Kafka 是一个发布-订阅、高吞吐量、分布式消息传递系统。Kafka 中的一个代理可以处理来自多个客户端的每秒 100 兆字节的读写。消息在整个集群中复制,并保存到磁盘上。Kafka 可用于流处理、网站活动跟踪、指标收集、监控和日志聚合。

Kafka 架构的主要组件是生产者、代理、主题和消费者。Kafka 在主题中保存信息的提要。生产者向主题发送(或编写)消息,消费者从主题中消费(或读取)消息。消息是数据的字节数组,可以是任何格式,最常见的是 String、JSON 和 Avro。邮件会保留指定的时间。一个动物园管理员协调 Kafka 集群。在单个生产者-消费者架构中,单个生产者向主题发送消息,单个消费者从主题中消费消息。

Kafka 类似于 Flume,因为它流式传输消息,但 Kafka 是为不同的目的而设计的。虽然 Flume 是为将消息流式传输到 HDFS 或 HBase 等接收器而设计的,但 Kafka 是为供多个应用使用的消息而设计的。

在本章中,我们将讨论使用 Kubernetes 集群管理器和 Apache Kafka。

  • 设置环境
  • 修改 Docker 映像
  • 创建服务
  • 创建复制控制器
  • 列出 POD
  • 描述一个 Pod
  • 启动交互式 Shell
  • 启动 Kafka 服务器
  • 创建主题
  • 创建 Kafka 制作人
  • 启动 Kafka 消费者
  • 生产和消费消息
  • 扩展集群
  • 删除复制控制器和服务

设置环境

我们使用了从 AMI Ubuntu Server 14.04 LTS (HVM)创建的 Amazon EC2 实例,SSD 卷类型- ami-d05e75b8。本章需要以下软件。

  • -Docker 引擎(最新版本)
  • -库服务器群集管理器 1.01 版
  • -Kubernetes(1.01 版)
  • -Docker 映像 dockerkafka/kafka(最新版本)

我们在本章中使用了 Docker 映像dockerkafka/kafkadockerkafka/kafka映像 docker 文件的默认设置不适合与 Kubernetes 进行编排。在下一节中,我们修改并重建了默认的 Docker 映像。首先,使用 Amazon EC2 实例的公共 IP 地址连接 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@54.146.140.160

Ubuntu 实例如图 12-1 所示连接。

A418863_1_En_12_Fig1_HTML.gif

图 12-1。

Connecting to an Ubuntu Instance on Amazon EC2

按照第一章所述安装所需软件。启动 Docker 服务并查找其状态。

sudo service docker start
sudo service docker status

如图 12-2 所示,Docker 应被列为正在运行。

A418863_1_En_12_Fig2_HTML.gif

图 12-2。

Starting Docker

列出永恒的服务。

kubectl get services

应列出“kubernetes”服务,如图 12-3 所示。

A418863_1_En_12_Fig3_HTML.gif

图 12-3。

Listing the “kubernetes” Service

修改 Docker 映像

启动 Apache Kafka 的过程包括以下序列。

Start Zookeeper Server   Start Apache Kafka Server  

Apache Kafka 服务器依赖于 Zookeeper 服务器,因此需要在 Kafka 服务器启动之前运行 Zookeeper 服务器。Kafka 服务器在启动时使用server.properties配置文件。server.properties文件中的默认设置不适合 Kafka 服务器基于运行在localhost:2181的 Zookeeper 服务器启动。我们需要在server.properties文件中修改 Zookeeper 的连接 url。

在本节中,我们将下载dockerkafka/kafka映像,修改server.properties并重建 Docker 映像。用下面的命令下载dockerkafka/kafka映像的源代码。

git clone https://github.com/DockerKafka/kafka-docker.git

dockerkafka/kafka映像的源代码被下载,如图 12-4 所示。

A418863_1_En_12_Fig4_HTML.gif

图 12-4。

Downloading the kafka-docker Docker Image Source Code

将目录(cd)更改为kafka-docker目录,并列出文件/目录。

cd kafka-docker
ls –l

Docker 镜像中的文件/目录被列出,如图 12-5 所示。

A418863_1_En_12_Fig5_HTML.gif

图 12-5。

Listing the Dockerfile and Image Directory for the kafka-source Docker Image

我们需要修改位于image/conf目录下的server.properties文件中的设置。Cd 到image/conf目录,并列出该目录的文件/目录。

cd image/conf
ls –l

server.properties文件被列出,如图 12-6 所示。

A418863_1_En_12_Fig6_HTML.gif

图 12-6。

Listing the Configuration Files for the Docker Image

在 vi 编辑器中打开server.properties文件。

sudo vi server.properties

server.properties文件如图 12-7 所示。取消带有host.name=localhost设置的行的注释。

A418863_1_En_12_Fig7_HTML.gif

图 12-7。

Uncommenting the host.name Property

如图 12-8 所示zookeeper.connect的默认设置为zookeeper:2181

A418863_1_En_12_Fig8_HTML.gif

图 12-8。

The default setting for the zookeeper.connect Property

zookeeper.connect设置修改为localhost:2181,如图 12-9 所示。用:wq 保存修改后的文件。我们需要修改设置,因为默认情况下不存在“zookeeper”这样的主机。

A418863_1_En_12_Fig9_HTML.gif

图 12-9。

Setting zookeeper.connect to localhost: 2181

随后,cd 回到 Docker 映像的根目录,即kafka-docker目录,并运行以下命令来重建 Docker 映像。

sudo docker build -t dockerkafka/kafka:v2.

该命令的输出如图 12-10 所示。

A418863_1_En_12_Fig10_HTML.gif

图 12-10。

Rebuilding the Docker Image for Kafka

Docker 映像得到重建,如图 12-11 所示。

A418863_1_En_12_Fig11_HTML.gif

图 12-11。

Completing the Rebuild of the Docker Image

我们随后将使用的 Docker 映像不是dockerkafka/kafka而是dockerkafka/kafka:v2

创建服务

创建一个名为kafka-service.yaml的服务定义文件,并将以下(表 12-1 )字段添加到该文件中。

表 12-1。

The Fields in the Service Definition File

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 服务 | | 元数据 | 服务元数据。 |   | | 元数据->标签 | 服务标签。不需要。 | 应用程式:Kafka | | 元数据->名称 | 服务名称。必选。 | Kafka | | 投机 | 服务规范。 |   | | 规格->端口 | 服务公开的端口。 |   | | 规格->端口->端口 | 服务公开的端口。9092 端口用于 Kafka 服务器。 | 端口:9092 目标端口:9092 | | 规格->端口->端口 | 服务公开的另一个端口。2181 端口是给动物园管理员的。 | 端口:2181 目标端口:2181 | | 规格->选择器 | 吊舱选择器。服务将流量路由到标签与选择器表达式匹配的 pod。 | 应用程式:Kafka | | 规格->选择器->类型 | 服务类型。 | LoadBalancer(负载均衡器) |

kafka-service.yaml已列出。

apiVersion: v1
kind: Service
metadata:
  labels:
    app: kafkaApp
  name: kafka
spec:
  ports:
    -
      port: 9092
      targetPort: 9092
    -
      port: 2181
      targetPort: 2181
  selector:
    app: kafkaApp
  type: LoadBalancer

可以在 vi 编辑器中创建kafka-service.yaml并用:wq 保存,如图 12-12 所示。

A418863_1_En_12_Fig12_HTML.gif

图 12-12。

Service Definition File in vi Editor

从定义文件创建服务。

kubectl create -f kafka-service.yaml

随后列出服务。

kubectl get services

“kafka”服务被列出,如图 12-13 所示。服务选择器是 app = kafkaApp。

A418863_1_En_12_Fig13_HTML.gif

图 12-13。

Creating a Service from the Definition File

创建复制控制器

为复制控制器创建一个名为kafka-rc.yaml的定义文件,并添加以下字段(表 12-2 )。

表 12-2。

Fields in the Replication Controller Definition File

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 复制控制器 | | 元数据 | 复制控制器元数据。 |   | | 元数据->标签 | 复制控制器标签。 | app:kafcapp 名称:kafca-RC | | 投机 | 复制控制器规范。 |   | | 规格->副本 | Pod 副本的数量。 | Two | | 规格->选择器 | key:用于选择要管理的窗格的值表达式。标签与选择器表达式相同的窗格由复制控制器管理。选择器表达式必须与规范->模板->元数据->标签表达式相同。如果没有指定,选择器默认为规范->模板->元数据->标签键:值表达式。 | 应用程式:Kafka | | 规格->模板 | Pod 模板。 |   | | 规格->模板->元数据 | Pod 模板元数据。 |   | | 规格->模板->元数据->标签 | Pod 模板标签。 | 应用程式:Kafka | | 规格->模板->规格 | Pod 模板规范。 |   | | 规格->模板->规格->容器 | Pod 模板的容器配置。 |   | | 规格->模板->规格->容器->命令 | 为 Docker 映像运行的命令。Dockerfile 中的默认命令是 CMD ["kafka-server-start.sh ","/opt/Kafka _ 2.10-0 . 8 . 2 . 1/config/server . properties "]。默认命令启动 Kakfa 服务器,但是我们希望 Zookeeper 服务器在 Kafka 服务器之前,因为 Kafka 服务器不会启动,除非 Zookeeper 服务器正在运行。修改后的命令只启动 Zookeeper 服务器。我们将单独启动 Kafka 服务器。 | -zookeeper-server-start . sh-/opt/Kafka _ 2.10-0 . 8 . 2 . 1/config/zookeeper . properties | | 规格->模板->规格->容器->映像 | Docker 的形象。 | dock fk/Kaka:v2 | | 规格->模板->规格->容器->名称 | 容器名称。 | 动物园管理员 | | 港口 | 指定容器端口。 | 容器港口:2181 |

kafka-rc.yaml已列出。

---

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    app: kafkaApp
  name: kafka-rc
spec:
  replicas: 1
  selector:
    app: kafkaApp
  template:
    metadata:
      labels:
        app: kafkaApp
    spec:
      containers:
        -
          command:
            - zookeeper-server-start.sh
            - /opt/kafka_2.10-0.8.2.1/config/zookeeper.properties
          image: "dockerkafka/kafka:v2"
          name: zookeeper
          ports:
            -
              containerPort: 2181

可以在 vi 编辑器中创建并保存kafka-rc.yaml文件,如图 12-14 所示。

A418863_1_En_12_Fig14_HTML.gif

图 12-14。

Replication Controller Definition File in vi Editor

从定义文件创建复制控制器。

kubectl create -f kafka-rc.yaml  

随后列出复制控制器。

kubectl get rc

复制控制器被创建并列出,如图 12-15 所示。

A418863_1_En_12_Fig15_HTML.gif

图 12-15。

Creating the Replication Controller from the Definition File

要描述kafka-rc,运行以下命令。

kubectl describe rc kafka-rc

复制控制器描述被列出,如图 12-16 所示。

A418863_1_En_12_Fig16_HTML.gif

图 12-16。

Describing the Replication Controller

列出 POD

要列出窗格,请运行以下命令。

kubectl get pods

吊舱被列出,如图 12-17 所示。

A418863_1_En_12_Fig17_HTML.gif

图 12-17。

Listing the pods for Kafka

描述一个 Pod

仅创建一个 Pod,因为定义文件kafka-rc.yaml中的“副本”设置为 1。要描述 Pod,请运行以下命令。

kubectl describe pod kafka-rc-k8as1

吊舱描述被列出,如图 12-18 所示。Pod 标签app=kafkaApp与服务选择器和复制控制器选择器相同,这使得服务和复制控制器可以管理 Pod。

A418863_1_En_12_Fig18_HTML.gif

图 12-18。

Describing a pod for Kafka

当 Pod 被创建和启动时,Zookeeper 服务器开始启动,因为用于修改的 Docker 映像的命令是启动 Zookeeper 服务器。接下来,我们将从 Docker 容器的交互式 shell 中启动 Kafka 服务器,用于修改后的 Docker 映像。

启动交互式 Shell

为了能够启动交互式 bash shell 来访问安装的 Kafka 软件,我们需要知道运行修改后的 Docker 映像的 Docker 容器的容器 id。用下面的命令列出 Docker 容器。

sudo docker ps

Docker 容器如图 12-19 所示。

A418863_1_En_12_Fig19_HTML.gif

图 12-19。

Obtaining the Docker Container Id

复制容器 id 并启动交互式 bash shell。

sudo docker exec -it 939ae2cb4f86 bash

交互外壳启动,如图 12-20 所示。

A418863_1_En_12_Fig20_HTML.gif

图 12-20。

Starting the Interactive TTY for the Docker Container

启动 Kafka 服务器

Kafka 服务器的配置属性在config/server.properties文件中设置,我们在重建 Docker 映像时修改了这个文件。因为 Zookeeper 已经在运行,所以用下面的命令启动 Kafka 服务器。

kafka-server-start.sh /opt/kafka_2.10-0.8.2.1/config/server.properties

前面的命令如图 12-21 所示。

A418863_1_En_12_Fig21_HTML.gif

图 12-21。

Starting the Kafka Server

Kafka 服务器启动,如图 12-22 所示。

A418863_1_En_12_Fig22_HTML.gif

图 12-22。

Kafka Server started at localhost:9092

创建主题

接下来,用下面的命令创建一个名为“kafka-on-kubernetes”的主题。将分区数量设置为 1,将复制因子设置为 1。动物园管理员设置为localhost:2181

kafka-topics.sh --create --topic kafka-on-kubernetes --zookeeper localhost:2181 --replication-factor 1 --partitions 1

如图 12-23 所示,kafka-on-kubernetes主题被创建。

A418863_1_En_12_Fig23_HTML.gif

图 12-23。

Creating a Kafka Topic

创建 Kafka 制作人

Kafka 生产者是用来生产信息的。启动 ZooKeeper 和 Kafka 服务器后,启动 Kafka producer。使用–topic选项将主题指定为“kafka-on-kubernetes”。--broker-list指定 Kafka 服务器为localhost:9092,这是在server.properties文件中配置的设置。

kafka-console-producer.sh --topic kafka-on-kubernetes --broker-list localhost:9092

如图 12-24 所示,Kafka 制作人开始了。

A418863_1_En_12_Fig24_HTML.gif

图 12-24。

Starting a Kafka Producer

启动 Kafka 消费者

Kafka 式的消费者消费信息。使用以下命令启动 Kafka 消费程序。使用–topic选项将主题指定为“kafka-on-kubernetes”。--zookeeper指定 Zookeeper 服务器为localhost:2181,这是在server.properties文件中配置的设置。--from-beginning选项指定从一开始就要消费消息,而不仅仅是消费者启动后消费的消息。

kafka-console-consumer.sh --topic kafka-on-kubernetes --from-beginning --zookeeper localhost:2181

如图 12-25 所示,Kafka 制作人开始了。

A418863_1_En_12_Fig25_HTML.jpg

图 12-25。

Starting a Kafka Consumer

生产和消费消息

启动了生产者和消费者之后,我们将在生产者处产生消息,在消费者处消费消息。如图 12-26 所示,在生产者处添加一条消息,例如“来自 Kafka 生产者的消息”,并点击输入按钮。信息被发送出去。

A418863_1_En_12_Fig26_HTML.jpg

图 12-26。

Producing a Message at the Kafka Producer

在消费者处,消息被消费,如图 12-27 所示。

A418863_1_En_12_Fig27_HTML.gif

图 12-27。

Consuming a Message at the Kafka Consumer

在生产者处发送更多消息,如图 12-28 所示。

A418863_1_En_12_Fig28_HTML.gif

图 12-28。

Producing More Messages at the Kafka Producer

并且消息在消费者处被消费,如图 12-29 所示。

A418863_1_En_12_Fig29_HTML.gif

图 12-29。

Consuming More Messages at the Kafka Consumer

扩展集群

要将群集从 1 个单元扩展到 4 个单元,请运行以下命令。

kubectl scale rc kafka-rc --replicas=4

随后列出 POD。

kubectl get pods

输出“scaled”表示集群已被缩放,如图 12-30 所示。随后吊舱被列出,也如图 12-30 所示。

A418863_1_En_12_Fig30_HTML.gif

图 12-30。

Scaling the Kafka Cluster

当 pod 的数量增加到 4 时,服务端点也增加到 4。描述服务kafka

kubectl describe svc kafka

如图 12-31 所示,这两个服务都列出了 4 个端点,一个用于 Zookeeper 服务器,另一个用于 Kafka 服务器。

A418863_1_En_12_Fig31_HTML.gif

图 12-31。

Describing the Kafka Service with 4 Endpoints

删除复制控制器和服务

要删除复制控制器和服务,请运行以下命令。

kubectl delete rc kafka-rc
kubectl delete service kafka

如图 12-32 所示,复制控制器和服务被删除。

A418863_1_En_12_Fig32_HTML.gif

图 12-32。

Deleting the Kafka Replication Controller and Service

摘要

Apache Kafka 是一个基于生产者和消费者的信息系统。在本章中,我们讨论了使用 Kubernetes 管理 Kafka 集群。管理 Kafka 不同于其他一些应用,因为必须启动两个服务器:Zookeeper 服务器和 Kafka 服务器。Kafka 服务器依赖于 Zookeeper 服务器,这意味着 Zookeeper 必须在 Kafka 服务器之前启动。我们需要修改 zookeeper 连接 url 的默认映像dockerkafka/kafka。在复制控制器定义文件中,我们使用一个定制命令来运行修改后的 Docker 映像,以启动 Zookeeper 服务器,Docker 映像中的默认设置是启动 Kafka 服务器。到目前为止,我们运行的所有应用都是基于单个容器 Pod 的。在下一章中,我们将开发一个多容器 Pod。

十三、创建多容器 Pod

Pod 是由 Kubernetes 管理的应用的原子单位。一个 Pod 有一个文件系统和 IP 地址;Pod 中的容器共享文件系统和网络 IP。一个 Pod 可以由一个或多个容器组成。使用 Pod 规范( http://kubernetes.io/v1.1/docs/api-reference/v1/definitions.html#_v1_podspec )在 Pod 或复制控制器的定义文件中定义 Pod。使用容器规范( http://kubernetes.io/v1.1/docs/api-reference/v1/definitions.html#_v1_container )指定 Pod 中的单个容器。在前面章节中讨论的所有应用中,使用了单个容器箱。在本章中,我们将开发一个多容器 Pod。我们已经为多容器 Pod 使用了tutum/hello-worldpostgres Docker 映像。在前面的章节中,这些映像中的每一个都在单个容器窗格中使用过。本章将涵盖以下主题。

  • 如何找到一个箱中的容器数量?
  • 使用多容器箱的应用类型
  • 设置环境
  • 创建服务
  • 描述服务
  • 创建复制容器
  • 列出 POD
  • 列出 Docker 容器
  • 创建复制控制器后描述服务
  • 在命令行上调用 Hello World 应用
  • 启动交互式 Shell
  • 正在启动 PostgreSQL Shell
  • 设置端口转发
  • 在浏览器中打开 Hello World 应用
  • 扩展集群
  • 描述扩展后的服务
  • 描述一个 Pod
  • 设置端口转发
  • 在浏览器中打开 Hello World 应用
  • 从命令行调用 Hello World 应用
  • 删除复制控制器
  • 删除服务

如何找到一个箱中的容器数量?

如前所述,可以使用以下命令列出 pod。

kubectl get pods

Kubernetes Pod k8s-master-127.0.0.1 Pod 有 3/3 在就绪列中,如图 13-1 所示。3/3 表示 Pod 有 3 个容器,并且这三个容器都准备好了。任何箱的就绪栏中的 n/n 表示容器总数中就绪的容器数。所有容器都运行在一个节点上,如后面的节点列表所示。

A418863_1_En_13_Fig1_HTML.gif

图 13-1。

Listing the Pods and the Number of Containers in the Pods

使用多容器 Pod 的应用类型

各种类型的应用可以利用多容器 Pod。一些例子如下:

  • Apache Sqoop 应用利用 CDH Docker 基于映像的容器和 MySQL 数据库 Docker 基于映像的容器将数据从 MySQL 数据库批量传输到 HDFS。
  • Apache Flume 应用利用基于 CDH Docker 映像的容器和基于 Kafka 的容器将数据从 Kafka 源传输到 HDFS。
  • Apache Solr 应用利用基于 Oracle 数据库的容器和 Solr 容器将数据从 Oracle 数据库导入 Solr。
  • -一个 Apache Hive 应用使用一个 CDH 容器和一个 MongoDB 容器,通过 MongoDB 存储处理程序创建一个 Hive 表。
  • -需要一个 Apache Solr 容器和一个 CDH 容器来将 Solr 数据存储在 HDFS,而不是本地文件系统。

设置环境

我们已经使用了从 AMI Ubuntu Server 14.04 LTS (HVM),SSD 卷类型- ami-d05e75b8 创建的 Amazon EC2 实例来安装以下所需的软件。

  • -Docker 引擎(最新版本)
  • -Kubernetes(1.01 版)
  • -Kubernetes(1.01 版)
  • -Docker image tutum/hello-world(最新版本)
  • -Docker 映像 postgres(最新版本)

按照第一章所述安装 Docker、Kubernetes 和 Kubectl。要登录 Ubuntu 实例,可以从亚马逊 EC2 控制台获取公共 IP 地址,如图 13-2 所示。

A418863_1_En_13_Fig2_HTML.gif

图 13-2。

Obtaining the Public IP Address

SSH 登录到 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@52.90.62.35

安装 Docker 后,启动 Docker 并验证其状态。

sudo service docker start
sudo service docker status

如图 13-3 所示,Docker 应被列为“正在运行”。

A418863_1_En_13_Fig3_HTML.gif

图 13-3。

Starting Docker

创建服务

创建一个服务定义文件hello-postgres-service.yaml来配置服务端口。我们将配置两个服务端口,一个用于hello-world应用,另一个用于postgres应用。服务定义文件中的字段在表 13-1 中讨论。

表 13-1。

Fields in the Service Definition File

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 服务 | | 元数据 | 服务元数据。 |   | | 元数据->标签 | 服务标签。该设置转换为标签 app = MultiContainerApp | app:多容器面板 | | 元数据->名称 | 服务名称。 | 你好-波斯特格里斯 | | 投机 | 服务规范。 |   | | 规格->端口 | 服务公开的端口。公开了两个端口,一个用于 hello-world 应用,另一个用于 postgres 应用。 | 名称:hello-world 端口:8080 名称:postgres 端口:5432 | | 规格->选择器 | 吊舱选择器。服务将流量路由到标签与选择器表达式匹配的 pod。该设置转换为选择器 app = MultiContainerApp | app:多容器面板 | | 规格->选择器->类型 | 服务类型。 | LoadBalancer(负载均衡器) |

列出了hello-postgres-service.yaml:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: MultiContainerApp
  name: hello-postgres
spec:
  ports:
    -
      name: hello-world
      port: 8080
    -
      name: postgres
      port: 5432
  selector:
    app: MultiContainerApp
  type: LoadBalancer

从定义文件创建服务。

kubectl create -f hello-postgres-service.yaml

随后列出服务。

kubectl get services

hello-postgres服务被创建并列出,如图 13-4 所示。

A418863_1_En_13_Fig4_HTML.gif

图 13-4。

Creating a Service from the Definition File

描述服务

可以用下面的命令描述hello-postgres服务。

kubectl describe service hello-postgres

服务描述包括名称、命名空间、标签、选择器、类型、IP、端口和端点,如图 13-5 所示。最初,该服务不管理任何 pod,因此没有列出任何端点。

A418863_1_En_13_Fig5_HTML.gif

图 13-5。

Describing the Service

创建复制容器

为复制控制器创建一个定义文件hello-postgres-rc.yaml。将以下(表 13-2 )字段添加到定义文件中。

表 13-2。

Fields in the Replication Controller Definition File

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 复制控制器 | | 元数据 | 复制控制器元数据。 |   | | 元数据->标签 | 复制控制器标签。 | app:“多容器” | | 元数据->名称 | 复制控制器的名称。 | “你好-波斯特格里斯” | | 投机 | 复制控制器规范。 |   | | 规格->副本 | Pod 副本的数量。 | one | | 规格->选择器 | key:用于选择要管理的窗格的值表达式。标签与选择器表达式相同的窗格由复制控制器管理。选择器表达式必须与规范->模板->元数据->标签表达式相同。如果没有指定,选择器默认为规范->模板->元数据->标签键:值表达式。 | app:“多容器” | | 规格->模板 | Pod 模板。 |   | | 规格->模板->元数据 | Pod 模板元数据。 |   | | 规格->模板->元数据->标签 | Pod 模板标签。如果未指定选择器,则默认为该设置。服务选择器必须与代表 Pod 的服务的 Pod 模板标签相同。服务选择器没有默认为与标签相同的值,我们已经将服务选择器设置为 app: MultiContainerApp。 | app:“多容器” | | 规格->模板->规格 | Pod 模板规范。 |   | | 规格->模板->规格->容器 | Pod 模板的容器配置。 |   | | 规格->模板->规格->容器->映像 | hello-world 容器的 Docker 映像。 | tutum/hello-world | | 规格->模板->规格->容器->名称 | hello-world 容器的容器名。 | hello-world | | 港口 | 指定 hello-world 容器的容器端口。 | 容器港口:8080 | | 规格->模板->规格->容器->映像 | postgres 容器的 Docker 映像。 | 数据库 | | 规格->模板->规格->容器->名称 | postgres 容器的容器名称。 | 数据库 | | 港口 | 邮政容器的容器港口。 | 容器港口:5432 |

列出了hello-postgres-rc.yaml:

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    app: "MultiContainerApp"
  name: "hello-postgres"
spec:
  replicas: 1
  selector:
    app: "MultiContainerApp"
  template:
    metadata:
      labels:
        app: "MultiContainerApp"
    spec:
      containers:
        -
          image: "tutum/hello-world"
          name: "hello-world"
          ports:
            -
              containerPort: 8080
        -
          image: "postgres"
          name: "postgres"
          ports:
            -
              containerPort: 5432

从定义文件创建一个复制控制器。

kubectl create -f hello-postgres-rc.yaml

随后列出复制控制器。

kubectl get rc

如图 13-6 所示,hello-postgres复制控制器被创建并列出。

A418863_1_En_13_Fig6_HTML.gif

图 13-6。

Creating a Replication Controller from the Definition File

列出 POD

要列出窗格,请运行以下命令。

kubectl get pods

当复制控制器中的replicas字段被设置为 1 时,只有一个 Pod 被创建,如图 13-7 所示。“就绪”列列出了 0/2,这表示 pod 中的两个容器都没有就绪。最初,容器可能被列为未运行和正在创建。几秒钟后运行前面的命令,Pod 状态应该是“正在运行”,就绪状态应该是 2/2,这意味着两个容器中有两个正在运行。

A418863_1_En_13_Fig7_HTML.gif

图 13-7。

Listing the Pods

列出 Docker 容器

要列出已启动的 Docker 容器,请运行以下命令。

sudo docker ps

列出的两个容器,基于postgres映像的容器和基于tutum/hello-world映像的容器,如图 13-8 所示,由复制控制器hello-postgres启动。

A418863_1_En_13_Fig8_HTML.gif

图 13-8。

Listing the Docker Containers

创建复制控制器后描述服务

在我们创建复制控制器之前,服务hello-postgres没有与任何端点相关联。创建复制控制器和 Pod 后,再次运行以下命令来描述服务。

kubectl describe service hello-postgres

为服务公开的每个端口列出一个端点,如图 13-9 所示。

A418863_1_En_13_Fig9_HTML.gif

图 13-9。

Describing the Service

在命令行上调用 Hello World 应用

使用 curl 调用服务端点172.17.0.2,如下所示。

curl 172.17.0.2

应用生成的 HTML 得到如图 13-10 所示的输出。

A418863_1_En_13_Fig10_HTML.gif

图 13-10。

Invoking an Endpoint for the Service

启动交互式 Shell

要为安装的软件启动一个交互式外壳,可使用多容器盒的任何一个 Docker 容器,如前面图 13-8 中所列。两个容器访问相同的文件系统和 IP。使用以下命令启动交互式 shell。

sudo docker exec -it 2e351a609b5b bash

如图 13-11 所示,启动一个交互式外壳。

A418863_1_En_13_Fig11_HTML.gif

图 13-11。

Starting an Interactive Shell

正在启动 PostgreSQL Shell

要启动名为psql的 PostgreSQL 命令 shell,请在交互式 shell 中运行以下命令。

psql postgres

启动psql并显示postgres命令提示符,如图 13-12 所示。

A418863_1_En_13_Fig12_HTML.gif

图 13-12。

Starting psql Shell

第五章讨论了带有 Kubernetes 的 PostgreSQL。

设置端口转发

我们之前调用了服务端点来输出在命令行上使用 curl 生成的 HTML,但是 HTML 最好在浏览器中显示。由于 Amazon EC2 实例在默认情况下不提供浏览器,我们需要设置本地机器的端口转发,以便能够在浏览器中访问服务端点。使用以下命令将172.17.0.2:80的端口转发设置为localhost:80

ssh -i "docker.pem" -f -nNT -L 80:172.17.0.2:80 ubuntu@ec2-52-90-62-35.compute-1.amazonaws.com

转发到localhost的端口设置如图 13-13 所示。

A418863_1_En_13_Fig13_HTML.gif

图 13-13。

Setting Port Forwarding

Amazon EC2 实例的公共 DNS 可以从 Amazon EC2 控制台获得,如图 13-14 所示。

A418863_1_En_13_Fig14_HTML.gif

图 13-14。

Obtaining Public DNS

在浏览器中打开 Hello World 应用

设置端口转发后,可以在 url 为http://localhost的本地机器上的浏览器中打开应用,如图 13-15 所示。除了主机名之外,HELLO_POSTGRES监听的两个端口也被列出。

A418863_1_En_13_Fig15_HTML.gif

图 13-15。

Invoking the Service Endpoint in a Browser

扩展集群

要将群集扩展到 3 个副本或单元,请运行以下命令。

kubectl scale rc hello-postgres --replicas=3

随后列出 POD。

kubectl get pods

三个吊舱被列出,如图 13-16 所示。一些 pod 可能没有运行或最初没有准备好。几秒钟后再次运行前面的命令,列出所有状态为“正在运行”且就绪状态为 2/2 的 pod。

A418863_1_En_13_Fig16_HTML.gif

图 13-16。

Scaling the Cluster to 3 Replicas

可使用kubectl describe pod 命令描述一个 Pod。例如,用下面的命令描述hello-postgres-jliem pod。

kubectl describe pod hello-postgres-jliem

如图 13-17 所示,Pod 描述被列出。

A418863_1_En_13_Fig17_HTML.gif

图 13-17。

Describing a Pod

列出 Docker 容器

由于每个单元由两个容器组成,将集群扩展到 3 个单元或副本会启动 4 个新容器,两个新单元各有 2 个容器。在扩展集群后,运行以下命令,使用默认输出格式再次列出正在运行的 Docker 容器。

sudo docker ps

总共列出了 3 个基于postgres映像的容器和 3 个基于tutum/hello-world映像的容器,如图 13-18 所示。

A418863_1_En_13_Fig18_HTML.gif

图 13-18。

Listing the Docker Containers

描述扩展后的服务

在扩展集群后再次描述服务。

kubectl describe service hello-postgres

服务公开的每个端口都与三个端点相关联,因为有 3 个 Pods 正在运行,如图 13-19 所示。

A418863_1_En_13_Fig19_HTML.gif

图 13-19。

Describing the Service including the Service Endpoints

设置端口转发

为了能够在浏览器中打开应用,我们需要将端口转发设置为 locahost。将端口转发设置为先前未绑定的端口。在之前创建的单个 Pod 的端口转发中,localhost:80 beind 地址已经用完。要为两个新的 pod 设置端口转发,请使用本地主机上的端口 81 和 82。

ssh -i "docker.pem" -f -nNT -L 81:172.17.0.3:80 ubuntu@ec2-52-90-62-35.compute-1.amazonaws.com
ssh -i "docker.pem" -f -nNT -L 82:172.17.0.4:80 ubuntu@ec2-52-90-62-35.compute-1.amazonaws.com

前面的命令不产生任何输出,但是端口被转发到localhost,如图 13-20 所示。

A418863_1_En_13_Fig20_HTML.gif

图 13-20。

Setting Port Forwarding

在浏览器中打开 Hello World 应用

该应用可以在每个转发端口的浏览器中打开;比如在http://localhost:81打开一个浏览器。应用 HTML 显示如图 13-21 所示。HELLO_POSTGRES服务正在监听两个端口 8020 和 5432。

A418863_1_En_13_Fig21_HTML.gif

图 13-21。

Invoking a Service Endpoint in a Browser

类似地,用 url http://localhost:82在浏览器中打开另一个服务端点。监听同一端口的不同主机名被转发到localhost上的不同端口。服务端点 HTML 得到如图 13-22 所示的输出。

A418863_1_En_13_Fig22_HTML.gif

图 13-22。

Invoking another Service Endpoint in a Browser

从命令行调用 Hello World 应用

对于单个容器 Pod,可以在命令行上调用两个新服务端点中的每一个。例如,用下面的 curl 命令调用172.17.0.3端点。

curl 172.17.0.3

服务端点的 HTML 得到如图 13-23 所示的输出。

A418863_1_En_13_Fig23_HTML.gif

图 13-23。

Invoking a Service Endpoint with curl

用下面的 curl 命令调用172.17.0.4端点。

 curl 172.17.0.4

服务端点的 HTML 得到如图 13-24 所示的输出。

A418863_1_En_13_Fig24_HTML.gif

图 13-24。

Invoking another Service Endpoint with curl

删除复制控制器

要删除hello-postgres复制控制器,请运行以下命令。

kubectl delete rc hello-postgres

随后使用以下命令列出 pod。

kubectl get pods

图 13-25 中没有列出hello-postgres复制控制器的吊舱。

A418863_1_En_13_Fig25_HTML.gif

图 13-25。

Deleting the Replication Controller

删除服务

要删除服务hello-postgres,运行以下命令。

kubectl delete service hello-postgres

随后运行以下命令列出服务。

kubectl get services

未列出hello-postgres服务,如图 13-26 所示。

A418863_1_En_13_Fig26_HTML.gif

图 13-26。

Deleting the Service

摘要

在本章中,我们讨论了在一个 Pod 中使用多个容器。我们讨论了多容器 Pod 的用例,并使用tutum/hello-worldpostgres Docker 映像来创建多容器 Pod。多容器 pod 为每个 Pod 启动多个 Docker 容器,即使 Pod 是原子单位。Pod 中的多个容器共享相同的 IP 地址和文件系统。缩放多容器单元时,将为每个新单元启动多个容器。在下一章,我们将讨论在多节点集群上安装 Kubernetes。