跳至内容

管理实例组

kOps 具有“实例组”的概念,它是一组类似的机器。在 AWS 上,它们映射到自动扩展组。

默认情况下,集群有

  • 每个节点区域有一个实例组,称为nodes-<zone>(例如nodes-us-east-1c)。这些实例是您的工作节点。
  • 每个主节点区域有一个实例组,称为master-<zone>(例如master-us-east-1c)。这些通常具有最小大小和最大大小 = 1,因此它们将运行单个实例。我们这样做是为了让云始终重新启动主节点,即使所有内容都立即终止。我们每个区域有一个实例组,因为我们需要强制云在每个区域中运行一个实例,这样我们才能挂载主节点卷 - 我们无法跨区域执行此操作。

本页介绍了一些常见的实例组操作。有关各种配置键的更详细文档,请参阅InstanceGroup 资源

实例组免责声明

  • 当一个区域(eu-central-1)中只有一个可用区,并且您想运行多个主节点时,您必须为每个主节点定义多个实例组。(例如master-eu-central-1-amaster-eu-central-1-b等等...)
  • 如果实例组未正确定义(尤其是在一个区域中存在偶数个主节点或将多个主节点组划分为一个可用区时),etcd 服务器将无法启动,主节点将无法签入。这是因为 etcd 服务器是按可用区配置的。在出现这些问题时,DNS 和 Route53 将是第一个检查的地方。

列出实例组

kops get instancegroups

NAME                    ROLE    MACHINETYPE     MIN     MAX     ZONES
master-us-east-1c       Master                  1       1       us-east-1c
nodes-us-east-1c        Node    t2.medium       2       2       us-east-1c

您也可以使用kops get ig别名。

更改实例组中的实例类型

首先使用kops edit ig nodes-us-east-1c编辑实例组规范。例如,将机器类型更改为t2.large。现在,如果您运行kops get ig,您将看到大型实例大小。但请注意,这些更改尚未应用。

要预览更改

kops update cluster <clustername>

...
Will modify resources:
  *awstasks.LaunchTemplate LaunchTemplate/mycluster.mydomain.com
    InstanceType t2.medium -> t2.large

假设您对更改感到满意,请继续应用它:kops update cluster <clustername> --yes

此更改将仅应用于新实例;如果您想立即将其推广到所有实例,则必须执行滚动更新。

使用以下命令查看预览:kops rolling-update cluster

然后使用以下命令重新启动机器:kops rolling-update cluster --yes

这将排空节点,使用新的实例类型重新启动它们,并在启动后验证它们。

更改节点数量

注意:这使用 GCE 作为示例。当 AWS 是云提供商时,它将看起来不同,但概念和配置相同。

如果您运行kops get ig,您应该会看到您有用于节点和主节点的 InstanceGroups。

> kops get ig
NAME            ROLE    MACHINETYPE MIN MAX SUBNETS
master-us-central1-a    Master  n1-standard-1   1   1   us-central1
nodes-us-central1-a Node    n1-standard-2   2   2   us-central1

让我们将节点数量更改为 3。我们将使用kops edit编辑 InstanceGroup 配置(如果您使用过kubectl edit,您应该非常熟悉它)。kops edit ig nodes-us-central1-a将在您的编辑器中打开 InstanceGroup,看起来有点像这样

apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: simple.k8s.local
  name: nodes-us-central1-a
spec:
  image: cos-cloud/cos-stable-57-9202-64-0
  machineType: n1-standard-2
  maxSize: 2
  minSize: 2
  role: Node
  subnets:
  - us-central1
  zones:
  - us-central1-a

编辑minSizemaxSize,将两者从 2 更改为 3,保存并退出编辑器。如果您想更改镜像或machineType,您也可以在这里进行更改。实际上还有更多字段,但大多数字段具有其默认值,因此除非设置它们,否则不会显示。不过,总体方法是相同的。

保存后,您会注意到什么也没发生。虽然您已经更改了模型,但您需要告诉 kOps 将更改应用到云中。

