在 Google Kubernetes Engine 上使用 GlusterFS 存储部署 IBM Db2 Warehouse

本教程介绍如何在 Google Kubernetes Engine (GKE) 上创建 IBM Db2 Warehouse 集群,并使用运行在 Kubernetes 集群中的 GlusterFS 文件系统作为存储层。 GlusterFS 是一个开源的可扩缩网络文件系统。

如果您是系统管理员、开发者、工程师或数据库管理员,并且希望在 Google Cloud 上部署 IBM Db2 Warehouse 集群,那么本教程非常适合您。

如需大致了解 IBM Db2 Warehouse 以及 Google Cloud 上的部署选项,请参阅系列文章概览

在本教程中,您将使用以下软件:

  • Ubuntu-server 16.04
  • IBM Db2 Warehouse Enterprise Edition
  • IBM Db2 Warehouse Client
  • GlusterFS 文件系统

目标

  • 从 Docker Store 获取 IBM Db2 Warehouse Docker 映像。
  • 预配一个自定义服务帐号,使其仅具有此架构所需的权限。
  • 启动 GKE 集群。
  • 验证集群是否正常运行。
  • 在 Kubernetes 集群中初始化 Docker Store 身份验证。
  • 在集群中部署并运行 GlusterFS。
  • 在集群中部署并运行 IBM Db2 Warehouse 容器。
  • 在 IBM Db2 Warehouse 中上传样本数据。
  • 连接到 IBM Db2 管理控制台并测试部署。

费用

本教程使用 Google Cloud 的以下收费组件:

请使用价格计算器根据您的预计使用情况来估算费用。

准备工作

  1. 登录您的 Google Cloud 帐号。如果您是 Google Cloud 新手,请创建一个帐号来评估我们的产品在实际场景中的表现。新客户还可获享 $300 赠金,用于运行、测试和部署工作负载。
  2. 在 Google Cloud Console 的项目选择器页面上,选择或创建一个 Google Cloud 项目。

    转到“项目选择器”

  3. 确保您的 Cloud 项目已启用结算功能。 了解如何确认您的项目是否已启用结算功能

  4. 启用 GKE API。

    启用 API

  5. 如果您没有 Docker ID,请在 Docker Store 中创建一个。

在本教程中,您将使用 IBM Db2 Warehouse Enterprise Edition。如果您还没有此软件的许可,则可以在本教程中使用免费试用版。

完成本教程后,您可以删除所创建的资源以避免继续计费。如需了解详情,请参阅清理

架构

在本教程中,您将在三个不同的 Google Cloud 区域中使用 GKE 部署 Kubernetes 集群。在集群中,您将部署三个 IBM Db2 Warehouse 实例:

  • 实例 db2wh-1,初始指定为头节点。
  • 实例 db2wh-2db2wh-3,初始指定为数据节点。

如果头节点发生故障转移,可更改各实例的角色(头节点或数据节点)。

您还将在三个节点上部署 GlusterFS 共享文件系统。部署在集群中的 GlusterFS 将被用作 IBM Db2 Warehouse 节点的共享文件系统。

下图展示了此架构:

架构

获取 IBM Db2 Warehouse Edition Docker 映像

在本教程中,您将使用 Docker Store 帐号从 Docker Store 下载 IBM Db2 Warehouse Edition 的免费试用版。这涉及下载两个不同的映像 - 服务器和客户端。

  1. 在浏览器中,转到 IBM Db2 Warehouse EE Docker 映像
  2. 使用您的 Docker 用户名和密码登录。
  3. 点击 Proceed to checkout
  4. 填写您的详细信息。
  5. 如果您同意这些条款,请选中右侧的 I agree ...I acknowledge ... 复选框。
  6. 点击 Get Content

    您将来到 Setup 页面。您无需按照这些说明操作,因为您将在本教程后面执行这些步骤。

  7. IBM Db2 Warehouse Client 映像重复此过程。

准备环境

本教程使用 us-central1 作为默认地区,使用 us-central1-b 作为默认区域。为节省在 gcloud 命令行工具中输入 Compute Engine 区域选项的时间,您可以将该地区和区域设置为默认值。

您将在 Cloud Shell 中执行本教程的大部分步骤。打开 Cloud Shell 时,您还可以自动克隆与本教程相关的 GitHub 代码库。

  1. 打开 Cloud Shell 并克隆本教程的 GitHub 代码库:

    打开 Cloud Shell

  2. 设置默认区域和地区:

    gcloud config set compute/region us-central1
    gcloud config set compute/zone us-central1-b
    

预配服务帐号以管理 GKE 集群

