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

83 阅读1小时+

Docker Kubenetes 微服务教程(三)

原文:Kubernetes Microservices with Docker

协议:CC BY-NC-SA 4.0

八、使用 Apache Cassandra 数据库

Apache Cassandra 是一个开源的宽列数据存储。Cassandra 是一个可伸缩的、可靠的、容错的、高度可用的 NoSQL 数据库。Cassandra 基于一种灵活的模式数据模型,在该模型中,数据存储在表的行中(也称为列族),主键标识一行。主键可以是单列或多列(复合)行键。关系数据库也在表行中存储数据,但 Cassandra 的不同之处在于表行不必遵循固定的模式。表中的每一行可能有不同的列,或者某些列可能与其他行相同。每行不必包含所有列或任何列数据。在这方面,Cassandra 提供了动态列规范。keyspace 是存储在 Cassandra 中的数据的名称空间容器。在本章中,我们将讨论在 Apache Cassandra 中使用 Kubernetes 集群管理器。本章包括以下几节。

  • 设置环境
  • 以声明方式创建 Cassandra 集群
  • 创建 Cassandra 集群势在必行

设置环境

本章需要以下软件。

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

按照第一章所述,在从 Ubuntu Server 14.04 LTS (HVM)、SSD 卷类型- ami-d05e75b8 AMI 创建的 Amazon EC2 实例上安装软件。使用 Amazon EC2 实例的公共 IP 地址 SSH 登录到 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@52.23.160.7

启动 Docker 引擎并验证其状态。

sudo service docker start
sudo service docker status

对接引擎应如图 8-1 所示运行。

A418863_1_En_8_Fig1_HTML.gif

图 8-1。

Starting Docker

列出服务。

kubectl

get services

应列出“kubernetes”服务,如图 8-2 所示。

A418863_1_En_8_Fig2_HTML.gif

图 8-2。

Listing the “kubernetes” Service

使用以下命令列出窗格和节点。

kubectl get pods
kubectl get nodes

最初,唯一运行的 pod 是 Kubernetes pod,如图 8-3 所示。

A418863_1_En_8_Fig3_HTML.gif

图 8-3。

Listing the Pod and Node for Kubernetes

Cassandra 集群可以通过声明和命令两种方式创建和管理,我们将讨论这两种方式。

以声明方式创建 Cassandra 集群

在下面的小节中,我们已经讨论了使用基于 YAML 格式的定义文件创建 Cassandra 集群。首先,创建一个代表 Cassandra 集群的服务。服务是 pod 集群的外部接口,在本章的上下文中称为 Apache Cassandra pods。

创建服务

创建一个名为cassandra-service.yaml的服务定义文件。添加表 8-1 中讨论的字段。

表 8-1。

Fields in the Service Definition File

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) | API 版本。 | 第五颅神经的眼支 | | 种类 | 类似于定义文件。 | 服务 | | 元数据 | 服务的元数据。 |   | | 元数据->名称 | 服务名称。必填字段。 | 凶事预言家 | | 元数据->标签 | 服务标签。标签可以是任何键->值对。一个服务标签设置为 app:cassandra。 | 应用:卡珊德拉 | | 投机 | 服务规范。 |   | | 规格->标签 | 规格标签。标签可以是任何键->值对。服务标签设置为 app:Cassandra。 | 应用:卡珊德拉 | | 规格->选择器 | 服务选择器。用于选择要管理的窗格。标签与选择器表达式相同的窗格由服务选择或管理。选择器表达式可以是任何键:值对。或者,可以使用','指定多个需求或表达式。app:cassandra 设置转换为服务选择器 app = cassandra。 | 应用:卡珊德拉 | | 规格->端口 | 服务端口。端口字段是必需的。 |   | | 规格->端口->端口 | 一个服务端口,服务通过该端口公开,供外部客户端访问。 | Nine thousand and forty-two | | 规格->类型 | 服务类型。 | LoadBalancer(负载均衡器) |

下面列出了cassandra-service.yaml。使用 YAML Lint ( http://www.yamllint.com/ )来验证语法。

apiVersion: v1
kind: Service
metadata:
  name: cassandra
  labels:
    app: cassandra
spec:
  labels:
    app: cassandra
  selector:
    app: cassandra
  ports:
    -
      port: 9042
  type: LoadBalancer

可以在 vi 编辑器中创建cassandra-service.yaml文件,并使用:wq 命令保存,如图 8-4 所示。

A418863_1_En_8_Fig4_HTML.gif

图 8-4。

Service Definition File in vi Editor

要创建服务,请运行以下命令。

kubectl create -f cassandra-service.yaml

随后列出服务。

kubectl get services

cassandra服务列表如图 8-5 所示。

A418863_1_En_8_Fig5_HTML.gif

图 8-5。

Creating and listing a Service for Apache Cassandra

用下面的命令描述cassandra服务。

kubectl describe svc cassandra

服务名称、名称空间、标签、选择器、类型、IP、端口、节点端口和端点被列出,如图 8-6 所示。最初没有列出服务端点,因为尚未创建 Pod。

A418863_1_En_8_Fig6_HTML.gif

图 8-6。

Describing the Service for Apache Cassandra

创建复制控制器

接下来,我们将为 Cassandra 创建一个复制控制器。复制控制器定义容器的配置和它们在 Pod 中各自的 Docker 映像。创建一个定义文件cassandra-rc.yaml并添加以下(表 8-2 )字段。

表 8-2。

Fields in the Replication Controller Definition File

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) | API 版本。 | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 复制控制器 | | 元数据 | 复制控制器元数据。 |   | | 元数据->标签 | 复制控制器标签。key:value pair app:cassandra 被设置为复制控制器上的一个标签。 | 应用:卡珊德拉 | | 投机 | 复制控制器规范。 |   | | 规格->副本 | 副本的数量。 | one | | 规格->选择器 | 复制控制器的选择器表达式。必须与规格->模板->元数据->标签字段中的标签之一相同。必填字段,但不需要明确设置,默认为规格->模板->元数据->标签字段中的标签。如果在选择器中设置了多个要求,Pod 模板标签中的多个标签必须匹配。例如,如果`selector`是`app=cassandra,name=cassandra`,则 Pod 模板标签 spec->template->metadata->标签必须包括这两个标签。 |   | | 规格->模板 | Pod 模板。必填字段。 |   | | 规格->模板->元数据 | 模板元数据。 |   | | 规格->模板->元数据->标签 | 模板标签。关键:值对 app:cassandra 设置为 Pod 上的标签。必须在模板上设置标签。标签设置翻译成 Pod 标签 app=cassandra。 | 应用:卡珊德拉 | | 规格->模板->规格 | 容器规格。 |   | | 规格->模板->规格->容器 | POD 里的容器。 |   | | 规格->模板->规格->容器->映像 | 容器的 Docker 映像。 | 凶事预言家 | | 规格->模板->规格->容器->名称 | 容器名称。 | 凶事预言家 | | 规格->模板->规格->容器->端口 | 容器港口。 |   | | 规格->模板->规格->容器->端口->容器端口 | CQL 命令 shell 的容器端口。 | Nine thousand and forty-two | | 规格->模板->规格->容器->端口->名称 | 端口名称。 | 持续查询语言 | | 规格->模板->规格->容器->端口->容器端口 | 节俭客户的容器港口。 | Nine thousand one hundred and sixty | | 规格->模板->规格->容器->端口->名称 | 端口名称。 | 节约 |

cassandra-rc.yaml已列出。

apiVersion: v1
kind: ReplicationController
metadata:
  name: cassandra-rc
  labels:
    app: cassandra
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: cassandra
    spec:
      containers:
        -
        image: cassandra
        name: cassandra
        ports:
          -
            containerPort: 9042
            name: cql
          -
            containerPort: 9160
            name: thrift

可以在 vi 编辑器中创建cassandra-rc.yaml字段,并用:wq 命令保存,如图 8-7 所示。

A418863_1_En_8_Fig7_HTML.gif

图 8-7。

Replication Controller Definition File in vi Editor

使用以下命令创建一个复制控制器。

kubectl create -f cassandra-rc.yaml

随后列出复制控制器。

kubectl get rc

cassandra-rc复制控制器被创建并列出,如图 8-8 所示。

A418863_1_En_8_Fig8_HTML.gif

图 8-8。

Creating a Replication Controller from Definition File

列出由复制控制器创建的窗格。

kubectl get pods

当复制控制器定义文件中的副本数量设置为 1 时,会创建一个 Pod,并在图 8-9 中列出。前面的命令可能需要运行多次才能将 Pod 列为正在运行和就绪。或者,在创建复制控制器几秒钟后第一次运行该命令;到一分钟时,所有的吊舱都应该已经启动了。

A418863_1_En_8_Fig9_HTML.gif

图 8-9。

Listing Pod/s for Apache Cassandra

描述一下卡珊德拉服务。

kubectl describe svc cassandra

为 Pod 列出一个端点,如图 8-10 所示。当在创建复制控制器之前列出服务描述时,没有列出任何端点。

A418863_1_En_8_Fig10_HTML.gif

图 8-10。

Describing the Service after creating the Replication Controller

在前面的示例中,我们创建了一个复制控制器,副本数量设置为 1。复制控制器不必一开始就创建副本。为了进行演示,我们将再次创建复制控制器,但使用不同的副本设置。删除先前创建的复制控制器。

kubectl delete rc cassandra-rc

修改cassandra-rc.yaml将副本字段设置为 0,如图 8-11 所示。

A418863_1_En_8_Fig11_HTML.gif

图 8-11。

Setting Replicas to 0

使用修改后的定义文件再次创建复制控制器。

kubectl create -f cassandra-rc.yaml

随后列出副本。

kubectl get rc

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

A418863_1_En_8_Fig12_HTML.gif

图 8-12。

Creating the Replication Controller with Modified Definition File

列出 POD。

kubectl get pods

因为副本字段被设置为 0,所以副本被列为 0,如图 8-13 所示。

A418863_1_En_8_Fig13_HTML.gif

图 8-13。

With Replicas as 0 no Pod gets created

扩展数据库

从创建了 0 个副本的复制控制器开始,我们应该将群集扩展到单个副本。运行以下命令将 Pod 集群扩展到 1 个副本。

