在 Compute Engine 虚拟机上创建 GKE on Bare Metal 混合集群

本页面介绍如何使用在 Compute Engine 上运行的虚拟机 (VM) 设置采用高可用性 (HA) 模式的 GKE on Bare Metal 混合集群。

您无需准备任何硬件,即可快速试用 GKE on Bare Metal。完成本页面上的步骤后,您可以获得在 Compute Engine 上运行的有效 GKE Clusters on Bare Metal 测试环境。

要在 Compute Engine 虚拟机上试用 GKE on Bare Metal,请完成以下步骤:

  1. 在 Compute Engine 中创建 6 个虚拟机
  2. 在所有虚拟机之间创建具有 L2 连接的 vxlan 网络
  3. 安装 GKE on Bare Metal 的前提条件
  4. 部署 GKE on Bare Metal 混合集群

  5. 验证集群

准备工作

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. 请记下项目 ID,因为您需要用它来设置本页面上的脚本和命令中使用的环境变量。如果您选择现有项目,请确保您是 Project Owner 或 Project Editor。
  7. 在 Linux 工作站上,请确保您已安装最新的 Google Cloud CLI(用于与 Google Cloud 交互的命令行工具)。如果您已安装 gcloud CLI,请运行以下命令来更新其组件:
    gcloud components update

    根据 gcloud CLI 的安装方式,您可能会看到以下消息:“您无法执行此操作,因为此安装已停用 Google Cloud CLI 组件管理器。您可以运行以下命令来实现此安装的相同结果:”。按照说明复制并粘贴命令以更新组件。

本指南中的步骤来自 anthos-samples 代码库中的安装脚本。常见问题解答部分详细介绍了如何自定义此脚本以使用一些热门变异。

在 Compute Engine 中创建 6 个虚拟机

完成以下步骤以创建以下虚拟机:

  • 一个虚拟机用于管理员工作站。管理员工作站托管命令行界面 (CLI) 工具和配置文件以在安装期间配置集群,以及用于在安装后与预配的集群交互的 CLI 工具。管理员工作站将通过 SSH 访问集群中的所有其他节点。
  • 三个用作控制平面节点的虚拟机,运行 GKE on Bare Metal 控制平面所需。
  • 两个用作工作器节点的虚拟机,运行 GKE on Bare Metal 集群的工作负载。
  1. 设置环境变量:

    export PROJECT_ID=PROJECT_ID
    export ZONE=ZONE
    export CLUSTER_NAME=CLUSTER_NAME
    export BMCTL_VERSION=1.16.8
    

    对于 ZONE,您可以使用 us-central1-a 或任何其他 Compute Engine 可用区

  2. 运行以下命令以使用您的 Google 账号登录,并将您的项目设置为默认项目:

    gcloud auth login
    gcloud config set project $PROJECT_ID
    gcloud config set compute/zone $ZONE
    
  3. 创建 baremetal-gcr 服务账号:

    gcloud iam service-accounts create baremetal-gcr
    
    gcloud iam service-accounts keys create bm-gcr.json \
        --iam-account=baremetal-gcr@"${PROJECT_ID}".iam.gserviceaccount.com
  4. 启用 Google Cloud API 和服务:

    gcloud services enable \
        anthos.googleapis.com \
        anthosaudit.googleapis.com \
        anthosgke.googleapis.com \
        cloudresourcemanager.googleapis.com \
        connectgateway.googleapis.com \
        container.googleapis.com \
        gkeconnect.googleapis.com \
        gkehub.googleapis.com \
        serviceusage.googleapis.com \
        stackdriver.googleapis.com \
        monitoring.googleapis.com \
        logging.googleapis.com \
        opsconfigmonitoring.googleapis.com
  5. baremetal-gcr 服务账号授予额外的权限,以避免为不同的 API 和服务使用多个服务账号:

    gcloud projects add-iam-policy-binding "$PROJECT_ID" \
      --member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/gkehub.connect" \
      --no-user-output-enabled
    
    gcloud projects add-iam-policy-binding "$PROJECT_ID" \
      --member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/gkehub.admin" \
      --no-user-output-enabled
    
    gcloud projects add-iam-policy-binding "$PROJECT_ID" \
      --member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/logging.logWriter" \
      --no-user-output-enabled
    
    gcloud projects add-iam-policy-binding "$PROJECT_ID" \
      --member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/monitoring.metricWriter" \
      --no-user-output-enabled
    
    gcloud projects add-iam-policy-binding "$PROJECT_ID" \
      --member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/monitoring.dashboardEditor" \
      --no-user-output-enabled
    
    gcloud projects add-iam-policy-binding "$PROJECT_ID" \
      --member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/stackdriver.resourceMetadata.writer" \
      --no-user-output-enabled
    
    gcloud projects add-iam-policy-binding "$PROJECT_ID" \
      --member="serviceAccount:baremetal-gcr@$PROJECT_ID.iam.gserviceaccount.com" \
      --role="roles/opsconfigmonitoring.resourceMetadata.writer" \
      --no-user-output-enabled
  6. 创建本页面上所有命令需要的变量和数组:

    MACHINE_TYPE=n1-standard-8
    VM_PREFIX=abm
    VM_WS=$VM_PREFIX-ws
    VM_CP1=$VM_PREFIX-cp1
    VM_CP2=$VM_PREFIX-cp2
    VM_CP3=$VM_PREFIX-cp3
    VM_W1=$VM_PREFIX-w1
    VM_W2=$VM_PREFIX-w2
    declare -a VMs=("$VM_WS" "$VM_CP1" "$VM_CP2" "$VM_CP3" "$VM_W1" "$VM_W2")
    declare -a IPs=()
  7. 使用以下循环创建 6 个虚拟机:

    for vm in "${VMs[@]}"
    do
        gcloud compute instances create "$vm" \
          --image-family=ubuntu-2004-lts --image-project=ubuntu-os-cloud \
          --zone="${ZONE}" \
          --boot-disk-size 200G \
          --boot-disk-type pd-ssd \
          --can-ip-forward \
          --network default \
          --tags http-server,https-server \
          --min-cpu-platform "Intel Haswell" \
          --enable-nested-virtualization \
          --scopes cloud-platform \
          --machine-type "$MACHINE_TYPE" \
          --metadata "cluster_id=${CLUSTER_NAME},bmctl_version=${BMCTL_VERSION}"
        IP=$(gcloud compute instances describe "$vm" --zone "${ZONE}" \
             --format='get(networkInterfaces[0].networkIP)')
        IPs+=("$IP")
    done

    此命令会创建具有以下名称的虚拟机实例:

    • abm-ws:管理员工作站的虚拟机。
    • abm-cp1abm-cp2abm-cp3:控制平面节点的虚拟机。
    • abm-w1abm-w2:运行工作负载的节点的虚拟机。
  8. 使用以下循环验证 SSH 是否在所有虚拟机上准备就绪:

    for vm in "${VMs[@]}"
    do
        while ! gcloud compute ssh root@"$vm" --zone "${ZONE}" --command "printf 'SSH to $vm succeeded\n'"
        do
            printf "Trying to SSH into %s failed. Sleeping for 5 seconds. zzzZZzzZZ" "$vm"
            sleep  5
        done
    done

