亚马逊AWS官方博客
OpenSource | 使用 virtual-kubelet 运行 AWS Fargate
AWS Fargate 是一项全新的技术。有了它,您无需预配置、管理或扩展服务器即可运行容器。现在,Fargate 与 Amazon Elastic Container Service (ECS) 直接实现了集成。自从我们在 re:Invent 2017 大会上发布 Fargate 后,许多客户向我们反映,他们对使用 Fargate 运行 Kubernetes 非常感兴趣。为了帮助实现这一点,我们已经开始探究使用 virtual-kubelet 连接 Fargate 和 Kubernetes。virtual-kubelet 是一个开源的社区主导型项目,它允许使用任意计算资源支持 Kubernetes 工作程序节点。我们已经编写了一个新的 provider 插件,它支持使用 virtual-kubelet 创建 Fargate 任务,并已将该插件并入 virtual-kubelet 上游项目。这款新插件是只是在将 AWS Fargate 托管的数据层面扩展到 Kubernetes 方面迈出的探索性的一步,在它可以在所有使用案例中无缝运行之前,我们还有许多工作要做。现在,您不妨自行尝试以下几个简单的步骤:
步骤 1:使用 kops 创建一个单主节点的 Kubernetes 集群
我们将创建一个简单的测试环境来展示由 AWS Fargate 支持的 Kubernetes 工作负载。
第一步是安装一个 kops 集群。在安装 kops 时,我们使用具有两个 EC2 工作程序节点和一个 virtual-kubelet 实例的混合环境。virtual-kubelet 和 Fargate 上不支持的任意 Kubernetes 工作负载都可以照常在两个工作程序节点上轻松安排。按照以下说明使用此存储库:github.com/kubernetes/kops/blob/master/docs/aws.md。阅读关于使用 kops 在 AWS 上管理 Kubernetes 集群的博文,也可能会有所帮助。
$ export KUBERNETES_VERSION=https://storage.googleapis.com/kubernetes-release/release/v1.9.0/
$ export AWS_AVAILABILITY_ZONES=us-east-1
$ export CLUSTER_NAME=dnishi-kops1.k8s.local
$ kops create cluster —name $CLUSTER_NAME —zones $AWS_AVAILABILITY_ZONES —kubernetes-version $KUBERNETES_VERSION --yes
##Tested with Kubernetes v1.8.0+
##Kops 1.6.2+ can be easily created as a gossip-based cluster and the cluster name has to end with k8s.local
完成 kops 安装后,验证您的节点是否正在使用 kubectl 运行:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-20-42-7.ec2.internal Ready master 5h v1.9.0
ip-172-20-44-230.ec2.internal Ready node 5h v1.9.0
ip-172-20-58-31.ec2.internal Ready node 5h v1.9.0
复制 kops 集群的 kubeconfig 文件并保存。在即将运行 virtual-kubelet 的 EC2 实例上需要使用此文件。
步骤 2:从上游存储库构建 virtual-kubelet
在构建之前,请先确保已安装 Go。首次使用的用户请按照以下方法设置变量:
$ export GOPATH=$HOME/go
我们将 github.com/virtual-kubelet
用作基础路径。
$ mkdir -p $GOPATH/src/github.com/virtual-kubelet
$ cd $GOPATH/src/github.com/virtual-kubelet
如果您是首次克隆此存储库,请使用以下命令。如果您之前克隆过 virtual-kublet,请将以下命令中的“git clone”替换为“git pull”。
$ git clone https://github.com/virtual-kubelet/virtual-kubelet
$ cd virtual-kubelet
$ make build
将所有依赖项都添加到存储库中,并与 virtual-kubelet 一起构建。二进制文件位于 virtual-kubelet/bin 目录中。
步骤 3:创建 Fargate 任务
如果您之前未使用过 AWS Fargate,最简单的入门方法就是体验 Fargate 的首次运行。这样会在您的 AWS 账户中对 Fargate 采用默认设置。它将创建一个默认的 Fargate 集群*、IAM 角色,以及一个具有 Internet 网关和默认安全组的默认 VPC。在第一次运行之后,对个别设置进行微调会比较容易。在 Fargate 上运行首个应用程序后,请访问 AWS ECS 控制台,仔细查看您的 Fargate 资源。记录示例应用程序的子网和安全组。*由于 Fargate 会将服务器抽离出来,因此该集群仅作为一个逻辑构造,对正在运行的容器进行分组。
步骤 4:创建一个 EC2 实例,以使用 Fargate provider 插件运行 virtual-kubelet
为 EC2 实例创建一个 IAM 角色。许多 AWS 服务要求您利用角色控制服务可以访问的内容。如果按 IAM 角色适用的特定目的进行分类,可分为 EC2 实例的服务角色(举例),或服务相关角色。运行 virtual-kubelet 的 EC2 实例需要对 ECS API 拥有完全访问权限。按照以下步骤创建适当的 IAM 角色:使用 AWS 控制台:
- 在 AWS 控制台上选择 us-east-1 区域中的 IAM 角色。
- 创建角色,选择 AWS服务,选择“EC2”作为将使用该角色的服务,然后单击“Next: Permissions”(下一步:权限)。
- 搜索并选择“AmazonECS_FullAccess”,然后单击“Next: Review”(下一步:查看)。
- 将角色命名为“VK-ECSFullAccess”,完成操作。您会在“IAM 角色”页面上看到该新角色。
使用 aws-cli:创建角色,然后附加信任策略,以支持 EC2 承担此角色:
$ aws iam create-role --role-name VK-ECSFullAccess --assume-role-policy-document file://VK-Role-Trust-Policy.json
以下是 VK-Role-Trust-Policy.json
:
$ cat VK-Role-Trust-Policy.json
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}
}
调用 attach-role-policy 命令,向此 IAM 角色授予权限,以访问您帐户中的资源:
$ aws iam attach-role-policy --role-name VK-ECSFullAccess --policy-arn arn:aws:iam::aws:policy/AmazonECS_FullAccess
创建 EC2 所需的实例配置文件以包含该角色:
$ aws iam create-instance-profile --instance-profile-name EC2-AmazonECS_FullAccess
最后,将角色添加到实例配置文件:
$ aws iam add-role-to-instance-profile --instance-profile-name EC2-AmazonECS_FullAccess --role-name VK-ECSFullAccess
创建 EC2 实例并将新角色附加到其中:
- 使用 EC2 控制台,在其他 kops 工作程序节点所在的同一 VPC 和子网中创建一个 EC2 节点,并在创建过程中将 VK-ECSFullAccess-Role 添加到 EC2 节点。
- 或者,使用以下 aws-cli 命令:
在其他 kops 工作程序节点所在的同一子网和安全组中创建一个 ec2 Debian GNU/Linux 8 (Jessie) 实例:
$ aws ec2 run-instances --image-id ami-b14ba7a7 --count 1 --instance-type t2.micro --key-name ${MyKeyPair-xxxxx} --security-group-ids ${sg-xxxxxxxx} --subnet-id ${subnet-xxxxxxxx} --associate-public-ip-address
调用 associate-iam-instance-profile 命令,将新创建的 IAM 角色 YourNewRole 的实例配置文件 YourNewRole-Instance-Profile 附加到 EC2 实例 YourInstanceId 中:
$ aws ec2 associate-iam-instance-profile --instance-id ${i-xxxxxxxxxxxxx} --iam-instance-profile Name=EC2-AmazonECS_FullAccess
调用 describe-iam-instance-profile-association 命令,验证现在是否已将 IAM 角色附加到该实例:
$ aws ec2 describe-iam-instance-profile-associations
将以下文件复制到新的 EC2 节点:
- “virtual-kubelet”二进制文件
- “fargate.toml”配置文件。将 fargate.toml 文件更新为步骤 3中的子网值、安全组值。此外,如果您需要从外部访问映像,请更改 AssignPublicIPv4Address = true。
- kops 集群中的“kubeconfig”文件。将此文件移动到 /root/.kube/config 路径
$ scp -r -i ${path-to-MyKeyPair-xxxxx} ${path-to-virtual-kubelet/providers/aws/fargate.toml} ~/.kube/config admin@ec2.xx-xxx-xxx-xx.compute-1.amazonaws.com
$ ssh -i ${path-to-MyKeyPair-xxxxx} admin@ec2.xx-xxx-xxx-xx.compute-1.amazonaws.com
$ sudo -i
$ mv config /root/.kube/config
运行 virtual-kubelet 并保持运行状态:
$ ./virtual-kubelet --provider aws --provider-config fargate.toml
步骤 5:通过您的 kubectl 客户端确认集群已准备就绪
启动 virtual-kubelet 进程后,您会看到它在集群上注册为代理。
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-20-42-7.ec2.internal Ready master 1d v1.9.0
ip-172-20-44-230.ec2.internal Ready node 1d v1.9.0
ip-172-20-58-31.ec2.internal Ready node 1d v1.9.0
virtual-kubelet Ready agent 14s v1.8.3
步骤 6:创建 Kubernetes 对象(pod、部署、副本集、服务)
使用文本编辑器部署带有三个副本的 nginx,以创建一个包含以下内容的 YAML 文件并运行它。要在 Fargate (virtual-kubelet) 上分配 pod,我们使用清单中的 nodeSelector
约束,这是 PodSpec
的一个字段。它指定了键值对的映射。此外,您还可以使用 Kubernetes taint 来模拟这一行为。nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
imagePullPolicy: IfNotPresent
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1000Mi"
cpu: "500m"
nodeSelector:
type: virtual-kubelet
现在,部署您创建的 YAML 文件:
$ kubectl create -f nginx-deployment.yaml
deployment.apps "nginx-deployment" created
$ kubectl get deployments -o wide
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 3 3 3 0 12s nginx nginx:1.7.9 app=nginx
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-6b488d64b-47hvk 1/1 Running 0 2m 10.0.1.23 virtual-kubelet
nginx-deployment-6b488d64b-dj45s 1/1 Running 0 2m 10.0.1.161 virtual-kubelet
nginx-deployment-6b488d64b-p6vsb 1/1 Running 0 2m 10.0.1.95 virtual-kubelet
请注意,粗体的 nginx pod 元数据已经作为任务定义显示在下面的 Fargate 控制面板中。
让我们将 Fargate 上运行的 nginx-deployment 从 v1.7.9 更新为 v1.9.1:
$ kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
deployment.apps "nginx-deployment" image updated
$ kubectl rollout status deployment/nginx-deployment
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
Fargate 任务同样会一次更新一项任务。如果您单击一项任务,您会看到映像版本已经从 v1.7.9 更新为 v1.9.1。几秒钟之内,每项任务都会更新到 v1.9.1,而且每次会对一项任务重复一次该进程。
使用单个命令部署 20 个 pod。使用 nginx-deployment-new.yaml。如 Fargate 控制面板所示,这些任务可以在几秒钟内完成:
$ kubectl create -f nginx-deployment-new.yaml
deployment.apps "nginx-deployment" created
$ kubectl get deployments -o wide
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 20 20 20 0 14s nginx nginx:1.7.9 app=nginx
总结观点
现在,virtual-kubelet provider 插件无法支持所有 Kubernetes 使用案例和应用程序模式。我们希望可以在计算方面为 Kubernetes 用户提供新的途径,而现在我们已经迈出了第一步。我们很高兴能与社区合作,共同讨论如何最好地实现 Kubernetes 的无节点设计概念。我们希望您能加入我们,提出建议、贡献代码,并使用您的应用程序帮助我们测试该插件。您可以:
- 在每周四下午 3:00(太平洋标准时间)参加通过 Zoom 举办的 virtual-kubelet 工作组会议。
- 通过 Github 了解更多关于项目的信息:github.com/virtual-kubelet/virtual-kubelet
- 通过 Github 了解更多关于 Fargate provider 插件的信息:github.com/virtual-kubelet/virtual-kubelet/pull/173
- 阅读 Contentful 关于使用 virtual-kubelet 运行 Fargate 和 Kubernetes 的相关内容。
AWS 将参加 2018 年 5 月 2 日至 4 日在丹麦哥本哈根举行的 KubeCon EU 大会。在此次大会上,我们将展示这一插件。此外,我们还会展示即将推出的托管型 Kubernetes 服务 Amazon Elastic Container Service for Kubernetes (Amazon EKS)。
注意:本博文是专门针对中级用户编写的。需掌握 Linux、Go、Docker 和 K8s 相关知识。此外,virtual-kubelet 目前还不是稳定的代码库,如果出现崩溃,属于正常现象。希望您能够为我们提供帮助,使之更稳定。
Nishi Davidson 在云计算基础架构和软件应用程序领域有着长达 15 年的工作经验,在东南亚和美国市场负责过相关领域的工程、产品管理和战略工作。目前,她在 AWS 主持 Kubernetes 社区的开源工程设计。之前,她曾负责 SAP 的私有云、内部 BU 的 Kubernetes 托管服务工程等工作。在 HP、TCS、Juniper Networks、NetApp 和 DSSD (EMC) 工作期间,Nishi 负责领导产品/现场工程团队,向市场推出了多款云产品/解决方案。Nishi 拥有麻省理工学院斯隆商学院的工商管理硕士学位和安那大学 Guindy 工程学院的电气与电子工程学士学位。