我们使用与最初创建集群时相同的kops update cluster命令;当在没有--yes的情况下运行时,它应该向您显示更改的预览,现在应该只有一个更改

> kops update cluster
Will modify resources:
  InstanceGroupManager/us-central1-a-nodes-us-central1-a-simple-k8s-local
    TargetSize               2 -> 3

这表示我们将更改名为us-central1-a-nodes-us-central1-a-simple-k8s-localInstanceGroupManager对象的TargetSize属性,将其从 2 更改为 3。

这就是我们想要的,所以我们运行kops update cluster --yes

kOps 将将 GCE 管理实例组的大小从 2 调整为 3,这将创建一个新的 GCE 实例,然后该实例将启动并加入集群。在一分钟左右的时间内,您应该会看到新节点加入

> kubectl get nodes
NAME                        STATUS    AGE       VERSION
master-us-central1-a-thjq   Ready     10h       v1.7.2
nodes-us-central1-a-g2v2    Ready     10h       v1.7.2
nodes-us-central1-a-tmk8    Ready     10h       v1.7.2
nodes-us-central1-a-z2cz    Ready     1s       v1.7.2

nodes-us-central1-a-z2cz刚刚加入了我们的集群!

更改镜像

这是一个相当简单的更改,因为我们不必重新启动节点。但是,大多数更改都需要滚动您的实例 - 这实际上是一个深思熟虑的设计决策,因为我们的目标是不可变的节点。一个例子是更改您的镜像。我们使用的是cos-stable,它是谷歌的容器操作系统。让我们尝试使用 Debian Stretch。

如果您运行gcloud compute images list来列出您在 GCE 中可用的镜像,您应该会看到一个 debian-9 镜像

> gcloud compute images list
...
debian-9-stretch-v20170918                        debian-cloud             debian-9                              READY
...

因此,现在我们将执行相同的kops edit ig nodes操作,只不过这次我们将镜像更改为debian-cloud/debian-9-stretch-v20170918

现在kops update cluster将显示您将要创建一个新的GCE 实例模板,并且管理实例组将使用它

Will create resources:
  InstanceTemplate/nodes-us-central1-a-simple-k8s-local
    Network                 name:default id:default
    Tags                    [simple-k8s-local-k8s-io-role-node]
    Preemptible             false
    BootDiskImage           debian-cloud/debian-9-stretch-v20170918
    BootDiskSizeGB          128
    BootDiskType            pd-standard
    CanIPForward            true
    Scopes                  [compute-rw, monitoring, logging-write, storage-ro]
    Metadata                {cluster-name: <resource>, startup-script: <resource>}
    MachineType             n1-standard-2

Will modify resources:
  InstanceGroupManager/us-central1-a-nodes-us-central1-a-simple-k8s-local
    InstanceTemplate         id:nodes-us-central1-a-simple-k8s-local-1507043948 -> name:nodes-us-central1-a-simple-k8s-local

请注意,BootDiskImage确实已设置为您请求的 debian 9 镜像。

kops update cluster --yes现在将应用更改,但如果您运行kubectl get nodes,您会发现实例尚未重新配置。底部有一个提示