在本教程中,您将创建一个服务帐号来管理 Compute Engine 实例。GKE 集群节点将使用此服务帐号而不是默认服务帐号。最佳做法是仅向服务帐号提供运行应用所需的角色和访问权限。

在本教程中,您将需要使用以下角色:

  • Compute Admin 角色 (roles/compute.admin)。此角色提供对所有 Compute Engine 资源的完全控制权。服务帐号需要此角色来管理 GlusterFS 卷的永久性磁盘。
  • Service Account User 角色 (roles/iam.serviceAccountUser)。此角色提供对项目中的所有服务帐号(包括将来可能创建的服务帐号)的访问权限。服务帐号需要此角色来为 GlusterFS 卷挂接永久性磁盘。
  1. 在 Cloud Shell 中,创建一个环境变量来存储服务帐号名称:

    export GKE_SERVICE_ACCOUNT_NAME=db2dw-gke-service-account
    
  2. 创建服务帐号:

    gcloud iam service-accounts create $GKE_SERVICE_ACCOUNT_NAME \
        --display-name=$GKE_SERVICE_ACCOUNT_NAME
    
  3. 创建一个环境变量来存储服务帐号的电子邮件帐号名称:

    export GKE_SERVICE_ACCOUNT_EMAIL=$(gcloud iam service-accounts list \
        --format='value(email)' \
        --filter=displayName:"$GKE_SERVICE_ACCOUNT_NAME")
    
  4. roles/compute.admin 角色绑定到服务帐号:

    gcloud projects add-iam-policy-binding $(gcloud config get-value project 2> /dev/null) \
        --member serviceAccount:$GKE_SERVICE_ACCOUNT_EMAIL \
        --role roles/compute.admin
    
  5. roles/iam.serviceAccountUser 角色绑定到服务帐号:

    gcloud projects add-iam-policy-binding $(gcloud config get-value project 2> /dev/null) \
        --member serviceAccount:$GKE_SERVICE_ACCOUNT_EMAIL \
        --role roles/iam.serviceAccountUser
    

准备 GKE 集群

在本节中,您将启动 GKE 集群、授予权限并完成集群配置。

启动 GKE 集群

您现在可以创建并启动 GKE 集群。

  • 在 Cloud Shell 中,创建一个区域性专用 GKE 集群,每个地区仅包含一个节点:

    gcloud container clusters create ibm-db2dw-demo \
        --enable-ip-alias \
        --image-type=ubuntu \
        --machine-type=n1-standard-16 \
        --metadata disable-legacy-endpoints=true \
        --node-labels=app=db2wh \
        --node-locations us-central1-a,us-central1-b,us-central1-c \
        --no-enable-basic-auth \
        --no-issue-client-certificate \
        --num-nodes=1 \
        --region us-central1 \
        --service-account=$GKE_SERVICE_ACCOUNT_EMAIL \
        --enable-private-nodes \
        --enable-master-authorized-networks \
        --master-authorized-networks=0.0.0.0/0 \
        --master-ipv4-cidr "172.18.0.0/28"
    

    这将创建一个名为 ibm-db2dw-demo 的集群。

    请注意,此选项为主节点设置了静态 IP 地址范围:

    --master-ipv4-cidr "172.18.0.0/28"

    如果此范围已在项目中被占用,请进行更改。

因为您只使用一个节点池(默认节点池)创建此集群,所以此集群的所有节点都可以运行 IBM Db2 Warehouse 工作负载。(只有已附加标签的节点才可以托管 IBM Db2 Warehouse pod。)如果想要更强的隔离性(例如,您需要 IBM Db2 Warehouse 的专用节点),则可以创建一个新的节点池或专用集群。

此集群的主节点将接受来自所有网络的连接,因为您将 --master-authorized-networks 选项设置为 0.0.0.0/0。这有助于从 Cloud Shell 管理集群。在生产环境中,请考虑采用防御性更强的方法,例如使用堡垒主机

配置 Cloud NAT 网关以访问外部互联网

由于您配置的是专用 GKE 集群,因此还必须配置 Cloud Router 和 Cloud NAT 以使 GKE 节点可以访问互联网。

  1. 在 Cloud Shell 中,创建一个 Cloud Router:

    gcloud compute routers create nat-router --network default
    
  2. 创建 Cloud NAT 网关:

    gcloud compute routers nats create nat-config \
        --router nat-router \
        --nat-all-subnet-ip-ranges \
        --auto-allocate-nat-external-ips
    

管理 Docker Store 身份验证