kubectl scale rc cassandra-rc --replicas=1

随后列出 POD。

kubectl get pods

前述命令的输出如图 8-14 所示。“scaled”输出表示群集已被缩放。单个 Pod 可能需要一段时间(几秒钟)才能启动并准备就绪。

A418863_1_En_8_Fig14_HTML.gif

图 8-14。

Scaling the Replication Controller to 1 Pod

再次描述一下cassandra服务。

kubectl describe svc cassandra

如图 8-15 所示,添加的 Pod 应列出一个端点。

A418863_1_En_8_Fig15_HTML.gif

图 8-15。

Describing the Service after Scaling the Cluster

描述 Pod

要描述 Pod,请运行以下命令。

kubectl describe pod cassandra-rc-tou4u

输出有关 Pod 的详细信息,如名称、名称空间、映像、节点、标签、状态、IP 地址和事件,如图 8-16 所示。Pod 标签是复制控制器定义文件中指定的app=cassandra

A418863_1_En_8_Fig16_HTML.gif

图 8-16。

Describing the single Pod

启动交互式 Shell

由于“cassandra”Docker 映像继承自“debian”Docker 映像,因此可以使用交互式 bash shell 来访问基于 Cassandra 映像的 Docker 容器。要启动一个交互式 bash shell 来访问 Docker 容器中运行的 Cassandra 服务器,我们需要获取容器 id。列出正在运行的容器。

sudo docker ps

所有正在运行的容器被列出,如图 8-17 所示。复制cassandra映像容器的容器 id。

A418863_1_En_8_Fig17_HTML.gif

图 8-17。

Listing the Docker Containers

使用容器 id 启动一个交互式 bash shell。

sudo docker exec -it e8fc5e8ddff57 bash

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

A418863_1_En_8_Fig18_HTML.gif

图 8-18。

Starting the Interactive Shell

启动 CQL Shell

Cassandra 查询语言(CQL)是 Apache Cassandra 的查询语言。在下面几节中,我们将运行 CQL 命令来创建一个键空间和一个表。使用以下命令启动 CQL Shell。

cqlsh

CQL 壳牌 5.0.1 启动如图 8-19 所示。

A418863_1_En_8_Fig19_HTML.gif

图 8-19。

Starting the cqlsh Shell

创建密钥空间

接下来,使用复制类 SimpleStrategy 和复制因子 3 创建一个名为 CatalogKeyspace 的键空间。

CREATE KEYSPACE CatalogKeyspace
            WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 3};

创建一个键空间,如图 8-20 所示。

A418863_1_En_8_Fig20_HTML.gif

图 8-20。

Creating a Keyspace

更改密钥空间

可以使用 ALTER KEYSPACE 命令更改密钥空间。运行以下命令,将密钥空间设置复制因子更改为 1。

ALTER KEYSPACE CatalogKeyspace
          WITH replication = {'class': 'SimpleStrategy', 'replication_factor' : 1};

如图 8-21 所示,键空间被改变。

A418863_1_En_8_Fig21_HTML.gif

图 8-21。

Altering a Keyspace

使用密钥空间

要使用CatalogKeyspace键区,运行以下命令。

use CatalogKeyspace;

键区CatalogKeyspace的设置如图 8-22 所示。

A418863_1_En_8_Fig22_HTML.gif

图 8-22。

Setting a Keyspace to be used

创建表格

表也称为柱族。CREATE TABLECREATE COLUMN FAMILY子句都可以用来创建一个表(列族)。使用下面的 CQL 语句创建一个名为catalog的表。

CREATE TABLE catalog(catalog_id text,journal text,publisher text,edition text,title text,author text,PRIMARY KEY (catalog_id)) WITH compaction = { 'class' : 'LeveledCompactionStrategy' };

使用以下 CQL 语句向表中添加两行数据。

INSERT INTO catalog (catalog_id, journal, publisher, edition,title,author) VALUES ('catalog1','Oracle Magazine', 'Oracle Publishing', 'November-December 2013', 'Engineering as a Service','David A. Kelly') IF NOT EXISTS;
INSERT INTO catalog (catalog_id, journal, publisher, edition,title,author) VALUES ('catalog2','Oracle Magazine', 'Oracle Publishing', 'November-December 2013', 'Quintessential and Collaborative','Tom Haunert') IF NOT EXISTS;

前述命令的输出如图 8-23 所示。创建一个 Cassandra 表并添加两行数据。

A418863_1_En_8_Fig23_HTML.gif

图 8-23。

Creating an Apache Cassandra Table

运行以下 CQL 查询语句从catalog表中选择数据。

SELECT * FROM catalog;

添加的两行数据被列出,如图 8-24 所示。

A418863_1_En_8_Fig24_HTML.gif

图 8-24。

Querying an Apache Cassandra Table

从表格中删除

要删除数据行,运行DELETE CQL 语句。主键列值不能用DELETE删除。用下面的 CQL 语句删除catalog_id为“目录”的行的其他列值。

DELETE journal, publisher, edition, title, author from catalog WHERE catalog_id='catalog1';

随后运行下面的 CQL 查询,从catalog表中选择数据。

SELECT * FROM catalog;

如图 8-25 所示,只有一行完整的数据被输出。另一行只列出了catalog_id列的值,其他所有列的值都是null

A418863_1_En_8_Fig25_HTML.gif

图 8-25。

Querying Table after deleting Data from a Row

截断表格

截断表意味着删除包括主键列值在内的所有表数据。运行下面的TRUNCATE CQL 语句删除所有行。

TRUNCATE catalog;

随后再次运行 CQL 查询语句。

SELECT * from catalog;

没有列出如图 8-26 所示的行;运行一个TRUNCATE语句后,甚至不会列出空值。

A418863_1_En_8_Fig26_HTML.gif

图 8-26。

Querying a Table after Truncating a Table

删除表和键空间

要删除一个表,请运行带有DROP TABLE子句的 CQL 语句。如果该表存在,则IF EXISTS子句删除该表,但如果该表不存在,则不返回错误。

DROP TABLE IF EXISTS catalog;

使用DROP KEYSPACE子句语句删除CatalogKeyspace键空间。如果键空间存在,则IF EXISTS子句删除该键空间,但是如果键空间不存在,则不返回错误。

DROP KEYSPACE IF EXISTS CatalogKeyspace;

要验证密钥空间CatalogKeyspace是否已被删除,请运行以下语句。

use CatalogKeyspace;

由于CatalogKeyspace键区不存在,产生如图 8-27 所示的错误。

A418863_1_En_8_Fig27_HTML.gif

图 8-27。

Dropping a Table

创建卷

在第七章中,我们介绍了卷,如何使用卷挂载将它们挂载到 Pod 中,以及如何在容器中访问它们。我们介绍了各种类型的卷,并演示了emptyDir类型的卷。在本节中,我们将使用另一种类型的卷,即hostPath卷。hostPath卷将一个目录从主机装载到 Pod 中。Pod 中的所有容器和基于使用hostPath类型卷的 Pod 模板的所有 Pod 都可以访问主机上的目录。作为对前面使用的复制控制器的修改,我们将向cassandra-rc.yaml文件添加一个类型为hostPath的卷。例如,如果主机目录/cassandra/data要安装在 Pod 中,则在 spec- >模板字段中添加以下卷。

volumes:
  -
    hostPath:
      path: /cassandra/data
    name: cassandra-storage

使用与emptyDir卷相同的字段将卷安装在 Pod 中。修改后的cassandra-rc.yaml被列出。

apiVersion: v1
kind: ReplicationController
metadata:
  name: cassandra-rc
  labels:
    app: cassandra
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: cassandra
    spec:
      containers:
        -
        image: cassandra
        name: cassandra
        ports:
          -
            containerPort: 9042
            name: cql
          -
            containerPort: 9160
            name: thrift
        volumeMounts:
          -
            mountPath: /cassandra/data
            name: cassandra-storage
      volumes:
        -
          hostPath:
            path: /cassandra/data
          name: cassandra-storage

cassandra-rc.yaml定义文件可以在 vi 编辑器中编辑,并用:wq 命令保存,如图 8-28 所示。建议在字段值中添加引号。

A418863_1_En_8_Fig28_HTML.gif

图 8-28。

Replication Controller Definition File with a Volume of type hostPath

装载到 Pod 中的主机目录必须预先存在。创建/cassandra/data目录并将其权限设置为全局(777)。

sudo mkdir –p /cassandra/data
sudo chmod –R 777 /cassandra/data

前述命令的输出如图 8-29 所示。创建了/cassandra/data目录。

A418863_1_En_8_Fig29_HTML.gif

图 8-29。

Creating the Directory for the Volume

将目录(cd)更改为主机上的/cassandra/data目录。

cd /cassandra/data

列出/cassandra/data目录中的文件和目录。

ls –l

最初/cassandra/data为空,如图 8-30 所示。使用 vi 编辑器将示例文件cassandra.txt添加到目录中。随后再次列出目录文件和目录。

A418863_1_En_8_Fig30_HTML.gif

图 8-30。

Adding a file in the hostPath Volume Directory

vi cassandra.txt
ls –l

如图 8-30 所示cassandra.txt文件被列出。hostPath卷的作用是使/cassandra/data目录对 Pod 中的所有容器可用。

按照前面对定义文件的讨论,创建一个复制控制器。应该创建一个 Pod。列出 Docker 容器。

sudo docker ps

复制映像“cassandra”的 Docker 容器的容器 id,如图 8-31 所示。

A418863_1_En_8_Fig31_HTML.gif

图 8-31。

Listing the Docker Containers

使用容器 id 启动一个交互式 shell。

sudo docker exec -it 11a4b26d9a09 bash

交互外壳启动,如图 8-32 所示。

A418863_1_En_8_Fig32_HTML.gif

图 8-32。

Starting an Interactive Shell

将目录(cd)更改为/cassandra/data目录,并列出目录中的文件。

cd /cassandra/data
ls –l

如图 8-33 所示,cassandra.txt 文件被列出。/cassandra/data 目录存在于主机上,但可以从容器中访问。

A418863_1_En_8_Fig33_HTML.gif

图 8-33。

Accessing the Volume in a Docker Container

