本教程介绍如何使用 DaemonSets 来自定义 Google Kubernetes Engine (GKE) 集群的节点。DaemonSet 可确保所有节点或所选节点运行的都是某个 Pod 的副本。 通过此方法,您可以使用修改 GKE 节点时所用的相同工具来编排工作负载。
如果您用于初始化集群的工具和系统与用于运行工作负载的工具和系统不同,则管理环境所需的工作量将会增加。例如,如果您使用某种配置管理工具来初始化集群节点,则会对其余工作负载所在的运行时环境之外的过程构成依赖。
本教程旨在帮助系统管理员、系统工程师或基础架构运营人员简化 Kubernetes 集群的初始化过程。
在阅读本文档之前,请确保您熟悉以下内容:
在本教程中,您将学习如何使用 Kubernetes 标签和选择器根据节点的标签来选择要运行的初始化过程。在这些步骤中,您将部署一个仅在具有 default-init
标签的节点上运行的 DaemonSet。但是,为了证明这种机制的灵活性,您可以再创建一个节点池,并将 alternative-init
标签应用于该新池中的节点。然后,您可以在集群中再部署一个仅在具有 alternative-init
标签的节点上运行的 DaemonSet。
此外,您还可以在每个节点上运行多个初始化过程,而不仅仅只运行一个。您可以利用此机制更好地构建初始化过程,明确区分每个过程的关注点。
在本教程中,作为示例,初始化过程会对带有 default-init
标签的每个节点执行以下操作:
- 将额外的磁盘挂接到节点。
- 使用节点的操作系统软件包管理系统安装一组软件包和库。
- 加载一组 Linux 内核模块。
目标
在本教程中,您将执行以下操作:
- 预配和配置 GKE 集群。
- 准备一个 DaemonSet 描述符,用于初始化集群中的节点。
- 在集群中部署 DaemonSet。
- 验证集群节点是否已初始化。
费用
在本文档中,您将使用 Google Cloud 的以下收费组件:
您可使用价格计算器根据您的预计使用情况来估算费用。
完成本文档中描述的任务后,您可以通过删除所创建的资源来避免继续计费。如需了解详情,请参阅清理。
准备工作
- 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.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
引导环境
在本部分中,您将执行以下操作:
启用 Cloud API
打开 Cloud Shell。
选择 Google Cloud 项目:
gcloud config set project project-id
将
project-id
替换为您为本教程创建或选择的 Google Cloud 项目的 ID。启用 Google Kubernetes Engine API:
gcloud services enable container.googleapis.com
预配服务账号以管理 GKE 集群
在本部分,您将创建一个与集群中的节点关联的服务账号。在本教程中,GKE 节点将使用此服务账号而不是默认服务账号。最佳实践是仅授予服务账号运行应用所需的角色和访问权限。
服务账号所需的角色如下所示:
- Monitoring Viewer 角色 (
roles/monitoring.viewer
)。此角色授予对 Cloud Monitoring 控制台和 API 的只读权限。 - Monitoring Metric Writer 角色 (
roles/monitoring.metricWriter
)。此角色允许写入监控数据。 - Logs Writer 角色 (
roles/logging.logWriter
)。此角色仅授予足以写入日志的权限。 - Service Account User 角色 (
roles/iam.serviceAccountUser
)。此角色授予访问项目中服务账号的权限。在本教程中,初始化过程将模拟服务账号来运行特权操作。 - Compute Admin 角色 (
roles/compute.admin
)。此角色提供对所有 Compute Engine 资源的完全控制权限。在本教程中,服务账号将需要此角色才能将其他磁盘挂接到集群节点。
要预配服务账号,请按照下列步骤操作:
在 Cloud Shell 中,将一个环境变量初始化以存储服务账号名称:
GKE_SERVICE_ACCOUNT_NAME=ds-init-tutorial-gke
创建服务账号:
gcloud iam service-accounts create "$GKE_SERVICE_ACCOUNT_NAME" \ --display-name="$GKE_SERVICE_ACCOUNT_NAME"
将一个环境变量初始化以存储服务账号的电子邮件账号名称:
GKE_SERVICE_ACCOUNT_EMAIL="$(gcloud iam service-accounts list \ --format='value(email)' \ --filter=displayName:"$GKE_SERVICE_ACCOUNT_NAME")"
将 Identity and Access Management (IAM) 角色绑定到服务账号:
gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role 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/monitoring.viewer gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/monitoring.metricWriter gcloud projects add-iam-policy-binding \ "$(gcloud config get-value project 2> /dev/null)" \ --member serviceAccount:"$GKE_SERVICE_ACCOUNT_EMAIL" \ --role roles/logging.logWriter 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 集群、授予权限并完成集群配置。
在本教程中,具有相对较少的小型通用节点的集群已足以演示本教程的概念。您将创建一个具有一个节点池(默认节点池)的集群。然后,您将为默认节点池中的所有节点添加 default-init
标签。
在 Cloud Shell 中,创建并启动区域级 GKE 集群:
gcloud container clusters create ds-init-tutorial \ --enable-ip-alias \ --image-type=ubuntu_containerd \ --machine-type=n1-standard-2 \ --metadata disable-legacy-endpoints=true \ --node-labels=app=default-init \ --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"
部署 DaemonSet
在本部分中,您将执行以下操作:
- 创建用于存储初始化过程的 ConfigMap。
- 部署用于安排和执行初始化过程的 DaemonSet。
DaemonSet 将执行以下操作:
- 配置一个卷,它将 ConfigMap 的内容提供给 DaemonSet 处理的容器。
- 为底层集群节点的特权文件系统区域配置卷。这些区域可让 DaemonSet 安排的容器直接与运行它们的节点进行交互。
- 安排并运行一个 init 容器,该容器会执行初始化过程,然后在完成时终止。
- 安排并运行一个处于空闲状态且不消耗资源的容器。
空闲容器可确保节点仅初始化一次。DaemonSet 的设计方式应确保所有符合条件的节点都运行 Pod 的副本。 如果您使用常规容器,则该容器将运行初始化过程,然后在完成时终止。根据设计,DaemonSet 将重新安排 Pod。为避免“持续重新安排”,DaemonSet 将首先在 init 容器中执行初始化过程,然后使容器保持运行状态。
以下初始化过程包含特权和非特权操作。通过使用 chroot
,您可以运行命令,就像您直接在节点上而不仅仅是在容器内执行它们一样。
建议您仔细检查每个初始化过程,因为这些过程可能会更改集群节点的状态。由于这些过程会极大地影响集群的可用性和安全性,因此应只有一小部分人员才有权修改这些过程。
要部署 ConfigMap 和 DaemonSet,请执行以下操作:
在 Cloud Shell 中,将工作目录更改为
$HOME
目录:cd "$HOME"
克隆包含脚本和清单文件的 Git 代码库,这些脚本和文件用于部署和配置初始化过程:
git clone https://github.com/GoogleCloudPlatform/solutions-gke-init-daemonsets-tutorial
将工作目录更改为新克隆的代码库目录:
cd "$HOME"/solutions-gke-init-daemonsets-tutorial
创建一个 ConfigMap 来保存节点初始化脚本:
kubectl apply -f cm-entrypoint.yaml
部署 DaemonSet:
kubectl apply -f daemon-set.yaml
验证节点初始化是否已完成:
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
验证初始化过程
在标有 default-init
标签的集群的每个节点执行初始化过程后,您就可验证结果。
对于每个节点,验证过程将检查以下各项:
- 其他磁盘是否已挂接且可供使用。
- 节点的操作系统软件包管理系统是否已安装软件包和库。
- 系统是否已加载内核模块。
执行验证过程:
在 Cloud Shell 中,运行验证脚本:
kubectl get nodes -o=jsonpath='{range .items[?(@.metadata.labels.app=="default-init")]}{.metadata.name}{" "}{.metadata.labels.failure-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}' | while IFS= read -r line ; do ./verify-init.sh $line < /dev/null; done
等待脚本运行,并检查每个节点是否已正确初始化,如以下输出所示:
Verifying gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Packages installed successfully in gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-5464b7e3-nzjm (us-central1-c) Verifying gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Packages installed successfully in gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-65baf745-0gwt (us-central1-a) Verifying gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) configuration Disk configured successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) Packages installed successfully in gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b) Kernel modules loaded successfully on gke-ds-init-tutorial-default-pool-6b125c50-3xvl (us-central1-b)
清理
为避免系统因本教程中使用的资源向您的 Google Cloud 账号收取费用,您可以删除为本教程创建的项目。如果您创建了一个专用于本教程的项目,可以将其完全删除。 如果您使用现有项目且不想删除该项目,请按以下步骤清理该项目。
清理项目
要在不删除项目的情况下对其进行清理,您需要移除在本教程中创建的资源。
在 Cloud Shell 中,删除 GKE 集群:
gcloud container clusters delete ds-init-tutorial --quiet --region us-central1
删除您在此示例初始化过程中创建的其他磁盘:
gcloud compute disks list --filter="name:additional" --format="csv[no-heading](name,zone)" | while IFS= read -r line ; do DISK_NAME="$(echo $line | cut -d',' -f1)"; ZONE="$(echo $line | cut -d',' -f2)"; gcloud compute disks delete "$DISK_NAME" --quiet --zone "$ZONE" < /dev/null; done
删除服务账号:
gcloud iam service-accounts delete "$GKE_SERVICE_ACCOUNT_EMAIL" --quiet
删除克隆的代码库目录:
rm -rf "$HOME"/solutions-gke-init-daemonsets-tutorial
删除项目
若要避免产生费用,最简单的方法是删除您为本教程创建的项目。
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
后续步骤
- 了解 GKE。
- 实现安全软件供应链。
- 了解如何强化 GKE 集群的安全性。
- 探索有关 Google Cloud 的参考架构、图表和最佳实践。查看我们的 Cloud 架构中心。