27、在 AWS 上搭建 Kubernetes 集群指南

在 AWS 上搭建 Kubernetes 集群指南

1. 引言

在云计算环境中,AWS(Amazon Web Services)提供了丰富的资源和服务来支持 Kubernetes 的部署和管理。本文将详细介绍如何在 AWS 上使用相关组件搭建 Kubernetes 集群,包括 ELB 的使用、Amazon EKS 的部署以及存储类和负载均衡器的配置。

2. ELB(Elastic Load Balancer)

AWS 提供了强大的基于软件的负载均衡器,即经典负载均衡器(Classic Load Balancer),也称为 ELB。它可以将网络流量负载均衡到一个或多个 EC2 实例,还能卸载 SSL/TLS 加密/解密工作,并且支持多可用区。

由于 AWS 引入了新类型的负载均衡器,如网络负载均衡器(L4)和应用程序负载均衡器(L7),所以原来的 ELB 被称为经典负载均衡器。不过,由于 ELB 稳定且健壮,Amazon EKS 默认会使用它。

以下是创建一个 ELB 并将其与公共子网中的 nginx 服务关联的示例:

# 创建新的安全组
$ aws ec2 create-security-group --vpc-id vpc-0ca37d4650963adbb --group-name elb --description "elb sg"
{
    "GroupId": "sg-024f1c5315bac6b9e"
}

# 为 ELB 开放 TCP 80 端口给所有 IP 地址
$ aws ec2 authorize-security-group-ingress --group-id sg-024f1c5315bac6b9e --protocol tcp --port 80 --cidr 0.0.0.0/0

# 在公共子网创建 ELB
$ aws elb create-load-balancer --load-balancer-name public-elb --listeners Protocol=HTTP,LoadBalancerPort=80,InstanceProtocol=HTTP,InstancePort=80 --subnets subnet-09f8f7f06c27cb0a0 subnet-026058e32f09c28af --security-group sg-024f1c5315bac6b9e
{
    "DNSName": "public-elb-1952792388.us-east-1.elb.amazonaws.com"
}

# 注册运行 nginx 的 EC2 实例
$ aws elb register-instances-with-load-balancer --load-balancer-name public-elb --instances i-0f2750f65dd857e54

# 从本地访问 ELB
$ curl -I public-elb-1952792388.us-east-1.elb.amazonaws.com
HTTP/1.1 200 OK
3. AWS 组件概述

下面总结了主要的 AWS 组件及其关系:
| 组件 | 描述 |
| ---- | ---- |
| VPC | 一个带有互联网网关(IGW)的虚拟专用云 |
| 子网 | 在 us-east-1a 和 us-east-1b 各有两个子网(公共和私有) |
| NAT-GW | 一个网络地址转换网关 |
| EC2 实例 | 一个公共子网中的带有 EBS 的公共 EC2 实例和一个私有子网中的私有 EC2 实例 |
| ELB | 将流量转发到公共 EC2 实例的负载均衡器 |

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(VPC):::process --> B(IGW):::process
    A --> C(Subnet - us-east-1a):::process
    A --> D(Subnet - us-east-1b):::process
    C --> C1(Public Subnet):::process
    C --> C2(Private Subnet):::process
    D --> D1(Public Subnet):::process
    D --> D2(Private Subnet):::process
    C1 --> E(Public EC2 with EBS):::process
    C2 --> F(Private EC2):::process
    D1 --> G(Public EC2 with EBS):::process
    D2 --> H(Private EC2):::process
    I(ELB):::process --> E
4. Amazon EKS

自 2018 年 6 月起,AWS 开始提供名为 Amazon Elastic Container Service for Kubernetes(EKS)的新服务,这是一种托管的 Kubernetes 服务,类似于 Google Kubernetes Engine 和 Azure Kubernetes Service。

AWS 还提供了另一个容器编排服务 Amazon Elastic Container Service(ECS),但它不是 Kubernetes 服务,不过能与 AWS 组件完全集成以启动容器应用。

EKS 使用 VPC、安全组、EC2 实例、EBS、ELB、IAM 等 AWS 组件来设置 Kubernetes 集群,并 24/7 管理集群,负责修补和替换有问题的组件。用户只需按小时向 AWS 付费,就能将安装、配置和监控 Kubernetes 集群的工作交给 AWS。

5. EKS 的主要组件

EKS 有两个主要组件:
- 控制平面(Control Plane):由 AWS 管理的 Kubernetes 主节点,包括 etcd 数据库,AWS 会帮助将其部署在多个可用区。用户可以通过 AWS Web 控制台或 AWS CLI 监控和访问控制平面,也可以使用 Kubernetes 客户端(如 kubectl 命令)访问 Kubernetes API 服务器。
- 工作节点(Worker Nodes):截至 2018 年 12 月,AWS 仅为工作节点提供自定义的 Amazon Machine Images(AMI),用户需要使用该 AMI 手动启动 EC2 实例来配置工作节点。