类似地,可以创建其他类型的卷。以下是 AWS 卷的volumeMountsvolumes fields设置。volumeID字段的格式为aws://zone/volume id。

    volumeMounts:
        -
          mountPath: /aws-ebs
          name: aws-volume
  volumes:
      -
        name: aws-volume
        awsElasticBlockStore:
              volumeID: aws://us-east-ib/vol-428ba3ae
              fsType: ext4

更完整的cassandra-rc.yaml文件如图 8-34 所示。

A418863_1_En_8_Fig34_HTML.gif

图 8-34。

Volume of type awsElasticBlockStore in a Replication Controller Definition File

创建 Cassandra 集群势在必行

如果要使用大多数字段的默认设置,强制创建一个复制控制器是更好的选择。

创建复制控制器

要在命令行上创建复制控制器,请使用kubectl run命令。对于基于 Docker 映像“cassandra”的复制控制器,运行以下命令,其中复制控制器名称为“cassandra ”,端口为 9042。副本设置为 1,也是默认值。

kubectl run cassandra --image=cassandra --replicas=1 --port=9042

随后列出复制控制器。

kubectl get rc

“cassandra”复制控制器被创建并列出,如图 8-35 所示。

A418863_1_En_8_Fig35_HTML.gif

图 8-35。

Creating a Replication Controller Imperatively

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

kubectl get pods

创建的单个 Pod 被列出,如图 8-36 所示。

A418863_1_En_8_Fig36_HTML.gif

图 8-36。

Listing the single Pod

要描述复制控制器,请运行以下命令。

kubectl describe rc cassandra

复制控制器的名称、命名空间、映像、选择器、标签、副本、pod 状态和事件会被列出,如图 8-37 所示。对于cassandra复制控制器,选择器默认为“run=cassandra”。

A418863_1_En_8_Fig37_HTML.gif

图 8-37。

Describing the Replication Controller

创建服务

要将复制控制器cassandra作为服务公开,请运行kubectl expose命令。需要指定端口,并为该服务设置为 9042。

kubectl expose rc cassandra --port=9042 --type=LoadBalancer

cassandra服务被创建,如图 8-38 所示。

A418863_1_En_8_Fig38_HTML.gif

图 8-38。

Creating a Service for Apache Cassandra Imperatively

用下面的命令描述服务。

kubectl describe service cassandra

如图 8-39 所示,列出了服务名称、名称空间、标签、选择器、类型、IP、端口、节点端口和端点。服务选择器 run=cassandra 必须与要管理的 Pod 上的标签相同。

A418863_1_En_8_Fig39_HTML.gif

图 8-39。

Describing the Service

扩展数据库

要扩展集群,运行kubectl scale命令。扩展 Cassandra 复制控制器的一个重要原因是运行更多的 Cassandra 节点,并让它们加入集群,我们演示了如何扩展集群。但是并不总是需要扩展集群。集群也可以缩小。要将群集缩减到 0 个副本,请运行以下命令。

kubectl scale rc cassandra --replicas=0

图 8-40 中的“scaled”输出表示组合仪表已经缩小。

A418863_1_En_8_Fig40_HTML.gif

图 8-40。

Scaling Down the Database Cluster to 0 Replicas

列出 POD。

kubectl get pods

没有 pod 被列出,如图 8-41 所示。

A418863_1_En_8_Fig41_HTML.gif

图 8-41。

Listing the Pods after Scaling Down

使用以下命令列出服务。

kubectl get services

将集群扩展到 0 个副本将不会为服务留下要管理的 Pod,但服务仍在运行,如图 8-42 所示。

A418863_1_En_8_Fig42_HTML.gif

图 8-42。

Listing the Services after Scaling Down

但是该服务没有任何与之关联的端点,如图 8-43 中的kubectl describe命令所示。

A418863_1_En_8_Fig43_HTML.gif

图 8-43。

Describing the Service after Scaling Down

删除复制控制器和服务

要删除复制控制器“cassandra ”,请运行以下命令。

kubectl delete rc cassandra

随后列出复制控制器。

kubectl get rc

要删除服务“cassandra ”,请运行以下命令。

kubectl delete service cassandra

随后列出服务。

kubectl get services

前面命令的输出如图 8-44 所示。复制控制器和服务将被删除,但不会列出。

A418863_1_En_8_Fig44_HTML.gif

图 8-44。

Deleting the Replication Controller and the Service

摘要

在本章中,我们使用 Kubernetes 创建了一个 Apache Cassandra 集群。我们同时使用了声明式和命令式方法。我们在前一章中介绍了卷,在本章中,我们讨论了使用另外两种类型的卷:hostPath 和 AWS 卷。我们不仅扩大了集群,还缩小了集群。我们演示了复制控制器不需要 Pod 运行,并且可以指定 0 个副本。在下一章中,我们将讨论使用 Kubernetes 集群管理器和另一个 NoSQL 数据库 Couchbase。

九、使用 Couchbase

Couchbase 是一个基于 JSON 数据模型的分布式 NoSQL 数据库。Couchbase 比 MongoDB 和 Apache Cassandra 都快。Couchbase 提供了一些 MongoDB 和 Cassandra 中没有的特性,比如图形用户界面(GUI),Couchbase Web 控制台。Couchbase 还提供了命令行工具,比如couchbase-clicbbackupcbrestorecbtransfer。作为一个分布式数据库,Couchbase 可以从 Kubernetes 集群管理器提供的集群管理中获益,这是我们将在本章中讨论的。本章包括以下几节。

  • 设置环境
  • 以声明方式创建 Couchbase 集群
  • 强制创建 Couchbase 集群

设置环境

我们在 Amazon EC2 上使用了一个 Ubuntu 实例,它是使用其他章节中使用的相同 AMI 创建的,Ubuntu Server 14.04 LTS (HVM),SSD 卷类型- ami-d05e75b8。如果从 AMI 创建的实例已经存在,则可以使用相同的实例。本章需要以下软件。

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

首先,我们需要登录到 Ubuntu 实例。从 Amazon EC2 实例控制台获取 Ubuntu 实例的公共 IP 地址,如图 9-1 所示。

A418863_1_En_9_Fig1_HTML.gif

图 9-1。

Getting Public IP Address

使用公共 IP 地址登录 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@54.172.55.212

Ubuntu 实例被登录,如图 9-2 所示。

A418863_1_En_9_Fig2_HTML.gif

图 9-2。

Logging into Ubuntu Instance on Amazon EC2

启动 Docker 引擎并验证其状态。

sudo service docker start
sudo service docker status

如图 9-3 所示,Docker 引擎应被列为正在运行。

A418863_1_En_9_Fig3_HTML.gif

图 9-3。

Starting Docker Engine

列出正在运行的服务。

kubectl get services

kubernetes 服务应被列为正在运行,如图 9-4 所示。

A418863_1_En_9_Fig4_HTML.gif

图 9-4。

Listing the “kubernetes” Service

列出节点。

kubectl get nodes

该节点应以“就绪”状态列出,如图 9-5 所示。

A418863_1_En_9_Fig5_HTML.gif

图 9-5。

Listing the Single Node

以声明方式创建 Couchbase 集群

在下面的小节中,我们将使用定义文件创建一个 Couchbase Pod、一个复制控制器和一个服务。

创建 Pod

Pod 定义文件用于创建单个 Pod。一个 Pod 可以有 0 个或多个容器配置。创建一个定义文件couchbase.yaml。将以下(表 9-1 )字段添加到定义文件中。

表 9-1。

Pod Definition File Fields

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | POD | | 元数据 | Pod 元数据。 |   | | 元数据->标签 | POD 标签。服务选择器利用标签来选择要管理的 pod。 | app:couch app | | 元数据->名称 | Pod 名称。 | 美洲狮号 | | 投机 | Pod 规格。 |   | | 规格->容器 | POD 里的容器。 |   | | 规格->容器->映像 | 容器映像。对于 Couchbase 服务器,映像是“couchbase” | 美洲狮号 | | 规格->容器->名称 | 容器名称。 | 美洲狮号 | | 规格->容器->端口 | 容器港口。 |   | | 规格->容器->端口->容器端口 | Couchbase 服务器的容器端口。 | Eight thousand and ninety-one |

列出couchbase.yaml定义文件。

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: couchbaseApp
  name: couchbase
spec:
  containers:
    -
      image: couchbase
      name: couchbase
      ports:
        -
          containerPort: 8091

可以在 vi 编辑器中创建couchbase.yaml文件,并用:wq 命令保存,如图 9-6 所示。

A418863_1_En_9_Fig6_HTML.gif

图 9-6。

Pod Definition file couchbase.yaml in vi Editor

运行以下命令从定义文件创建一个 Pod。

kubectl create -f couchbase.yaml

如图 9-7 中的“Pod/couch base”输出所示,创建一个 Pod。

A418863_1_En_9_Fig7_HTML.gif

图 9-7。

Creating a Pod from the Definition File

随后列出 POD。

kubectl get pods

名为“couchbase”的 Pod 被列出,如图 9-7 所示。最初,状态可以不同于“正在运行”,并且就绪列可以是未就绪的;1/1 处于就绪状态,0/1 未就绪。

几秒钟后再次运行以下命令。

kubectl get pods

如图 9-8 所示couchbase吊舱被列为“运行中”和就绪- > 1/1。

A418863_1_En_9_Fig8_HTML.gif

图 9-8。

Listing the couchbase Pod

创建服务

在本节中,我们将使用服务定义文件创建一个服务。创建一个couchbase-service.yaml文件,并将以下(表 9-2 )字段添加到文件中。

表 9-2。

Service Definition File couchbase-service.yaml

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 服务 | | 元数据 | 服务元数据。 |   | | 元数据->标签 | 服务标签。 | app:couch app | | 元数据->名称 | 服务名称。 | 美洲狮号 | | 投机 | 服务规范。 |   | | 规格->端口 | 服务公开的端口。 |   | | 规格->端口->端口 | 服务公开的端口。 | Eight thousand and ninety-one | | 规格>连接埠>目标连接埠 | 服务的目标端口,可以是端口号或后端端口的名称。目标端口设置增加了灵活性,因为端口号可以修改,而端口名称保持不变。 | Eight thousand and ninety-one | | 规格->选择器 | Pod 选择器,可以是一个或多个标签键:值表达式/标签。选择器中的所有 key:value 表达式必须与服务要选择的 Pod 的标签相匹配。Pod 可以有额外的标签,但必须在服务选择的选择器中包含标签。服务将流量路由到标签与选择器表达式匹配的 pod。在示例服务定义文件中仅使用了一个选择器表达式。如果选择器为空,则选择所有窗格。app: couchbaseApp 设置默认为选择器 app = couchbaseApp。 | app:couch app | | 规格->选择器->类型 | 服务类型。 | LoadBalancer(负载均衡器) |