在本教程中,您将创建一个密钥 (secret) 来存储 Docker Store 凭据,以使您的 GKE 集群可以从 Docker Store 下载 IBM Db2 Warehouse Docker 映像。如需了解详情,请参阅 Kubernetes 文档的相关内容。 此方法对私有 Docker 注册表实例也有效。

  1. 在 Cloud Shell 中登录 Docker Store(您将要使用的 Docker 注册表实例):

    docker login
    
  2. 使用 Docker Store 凭据创建 Kubernetes 密钥:

    kubectl create secret generic dockerstore \
        --type=kubernetes.io/dockerconfigjson \
        --from-file=.dockerconfigjson="$HOME"/.docker/config.json
    

向用户授予集群管理员权限

您需要授予您的用户在 GKE 中创建新角色的能力,具体请参见 GKE 文档

  • 在 Cloud Shell 中授予用户创建新角色的权限:

    kubectl create clusterrolebinding cluster-admin-binding \
        --clusterrole cluster-admin \
        --user $(gcloud config list \
        --format 'value(core.account)')
    

部署 GlusterFS

下一个任务是在集群中部署 GlusterFS。作为此任务的一部分,您将部署 Heketi,它提供管理 GlusterFS 卷的 RESTful API。

  1. 在 Cloud Shell 中,下载 GlusterFS 软件分发包:

    wget -q https://github.com/gluster/gluster-kubernetes/archive/master.zip
    
  2. 从软件包中提取 GlusterFS 部署脚本:

    unzip master.zip
    
  3. 创建一个 ConfigMap 来保存节点初始化脚本:

    kubectl apply -f solutions-db2wh/gluster/cm-entrypoint.yaml
    
  4. 部署节点初始化 DaemonSet

    kubectl apply -f solutions-db2wh/gluster/daemon-set.yaml
    
  5. 验证节点初始化是否完成:

    kubectl get ds --watch
    

    等待 DaemonSet 报告为就绪并且最新,如以下输出中所示:

    NAME              DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
    node-initializer   3         3         3         3            3          <none>          2h
    
  6. 部署 Heketi LoadBalancer 服务:

    kubectl apply -f solutions-db2wh/gluster/heketi-lb.yaml
    
  7. 等待系统为 heketi-lb 负载平衡器服务分配一个外部 IP 地址:

    kubectl get services --watch
    

    在输出中,您会看到 CLUSTER-IPEXTERNAL-IP 的 IP 地址:

    NAME        TYPE           CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
    heketi-lb   LoadBalancer   yy.yy.yy.yy  xx.xx.xx.xx   8080:30973/TCP   7s
    
  8. 填充 Heketi 拓扑文件:

    kubectl get nodes -o=jsonpath='{range .items[?(@.metadata.labels.app=="db2wh")]}{.metadata.name}{" "}{.status.addresses[?(@.type=="InternalIP")].address}{"\n"}{end}' | xargs -n 2 sh -c 'jq ".clusters[0].nodes += [{"node": {"hostnames": {"manage": [\""$0"\"], "storage": [\""$1"\"]}, "zone": 1}, "devices": [\"/dev/sdb\"]}]" solutions-db2wh/gluster/topology.json | sponge solutions-db2wh/gluster/topology.json'
    
  9. 在集群中部署 GlusterFS:

    ./gluster-kubernetes-master/deploy/gk-deploy -gvy solutions-db2wh/gluster/topology.json
    
  10. 创建一个环境变量来存储 Heketi 服务集群 IP 地址:

    HEKETI_SERVICE_IP="$(kubectl get svc heketi-lb -o=jsonpath='{.status.loadBalancer.ingress[0].ip}')"
    
  11. StorageClass 描述符中配置 Heketi 网址:

    sed -i "s/heketi.default.svc.cluster.local/$HEKETI_SERVICE_IP/g" solutions-db2wh/gluster/storage-class.yaml
    

    这是 Kubernetes 中 GH-42306 问题的解决方法。

  12. 创建一个 StorageClass,以使 GlusterFS 卷支持 PersistentVolumeClaims

    kubectl apply -f solutions-db2wh/gluster/storage-class.yaml
    

创建节点文件

现在,您可以创建 IBM Db2 Warehouse 所需的配置文件,以引导每个实例。

  1. 在 Cloud Shell 中,创建 nodes 文件:

    kubectl get nodes -o=jsonpath="{range \
    .items[?(@.metadata.labels.app=='db2wh')]}\
    {.metadata.name}{':'}{.status.addresses[?(@.type=='InternalIP')]\
    .address}{\"\n\"}{end}" | sed '1s/^/head_node=/' | \
    sed -e '2,$ s/^/data_node=/' > nodes
    
  2. 创建包含 nodes 文件的 ConfigMap

    kubectl create configmap db2wh-nodes --from-file=nodes
    