6. 部署 EKS 前的准备工作

在设置 Amazon EKS 之前,需要进行以下准备:
1. 设置 IAM 服务角色

$ aws iam create-role --role-name eksServiceRole --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "eks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }'
$ aws iam attach-role-policy --role-name eksServiceRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
$ aws iam attach-role-policy --role-name eksServiceRole --policy-arn arn:aws:iam::aws:policy/AmazonEKSServicePolicy
  1. 设置安全组
$ aws ec2 create-security-group --vpc-id vpc-0ca37d4650963adbb --group-name eks-control-plane --description "EKS Control Plane"
{
    "GroupId": "sg-0fbac0a39bf64ba10"
}
  1. 标记私有子网
$ aws ec2 create-tags --resources subnet-04b78ed9b5f96d76e --tags Key=kubernetes.io/role/internal-elb,Value=1
$ aws ec2 create-tags --resources subnet-08e16157c15cefcbc --tags Key=kubernetes.io/role/internal-elb,Value=1
7. 启动 EKS 控制平面

使用 AWS CLI 指定 IAM、子网和安全组来启动 EKS 控制平面,以下示例指定 Kubernetes 版本为 1.10:

$ aws eks create-cluster --name chap10 --role-arn arn:aws:iam::xxxxxxxxxxxx:role/eksServiceRole --resources-vpc-config subnetIds=subnet-09f8f7f06c27cb0a0,subnet-04b78ed9b5f96d76e,subnet-026058e32f09c28af,subnet-08e16157c15cefcbc,securityGroupIds=sg-0fbac0a39bf64ba10 --kubernetes-version 1.10

该过程大约需要 10 分钟完成,可以使用 aws eks describe-cluster --name chap10 检查状态。当控制平面状态为 ACTIVE 时,就可以设置 kubeconfig 来访问 Kubernetes API 服务器。

由于 AWS 将 Kubernetes API 访问控制与 AWS IAM 凭证集成,因此在运行 kubectl 命令时需要使用 aws-iam-authenticator 生成令牌:

# 下载并安装 aws-iam-authenticator
# 验证 aws-iam-authenticator 是否正常工作
$ aws-iam-authenticator token -i chap10

# 生成 kubeconfig
$ aws eks update-kubeconfig --name chap10

# 检查是否可以访问 Kubernetes 主节点
$ kubectl cluster-info
$ kubectl get svc
8. 添加工作节点

由于 AWS 不允许使用 AWS CLI 设置 EKS 工作节点,因此需要使用 CloudFormation。它会为工作节点创建必要的 AWS 组件,如安全组、自动扩展组和 IAM 实例角色。

以下是使用 CloudFormation 模板启动工作节点的参数设置:
| 参数 | 值 |
| ---- | ---- |
| Stack name | chap10-worker |
| ClusterName | chap10 |
| ClusterControlPlaneSecurityGroup | sg-0fbac0a39bf64ba10 |
| NodeGroupName | chap10 EKS worker node |
| NodeImageId | ami-027792c3cc6de7b5b |
| KeyName | my-key |
| VpcId | vpc-0ca37d4650963adbb |
| Subnets | subnet-04b78ed9b5f96d76e (10.0.2.0/24)
subnet-08e16157c15cefcbc (10.0.4.0/24) |

CloudFormation 执行大约需要 5 分钟完成,之后需要从输出中获取 NodeInstanceRole 值。

最后,通过添加 ConfigMap 将这些节点添加到 Kubernetes 集群:

$ cat aws-auth-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
    name: aws-auth
    namespace: kube-system
data:
    mapRoles: |
        - rolearn: arn:aws:iam::xxxxxxxxxxxx:role/chap10-worker-NodeInstanceRole-8AFV8TB4IOXA
          username: system:node:{{EC2PrivateDNSName}}
          groups:
            - system:bootstrappers
            - system:nodes

$ kubectl create -f aws-auth-cm.yaml

几分钟后,工作节点将注册到 Kubernetes 主节点:

$ kubectl get nodes
NAME                         STATUS    ROLES     AGE       VERSION
ip-10-0-2-218.ec2.internal   Ready     <none>    3m        v1.10.3
ip-10-0-4-74.ec2.internal    Ready     <none>    3m        v1.10.3
9. EKS 上的云提供商集成

EKS 将 Kubernetes 云提供商集成到 AWS 组件中,如弹性负载均衡器和弹性块存储。下面将详细介绍存储类和负载均衡器的配置。

10. 存储类

截至 2018 年 12 月,如果部署 Kubernetes 版本 1.10,EKS 默认不会创建存储类;而在 1.11 及以上版本,EKS 会自动创建默认存储类。可以使用以下命令检查存储类是否存在:

$ kubectl get sc

如果没有找到存储类,则需要为每个可用区创建存储类:

# 为 us-east-1a 创建存储类
$ cat storage-class-us-east-1a.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
    name: gp2-us-east-1a
provisioner: kubernetes.io/aws-ebs
parameters:
    type: gp2
    fsType: ext4
    zone: us-east-1a

# 为 us-east-1b 创建存储类
$ cat storage-class-us-east-1b.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
    name: gp2-us-east-1b
provisioner: kubernetes.io/aws-ebs
parameters:
    type: gp2
    fsType: ext4
    zone: us-east-1b

# 创建存储类
$ kubectl create -f storage-class-us-east-1a.yaml
$ kubectl create -f storage-class-us-east-1b.yaml

# 查看存储类
$ kubectl get sc
NAME             PROVISIONER           AGE
gp2-us-east-1a   kubernetes.io/aws-ebs   6s
gp2-us-east-1b   kubernetes.io/aws-ebs   3s

PersistentVolumeClaim 可以指定 gp2-us-east-1a gp2-us-east-1b 存储类来配置持久卷:

$ cat pvc-a.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-a
spec:
    storageClassName: "gp2-us-east-1a"
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 10Gi

$ cat pvc-b.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
    name: pvc-b
spec:
    storageClassName: "gp2-us-east-1b"
    accessModes:
        - ReadWriteOnce
    resources:
        requests:
            storage: 10Gi

# 创建 PersistentVolumeClaim
$ kubectl create -f pvc-a.yaml
$ kubectl create -f pvc-b.yaml

# 查看持久卷
$ kubectl get pv

可以使用以下 AWS CLI 命令搜索 EBS 实例:

$ aws ec2 describe-volumes --query "Volumes[*].{Id:VolumeId,AZ:AvailabilityZone,Tags:Tags[?Key=='kubernetes.io/created-for/pv/name'].Value}" --filter "Name=tag-key,Values=kubernetes.io/cluster/chap10"

由于工作节点有 failure-domain.beta.kubernetes.io/zone 标签,因此可以指定 nodeSelector 将 Pod 部署到所需的可用区:

# 查看节点标签
$ kubectl get nodes --show-labels

# 创建 Pod 并指定 nodeSelector
$ cat pod-us-east-1a.yaml
apiVersion: v1
kind: Pod
metadata:
    name: nginx
    labels:
        project: devops-with-kubernetes
        app: nginx
spec:
    containers:
        - name: nginx
            image: nginx
            volumeMounts:
                - mountPath: /var/log/nginx
                  name: nginx-log
    volumes:
        - name: nginx-log
            persistentVolumeClaim:
                claimName: "pvc-a"
    nodeSelector:
        failure-domain.beta.kubernetes.io/zone: us-east-1a

$ kubectl create -f pod-us-east-1a.yaml

# 查看 Pod 部署情况
$ kubectl get pods -o wide

# 验证 PVC 是否成功挂载
$ kubectl exec -it nginx /bin/bash
root@nginx:/# df -h /var/log/nginx
11. 负载均衡器

EKS 将 Kubernetes Service 集成到经典负载均衡器(ELB)中。当创建类型为 LoadBalancer 的 Kubernetes Service 时,EKS 会自动创建经典 ELB 实例和安全组,并将 ELB 与工作节点关联。

可以创建面向互联网(公共子网)或内部(私有子网)的负载均衡器。如果不需要向外部互联网提供服务,出于安全考虑,应使用内部负载均衡器。

11.1 内部负载均衡器

为之前的 nginx Pod 创建内部负载均衡器,需要添加注解 service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0

$ cat internal-elb.yaml
apiVersion: v1
kind: Service
metadata:
    name: nginx
    annotations:
        service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
spec:
    ports:
        - protocol: TCP
          port: 80
    type: LoadBalancer
    selector:
        project: devops-with-kubernetes
        app: nginx

$ kubectl create -f internal-elb.yaml

由于是内部 ELB,无法从 AWS 网络外部(如本地笔记本)访问,但可以在 VPC 内将应用暴露给 Kubernetes 集群外部。

11.2 面向互联网的负载均衡器

创建面向互联网的负载均衡器的步骤与内部负载均衡器相同,但不需要注解:

$ cat external-elb.yaml
apiVersion: v1
kind: Service
metadata:
    name: nginx-external
spec:
    ports:
        - protocol: TCP
          port: 80
    type: LoadBalancer
    selector:
        project: devops-with-kubernetes
        app: nginx

$ kubectl create -f external-elb.yaml

通过 AWS Web 控制台可以看到 Scheme 为面向互联网,并且可以从本地笔记本访问该 ELB。