couchbase-service.yaml已列出。

apiVersion: v1
kind: Service
metadata:
  labels:
    app: couchbaseApp
  name: couchbase
spec:
  ports:
    -
      port: 8091
      targetPort: 8091
  selector:
    app: couchbaseApp
  type: LoadBalancer

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

kubectl create -f couchbase-service.yaml

随后列出正在运行的服务。

kubectl get services

如图 9-9 所示的“services/couchbase”输出表明couchbase服务已经被创建。“couchbase”服务被列出,如图 9-9 所示。

A418863_1_En_9_Fig9_HTML.gif

图 9-9。

Listing the couchbase Service

使用以下命令列出服务端点。

kubectl get endpoints

couchbase服务的服务端点如图 9-10 所示。

A418863_1_En_9_Fig10_HTML.gif

图 9-10。

Listing the Endpoints

创建复制控制器

在本节中,我们将使用一个定义文件创建一个复制控制器。创建一个couchbase-rc.yaml文件,并将以下(表 9-3 )字段添加到文件中。

表 9-3。

Definition File for Replication Controller

| 田 | 描述 | 价值 | 必填字段(包括默认设置) | | --- | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | 是 | | 种类 | 定义文件的种类。 | 复制控制器 | 是 | | 元数据 | 复制控制器元数据。 |   | 是 | | 元数据->标签 | 复制控制器标签。 | app:couch app | 不 | | 元数据->名称 | 复制控制器的名称。 | 美洲狮号 | 是 | | 投机 | 复制控制器规范。 |   | 是 | | 规格->副本 | Pod 副本的数量。默认为 1 个副本。 | Two | 是 | | 规格->选择器 | 一个或多个 key:value 表达式,用于选择要管理的窗格。包含具有与选择器表达式相同的表达式的标签的窗格由复制控制器管理。Pod 可以包括附加标签,但必须包括由复制控制器管理的选择器中的标签。如果未指定,选择器默认为规范->模板->元数据->标签键:值表达式。app 的一个设置:couchbaseApp 翻译成选择器 app = couchbaseApp。 | app:couch app | 是 | | 规格->模板 | Pod 模板。 |   | 是 | | 规格->模板->元数据 | Pod 模板元数据。 |   | 是 | | 规格->模板->元数据->标签 | Pod 模板标签。 | app:couch app | 是 | | 规格->模板->规格 | Pod 模板规范。 |   | 是 | | 规格->模板->规格->容器 | Pod 模板的容器配置。 |   | 是 | | 规格->模板->规格->容器->映像 | Docker 的形象。 | 美洲狮号 | 是 | | 规格->模板->规格->容器->名称 | 容器名称。 | 美洲狮号 | 是 | | 规格->模板->规格->容器->端口 | 容器港口。 |   | 不 | | 规格->模板->规格->容器->端口->容器端口 | 容器港口。 | Eight thousand and ninety-one | 不 |

couchbase-rc.yaml已列出。

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    app: couchbaseApp
  name: couchbase
spec:
  replicas: 2
  selector:
    app: couchbaseApp
  template:
    metadata:
      labels:
        app: couchbaseApp
    spec:
      containers:
        -
          image: couchbase
          name: couchbase
          ports:
          -
            containerPort: 8091

可以在 vi 编辑器中创建couchbase-rc.yaml,如图 9-11 所示。

A418863_1_En_9_Fig11_HTML.gif

图 9-11。

Replication Controller Definition File couchbase-rc.yaml in vi Editor

使用以下命令创建复制控制器。

kubectl create -f couchbase-rc.yaml

随后,列出复制控制器。

kubectl get rc

如图 9-12 所示的“replication controllers/couchbase”的输出表明“couch base”复制控制器已经被创建。第二个命令列出了“couchbase”复制控制器。副本列为 2,但这并不意味着复制控制器创建了两个新副本。复制控制器基于匹配 Pod 标签的选择器表达式来管理 Pod。如果具有匹配标签的某个其他 Pod 已经在运行,它将计入副本设置。

A418863_1_En_9_Fig12_HTML.gif

图 9-12。

Creating and listing a Replication Controller from the Definition File

列出 POD

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

kubectl get pods

如图 9-13 所示,列出了两个 Pod,其中一个 Pod 是之前使用 Pod 定义文件创建的 Pod。Pod 定义文件中的标签是 app:“couch base app”,这也是复制控制器的选择器表达式。表达式 app:“couch base app”翻译成 app= couchbaseApp。因此,当创建副本设置为 2 的复制控制器时,仅创建一个新的 Pod。

A418863_1_En_9_Fig13_HTML.gif

图 9-13。

Listing the Pods for Couchbase Server

列出日志

要列出一个 Pod 的日志,运行kubectl logs命令。pod 名称可以从前面的 pod 列表中复制。

kubectl logs couchbase-0hglx

输出如图 9-14 所示。输出表明 WEB UI 在http://<ip>:8091可用。

A418863_1_En_9_Fig14_HTML.gif

图 9-14。

Listing Pod Logs

描述服务

要描述couchbase服务,请运行以下命令。

kubectl describe svc couchbase

服务名、名称空间、标签、选择器、类型、IP、端口、节点端口和端点被列出,如图 9-15 所示。将selector列为app=couchbaseApp

A418863_1_En_9_Fig15_HTML.gif

图 9-15。

Describing the Service for Couchbase

列出端点

再次列出端点。

kubectl get endpoints

之前列出端点时,因为只有一个 Pod 在运行,所以只列出了一个端点。两个吊舱运行时,两个端点被列出,如图 9-16 所示。

A418863_1_En_9_Fig16_HTML.gif

图 9-16。

Listing the Endpoints for Couchbase

设置端口转发

当我们列出 Couchbase Pod 的日志时,调用 web 控制台的 URL 被列为http://<ip>:8091< ip >是 Pod 的服务端点。上一节列出了两个服务端点。例如,在主机浏览器上调用http://172.17.0.2:8091将打开 web 控制台。默认情况下,Amazon EC2 Ubuntu 实例不会安装 web 浏览器。或者,我们将端口转发设置到本地机器,并从本地机器上的浏览器打开 web 控制台,这需要有一个可用的浏览器。要设置端口转发,我们需要知道运行 Kubernetes 的 Amazon EC2 实例的公共 DNS。公共 DNS 可以从亚马逊 EC2 控制台获得,如图 9-17 所示。

A418863_1_En_9_Fig17_HTML.gif

图 9-17。

Obtaining the Public DNS

本地计算机上要转发到的端口必须是打开的,并且尚未绑定。例如,使用以下命令将一个端点绑定到localhost上的端口 8093,将另一个端点绑定到localhost上的端口 8094。

ssh -i "docker.pem" -f -nNT -L 8093:172.17.0.3:8091 ubuntu@ec2-54-172-55-212.compute-1.amazonaws.com
ssh -i "docker.pem" -f -nNT -L 8094:172.17.0.2:8091 ubuntu@ec2-54-172-55-212.compute-1.amazonaws.com

从服务端点到localhost端口的端口转发如图 9-18 所示。

A418863_1_En_9_Fig18_HTML.gif

图 9-18。

Setting Port Forwarding to localhost:8093 and localhost:8094

登录 Couchbase Web 控制台

本地机器上有两个端口可用于打开 Couchbase web 控制台,8093 和 8094。这两种方法中的一种或两种都可以用来打开 Couchbase web 控制台。例如,在网络浏览器中打开 URL http://localhost:8093。如图 9-19 所示,治疗床控制台打开。点击设置来设置 Couchbase 服务器。

A418863_1_En_9_Fig19_HTML.gif

图 9-19。

Setting Up Couchbase Server

配置 Couchbase 服务器

在这一节中,我们将配置 Couchbase 服务器,这与使用 Kubernetes 没有直接关系,但为了完整起见会进行讨论。当点击设置按钮时,显示配置服务器窗口,如图 9-20 所示。

A418863_1_En_9_Fig20_HTML.gif

图 9-20。

Configuring Server Disk Storage, Hostname

保留默认设置,向下滚动选择 Start a new cluster。如果没有足够的 RAM 可用,可能必须降低 RAM 设置。点击下一步,如图 9-21 所示。

A418863_1_En_9_Fig21_HTML.gif

图 9-21。

Starting New Cluster

列出了一些样本桶,但不要求选择样本桶。点击下一步,如图 9-22 所示。

A418863_1_En_9_Fig22_HTML.gif

图 9-22。

Sample Buckets are not required to be selected

创建默认存储桶设置包括存储桶类型,它应该是 Couchbase,如图 9-23 所示。应通过“启用”复选框启用副本。

A418863_1_En_9_Fig23_HTML.gif

图 9-23。

Configuring Default Bucket

向下滚动,使用“启用”复选框启用冲洗模式。点击下一步,如图 9-24 所示。

A418863_1_En_9_Fig24_HTML.gif

图 9-24。

Enabling Flush Mode and completing Server Configuration

接下来,接受如图 9-25 所示的条款和条件,并点击下一步。

A418863_1_En_9_Fig25_HTML.gif

图 9-25。

Accepting Terms and Conditions

如图 9-26 所示,为确保服务器安全,指定一个密码,并在验证密码字段中指定相同的密码。

A418863_1_En_9_Fig26_HTML.gif

图 9-26。

Securing the Server with Username and Password

Couchbase 服务器得到配置。选择“服务器节点”页签,列出服务器节点名称,如图 9-27 所示。服务器节点名称是服务端点之一。

A418863_1_En_9_Fig27_HTML.gif

图 9-27。

Server Node Name is the same as a Service Endpoint

添加文档

接下来,我们将向 Couchbase 服务器添加一些文档。选择数据桶选项卡,如图 9-28 所示。