部署 IBM Db2 Warehouse pod

现在,您可以创建运行 IBM Db2 Warehouse 所需的所有 GKE pod。

  1. 在 Cloud Shell 中,创建 PersistentVolumeClaim,它将在 GlusterFS 集群中创建 PersistentVolume 以支持声明:

    kubectl apply -f solutions-db2wh/persistent-volume-claim.yaml
    
  2. 运行一个作业来复制 GlusterFS 卷中的 nodes 文件:

    kubectl apply -f solutions-db2wh/nodes-file-deploy-job.yaml
    
  3. 验证 nodes 文件部署作业是否已运行:

    kubectl get jobs --watch
    

    nodes-config 报告为 Successful 时,则表示作业已运行:

    NAME           DESIRED   SUCCESSFUL   AGE
    nodes-config   1         1            19s
    
  4. 部署 LoadBalancer 服务以允许访问 IBM Db2 Warehouse 管理控制台:

    kubectl apply -f solutions-db2wh/service.yaml
    
  5. 等待系统为名为 db2wh-ext 的负载平衡器服务分配一个外部 IP 地址:

    kubectl get services --watch
    

    在输出中,您会看到 CLUSTER-IPEXTERNAL-IP 的 IP 地址:

    NAME       TYPE          CLUSTER-IP   EXTERNAL-IP  PORT(S)                         AGE
    db2wh-ext  LoadBalancer  yy.yy.yy.yy  xx.xx.xx.xx  8443:30973/TCP,50000:30613/TCP  7s
    
  6. 部署 StatefulSet 以启动 IBM Db2 Warehouse pod:

    kubectl apply -f solutions-db2wh/statefulset.yaml
    
  7. 验证 IBM Db2 Warehouse pod(db2wh-0db2wh-1db2wh-2)是否正在运行:

    kubectl get pods --watch
    

    这可能需要几分钟时间。

    当您看到所有 pod 的状态均为 Running 时,表示 pod 正在运行:

    db2wh-1   0/1       Running   0         3m
    db2wh-2   0/1       Running   0         3m
    db2wh-0   0/1       Running   0         3m
    
  8. 创建一个环境变量来存储运行 IBM Db2 Warehouse 头节点的节点的 IP 地址:

    HEAD_NODE_IP=$(grep "head_node" nodes | awk -F ':' '{print $2}')
    
  9. 创建一个环境变量来存储头节点的 pod 名称:

    HEAD_NODE_POD_NAME=$(kubectl get pods \
    --field-selector=status.phase=Running -o=jsonpath="{range \
    .items[?(@.metadata.labels.app=='db2wh')]} \
    {.metadata.name}{':'}{.status.\
    hostIP}{'\n'}{end}" | grep $HEAD_NODE_IP | awk -F ':' '{print $1}')
    
  10. 检查其中一个 pod 的日志,以确保引导过程运行正常:

    kubectl exec -it $HEAD_NODE_POD_NAME -- status --check-startup
    

    这可能需要 40 到 60 分钟,在此期间系统可能会检测到一些错误。这些错误在本教程中可以忽略。

    如果您在输出中看到状态为 running successfully,则表示此过程在正常运行。

    HA Management up and running successfully!
    Successfully started IBM Db2 Warehouse service stack!
    
  11. 设置管理控制台密码:

    DB2_ADMIN_PASSWORD=$(openssl rand -hex 8)
    kubectl exec -it $HEAD_NODE_POD_NAME -- setpass ${DB2_ADMIN_PASSWORD}
    

测试您的部署

您已完成 pod 的配置,现在可以测试您的部署。

部署 IBM Db2 Warehouse Client 容器

要将数据上传到 IBM Db2 Warehouse,您应部署 Client 容器并使用 Kubernetes ConfigMap 将样本数据映射到 Client 容器。

  1. 在 Cloud Shell 中,创建包含样本数据的 ConfigMap:

    kubectl create configmap sample-data \
        --from-file=solutions-db2wh/sample-data/nyc-wifi-locs.csv \
        --from-file=solutions-db2wh/sample-data/sample-table.sql
    
  2. 创建部署以启动 IBM Db2 Warehouse Client 容器:

    kubectl apply -f solutions-db2wh/client.yaml
    
  3. 验证 IBM Db2 Warehouse Client pod 是否正在运行:

    kubectl get pods --watch
    

    这可能需要几分钟时间。

    当状态为 Running 时,则 pod 正在运行:

    db2wh-client-xxxxx-xxxx   1/1       Running   0         3m
    

上传样本数据