在虚拟机之间创建具有 L2 连接的 vxlan 网络

使用 Linux 的标准 vxlan 功能创建通过 L2 连接连接所有虚拟机的网络。

以下命令包含两个循环,它们执行以下操作:

  1. 通过 SSH 连接到每个虚拟机。
  2. 更新并安装所需软件包。
  3. 执行所需命令以使用 vxlan 配置网络。

    i=2 # We start from 10.200.0.2/24
    for vm in "${VMs[@]}"
    do
        gcloud compute ssh root@"$vm" --zone "${ZONE}" << EOF
            apt-get -qq update > /dev/null
            apt-get -qq install -y jq > /dev/null
            set -x
            ip link add vxlan0 type vxlan id 42 dev ens4 dstport 0
            current_ip=\$(ip --json a show dev ens4 | jq '.[0].addr_info[0].local' -r)
            printf "VM IP address is: \$current_ip"
            for ip in ${IPs[@]}; do
                if [ "\$ip" != "\$current_ip" ]; then
                    bridge fdb append to 00:00:00:00:00:00 dst \$ip dev vxlan0
                fi
            done
            ip addr add 10.200.0.$i/24 dev vxlan0
            ip link set up dev vxlan0
    
    EOF
        i=$((i+1))
    done

现在,10.200.0.0/24 网络内具有 L2 连接。虚拟机具有以下 IP 地址:

  • 管理员工作站虚拟机:10.200.0.2
  • 运行控制平面节点的虚拟机:
    • 10.200.0.3
    • 10.200.0.4
    • 10.200.0.5
  • 运行工作器节点的虚拟机:
    • 10.200.0.6
    • 10.200.0.7

安装 GKE on Bare Metal 的前提条件

在安装 GKE on Bare Metal 之前,您需要先在管理员工作站上安装以下工具:

  • bmctl
  • kubectl
  • Docker