A418863_1_En_9_Fig28_HTML.gif

图 9-28。

Selecting Data Buckets Tab

默认存储桶被列出,如图 9-29 所示。点击文档。

A418863_1_En_9_Fig29_HTML.gif

图 9-29。

Clicking on Documents Button for the default Bucket

最初,“默认”铲斗是空的,如图 9-30 所示。

A418863_1_En_9_Fig30_HTML.gif

图 9-30。

Initially no Documents are present in the default Data Bucket

点击创建文档,添加一个文档,如图 9-31 所示。

A418863_1_En_9_Fig31_HTML.gif

图 9-31。

Clicking on Create Document

在创建文档对话框中指定一个文档 Id 并点击创建,如图 9-32 所示。

A418863_1_En_9_Fig32_HTML.gif

图 9-32。

Specifying Document ID

添加一个带有默认字段的新 JSON 文档,如图 9-33 所示。

A418863_1_En_9_Fig33_HTML.gif

图 9-33。

The catalog1 Document gets created with Default Fields

将下面的 JSON 文档复制粘贴到catalog1文档中。

{
  "journal": "Oracle Magazine",
  "publisher": "Oracle Publishing",
  "edition": "November-December 2013",
  "title": "Quintessential and Collaborative",
  "author": "Tom Haunert"
}

点击保存更新catalog1文件,如图 9-34 所示。

A418863_1_En_9_Fig34_HTML.gif

图 9-34。

Saving a JSON Document

如图 9-35 所示,当选择“默认”存储桶的文档链接时,catalog1文档被保存并被列出。

A418863_1_En_9_Fig35_HTML.gif

图 9-35。

The catalog1 Document in default Bucket

类似地,添加文档 ID 为catalog2的另一个文档,并将下面的清单复制并粘贴到该文档中。

{
"journal": “Oracle Magazine”,
"publisher": "Oracle Publishing",
"edition": "November December 2013",
"title": "Engineering as a Service",
"author": "David A. Kelly",
}

catalog2文件如图 9-36 所示。

A418863_1_En_9_Fig36_HTML.gif

图 9-36。

Adding another Document catalog2

如图 9-37 所示,“默认”存储桶的文档链接链接添加的两个文档。

A418863_1_En_9_Fig37_HTML.gif

图 9-37。

Listing the two Documents in the default Bucket

启动交互式 Shell

接下来,我们将启动一个交互式 bash shell 来从命令行访问 Couchbase 服务器。根据 Docker 映像“couchbase”获取其中一个 Docker 容器的容器 id,如图 9-38 所示。

A418863_1_En_9_Fig38_HTML.gif

图 9-38。

Obtaining the Container Id

使用容器 id,启动一个交互式 shell。

sudo docker exec -it e1b2fe2f24bd bash

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

A418863_1_En_9_Fig39_HTML.gif

图 9-39。

Starting an Interactive Shell

使用 cbtransfer 工具

从交互式外壳中,可以运行命令行工具来访问 Couchbase 服务器。例如,运行cbtransfer工具,该工具用于在集群之间和文件之间传输数据,将服务器http://172.17.0.3:8091的默认存储桶中的文档输出到stdout

cbtransfer http://172.17.0.3:8091/ stdout:

从 web 控制台添加的两个文档得到如图 9-40 所示的输出。

A418863_1_En_9_Fig40_HTML.gif

图 9-40。

Using the cbtransfer Tool

在下一节中,我们将在命令行上强制使用 Kubernetes 创建一个 Couchbase 集群。因为我们将使用相同的复制控制器名称和服务名称,所以删除复制控制器“couchbase”并删除名为“couchbase”的服务

kubectl delete rc couchbase
kubectl delete svc couchbase

强制创建 Couchbase 集群

在下面的小节中,我们将在命令行上创建一个 Couchbase 集群。

创建复制控制器

使用 Docker 映像“couchbase”创建一个名为“couchbase”的复制控制器,带有两个副本和容器端口 as 8091,使用以下命令。

kubectl run couchbase --image=couchbase --replicas=2 --port=8091

复制控制器的创建如图 9-41 所示。默认的选择器是“run=couchbase”,这意味着带有标签“run=couchbase”的 pod 应该由复制控制器来管理。Pod 标签被设置为“run=couchbase”。

A418863_1_En_9_Fig41_HTML.gif

图 9-41。

Creating a Replication Controller Imperatively

使用以下命令列出复制控制器。

kubectl get rc

couchbase复制控制器列表如图 9-42 所示。

A418863_1_En_9_Fig42_HTML.gif

图 9-42。

Listing the Replication Controllers

列出 POD

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

kubectl get pods

如图 9-43 所示,两个吊舱被列出。

A418863_1_En_9_Fig43_HTML.gif

图 9-43。

Listing the Pods

要描述任何特定的 Pod,运行kubectl describe pod 命令,例如,Pod couchbase-rd44o用以下命令描述。

kubectl describe pod couchbase-rd44o

吊舱细节得到如图 9-44 所示的输出。Pod 标签列为run=couchbase

A418863_1_En_9_Fig44_HTML.gif

图 9-44。

Describing a Pod

创建服务

要从在端口 8091 公开的复制控制器创建服务,请运行以下命令,该命令还指定了服务类型。

kubectl expose rc couchbase --port=8091 --type=LoadBalancer

随后列出服务。

kubectl get services

couchbase服务被创建并列出,如图 9-45 所示。

A418863_1_En_9_Fig45_HTML.gif

图 9-45。

Creating a Service for Couchbase Imperatively

要描述couchbase服务,请运行以下命令。

kubectl describe svc couchbase

服务名称、名称空间、标签、选择器、类型、Ip、端口、节点端口和端点会被列出,如图 9-46 所示。因为服务管理两个 pod,所以列出了两个端点。

A418863_1_En_9_Fig46_HTML.gif

图 9-46。

Describing a Service

扩展集群

使用 Kubernetes 集群管理器可以扩大或缩小 Couchbase 集群。例如,要将名为“couchbase”的复制控制器缩减为 1 个副本,运行下面的kubectl scale命令。

kubectl scale rc couchbase --replicas=1

“scaled”输出表示 rc 已被缩放。但是“缩放”输出并不总是意味着缩放数量的副本正在运行并准备就绪。运行以下命令列出窗格。

kubectl get pods

如图 9-47 所示,列出一个床座箱。

A418863_1_En_9_Fig47_HTML.gif

图 9-47。

Scaling Down the Couchbase Cluster to a Single Pod

运行以下命令列出复制控制器,如图 9-48 所示couchbase rc 与副本一起列为 1。

A418863_1_En_9_Fig48_HTML.gif

图 9-48。

Scaling Up the Couchbase Cluster

kubectl get rc

要将 rc 缩放回 2 个 pod,请运行以下命令。

kubectl scale rc couchbase --replicas=2

随后列出 POD。

kubectl get pods

最初,要添加的新 Pod 可能未运行或未就绪,但几秒钟后,两个 Pod 会被列为运行和就绪,如图 9-48 所示。

保持复制级别

复制控制器的主要目的是将副本的数量保持在配置的水平。在couchbase rc 中配置了 2 个副本的情况下,pod 的数量保持在 2。例如,删除其中一个窗格。

kubectl delete pod couchbase-4z3hx

一个单元被删除,但单元总数为 1,低于配置的副本数。因此,复制控制器启动一个新的副本。随后列出 POD。

kubectl get pods

最初,新的 Pod 可能没有运行和/或没有准备好,但几秒钟后,两个 Pod 正在运行并准备好,如图 9-49 所示。

A418863_1_En_9_Fig49_HTML.gif

图 9-49。

Running the kubectl get pods Command Multiple Times until all Pods are Running and Ready

描述couchbase服务。

kubectl describe svc couchbase

列出两个端点,如图 9-50 所示。

A418863_1_En_9_Fig50_HTML.gif

图 9-50。

Describing the couchbase Service

设置端口转发

将服务端点的端口转发设置为一个localhost端口,例如端口 8095,如前所述。

ssh -i "docker.pem" -f -nNT -L 8095:172.17.0.2:8091 ubuntu@ec2-52-91-80-177.compute-1.amazonaws.com

前面的命令不产生任何输出,如图 9-51 所示。

A418863_1_En_9_Fig51_HTML.gif

图 9-51。

Setting Port Forwarding

登录 Couchbase 管理控制台

使用localhost上的转发端口登录 Couchbase Web 控制台。

http://localhost:8095/index.html

Couchbase Web 控制台显示如图 9-52 所示。

A418863_1_En_9_Fig52_HTML.gif

图 9-52。

Displaying the Couchbase Console

摘要

在本章中,我们使用 Kubernetes 集群管理器创建了一个 Couchbase 集群。我们讨论了声明式和命令式方法。声明性方法利用定义文件,命令性方法利用命令行配置参数。我们演示了使用端口转发从本地主机浏览器访问 Couchbase Web 控制台。我们还在运行 Couchbase server 的 Docker 容器的交互式 shell 中使用了 cbtransfer 工具。Docker 映像“couchbase”用于创建一个 Couchbase 服务器。在下一章中,我们将讨论在 Apache Hadoop 集群中使用 Kubernetes 集群管理器。

十、使用 Apache Hadoop 生态系统

Apache Hadoop 已经发展成为处理大量数据的事实框架。Apache Hadoop 生态系统由多个项目组成,包括 Apache Hive 和 Apache HBase。Docker 映像“svds/cdh”基于最新的 cdh 版本,包括 Apache Hadoop 生态系统中的所有主要框架。Apache Hadoop、Apache Hive 和 Apache HBase 等所有框架都安装在同一个 Docker 映像中,因此有助于开发利用 Apache Hadoop 生态系统中多个框架的应用。在本章中,我们将讨论使用 Kubernetes 集群管理器来管理基于 svds/cdh 映像的 pod 集群。

  • 设置环境
  • 以声明方式创建 Apache Hadoop 集群
  • 创建 Apache Hadoop 集群势在必行

设置环境

本章需要安装以下软件,除 Docker 镜像外,其他章节使用的软件相同。

  • -Docker 引擎(最新版本)
  • -库服务器群集管理器 1.01 版
  • -Kubernetes(1.01 版)
  • -SVS/CDH 影像对接器(最新版本)