为了帮助测试部署,您应将样本数据上传到 IBM Db2 Warehouse 服务器。

  1. 在 Cloud Shell 中,显示之前创建的密码:

    echo $DB2_ADMIN_PASSWORD
    
  2. 创建一个环境变量来存储 IBM Db2 Warehouse Client 容器名称:

    CLIENT_CONTAINER_NAME=$(kubectl get pods -l app=db2wh-client -o=jsonpath='{.items[0].metadata.name}')
    
  3. 在 Client 容器中打开一个 shell 窗口:

    kubectl exec -it $CLIENT_CONTAINER_NAME -- cli
    
  4. 创建一个环境变量来存储密码,其中 [PASSWORD] 是您先前在本过程中获得的密码。

    DB_PASSWORD=[PASSWORD]
    
  5. 创建一个环境变量来存储数据库别名:

    DB_ALIAS=BLUDB
    

    BLUDB 是 IBM Db2 Warehouse 中的默认数据库名称。

  6. 创建一个环境变量来存储数据库主机名:

    DB_HOST=db2wh-ext.default.svc.cluster.local
    
  7. 设置数据库目录:

    db_catalog --add $DB_HOST --alias $DB_ALIAS
    
  8. 创建一个表来保存 IBM Db2 Warehouse 服务器中的样本数据:

    dbsql -f /sample-table.sql -d $DB_ALIAS -h $DB_HOST -u bluadmin -W $DB_PASSWORD
    
  9. 将数据上传到 IBM Db2 Warehouse 服务器:

    dbload -verbose -host $DB_HOST -u bluadmin \
    -pw $DB_PASSWORD -db $DB_ALIAS -schema BLUADMIN \
    -t NYC_FREE_PUBLIC_WIFI -df /nyc-wifi-locs.csv -delim ',' \
    -quotedValue DOUBLE -timeStyle 12HOUR -skipRows 1
    
  10. 关闭 IBM Db2 Warehouse Client shell:

    exit
    

使用管理控制台验证数据

现在,您可以连接 IBM Db2 Warehouse 管理控制台并验证上传的数据。

  1. 在 Cloud Shell 中,找到服务的外部 IP 地址:

    kubectl get svc db2wh-ext
    
  2. 打开浏览器并转到以下网址,其中 [EXTERNAL_IP] 是上一步中获得的 IP 地址:

    https://[EXTERNAL_IP]:8443
    

    您可以忽略安全警告。

  3. 使用以下凭据登录:

    • 用户名:bluadmin
    • 密码:(您此前在操作过程中创建的密码)
  4. 如果您接受 IBM Db2 Warehouse EULA,请点击 Accept

  5. 打开左侧的菜单,然后选择 Administer > Tables

    显示了 Tables 文件夹的 IBM Db2 Warehouse 管理界面

  6. 关闭 Quick Tour 弹出窗口。

  7. 点击 NYC_FREE_PUBLIC_WIFI

    可用的 Wi-Fi 热点的列表

  8. 点击 Data Distribution 标签页,确保表中已填充了数据:

    Tables 列表中的 Data Distribution 标签页

    您总共可以看到 2871 行,这是整个数据集。

  9. 点击 Generate SQL

  10. 选择 SELECT statement

  11. 点击 OK

    这将打开 Generate SQL 标签页,其中预先填充了自动生成的 SELECT 语句。

  12. LIMIT 子句添加到自动生成的 SELECT 语句,以将结果限制为前五条记录:

    SELECT "THE_GEOM", "OBJECTID", "BORO", "TYPE", "PROVIDER", "NAME", "LOCATION",
           "LAT", "LON", "X", "Y", "LOCATION_T", "REMARKS", "CITY", "SSID",
           "SOURCEID", "ACTIVATED", "BOROCODE", "BORONAME", "NTACODE", "NTANAME",
           "COUNDIST", "POSTCODE", "BOROCD", "CT2010", "BOROCT2010", "BIN", "BBL", "DOITT_ID"
      FROM "BLUADMIN"."NYC_FREE_PUBLIC_WIFI"
      LIMIT 5;
    
  13. 点击 Run,然后选择 Run All

    Result Set 标签页中显示记录列表,表明您已成功上传样本数据。

    运行 SQL 语句产生的结果,其中显示了所上传数据中的 5 条记录

清理

为避免因本教程中使用的资源导致您的 Google Cloud 帐号产生费用,请删除包含这些资源的项目,或者保留项目但删除各个资源。

删除项目

  1. 在 Cloud Console 中,转到管理资源页面。

    转到“管理资源”

  2. 在项目列表中,选择要删除的项目,然后点击删除
  3. 在对话框中输入项目 ID,然后点击关闭以删除项目。

后续步骤