如需安装这些工具并为 GKE on Bare Metal 安装做好准备,请执行以下操作:

  1. 运行以下命令,将服务账号密钥下载到管理员工作站并安装所需工具:

    gcloud compute ssh root@$VM_WS --zone "${ZONE}" << EOF
    set -x
    
    export PROJECT_ID=\$(gcloud config get-value project)
    BMCTL_VERSION=\$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/bmctl_version -H "Metadata-Flavor: Google")
    export BMCTL_VERSION
    
    gcloud iam service-accounts keys create bm-gcr.json \
      --iam-account=baremetal-gcr@\${PROJECT_ID}.iam.gserviceaccount.com
    
    curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
    
    chmod +x kubectl
    mv kubectl /usr/local/sbin/
    mkdir baremetal && cd baremetal
    gsutil cp gs://anthos-baremetal-release/bmctl/$BMCTL_VERSION/linux-amd64/bmctl .
    chmod a+x bmctl
    mv bmctl /usr/local/sbin/
    
    cd ~
    printf "Installing docker"
    curl -fsSL https://get.docker.com -o get-docker.sh
    sh get-docker.sh
    EOF
  2. 运行以下命令确保 root@10.200.0.x 有效。这些命令执行以下任务:

    1. 在管理员工作站上生成新的 SSH 密钥。
    2. 将公钥添加到部署中的所有其他虚拟机上。
    gcloud compute ssh root@$VM_WS --zone "${ZONE}" << EOF
    set -x
    ssh-keygen -t rsa -N "" -f /root/.ssh/id_rsa
    sed 's/ssh-rsa/root:ssh-rsa/' ~/.ssh/id_rsa.pub > ssh-metadata
    for vm in ${VMs[@]}
    do
        gcloud compute instances add-metadata \$vm --zone ${ZONE} --metadata-from-file ssh-keys=ssh-metadata
    done
    EOF

部署 GKE on Bare Metal 混合集群

以下代码块包含完成以下任务所需的所有命令和配置:

  1. 为所需的混合集群创建配置文件。
  2. 运行预检检查。
  3. 部署集群。