在 Amazon EC2 的 Ubuntu 实例上安装第一章中讨论的软件。SSH 登录到 Ubuntu 实例。

ssh -i "docker.pem" ubuntu@54.86.45.173

使用以下命令启动 Docker 引擎。

sudo service docker start

随后运行以下命令来验证 Docker 的状态。

sudo service docker status

如图 10-1 所示,Docker 应列为“正在运行”。

A418863_1_En_10_Fig1_HTML.gif

图 10-1。

Starting Docker

使用以下命令列出服务。

kubectl get services

kubernetes服务应该被列为正在运行,如图 10-2 所示。

A418863_1_En_10_Fig2_HTML.gif

图 10-2。

Listing the “kubernetes” Service

使用以下命令列出 pod。

kubectl get pods

使用以下命令列出节点。

kubectl get nodes

唯一列出的 Pod 是 Kubernetes,如图 10-3 所示。还会列出节点 127.0.0.1。

A418863_1_En_10_Fig3_HTML.gif

图 10-3。

Listing the Pod and Node for Kubernetes

以声明方式创建 Apache Hadoop 集群

在下面的小节中,我们将使用定义文件声明性地创建一个 Kubernetes 服务和一个 Kubernetes 复制控制器。服务是 pod 的外部接口,并将客户端请求路由到其中一个 pod。复制控制器管理 pod 的复制级别,并将副本的数量维持在定义文件中的指定值。复制控制器还用于扩展 pod 集群。

创建服务

要为 CDH pod 运行服务,请创建一个服务定义文件cdh-service.yaml并将以下(表 10-1 )字段添加到定义文件中。

表 10-1。

Service Definition File Fields

| 田 | 描述 | 价值 | 必填字段(包括默认值) | | --- | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | 是 | | 种类 | 定义文件的种类。 | 服务 | 是 | | 元数据 | 服务元数据。 |   | 是 | | 元数据->标签 | 服务标签。 | app:HRC | 不 | | 元数据->名称 | 服务名称。 | 鼎晖投资 | 是 | | 投机 | 服务规范。 |   | 是 | | 规格->端口 | 服务公开的端口。 |   | 是 | | 规格->端口->端口 | 服务公开的端口。50010 端口用于 DataNode。 | Fifty thousand and ten |   | | 规格->端口->端口 | 服务公开的另一个端口。8020 端口是用于 NameNode 的。 | Eight thousand and twenty |   | | 规格->选择器 | 吊舱选择器。服务将流量路由到标签与选择器表达式匹配的 pod。 | app:HRC | 是 | | 规格->选择器->类型 | 服务类型。 | LoadBalancer(负载均衡器) | 不 |

服务定义文件cdh-service.yaml被列出:

apiVersion: v1
kind: Service
metadata:
labels:
    app: cdh
  name: cdh
spec:
ports:
    -
      port: 50010
    -
      port: 8020
  selector:
    app: cdh
type: LoadBalancer

可以在 vi 编辑器中创建并保存服务定义文件,如图 10-4 所示。

A418863_1_En_10_Fig4_HTML.gif

图 10-4。

Service Definition File in vi Editor

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

kubectl create -f cdh-service.yaml

随后列出服务。

kubectl get services

第一个命令的输出“services/cdh”表示服务已经创建,如图 10-5 所示。第二个命令列出了名为“cdh”的服务。服务选择器在选择器列中列为 app = cdh。

A418863_1_En_10_Fig5_HTML.gif

图 10-5。

Creating a Service from a Definition File

创建复制控制器

在本节中,我们将使用一个定义文件创建一个复制控制器。创建一个 cdh-rc.yaml 文件,并将以下(表 10-2 )字段添加到该文件中。

表 10-2。

Replication Controller Definition File Fields

| 田 | 描述 | 价值 | | --- | --- | --- | | apiVersion(堆叠版本) |   | 第五颅神经的眼支 | | 种类 | 定义文件的种类。 | 复制控制器 | | 元数据 | 复制控制器元数据。 |   | | 元数据->标签 | 复制控制器标签。 | app:HRC | | 元数据->名称 | 复制控制器的名称。 | 人权委员会 | | 投机 | 复制控制器规范。 |   | | 规格->副本 | Pod 副本的数量。 | Two | | 规格->选择器 | 选择器键:用于选择要管理的窗格的值表达式。标签与选择器表达式相同的窗格由复制控制器管理。对于单个选择器表达式,选择器表达式必须与规范->模板->元数据->标签标签相同。如果没有指定,选择器默认为规范->模板->元数据->标签。 | 未设置。默认为与键相同的值:规范->模板->元数据->标签中的值对。 | | 规格->模板 | Pod 模板。 |   | | 规格->模板->元数据 | Pod 模板元数据。 |   | | 规格->模板->元数据->标签 | Pod 模板标签。 | app: cdh 名称:cdh | | 规格->模板->规格 | Pod 模板规范 |   | | 规格->模板->规格->容器 | Pod 模板的容器配置 |   | | 规格->模板->规格->容器->映像 | Docker 形象 | svds/人权中心 | | 规格->模板->规格->容器->名称 | 容器名称 | 鼎晖投资 |

列出了复制控制器的定义文件cdh-rc.yaml

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    app: cdh
  name: cdh-rc
spec:
  replicas: 2
  template:
    metadata:
      labels:
      app: cdh
      name: cdh
    spec:
      containers:
      image: svds/cdh
      name: cdh

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

kubectl create -f cdh-rc.yaml

列出复制控制器。

kubectl get rc

第一个命令输出“replicationcontrollers/cdh”,这意味着已经成功创建了一个 rc。第二个命令列出了复制控制器。复制控制器“cdh”被列出,如图 10-6 所示。复制控制器文件中没有指定SELECTOR,它被列为与模板标签相同的两个键:值对app=cdh,name=cdh。由复制控制器管理的 Pod 必须包括这两个标签,并且可以包括其他标签。副本的数量设置为 2。

A418863_1_En_10_Fig6_HTML.gif

图 10-6。

Creating a Replication Controller from a Definition File

列出 POD

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

kubectl get pods

两个吊舱被列出,如图 10-7 所示。最初,pod 可能被列为未运行或/和未就绪。“未就绪”箱由“就绪”栏中的 0/1 值表示,这意味着箱中的 1 个容器中的 0 个已经就绪。

A418863_1_En_10_Fig7_HTML.gif

图 10-7。

Listing the Pods for CDH, created but not Ready

再次运行相同的命令以列出窗格。

kubectl get pods

如图 10-8 所示,两个 pod 应被列为状态->运行和就绪- > 1/1。

A418863_1_En_10_Fig8_HTML.gif

图 10-8。

Listing the Pods as Ready

列出日志

要列出特定 Pod 的日志,例如 cdh-612pr Pod,请运行以下命令。

kubectl logs cdh-612pr

该命令的输出列出了日志,表明 Hadoop datanode、namenode、secondarynamenode、resourcemanager 和 nodemanager 已经启动,如图 10-9 所示。

A418863_1_En_10_Fig9_HTML.gif

图 10-9。

Listing Pod Logs

HBase 等其他组件也会启动。

扩展集群

最初,CDH 群集有两个副本。要将复制副本扩展到 4,请运行以下命令。

kubectl scale rc cdh --replicas=4

随后列出集群中的单元。

kubectl get pods

向上扩展群集后,会列出 4 个 pod,而不是最初列出的 2 个。一些 pod 可能被列为未运行或未准备好。几秒钟后周期性地运行前面的命令,所有的吊舱都应该启动,如图 10-10 所示。

A418863_1_En_10_Fig10_HTML.gif

图 10-10。

Scaling the Pod Cluster

启动交互式 Shell

由于“svds/CDH”Docker 映像基于 Linux“Ubuntu”Docker 映像,因此可以启动一个交互式 bash shell 来访问基于 svds/cdh Docker 映像的 Docker 容器。为了启动 cdh 软件的交互式 bash shell,我们需要获取运行“cdh”映像的 Docker 容器的容器 id,如图 10-11 所示。

A418863_1_En_10_Fig11_HTML.gif

图 10-11。

Copying the Docker Container Id

随后使用容器 id 启动交互式 shell。

sudo docker exec -it f1efdb5937c6 bash

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

A418863_1_En_10_Fig12_HTML.gif

图 10-12。

Starting an Interactive Shell

运行 MapReduce 应用

在本节中,我们将在交互式 shell 中运行一个示例 MapReduce 应用。hdfs命令用于运行 MapReduce 应用。在交互式 shell 中调用hdfs命令。

hdfs

命令用法应如图 10-13 所示。

A418863_1_En_10_Fig13_HTML.gif

图 10-13。

Command Usage for hdfs Command

要将用户更改为“hdfs ”,请运行以下命令。

su –l hdfs

用户变成“hdfs”,如图 10-14 所示。

A418863_1_En_10_Fig14_HTML.gif

图 10-14。

Setting User as hdfs

接下来,我们将运行一个wordcount应用。我们将从/input目录文件中获取输入,并在/output目录中输出。创建/input目录并将其权限设置为全局(777)。

hdfs dfs -mkdir /input
hdfs dfs -chmod -R 777 /input

如图 10-15 所示,/input目录被创建,其权限被设置为全局权限。

A418863_1_En_10_Fig15_HTML.gif

图 10-15。

Creating the Input Directory

在 vi 编辑器中创建一个输入文件input.1.txt

sudo vi input1.txt

将以下文本添加到 input1.txt 中。

Hello World Application for Apache Hadoop
Hello World and Hello Apache Hadoop

图 10-16 中的 vi 编辑器显示了input1.txt

A418863_1_En_10_Fig16_HTML.gif

图 10-16。

Creating an Input Text File

用下面的命令将input1.txt放到 HDFS 目录/input中,如果以root用户的身份运行,应该用sudo –u hdfs运行。如果用户已经设置为“hdfs ”,则在命令中省略“sudo–u HDFS”。

sudo -u hdfs hdfs dfs -put input1.txt /input

input1.txt文件被添加到/input目录中,命令没有产生输出,如图 10-17 所示。

A418863_1_En_10_Fig17_HTML.gif

图 10-17。