EKS 云提供商与 Kubernetes Service 的集成非常强大,能够将流量分发到多个 Pod,实现流量的扩展。

通过以上步骤,你可以在 AWS 上成功搭建和配置 Kubernetes 集群,并利用其强大的功能来部署和管理容器化应用。

在 AWS 上搭建 Kubernetes 集群指南(续)

12. 负载均衡器的优势和使用场景总结

负载均衡器在 Kubernetes 集群中起着至关重要的作用,不同类型的负载均衡器适用于不同的场景,以下是它们的优势和使用场景总结:
| 负载均衡器类型 | 优势 | 使用场景 |
| ---- | ---- | ---- |
| 内部负载均衡器 | 增强安全性,仅在 VPC 内部提供服务,防止外部未经授权的访问 | 当应用不需要对外提供服务,仅在内部网络使用时,如企业内部的业务系统 |
| 面向互联网的负载均衡器 | 可以将流量从外部互联网引入到 Kubernetes 集群,实现应用的对外服务 | 当需要将应用暴露给外部用户时,如面向公众的网站、API 服务等 |

13. 常见问题及解决方法

在搭建和使用 AWS 上的 Kubernetes 集群过程中,可能会遇到一些常见问题,以下是一些问题及解决方法:
- 问题 1:无法访问 Kubernetes API 服务器
- 可能原因 :AWS IAM 凭证配置错误,或者 aws-iam-authenticator 未正确安装和配置。
- 解决方法 :确保使用创建控制平面时的同一 IAM 用户,并正确安装和配置 aws-iam-authenticator ,使用 aws-iam-authenticator token -i <cluster-name> 验证令牌生成是否正常。
- 问题 2:工作节点无法加入集群
- 可能原因 :CloudFormation 模板参数配置错误,或者 IAM 实例角色权限不足。
- 解决方法 :检查 CloudFormation 模板参数是否正确,确保 IAM 实例角色具有足够的权限,如 AmazonEKSWorkerNodePolicy、AmazonEKS_CNI_Policy 等。
- 问题 3:存储类创建失败
- 可能原因 :AWS EBS 和 EC2 不在同一可用区,或者存储类参数配置错误。
- 解决方法 :确保 EBS 和 EC2 在同一可用区,检查存储类参数,如 type fsType zone 等是否正确。

14. 最佳实践建议

为了更好地在 AWS 上搭建和管理 Kubernetes 集群,以下是一些最佳实践建议:
- 安全方面
- 使用内部负载均衡器来保护不需要对外暴露的应用。
- 定期更新 IAM 策略,确保只有授权用户和角色可以访问 Kubernetes 集群。
- 启用 AWS 安全组和网络访问控制列表(NACL)来限制网络流量。
- 性能方面
- 根据应用的负载情况,合理调整 EC2 实例的类型和数量。
- 使用自动扩展组(AutoScaling Group)来实现工作节点的自动伸缩,以应对流量的变化。
- 优化存储类的配置,选择合适的 EBS 卷类型和大小。
- 管理方面
- 使用 CloudFormation 模板来自动化集群的创建和管理,提高部署效率和一致性。
- 定期备份 Kubernetes 集群的配置和数据,以防数据丢失。
- 监控集群的性能和资源使用情况,及时发现和解决问题。

15. 总结与展望

通过本文的介绍,我们详细了解了在 AWS 上搭建 Kubernetes 集群的步骤,包括 ELB 的使用、Amazon EKS 的部署、存储类和负载均衡器的配置等。这些步骤和方法可以帮助我们快速、高效地在 AWS 上搭建和管理 Kubernetes 集群,实现容器化应用的部署和运行。

未来,随着云计算和容器技术的不断发展,AWS 上的 Kubernetes 服务也将不断完善和优化。例如,可能会提供更多的自动化工具和功能,进一步简化集群的搭建和管理过程;同时,也可能会加强与其他 AWS 服务的集成,提供更强大的功能和更丰富的应用场景。我们可以持续关注这些发展趋势,不断提升自己的技术能力和应用水平。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(搭建 Kubernetes 集群):::process --> B(使用 ELB):::process
    A --> C(部署 Amazon EKS):::process
    A --> D(配置存储类):::process
    A --> E(配置负载均衡器):::process
    B --> B1(创建 ELB):::process
    B --> B2(关联 ELB 和 EC2 实例):::process
    C --> C1(启动控制平面):::process
    C --> C2(添加工作节点):::process
    D --> D1(检查存储类):::process
    D --> D2(创建存储类):::process
    E --> E1(创建内部负载均衡器):::process
    E --> E2(创建面向互联网的负载均衡器):::process

通过以上的总结和展望,希望能帮助你更好地理解和应用在 AWS 上搭建 Kubernetes 集群的技术,为你的业务发展提供有力的支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值