gcloud compute ssh root@$VM_WS --zone "${ZONE}" <<EOF
set -x
export PROJECT_ID=$(gcloud config get-value project)
CLUSTER_NAME=\$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/cluster_id -H "Metadata-Flavor: Google")
BMCTL_VERSION=\$(curl http://metadata.google.internal/computeMetadata/v1/instance/attributes/bmctl_version -H "Metadata-Flavor: Google")
export CLUSTER_NAME
export BMCTL_VERSION
bmctl create config -c \$CLUSTER_NAME
cat > bmctl-workspace/\$CLUSTER_NAME/\$CLUSTER_NAME.yaml << EOB
---
gcrKeyPath: /root/bm-gcr.json
sshPrivateKeyPath: /root/.ssh/id_rsa
gkeConnectAgentServiceAccountKeyPath: /root/bm-gcr.json
gkeConnectRegisterServiceAccountKeyPath: /root/bm-gcr.json
cloudOperationsServiceAccountKeyPath: /root/bm-gcr.json
---
apiVersion: v1
kind: Namespace
metadata:
  name: cluster-\$CLUSTER_NAME
---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: \$CLUSTER_NAME
  namespace: cluster-\$CLUSTER_NAME
spec:
  type: hybrid
  anthosBareMetalVersion: \$BMCTL_VERSION
  gkeConnect:
    projectID: \$PROJECT_ID
  controlPlane:
    nodePoolSpec:
      clusterName: \$CLUSTER_NAME
      nodes:
      - address: 10.200.0.3
      - address: 10.200.0.4
      - address: 10.200.0.5
  clusterNetwork:
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 172.26.232.0/24
  loadBalancer:
    mode: bundled
    ports:
      controlPlaneLBPort: 443
    vips:
      controlPlaneVIP: 10.200.0.49
      ingressVIP: 10.200.0.50
    addressPools:
    - name: pool1
      addresses:
      - 10.200.0.50-10.200.0.70
  clusterOperations:
    # might need to be this location
    location: us-central1
    projectID: \$PROJECT_ID
  storage:
    lvpNodeMounts:
      path: /mnt/localpv-disk
      storageClassName: node-disk
    lvpShare:
      numPVUnderSharedPath: 5
      path: /mnt/localpv-share
      storageClassName: local-shared
  nodeConfig:
    podDensity:
      maxPodsPerNode: 250
---
apiVersion: baremetal.cluster.gke.io/v1
kind: NodePool
metadata:
  name: node-pool-1
  namespace: cluster-\$CLUSTER_NAME
spec:
  clusterName: \$CLUSTER_NAME
  nodes:
  - address: 10.200.0.6
  - address: 10.200.0.7
EOB

bmctl create cluster -c \$CLUSTER_NAME
EOF

验证集群

您可以在管理员工作站的 root 账号的 bmctl-workspace 目录中找到集群的 kubeconfig 文件。如需验证部署,请完成以下步骤。

  1. 以根用户身份通过 SSH 连接到管理员工作站:

    gcloud compute ssh root@abm-ws --zone ${ZONE}
    

    您可以忽略任何有关更新虚拟机的消息并完成本教程。如果您计划将虚拟机保留为测试环境,则可能需要按照 Ubuntu 文档中的说明更新操作系统或升级到下一个版本。

  2. 使用集群配置文件的路径设置 KUBECONFIG 环境变量,以便在集群上运行 kubectl 命令。

    export clusterid=CLUSTER_NAME
    export KUBECONFIG=$HOME/bmctl-workspace/$clusterid/$clusterid-kubeconfig
    kubectl get nodes
    
  3. 在环境变量中设置当前上下文:

    export CONTEXT="$(kubectl config current-context)"
    
  4. 运行以下 gcloud 命令。此命令会执行以下操作:

    • 为您的用户账号授予集群上的 Kubernetes clusterrole/cluster-admin 角色。
    • 配置集群,以便在本地计算机上运行 kubectl 命令,而无需通过 SSH 连接到管理员工作站。

    GOOGLE_ACCOUNT_EMAIL 替换为与您的 Google Cloud 账号关联的电子邮件地址。例如:--users=alex@example.com

    gcloud container fleet memberships generate-gateway-rbac  \
        --membership=CLUSTER_NAME \
        --role=clusterrole/cluster-admin \
        --users=GOOGLE_ACCOUNT_EMAIL \
        --project=PROJECT_ID \
        --kubeconfig=$KUBECONFIG \
        --context=$CONTEXT\
        --apply
    

    此命令的输出类似于以下内容,为了便于阅读,已将其截断:

    Validating input arguments.
    Specified Cluster Role is: clusterrole/cluster-admin
    Generated RBAC policy is:
    --------------------------------------------
    ...
    
    Applying the generate RBAC policy to cluster with kubeconfig: /root/bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig, context: CLUSTER_NAME-admin@CLUSTER_NAME
    Writing RBAC policy for user: GOOGLE_ACCOUNT_EMAIL to cluster.
    Successfully applied the RBAC policy to cluster.
    
  5. 探索完毕后,输入 exit 以退出管理员工作站。

  6. 获取可通过 Connect 网关访问集群的 kubeconfig 条目。

    gcloud container fleet memberships get-credentials CLUSTER_NAME
    

    输出类似于以下内容:

    Starting to build Gateway kubeconfig...
    Current project_id: PROJECT_ID
    A new kubeconfig entry "connectgateway_PROJECT_ID_global_CLUSTER_NAME" has been generated and set as the current context.
    
  7. 您现在可以通过 Connect 网关运行 kubectl 命令:

    kubectl get nodes
    kubectl get namespaces
    

从 Google Cloud 控制台登录集群

如需在 Google Cloud 控制台中观察 GKE Clusters on Bare Metal 上的工作负载,您需要登录集群。在首次登录控制台之前,您需要配置身份验证方法。配置身份验证的较简单方法是使用 Google 身份。此身份验证方法让您可以使用与您的 Google Cloud 账号关联的电子邮件地址登录。

您在上一部分中运行的 gcloud container fleet memberships generate-gateway-rbac 命令会配置集群,以便您可以使用 Google 身份登录。

  1. 在 Google Cloud 控制台中,前往 GKE 集群页面。

    前往 GKE 集群

  2. 点击已注册集群旁边的 操作,然后点击登录

  3. 选择使用您的 Google 身份登录

  4. 点击 Login(登录)。

清理

  1. 连接到管理员工作站,以便将集群虚拟机重置为安装之前的状态,并从 Google Cloud 项目中取消注册集群:

    gcloud compute ssh root@abm-ws --zone ${ZONE} << EOF
    set -x
    export clusterid=CLUSTER_NAME
    bmctl reset -c \$clusterid
    EOF
    
  2. 列出名称中包含 abm 的所有虚拟机:

    gcloud compute instances list | grep 'abm'
    
  3. 验证您是否可以安全删除名称中包含 abm 的所有虚拟机。

    验证后,您可以通过运行以下命令来删除 abm 虚拟机:

    gcloud compute instances list --format="value(name)" | grep 'abm'  | xargs gcloud \
        --quiet compute instances delete