Putting the Input Text File in HDFS

类似地,创建另一个文件 input2.txt。

sudo vi input2.txt

将以下文本添加到 input2.txt。

Hello World
Hello Apache Hadoop

在 vi 编辑器中用:wq 命令保存input2.txt,如图 10-18 所示。

A418863_1_En_10_Fig18_HTML.gif

图 10-18。

Creating another Text File input2.txt

input2.txt放入/input目录。

sudo -u hdfs hdfs dfs -put input2.txt /input

input2.txt也被添加到/input目录中,如图 10-19 所示。

A418863_1_En_10_Fig19_HTML.gif

图 10-19。

Putting the input2.txt File into HDFS

可以用下面的命令列出 HDFS 中/input目录下的文件。

 hdfs dfs -ls /input

增加的两个文件input1.txtinput2.txt被列出,如图 10-20 所示。

A418863_1_En_10_Fig20_HTML.gif

图 10-20。

Listing the Files in HDFS

接下来,使用下面的命令运行wordcount示例应用,其中包含示例应用的 jar 文件由 jar 参数指定,并且/input/output目录分别被设置为输入目录和输出目录的最后两个命令参数。

sudo -u hdfs hadoop jar /usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.4.7.jar wordcount /input /output

一个 MapReduce 作业开始,如图 10-21 所示。

A418863_1_En_10_Fig21_HTML.gif

图 10-21。

Starting a YARN Application for Word Count Example

MapReduce 作业完成后运行wordcount应用。图 10-22 中显示的是wordcount MapReduce 作业的输出,而不是字数统计结果。

A418863_1_En_10_Fig22_HTML.gif

图 10-22。

Output from the MapReduce Job

下面列出了 MapReduce 应用的更详细的输出:

root@cdh-6l2pr:/# sudo -u hdfs hadoop jar /usr/lib/hadoop-mapreduce/hadoop-mapreduce-examples-2.6.0-cdh5.4.7.jar wordcount /input /output
15/12/21 16:39:52 INFO client.RMProxy: Connecting to ResourceManager at /0.0.0.0:8032
15/12/21 16:39:53 INFO input.FileInputFormat: Total input paths to process : 2
15/12/21 16:39:53 INFO mapreduce.JobSubmitter: number of splits:2
15/12/21 16:39:53 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1450714825612_0002
15/12/21 16:39:53 INFO impl.YarnClientImpl: Submitted application application_1450714825612_0002
15/12/21 16:39:53 INFO mapreduce.Job: The url to track the job: http://cdh-6l2pr:8088/proxy/application_1450714825612_0002/
15/12/21 16:39:53 INFO mapreduce.Job: Running job: job_1450714825612_0002
15/12/21 16:39:59 INFO mapreduce.Job: Job job_1450714825612_0002 running in uber mode : false
15/12/21 16:39:59 INFO mapreduce.Job: map 0 % reduce 0 %
15/12/21 16:40:04 INFO mapreduce.Job: map 100 % reduce 0 %
15/12/21 16:40:10 INFO mapreduce.Job: map 100 % reduce 100 %
15/12/21 16:40:10 INFO mapreduce.Job: Job job_1450714825612_0002 completed successfully
15/12/21 16:40:10 INFO mapreduce.Job: Counters: 49
       File System Counters
           FILE: Number of bytes read=144
           FILE: Number of bytes written=332672
           FILE: Number of read operations=0
           FILE: Number of large read operations=0
           FILE: Number of write operations=0
           HDFS: Number of bytes read=317
           HDFS: Number of bytes written=60
           HDFS: Number of read operations=9
           HDFS: Number of large read operations=0
           HDFS: Number of write operations=2
       Job Counters
           Launched map tasks=2
           Launched reduce tasks=1
           Data-local map tasks=2
           Total time spent by all maps in occupied slots (ms)=4939
           Total time spent by all reduces in occupied slots (ms)=2615
           Total time spent by all map tasks (ms)=4939
           Total time spent by all reduce tasks (ms)=2615
           Total vcore-seconds taken by all map tasks=4939
           Total vcore-seconds taken by all reduce tasks=2615
           Total megabyte-seconds taken by all map tasks=5057536
           Total megabyte-seconds taken by all reduce tasks=2677760
       Map-Reduce Framework
           Map input records=5
           Map output records=17
           Map output bytes=178
           Map output materialized bytes=150
           Input split bytes=206
           Combine input records=17
           Combine output records=11
           Reduce input groups=7
           Reduce shuffle bytes=150
           Reduce input records=11
           Reduce output records=7
           Spilled Records=22
           Shuffled Maps =2
           Failed Shuffles=0
           Merged Map outputs=2
           GC time elapsed (ms)=158
           CPU time spent (ms)=2880
           Physical memory (bytes) snapshot=1148145664
           Virtual memory (bytes) snapshot=5006991360
           Total committed heap usage (bytes)=2472542208
Shuffle Errors
           BAD_ID=0
           CONNECTION=0
           IO_ERROR=0
           WRONG_LENGTH=0
           WRONG_MAP=0
           WRONG_REDUCE=0
File Input Format Counters
           Bytes Read=111
File Output Format Counters
           Bytes Written=60
root@cdh-6l2pr:/#

随后,列出/output目录中的文件。

bin/hdfs dfs -ls /output

列出两个文件:_SUCCESSpart-r-00000,如图 10-23 所示。_SUCCESS文件表示 MapReduce 命令成功完成,part-r-00000命令包含字数统计的结果。

A418863_1_En_10_Fig23_HTML.gif

图 10-23。

Listing the Files generated by the MapReduce Job

要列出 wordcount 应用的结果,请运行以下命令。

hdfs dfs -cat /output/part-r-00000

如图 10-24 所示,列出了输入中每个单词的字数。

A418863_1_En_10_Fig24_HTML.gif

图 10-24。

The Word Count for the Input Files

运行蜂箱

Apache Hive 是一个数据仓库框架,用于存储、管理和查询 HDFS 的大型数据集。如前所述,CDH 的所有/大部分组件都是在运行svds/cdh映像时安装的。在这一节中,我们将测试 Apache Hive 框架。配置单元配置目录在配置单元conf目录中,在/etc/hive目录中。将目录(cd)更改为/etc/hive目录。

cd /etc/hive

conf目录被列出,如图 10-25 所示。

A418863_1_En_10_Fig25_HTML.gif

图 10-25。

Listing the Files and Directories in the Hive Root Directory

配置单元 metastore 保存在/var/lib/hive目录中。Cd 到/var/lib/hive目录。

cd /var/lib/hive

metastore目录被列出,如图 10-26 所示。

A418863_1_En_10_Fig26_HTML.gif

图 10-26。

Listing the Hive Metastore Directory

配置单元主目录是/usr/lib/hive。Cd 到/usr/lib/hive目录。随后列出文件和目录。

cd /usr/lib/hive
ls –l

Apache Hive 的binconf,lib目录如图 10-27 所示。bin目录包含可执行文件,conf目录包含配置文件,lib目录包含 jar 文件。

A418863_1_En_10_Fig27_HTML.gif

图 10-27。

The Hive Home Directory

所有的环境变量都是预先配置的。运行以下命令启动直线 CLI。

beeline

直线版本 1.1.0-cdh5.4.7 启动,如图 10-28 所示。

A418863_1_En_10_Fig28_HTML.gif

图 10-28。

Starting Beeline CLI

最初,没有到 Apache Hive 服务器的连接。为了进行演示,运行以下命令将数据库设置为默认数据库并显示表。

use default;
show tables;

显示如图 10-29 所示的“无电流连接”信息。

A418863_1_En_10_Fig29_HTML.gif

图 10-29。

No Current Connection

使用驱动程序、用户名和密码的默认设置与 Hive2 服务器连接,如三个空""所示。

!connect jdbc:hive2://localhost:10000/default "" "" ""

Apache Hive2 服务器使用 Apache Hive JDBC 驱动程序进行连接,如图 10-30 所示。

A418863_1_En_10_Fig30_HTML.gif

图 10-30。

Connecting with Hive Server

运行命令将数据库设置为默认值并显示表格。

use default;
show tables;

连接到的数据库已经是默认的,第一个命令基本上是多余的,但是需要注意的是,前面生成的错误没有生成。第二个命令列出了表,因为默认数据库最初没有任何表,所以没有列出任何表。前面命令的输出如图 10-31 所示。

A418863_1_En_10_Fig31_HTML.gif

图 10-31。

Setting the database to Use and the listing to the Hive Tables

在创建配置单元表之前,我们需要将/user/hive/warehouse目录的权限设置为全局(777)。

sudo –u hdfs hdfs dfs –chmod –R 777 /user/hive/warehouse

配置单元仓库目录的权限设置如图 10-32 所示。

A418863_1_En_10_Fig32_HTML.gif

图 10-32。

Setting Permissions on the Hive Warehouse Directory

用下面的 HiveQL 命令创建一个名为wlslog的表。