Changes may require instances to restart: kops rolling-update cluster`

这些更改需要您的实例重新启动(我们将删除 COS 镜像并用 Debian 镜像替换它们)。kOps 可以执行滚动更新以最大程度地减少中断,但即使如此,您可能也不想立即执行更新;您可能想进行更多更改,或者您可能想等待非高峰时间。您可能只是想等待实例自然终止 - 新实例将使用新配置启动 - 虽然如果您没有使用抢占式/竞价实例,您可能需要等待很长时间。

通过 AWS SSM 获取镜像(仅 AWS)

推出
kOps 1.25.3

如果您使用的是 AWS,您可以从 AWS SSM 参数动态获取实例组映像。kOps 会在每次 kops update cluster 运行时自动获取 SSM 参数并查找 AMI ID。如果您经常更新映像,并且不想每次都更新实例组配置,这将非常有用。您的 SSM 参数必须以 ssm: 开头,并包含 SSM 参数的完整路径。

示例规范如下所示

metadata:
  name: nodes-us-west-2a
spec:
  image: ssm:/aws/service/canonical/ubuntu/server/18.04/stable/current/amd64/hvm/ebs-gp2/ami-id
  machineType: t3.medium
  maxSize: 1
  minSize: 1
  role: Node

更改根卷大小或类型

主节点的默认卷大小为 64 GB,而节点的默认卷大小为 128 GB。

调整根卷大小的过程相同

  • 编辑实例组,将 rootVolumeSize 和/或 rootVolumeType 设置为所需的值:kops edit ig nodes-us-east-1c
  • rootVolumeType 必须是 支持的卷类型 之一,例如 gp2(默认)、io1(高性能)或 standard(用于测试)。
  • 如果 rootVolumeType 设置为 io1,则可以通过指定 rootVolumeIops(如果未定义,则默认为 100)来定义 IOPS 数。
  • 预览更改:kops update cluster <clustername>
  • 应用更改:kops update cluster <clustername> --yes
  • 滚动更新以更新现有实例:kops rolling-update cluster --yes

例如,要设置 200GB gp2 根卷,您的 InstanceGroup 规范可能如下所示

metadata:
  name: nodes-us-east-1c
spec:
  machineType: t3.medium
  maxSize: 2
  minSize: 2
  role: Node
  rootVolumeSize: 200
  rootVolumeType: gp2

另一个例子是设置一个 200GB io1 根卷,并提供 200 个预置 IOPS,这将使您的 InstanceGroup 规范看起来像

metadata:
  name: nodes-us-east-1c
spec:
  machineType: t3.medium
  maxSize: 2
  minSize: 2
  role: Node
  rootVolumeSize: 200
  rootVolumeType: io1
  rootVolumeIops: 200

从 kOps 1.19 开始,您可以使用 gp3 卷来获得更好的性能,这将使您的 InstanceGroup 规范看起来像

metadata:
  name: nodes-us-east-1c
spec:
  machineType: t3.medium
  maxSize: 2
  minSize: 2
  role: Node
  rootVolumeSize: 200
  rootVolumeType: gp3
  rootVolumeIops: 4000
  rootVolumeThroughput: 200

加密根卷

推出
kOps 1.19

您可以通过实例组规范加密根卷(注意,目前仅限于 AWS)

metadata:
  name: nodes-us-east-1a
spec:
  ...
  role: Node
  rootVolumeSize: 200
  rootVolumeEncryption: true
  rootVolumeEncryptionKey: arn:aws:kms:us-east-1:012345678910:key/1234abcd-12ab-34cd-56ef-1234567890ab

在上面的示例中,加密密钥是可选的。未指定时,将使用 EBS 加密的默认密钥。加密密钥可以指定为密钥 ID、别名或 ARN,如 AWS 文档 中所述。

向实例组添加额外存储

推出
kOps 1.12

您可以通过实例组规范添加额外存储(注意,目前仅限于 AWS)

---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: my-beloved-cluster
  name: compute
spec:
  cloudLabels:
    role: compute
  image: coreos.com/CoreOS-stable-1855.4.0-hvm
  machineType: m4.large
  ...
  volumes:
  - device: /dev/xvdd
    size: 20
    type: gp2
    encrypted: true
    key: arn:aws:kms:us-east-1:012345678910:key/1234abcd-12ab-34cd-56ef-1234567890ab

在 AWS 中,上面的示例显示了如何添加一个额外的 20gb EBS 加密卷,该卷适用于实例组中的每个节点。

自动格式化和挂载额外存储

您可以通过上面的 volumes 集合添加额外存储,但这只会配置存储本身。假设您不希望自己处理格式化和挂载设备的机制(也许通过钩子),您可以使用实例组的 volumeMounts 部分为您处理此问题。

---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: my-beloved-cluster
  name: compute
spec:
  cloudLabels:
    role: compute
  image: coreos.com/CoreOS-stable-1855.4.0-hvm
  machineType: m4.large
  ...
  volumeMounts:
  - device: /dev/xvdd
    filesystem: ext4
    path: /var/lib/docker
  volumes:
  - device: /dev/xvdd
    encrypted: true
    size: 20
    type: gp2

上面的操作将配置额外存储,格式化并挂载设备到节点。请注意,此功能与 volumes 有意区分,以便可以在诸如短暂存储之类的区域中重复使用它。以 c5d.large 实例为例,它带有一个 50gb SSD 驱动器;我们可以使用 volumeMounts 将其挂载到 /var/lib/docker 中。

---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: my-beloved-cluster
  name: compute
spec:
  cloudLabels:
    role: compute
  image: coreos.com/CoreOS-stable-1855.4.0-hvm
  machineType: c5d.large
  ...
  volumeMounts:
  - device: /dev/nvme1n1
    filesystem: ext4
    path: /data
  # -- mount the instance storage --
  - device: /dev/nvme2n1
    filesystem: ext4
    path: /var/lib/docker
  volumes:
  - device: /dev/nvme1n1
    encrypted: true
    size: 20
    type: gp2

对于 AWS,您可以在 此处 找到有关设备命名约定的更多信息

$ df -h | grep nvme[12]
/dev/nvme1n1      20G   45M   20G   1% /data
/dev/nvme2n1      46G  633M   45G   2% /var/lib/docker

注意:目前,用户需要确保设备名称正确。

创建新的实例组

假设您想添加一组新的节点,也许是使用不同的实例类型。您可以使用 kops create ig <InstanceGroupName> --subnet <zone(s)> 来完成此操作。目前 --subnet 标志是必需的,它接收实例组所在的子网的区域。该命令将打开一个带有基本配置的编辑器,允许您在创建之前对其进行编辑。

因此,过程如下

  • kops create ig morenodes --subnet us-east-1a

或者,如果您需要它位于多个子网中,请使用逗号分隔的列表

  • kops create ig morenodes --subnet us-east-1a,us-east-1b,us-east-1c
  • 预览:kops update cluster <clustername>
  • 应用:kops update cluster <clustername> --yes
  • (不需要重新启动任何实例,因此不需要滚动更新)

创建混合实例类型实例组(仅限 AWS)

推出
kOps 1.12

AWS 允许使用 混合实例策略 创建混合实例 EC2 自动扩展组,允许用户构建目标容量并组成按需实例和竞价实例,同时将分配策略卸载到 AWS。

---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: your.cluster.name
  name: compute
spec:
  cloudLabels:
    role: compute
  image: coreos.com/CoreOS-stable-1911.4.0-hvm
  machineType: m4.large
  maxSize: 50
  minSize: 10
  # You can manually set the maxPrice you're willing to pay - it will default to the onDemand price.
  maxPrice: "1.0"
  # add the mixed instance policy here
  mixedInstancesPolicy:
    instances:
    - m4.xlarge
    - m5.large
    - m5.xlarge
    - t2.medium
    onDemandAboveBase: 5
    spotInstancePools: 3

混合实例策略允许设置以下可配置项,但有关更多详细信息,请参阅 AWS 文档。

注意:截至撰写本文时,kube 集群自动扩展器不支持混合实例组,从某种意义上说,它仍然会根据容量来扩展组,但它执行的一些模拟可能是错误的,因为它不知道进入组的实例类型。

注意:从使用混合实例策略的启动配置升级到启动模板时,启动配置将保持未删除状态,必须手动删除。

从跨多个 AZ 的一个实例组迁移到每个 AZ 一个实例组

每个 AZ 一个 IG 比一个 IG 跨多个 AZ 更有利。一个常见的例子是,当您有一个与 AWS EBS 卷绑定的持久卷声明时,该卷绑定到它创建所在的 AZ,因此任何依赖该卷的资源(例如 StatefulSet)都绑定到同一个 AZ。在这种情况下,您必须确保在同一个 AZ 中至少运行一个节点,而一个 IG 无法保证这一点。但是,每个 AZ 一个 IG 可以保证这一点。

因此,过程如下

  • kops edit ig nodes
  • 删除两个子网,例如 eu-central-1beu-central-1c
  • 或者,您也可以删除现有的 IG 并创建一个具有更合适名称的新 IG
  • kops create ig nodes-eu-central-1b --subnet eu-central-1b
  • kops create ig nodes-eu-central-1c --subnet eu-central-1c
  • 预览:kops update cluster <clustername>
  • 应用:kops update cluster <clustername> --yes
  • 滚动更新以更新现有实例:kops rolling-update cluster --yes

将实例组转换为使用竞价实例

按照重新配置 InstanceGroup 的正常步骤操作,但将 maxPrice 属性设置为您的出价。例如,0.10 代表每小时 0.10 美元(10 美分)的竞价出价。

示例规范如下所示

metadata:
  name: nodes-us-east-1a
spec:
  machineType: t2.medium
  maxPrice: "0.01"
  maxSize: 3
  minSize: 3
  role: Node

因此,过程如下

  • 编辑:kops edit ig nodes-us-east-1a
  • 预览:kops update cluster <clustername>
  • 应用:kops update cluster <clustername> --yes
  • 滚动更新,仅当您想立即应用更改时:kops rolling-update cluster

向实例组添加污点或标签

如果您运行的是 Kubernetes 1.6.0 或更高版本,您也可以在 InstanceGroup 中控制污点。taints 属性接受字符串列表。以下示例将向 IG 添加两个污点,使用与上面相同的 edit -> update -> rolling-update 过程。

此外,可以向 IG 添加 nodeLabels 以利用 Pod 亲和性。IG 中的每个节点都将分配所需的标签。有关更多信息,请参阅 标签 文档。

metadata:
  name: nodes-us-east-1a
spec:
  machineType: m3.medium
  maxSize: 3
  minSize: 3
  role: Node
  taints:
  - dedicated=gpu:NoSchedule
  - team=search:PreferNoSchedule
  nodeLabels:
    spot: "false"

调整主节点大小

(此过程应该很熟悉!)

您的主节点实例组可能被称为 master-us-west-1c 或类似名称。

kops edit ig master-us-west-1c

添加或设置 machineType

spec:
  machineType: m3.large
  • 预览更改:kops update cluster <clustername>

  • 应用更改:kops update cluster <clustername> --yes

  • 滚动更新,仅当您想立即应用更改时:kops rolling-update cluster

如果您想最大程度地减少停机时间,请将主 ASG 扩展到大小 2,然后等待 kubectl get nodes 中的新主节点处于就绪状态,然后删除旧的主节点实例,并将 ASG 缩减回大小 1。(未来版本的滚动更新可能会自动执行此操作)

删除实例组

如果您决定不再需要 InstanceGroup,您可以使用以下命令将其删除:kops delete ig <name>

示例:kops delete ig morenodes

不需要 kops update cluster 也不需要 kops rolling-update,因此在删除实例组时要小心,您的节点将被自动删除(请注意,目前这并非优雅的,因此工作负载可能会中断,这些工作负载的 pod 正在这些节点上运行)。

EBS 卷优化

可以通过设置以下字段来创建 EBS 优化实例

spec:
  rootVolumeOptimization: true

从 OpenStack 中的卷启动

如果您想在 Openstack 中运行时从卷启动,可以在实例组上设置注释。

# Example for nodes
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
  labels:
    kops.k8s.io/cluster: k8s.dev.local
  name: nodes
  annotations:
    openstack.kops.io/osVolumeBoot: enabled
    openstack.kops.io/osVolumeSize: "15" # In gigabytes
spec:
  detailedInstanceMonitoring: true
  machineType: t2.medium
  maxSize: 2
  minSize: 2
  role: Node

如果未设置 openstack.kops.io/osVolumeSize,它将默认为映像指定的最小磁盘。

使用 InstanceGroup

kOps InstanceGroup 是节点组的声明性模型。通过修改对象,您可以更改使用的实例类型、节点数量、运行的操作系统映像 - 本质上,所有每个节点配置都在 InstanceGroup 中。

我们将假设您有一个正常运行的集群 - 如果没有,您可能需要阅读 如何在 GCE 上开始