管理实例组 ¶
kOps 具有“实例组”的概念,它是一组类似的机器。在 AWS 上,它们映射到自动扩展组。
默认情况下,集群有
- 每个节点区域有一个实例组,称为
nodes-<zone>
(例如nodes-us-east-1c
)。这些实例是您的工作节点。 - 每个主节点区域有一个实例组,称为
master-<zone>
(例如master-us-east-1c
)。这些通常具有最小大小和最大大小 = 1,因此它们将运行单个实例。我们这样做是为了让云始终重新启动主节点,即使所有内容都立即终止。我们每个区域有一个实例组,因为我们需要强制云在每个区域中运行一个实例,这样我们才能挂载主节点卷 - 我们无法跨区域执行此操作。
本页介绍了一些常见的实例组操作。有关各种配置键的更详细文档,请参阅InstanceGroup 资源。
实例组免责声明 ¶
- 当一个区域(eu-central-1)中只有一个可用区,并且您想运行多个主节点时,您必须为每个主节点定义多个实例组。(例如
master-eu-central-1-a
和master-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
编辑minSize
和maxSize
,将两者从 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-local
的InstanceGroupManager
对象的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-1b
和eu-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 上开始。