CREATE TABLE wlslog(time_stamp STRING,category STRING,type STRING,servername STRING,code STRING,msg STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';

在默认数据库中创建wlslog表,如图 10-33 所示。

A418863_1_En_10_Fig33_HTML.gif

图 10-33。

Creating a Hive Table called wlslog

使用以下命令描述 wlslog 表。

desc wlslog;

表格列(名称和数据类型)如图 10-34 所示。

A418863_1_En_10_Fig34_HTML.gif

图 10-34。

Describing the Hive Table wlslog

wlslog表添加 7 行数据。

INSERT INTO TABLE wlslog VALUES ('Apr-8-2014-7:06:16-PM-PDT','Notice','WebLogicServer','AdminServer,BEA-000365','Server state changed to STANDBY');
INSERT INTO TABLE wlslog VALUES ('Apr-8-2014-7:06:17-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to STARTING');
INSERT INTO TABLE wlslog VALUES ('Apr-8-2014-7:06:18-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to ADMIN');
INSERT INTO TABLE wlslog VALUES ('Apr-8-2014-7:06:19-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to RESUMING');
INSERT INTO TABLE wlslog VALUES ('Apr-8-2014-7:06:20-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000331','Started WebLogic AdminServer');
INSERT INTO TABLE wlslog VALUES ('Apr-8-2014-7:06:21-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000365','Server state changed to RUNNING');
INSERT INTO TABLE wlslog VALUES ('Apr-8-2014-7:06:22-PM-PDT','Notice','WebLogicServer','AdminServer','BEA-000360','Server started in RUNNING mode');

针对每个INSERT语句运行一个 MapReduce 作业,将数据添加到配置单元表wlslog中,如图 10-35 所示。

A418863_1_En_10_Fig35_HTML.gif

图 10-35。

Adding Data to Hive Table wlslog

随后查询wlslog表。

select * from wlslog;

添加的 7 行数据被列出,如图 10-36 所示。

A418863_1_En_10_Fig36_HTML.gif

图 10-36。

Querying the Hive Table

要退出 Beeline CLI,请运行以下命令。

!q

如图 10-37 所示,蜂箱直线 CLI 退出。将显示交互式 shell 命令提示符。

A418863_1_En_10_Fig37_HTML.gif

图 10-37。

Exiting the Beeline CLI

从交互式 shell 中,可以运行 CDH 的任何框架。接下来,我们将运行 Apache HBase。

运行 HBase

Apache HBase 是 Apache Hadoop 数据库,默认情况下,它也将数据存储在 HDFS。要启动 HBase shell,请在 bash shell 中运行以下命令,用于基于 svds/cdh Docker 映像的 Docker 容器。

hbase shell

HBase shell 启动,如图 10-38 所示。

A418863_1_En_10_Fig38_HTML.gif

图 10-38。

Starting HBase Shell

使用列族“log”创建一个名为“wlslog”的表。

create 'wlslog' , 'log'

wlslog表被创建,如图 10-39 所示。

A418863_1_En_10_Fig39_HTML.gif

图 10-39。

Creating a HBase Table

将 7 行数据放入wlslog表中。

put 'wlslog', 'log1', 'log:time_stamp', 'Apr-8-2014-7:06:16-PM-PDT'
put 'wlslog', 'log1', 'log:category', 'Notice'
put 'wlslog', 'log1', 'log:type', 'WeblogicServer'
put 'wlslog', 'log1', 'log:servername', 'AdminServer'
put 'wlslog', 'log1', 'log:code', 'BEA-000365'
put 'wlslog', 'log1', 'log:msg', 'Server state changed to STANDBY'

put 'wlslog', 'log2', 'log:time_stamp', 'Apr-8-2014-7:06:17-PM-PDT'
put 'wlslog', 'log2', 'log:category', 'Notice'
put 'wlslog', 'log2', 'log:type', 'WeblogicServer'
put 'wlslog', 'log2', 'log:servername', 'AdminServer'
put 'wlslog', 'log2', 'log:code', 'BEA-000365'
put 'wlslog', 'log2', 'log:msg', 'Server state changed to STARTING'
put 'wlslog', 'log3', 'log:time_stamp', 'Apr-8-2014-7:06:18-PM-PDT'
put 'wlslog', 'log3', 'log:category', 'Notice'
put 'wlslog', 'log3', 'log:type', 'WeblogicServer'
put 'wlslog', 'log3', 'log:servername', 'AdminServer'
put 'wlslog', 'log3', 'log:code', 'BEA-000365'
put 'wlslog', 'log3', 'log:msg', 'Server state changed to ADMIN'
put 'wlslog', 'log4', 'log:time_stamp', 'Apr-8-2014-7:06:19-PM-PDT'
put 'wlslog', 'log4', 'log:category', 'Notice'
put 'wlslog', 'log4', 'log:type', 'WeblogicServer'
put 'wlslog', 'log4', 'log:servername', 'AdminServer'
put 'wlslog', 'log4', 'log:code', 'BEA-000365'
put 'wlslog', 'log4', 'log:msg', 'Server state changed to RESUMING'
put 'wlslog', 'log5', 'log:time_stamp', 'Apr-8-2014-7:06:20-PM-PDT'
put 'wlslog', 'log5', 'log:category', 'Notice'
put 'wlslog', 'log5', 'log:type', 'WeblogicServer'
put 'wlslog', 'log5', 'log:servername', 'AdminServer'
put 'wlslog', 'log5', 'log:code', 'BEA-000331'
put 'wlslog', 'log5', 'log:msg', 'Started Weblogic AdminServer'
put 'wlslog', 'log6', 'log:time_stamp', 'Apr-8-2014-7:06:21-PM-PDT'
put 'wlslog', 'log6', 'log:category', 'Notice'
put 'wlslog', 'log6', 'log:type', 'WeblogicServer'
put 'wlslog', 'log6', 'log:servername', 'AdminServer'
put 'wlslog', 'log6', 'log:code', 'BEA-000365'
put 'wlslog', 'log6', 'log:msg', 'Server state changed to RUNNING'
put 'wlslog', 'log7', 'log:time_stamp', 'Apr-8-2014-7:06:22-PM-PDT'
put 'wlslog', 'log7', 'log:category', 'Notice'
put 'wlslog', 'log7', 'log:type', 'WeblogicServer'
put 'wlslog', 'log7', 'log:servername', 'AdminServer'
put 'wlslog', 'log7', 'log:code', 'BEA-000360'
put 'wlslog', 'log7', 'log:msg', 'Server started in RUNNING mode'

put 命令的输出如图 10-40 所示。

A418863_1_En_10_Fig40_HTML.gif

图 10-40。

Putting Data into HBase Table

要列出这些表,请运行以下命令。

list

wlslog表被列出,如图 10-41 所示。

A418863_1_En_10_Fig41_HTML.gif

图 10-41。

Listing HBase Tables

要获取行关键字为“log1”的行中的数据,请运行以下命令。

get 'wlslog', 'log1'

单列数据被列出,如图 10-42 所示。

A418863_1_En_10_Fig42_HTML.gif

图 10-42。

Getting a Single Row of Data

从具有行关键字log7的行中获取单个列log.msg中的数据。使用列族:列格式指定列。

get 'wlslog', 'log7', {COLUMNS=>['log:msg']}

单列数据输出如图 10-43 所示。

A418863_1_En_10_Fig43_HTML.gif

图 10-43。

Getting a Single Column Value in a Row

scan命令扫描wlslog工作台。

scan 'wlslog'

扫描命令如图 10-44 所示。

A418863_1_En_10_Fig44_HTML.gif

图 10-44。

Scanning a HBase Table

来自wlslog表的所有数据被列出,如图 10-45 所示。

A418863_1_En_10_Fig45_HTML.gif

图 10-45。

The scan Command outputs 7 Rows of Data

删除复制控制器和服务

在下一节中,我们将在命令行上强制为svds/cdh映像创建一个集群。删除复制控制器和以声明方式创建的服务。

kubectl delete rc cdh
kubectl delete service cdh

创建 Apache Hadoop 集群势在必行

在下面的小节中,我们将从命令行上的svds/cdh Docker 映像创建一个 CDH 集群。首先,我们将创建一个复制控制器。

创建复制控制器

运行以下命令创建一个名为cdh的复制控制器,包含两个副本。

kubectl run cdh --image=svds/cdh --replicas=2

cdh控制器创建完成,如图 10-46 所示。选择器默认设置为run=cdh

A418863_1_En_10_Fig46_HTML.gif

图 10-46。

Creating a Replication Controller Imperatively

列出复制控制器。

kubectl get rc

cdh复制控制器列表如图 10-47 所示。

A418863_1_En_10_Fig47_HTML.gif

图 10-47。

Getting the Replication Controller

列出 POD

要列出集群中的 pod,请运行以下命令。

kubectl get pods

这两个 pod 会被列出。如图 10-48 所示,最初一些或所有的吊舱可能不“运行”或不处于就绪状态 1/1。

A418863_1_En_10_Fig48_HTML.gif

图 10-48。

Listing the Pods with some Pod/s not READY yet

几秒钟后再次运行前面的命令。

kubectl get pods

如图 10-49 所示,所有的吊舱应列出状态“运行”和就绪状态 1/1。

A418863_1_En_10_Fig49_HTML.gif

图 10-49。

Listing all Pods as Running and Ready

扩展集群

要将群集扩展到 4 个副本,请运行以下命令。

kubectl scale rc cdh --replicas=4

随后列出 POD。

kubectl get pods

第一个命令的输出“scaled”表示集群已被缩放。第二个命令列出了 4 个 pod,而不是最初创建的 2 个,如图 10-50 所示。第二个命令可能需要运行多次才能列出所有状态为“正在运行”和就绪状态为 1/1 的 pod。

A418863_1_En_10_Fig50_HTML.gif

图 10-50。

Scaling the CDH Cluster

创建服务

服务在服务端点公开由复制控制器管理的 pod,服务端点只是外部客户机可以调用应用的主机:端口设置。运行以下命令创建服务。

kubectl expose rc cdh --type=LoadBalancer

随后列出服务。

kubectl get services

“cdh”服务列出选择器和端口的默认设置,如图 10-51 所示。默认的服务选择器是run=cdh,它的默认格式是 run = 。默认端口是 8020。

A418863_1_En_10_Fig51_HTML.gif

图 10-51。

Creating a Service

启动交互式 Shell

交互式外壳可以像以声明方式启动的 CDH 集群一样启动。复制运行 CDH 映像的 Docker 容器的容器 id,并运行以下命令(包括容器 id)来启动交互式 bash shell。

sudo docker exec -it 42f2d8f40f17 bash

交互外壳启动,如图 10-52 所示。

A418863_1_En_10_Fig52_HTML.gif

图 10-52。

Starting an Interactive Shell

运行hdfs命令。

hdfs

hdfs命令用法得到如图 10-53 所示的输出。

A418863_1_En_10_Fig53_HTML.gif

图 10-53。

Command Usage for hdfs Command

摘要

在本章中,我们使用 Kubernetes 集群管理器根据 Docker 映像svds/cdh创建了一个 Pods 集群。我们使用声明式和命令式方法来创建集群。我们使用 kubectl scale 命令来扩展集群。我们还演示了如何使用打包在cdh映像中的一些 Apache Hadoop 框架。我们运行了一个 MapReduce wordcount示例应用。我们还运行了 Apache Hive 和 Apache HBase 工具。在下一章,我们将讨论在索引和存储框架 Apache Solr 中使用 Kubernetes。