长文多图预警
简介
前面我们介绍的 EKS 都是利用 node(EC2)来运行 Pod,本文中我们介绍如何在 EKS 中利用 Fargate 运行 Pod。
AWS Fargate 最大的特点就是没有下层服务器(EC2),所以不需要提前配置部署 node 就可以运行容器。
使用 Fargate 我们只需要设置需要的 CPU 和内存(或者不设置由默认指定)即可,非常方便。我们在之前的文章中多次介绍过相关的内容,有兴趣的朋友可以在公众号回中回复“历史文章列表”查看。
当我们直接使用 AWS Fargate 服务时,我们需要用 Fargate 环境下的 service、task 等概念来运行容器,这些概念与 K8s 不兼容,不能直接套用使用 K8s 的现成方法。
而当我们在 EKS 中使用 Fargate 时,我们可以使用 K8s 的方法把 Pod 部署在 Fargate 上,这样既可以利用到 Fargate 的无服务器特性,又避免了需要同时使用两种部署方法。
注意:中国区目前不支持 EKS 在 Fargate 上运行 Pod。
目录
- 环境(配置)
- EKS 在 Fargate 上部署 Pod 介绍
- 实战步骤
1. 创建 Fargate pod execution role
2. 创建 NAT gateway,Route table
- NAT gateway
- Route table
3. 创建 Private subnet
4. 创建 Fargate profile
5. 更新 CoreDNS(选做)
6. 部署 Fargate 测试应用
- 总结
- 后记
环境(配置)
- AWS Global 帐号,可在官网申请,一年内使用指定资源免费
- AWS EKS
- Win10 + WSL
- AWS CLI 2.2.17 如何 aws 版本太低还需要手工安装插件,建议升级到高版本
- Kubectl
EKS 在 Fargate 上部署 Pod 介绍
AWS 利用 K8s 提供的模型开发了相关 controller,用来把 Pod 部署到 Fargate 上。
这些 controller 运行在 K8s control plane 上,所以我们是看不到这些 controller 的。
下面列出 EKS 使用 Fargate 时需要注意的一些问题
- 运行在 Fargate 上的 Pod 拥有自己的 kernal、CPU、MEM、网络接口,并不与其它 Pod 共享
- Network/Application Load Balancer 与 Fargate 中的 Pod 关联使用时,只支持 IP Target
- Pod 只有在符合某个 Fargate profile 的条件,才会部署到 Fargate。已经在运行的 Pod 不会自动迁移到 Fargate 上,需要重建 Pod
- k8s Daemonsets 不支持运行在 Fargate 上
- 通过 EKS 运行在 Fargate 上的 Pod 只能运行在 Private subnet 中,使用 Public subnet 时会报错
- VPC 需要启动 DNS 解析和 DNS hostnames
- 部署在 Fargate 中的 Pod 不能使用 Amazon EC2 instance metadata service (IMDS)
如果我们想在已存在 node 的 EKS 中部署 Pod 到 Fargate 上,我们需要确保当前 node 上运行的 Pod 可以与 Fargate 中运行的 Pod 通信。
在 Fargate 上运行的 Pod 自动会使用 EKS 集群的 security group,而 Managed node group(由 EKS 创建,不是自行创建的 node gruop)也会自动使用相同的 security group。
在这种情况下,node 上运行的 Pod 就自动可以与 Fargate 上运行的 Pod 通信,我们目前创建的 EKS 和其中的 node 就是属于这种情况,所以不必做相关调整,
但是,如果在 EKS 中使用了自行搭建的 node,那可能需要调整 node 的 security group 确保 node 上 Pod 和 Fargate 上的 Pod 能通信。
实战步骤
1. 创建 Fargate pod execution role
Fargate pod execution role 用来给 Fargate 提供访问 AWS 的权限,比如从 ECR 中下载镜像,或者向其它 AWS 服务发送日志等等。
在 AWS 中控台选择“IAM”,进入 IAM 界面,点击“Roles”,点击“Create role”
选择“AWS service”,点击“EKS”,选择“EKS - Fargate pod”,点击“Next: Permission”
IAM 已经自动选择“AmazonEKSFargatePodExecutionRolePolicy”,直接点击“Next: Tags”
可以添加一个 Tag,然后点击“Next:Review”
为 Role 指定名称“AmazonEKSFargatePodExecutionRole”,点击“Create role”
创建完成
下面我们会创建 NAT 和 Private subnet,这里只简单罗列了创建过程。有关 NAT, Private/Public Subnet,route table 等 AWS 服务的详细介绍,
请参考《一文搞懂 AWS Region, VPC, VPC endpoint,AZ, Subnet 基础篇上》和《一文搞懂 AWS EC2, IGW, RT, NAT, SG 基础篇下》两篇文章。
2. 创建 NAT gateway,Route table
NAT gateway
我们先创建 NAT gateway,Private sbunet 会利用 Nat gateway 访问 internet 和其它 AWS 服务。
在 AWS 中控台选择“VPC”,进入 VPC 界面,选择“NAT Gateways”,点击“Create NAT gateway”
做下列配置,然后点击“Create NAT gateway”
- 添加 NAT 名称“testest-nat”
- Subnet 选择 AZ “us-east-1a”的 Public Subnet
- Connectivity type 选择“Public”
- 如果没有空闲的 Elastic IP,则点击“Allocate Elastic IP”说明:Nat gateway 需要放在 public subnet 中
创建成功
Route table
NAT gateway 创建好之后,还要在 Private subnet 中配置路由,使访问 internet 的请求通过 NAT 发送出去,这个功能要用 Route table 实现。
在 AWS 中控台选择“VPC”,进入 VPC 界面,选择“Route Tables”,点击“Create route table”说明:可以看到目前只有一个默认的主路由表
添加名称“ts-pri-route”,选择我们的 VPC,点击“Create route table”
创建成功,自动进入“ts-pri-route”,在“Routes”下,点击“Edit routes”
点击“Add route”,在 Destination 中添加“0.0.0.0/0”,Target 选择 NAT gateway,然后选择我们新建的 Nat,点击“Save changes”
3. 创建 Private subnet
EKS 使用 Fargate 部署 Pod 时,要求 Pod 必须部署在 Private subnet 中,我的测试环境没有 Private subnet,所以先要创建 Private subnet。
在 AWS 中控台选择“VPC”,进入 VPC 界面,选择“Subnets”,点击“Create subnet”
选择默认 VPC,添加 subnet 名称“ts-pri-1a”,选择 AZ “us-east-1a”,添加 Ipv4 CIDR “172.31.96.0/20”,然后点击“Create subnet”说明:172.31.96.0/20 指定了一个 subnet 可用的 IP 网段,注意不能与已有的 subnet 网段重合
创建完成,选择建好的 Subnet,选择“Route table”,可以看到自动添加的路由中有 0.0.0.0/0 -> igw-b6001ace,说明这个 subnet 可以直接访问 internet,是 public subnet。我们需要把它改成可以访问 internet 的 private subnet,点击“Edit route table association”
在 Route table ID 中选择上面创建的“ts-pri-route”,点击“save”
我们用同样的方法再建一个 subnet “ts-pri-1b”,选择 AZ “us-east-1b”
3. 创建 Fargate profile
Farget profile 用来指定哪些 Pod 会运行在 Fargate 上,我们可以创建多个 Fargate profile 来指定不同的 Pod。
下面我们创建的 Fargate profile 指定了 Namespace 为 default 的,lable 中包含“infrastructure: fargate”的 Pod 会运行在 Fargate 上。
在 AWS 中控台选择“Elastic Kubernetes Service”,进入 Amazon Container Services 界面,选择“Amazon EKS”下的“Clusters”,然后点击自己的集群“tsEKS”,选择“Configuration”,点击“Compute”,在 Fargate Profiles block 点击“Add Fargate Profile”
在 Profile configuration 页面,做下列配置后,点击“Next”
- 添加 Profile 名称“tsEKSFargateprofile”
- Pod execution role 选择上面创建的 role“AmazonEKSFargatePodExecutionRole”
- Subnet 中选择上面创建的两个新的 Subnet
在 Namespace 中,我们添加“default”,再添加 Tag “infrastructure:fragate”,点击“Next”说明:
- Namespace:指定这个空间中的 Pod 会在 Fargate 中运行,我们这里指定了
- Match labels(可选项):如果在这里指定了 Tag(label),则上述 Namespace 中的 Pod 在具有相同的 Kubernetes label 时,会被分配置 Fargate 中运行
- 这里可以添加多个 namespace
点击“Create”创建 profile
如果所选的 subnet 不是 private subnet 则会报已下错误
Subnet subnet-040b0747b9d8fd8b3 provided in Fargate Profile is not a private subnet
创建中
过 6,7 分钟创建完成
5. 更新 CoreDNS(选做)
在 EKS 中,CoreDNS 默认配置运行在 EC2 上。
查看当前的 Node(EC2)和 CoreDNS Pod 运行情况
kubectl get nodes
kubectl get pods -n kube-system --selector eks.amazonaws.com/component=coredns,k8s-app=kube-dns -o wide
可以看到 CoreDNS Pod 运行在 node(EC2)上
如果你的 EKS 的 Pod 只想运行在 Fargate 上,则我们需要修改 CoreDNS deployment 的配置,
去掉 annotation “eks.amazonaws.com/compute-type : ec2”,让 CoreDNS 的 Pod 运行在 Fargate 上。
如果你的 EKS 中的 Pod 既有运行在 EC2 上的,又有运行在 Fargate 上的,那就可以忽略此步骤。
为了使 CoreDNS Pod 运行在 Fargate 上,除了要删除上面的 annotation,我们还要为 CoreDNS Pod 创建一个 Fargate profile。
下面我们利用 AWS CLi 和 json 文件创建一个新的 Fargate profile,效果与在 AWS 界面上创建相同。
新建文件 coredns.json,粘贴以下内容
{
"fargateProfileName": "coredns",
"clusterName": "tsEKS",
"podExecutionRoleArn": "arn:aws:iam::252557384592:role/AmazonEKSFargatePodExecutionRole",
"subnets": [
"subnet-0f3d033b4f5792344",
"subnet-040b0747b9d8fd8b3"
],
"selectors": [
{
"namespace": "kube-system",
"labels": {
"k8s-app": "kube-dns"
}
}
]
}
说明:
- clusterName:指定 EKS 名称
- podExecutionRoleArn:上面创建的 Pod execution role 的 ARN
- subnets:上面创建的两个 private subnets
- selectors:通过 namespace 和 labels 来指定 CoreDNS Pod
运行以下命令,创建 Fargate profile
aws eks create-fargate-profile --cli-input-json file://coredns.json
创建成功
在 EKS 的 Compute 界面,我们也可以看到新建的 Fargate profile
建好 Profile 之后,我们运行下列语句,删除 annotation “eks.amazonaws.com/compute-type : ec2”
kubectl patch deployment coredns \
-n kube-system \
--type json \
-p='[{"op": "remove", "path": "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type"}]'
运行结果
然后,我们可以运行下列语句重建 coredns Pod,使其运行在 Fargate 上
kubectl rollout restart -n kube-system deployment/coredns
运行结果
再次查看 coredns pod
kubectl get pods -n kube-system --selector eks.amazonaws.com/component=coredns,k8s-app=kube-dns -o wide
可以看到 node 显示为 Fargate 了,这表示 Pod 运行在 Fargate 上
提示:
其实在我们用 kubetl patch 删除掉 annotation 时,Pod 就重建了,这时新 Pod 满足 Fargate Profile 的要求就自动建在 Fargate 上。
但对于正在运行的 Pod,启用 Fargate profile 后,Pod 是不会自动迁移到 Fargate 上的,需要通过手工重建 Pod 来迁移到 Fargate 上。
6. 部署 Fargate 测试应用
我们对《AWS EKS 集群配置 ALB Ingress》文章中的测试应用稍做修改,添加一个 label 来测试。
先删除原应用
kubectl delete -f foo_app.yaml
kubectl delete -f bar_app.yaml
kubectl delete -f eks_ingress.yaml
修改 foo_app.yaml 文件
kind: Pod
apiVersion: v1
metadata:
name: foo-app
labels:
app: foo
infrastructure: fargate
spec:
containers:
- name: foo-app
image: hashicorp/http-echo:0.2.3
args:
- "-text=foo"
---
kind: Service
apiVersion: v1
metadata:
name: foo-service
spec:
selector:
app: foo
infrastructure: fargate
ports:
# Default port used by the image
- port: 5678
说明:
- 在 Pod .metadata.labels 中增加“infrastructure: fargate”
- 在 Service .spec.selector 中增加“infrastructure: fargate”
同样的修改 bar_app.yaml。
这两个 Pod 没有指定 namespace 所以 namespace 为 default,再增加 lable “infrastructure: fargate”后,满足 Fargate profile “tsEKSFargateprofile”
eks_ingress.yaml 文件内容如下,注意连接运行在 Fargate 的 Pod 时,alb.ingress.kubernetes.io/target-type 为 IP
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tstestingress
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- pathType: Prefix
path: "/foo"
backend:
serviceName: foo-service
servicePort: 5678
- pathType: Prefix
path: "/bar"
backend:
serviceName: bar-service
servicePort: 5678
依次运行下列命令创建测试应用
kubectl apply -f foo_app.yaml
kubectl apply -f bar_app.yaml
kubectl apply -f eks_ingress.yaml
运行结果
查看 Pod 详情
kubectl get pods/bar-app -o wide
kubectl get pods/foo-app -o wide
可以看到 Pod 都运行在 Fargate 上
这时我们再次查看 nodes
kubectl get nodes
可以看到,多个两个 Fargate,但这两行并不是代表 node(EC2)
总结
我们在原来 EKS 上的基础上,通过创建 Fargate profile,使得满足条件的 Pod 可以运行在 Fargate 上。
在 EKS 中部署 Pod 到 Fargate 上时,我们可以利用 kubectl/helm 等工具部署,不需要使用 Fargate 专用的 service、task。
测试例子中的 Pod 运行在 Fargate 上,通过 ALB ingress 创建了一个 ALB,ALB ingress 的 controller 则是运行在 node(EC2)上,说明 Fargate 上的 Pod 和 node 上的 Pod 是可以互相通信的。
后记
EKS 中加了 Fargate 完整了。EKS 或者说 K8s 功能是强大,不过要说简单易上手,那还是 Fargate 用起来更容易。
喜欢请点赞,禁止转载,转发请标明出处
关注 B 站 UP 主“我是手拉面” 观看更多视频
微信公众号“全是 AWS 干货”