跳到内容

在 AWS 上入门 kOps

确保您已安装 kOps安装 kubectl

设置您的环境

AWS

为了正确地为 kops 准备您的 AWS 账户,我们要求您安装 AWS CLI 工具,并为一个账户提供 API 凭据,该账户在指南的后面部分拥有创建新的 IAM 账户的权限来为 kops 使用。

一旦您安装了 AWS CLI 工具,并正确地设置了您的系统以使用官方 AWS 方法注册安全凭据,如这里所定义,我们就可以准备运行 kops,因为它使用的是 Go AWS SDK。

设置 IAM 用户

为了在 AWS 中构建集群,我们将为 kops 创建一个专用的 IAM 用户。此用户需要 API 凭据才能使用 kops。使用AWS 控制台创建用户和凭据。

kops 用户需要以下 IAM 权限才能正常运行

AmazonEC2FullAccess
AmazonRoute53FullAccess
AmazonS3FullAccess
IAMFullAccess
AmazonVPCFullAccess
AmazonSQSFullAccess
AmazonEventBridgeFullAccess

您可以使用以下命令从命令行创建 kOps IAM 用户

aws iam create-group --group-name kops

aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonVPCFullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonSQSFullAccess --group-name kops
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEventBridgeFullAccess --group-name kops

aws iam create-user --user-name kops

aws iam add-user-to-group --user-name kops --group-name kops

aws iam create-access-key --user-name kops

您应该记录返回的 JSON 输出中的 SecretAccessKey 和 AccessKeyID,然后在下面使用它们

# configure the aws client to use your new IAM user
aws configure           # Use your new access and secret key here
aws iam list-users      # you should see a list of all your IAM users here

# Because "aws configure" doesn't export these vars for kops to use, we export them now
export AWS_ACCESS_KEY_ID=$(aws configure get aws_access_key_id)
export AWS_SECRET_ACCESS_KEY=$(aws configure get aws_secret_access_key)

配置 DNS

为了使用 kops 构建 Kubernetes 集群,我们需要准备一个地方来构建所需的 DNS 记录。下面有三种场景,您应该选择最符合您 AWS 情况的场景。

注意:如果您想使用基于 Gossip 的 DNS,您可以跳过本节。

场景 1a:通过 AWS 购买/托管的域名

如果您在 AWS 购买了域名,那么您应该已经在 Route53 中拥有托管区域。如果您打算使用此域名,则无需再进行任何操作。

在本例中,您拥有 example.com,而您的 Kubernetes 记录将类似于 etcd-us-east-1c.internal.clustername.example.com

场景 1b:通过 AWS 购买/托管的域名下的子域名

在本例中,您希望将所有 Kubernetes 记录包含在您在 Route53 中托管的域名的子域名下。这需要在 Route53 中创建一个第二个托管区域,然后为新区域设置路由委托。

在本例中,您拥有 example.com,而您的 Kubernetes 记录将类似于 etcd-us-east-1c.internal.clustername.subdomain.example.com

这将把您 **子域名** 的 NS 服务器复制到 Route53 中的 **父域名**。为此,您应该

  • 创建子域名,并记下您的 **子域名** 命名服务器(如果您已经完成了此操作,您还可以获取这些值
# Note: This example assumes you have jq installed locally.
ID=$(uuidgen) && aws route53 create-hosted-zone --name subdomain.example.com --caller-reference $ID | \
    jq .DelegationSet.NameServers
  • 记下您的 **父域名** 托管区域 ID
# Note: This example assumes you have jq installed locally.
aws route53 list-hosted-zones | jq '.HostedZones[] | select(.Name=="example.com.") | .Id'
  • 使用您的值创建一个新的 JSON 文件(subdomain.json

注意:这里的 NS 值适用于 **子域名**

{
  "Comment": "Create a subdomain NS record in the parent domain",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "subdomain.example.com",
        "Type": "NS",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "ns-1.<example-aws-dns>-1.co.uk"
          },
          {
            "Value": "ns-2.<example-aws-dns>-2.org"
          },
          {
            "Value": "ns-3.<example-aws-dns>-3.com"
          },
          {
            "Value": "ns-4.<example-aws-dns>-4.net"
          }
        ]
      }
    }
  ]
}
  • 将 **子域名** NS 记录应用于 **父域名** 托管区域。
aws route53 change-resource-record-sets \
 --hosted-zone-id <parent-zone-id> \
 --change-batch file://subdomain.json

现在,指向 *.subdomain.example.com 的流量将被路由到 Route53 中正确的子域名托管区域。

场景 2:为通过其他注册商购买的域名设置 Route53

如果您在其他地方购买了域名,并且想将整个域名专门用于 AWS,您应该按照这里的指南操作。

场景 3:为 Route53 中的集群设置子域名,将域名保留在其他注册商

如果您在其他地方购买了域名,但 **只想在 AWS Route53 中使用子域名**,则您必须修改注册商的 NS(命名服务器)记录。我们将在 Route53 中创建一个托管区域,然后将子域名的 NS 记录迁移到您的其他注册商。

您可能需要为以下某些说明获取jq

  • 创建子域名,并记下您的命名服务器(如果您已经完成了此操作,您还可以获取这些值
ID=$(uuidgen) && aws route53 create-hosted-zone --name subdomain.example.com --caller-reference $ID | jq .DelegationSet.NameServers
  • 您现在将访问注册商的页面并登录。您需要创建一个新的 **子域名**,并为新的 **子域名** 使用从上述命令接收的 4 个 NS 记录。必须执行此操作才能使用您的集群。**不要**更改您的顶级 NS 记录,否则您可能会使您的网站脱机。

  • 关于使用Godaddy.com添加 NS 记录的信息

  • 关于使用Google Cloud Platform添加 NS 记录的信息

使用公共/私有 DNS (kOps 1.5+)

默认情况下,假设 NS 记录是公开可用的。如果您需要私有 DNS 记录,您应该修改我们稍后在本指南中运行的命令,以包含以下内容

kops create cluster --dns private $NAME

如果您拥有公共和私有区域的混合,您还需要包含 --dns-zone 参数以及您希望在其中部署的托管区域 ID

kops create cluster --dns private --dns-zone ZABCDEFG $NAME

测试您的 DNS 设置

如果您创建的是基于 Gossip 的集群,则不需要执行本节。

您现在应该能够挖掘您的域名(或子域名)并在另一端看到 AWS 命名服务器。

dig ns subdomain.example.com

应该返回类似于以下内容的内容

;; ANSWER SECTION:
subdomain.example.com.        172800  IN  NS  ns-1.<example-aws-dns>-1.net.
subdomain.example.com.        172800  IN  NS  ns-2.<example-aws-dns>-2.org.
subdomain.example.com.        172800  IN  NS  ns-3.<example-aws-dns>-3.com.
subdomain.example.com.        172800  IN  NS  ns-4.<example-aws-dns>-4.co.uk.

这是设置集群的关键组件。如果您发现 Kubernetes API 无法启动,很有可能是集群 DNS 出现了问题。

请在验证您的 NS 记录之前**不要继续**!如果您创建的是基于 Gossip 的集群,则不需要执行此操作。

集群状态存储

为了存储集群的状态和集群的表示,我们需要为 kops 创建一个专用的 S3 存储桶以供使用。此存储桶将成为我们集群配置的真实来源。在本指南中,我们将此存储桶称为 example-com-state-store,但您应该添加自定义前缀,因为存储桶名称需要是唯一的。

我们建议将此存储桶的创建限制在 us-east-1 区域,否则需要更多工作。

aws s3api create-bucket \
    --bucket prefix-example-com-state-store \
    --region us-east-1

注意:S3 要求使用 --create-bucket-configuration LocationConstraint=<region> 来创建除 us-east-1 以外的区域存储桶。

注意:我们强烈建议您为 S3 存储桶启用版本控制,以防您需要恢复或还原先前状态存储。

aws s3api put-bucket-versioning --bucket prefix-example-com-state-store  --versioning-configuration Status=Enabled

集群 OIDC 存储

为了让 ServiceAccounts 使用外部权限(即 IAM Roles for ServiceAccounts),您还需要一个存储桶来托管 OIDC 文档。虽然您可以重复使用上面的存储桶(前提是您授予其公共 ACL),但我们建议为这些文件使用单独的存储桶。

ACL 必须是公共的,以便 AWS STS 服务能够访问它们。

aws s3api create-bucket \
    --bucket prefix-example-com-oidc-store \
    --region us-east-1 \
    --object-ownership BucketOwnerPreferred
aws s3api put-public-access-block \
    --bucket prefix-example-com-oidc-store \
    --public-access-block-configuration BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false
aws s3api put-bucket-acl \
    --bucket prefix-example-com-oidc-store \
    --acl public-read

使用 kops 命令行工具时,必须设置有关集群状态存储位置的信息。有关更多信息,请参阅 状态存储

使用 S3 默认存储桶加密

kops 支持 默认存储桶加密 来加密存储在 S3 存储桶中的状态。这样,为您的存储桶设置的默认服务器端加密也会用于 kOps 状态。您可能希望使用此 AWS 功能,例如,默认情况下轻松加密每个写入的对象,或者当您需要出于合规性原因使用特定加密密钥(KMS、CMK)时。

如果您的 S3 存储桶已设置默认加密,kops 将使用它。

aws s3api put-bucket-encryption --bucket prefix-example-com-state-store --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'

如果未设置默认加密或无法检查默认加密,kops 将使用服务器端 AES256 存储桶加密(使用 Amazon S3 托管的加密密钥 (SSE-S3))。

跨多个帐户共享 S3 存储桶

通过使用 跨帐户存储桶策略,可以将单个 S3 存储桶用于存储位于不同帐户中的集群的 kOps 状态。

kops 默认情况下可以利用配置了跨帐户策略的存储桶。

在这种情况下,您可能希望覆盖 kOps 在状态文件上放置的对象 ACL,因为默认的 AWS ACL 将使拥有委托访问权限的帐户能够写入存储桶所有者无法读取的文件。

为此,您应该将环境变量 KOPS_STATE_S3_ACL 设置为首选的对象 ACL,例如:bucket-owner-full-control

有关可用的预定义 ACL,请查阅 Amazon 的 S3 文档

创建您的第一个集群

准备本地环境

我们准备开始创建第一个集群!让我们先设置一些环境变量,以简化操作流程。

export NAME=myfirstcluster.example.com
export KOPS_STATE_STORE=s3://prefix-example-com-state-store

对于基于 Gossip 的集群,请确保名称以 k8s.local 结尾。例如

export NAME=myfirstcluster.k8s.local
export KOPS_STATE_STORE=s3://prefix-example-com-state-store

注意:您不必在此处使用环境变量。您始终可以使用 –name 和 –state 标志稍后定义这些值。

创建集群配置

我们需要记录哪些可用区对我们可用。在此示例中,我们将把集群部署到 us-west-2 区域。

aws ec2 describe-availability-zones --region us-west-2

以下是一个创建集群的命令。我们将使用最基本的示例,在 高可用性 中提供更详细的示例。以下命令将生成一个集群配置,但不会开始构建。请确保在创建集群之前已生成 SSH 密钥对。

kops create cluster \
    --name=${NAME} \
    --cloud=aws \
    --zones=us-west-2a \
    --discovery-store=s3://prefix-example-com-oidc-store/${NAME}/discovery

kops 创建的所有实例都将在 ASG(自动扩展组)中构建,这意味着如果实例发生故障,AWS 将自动监控和重建每个实例。

自定义集群配置

现在我们拥有了一个集群配置,我们可以通过编辑描述来查看定义集群的各个方面。

kops edit cluster --name ${NAME}

这将打开您的编辑器(由 $EDITOR 定义),并允许您编辑配置。配置从我们之前创建的 S3 存储桶中加载,并在我们保存并退出编辑器时自动更新。

现在我们将所有内容都设置为默认值,但 kops 文档的其他部分介绍了您可以启用的其他设置和配置。

构建集群

现在我们采取最后一步,真正构建集群。这需要一些时间。完成后,您需要等待更长时间,直到启动的实例完成下载 Kubernetes 组件并进入“就绪”状态。

kops update cluster --name ${NAME} --yes --admin

使用集群

您还记得之前安装 kubectl 吗?您的集群配置已自动生成并写入 ~/.kube/config

可以使用简单的 Kubernetes API 调用来检查 API 是否在线并正在监听。让我们使用 kubectl 来检查节点。

kubectl get nodes

您将看到一个节点列表,该列表应与之前定义的 --zones 标志匹配。这是一个很好的迹象,表明您的 Kubernetes 集群已上线并正常工作。

kops 还附带一个方便的验证工具,可以运行该工具来确保您的集群按预期工作。

kops validate cluster --wait 10m

您可以使用以下命令查看所有系统组件。

kubectl -n kube-system get po

删除集群

在 AWS 中运行 Kubernetes 集群显然需要付费,因此如果您已完成运行实验,则可能需要删除集群。

您可以通过发出以下命令来预览删除集群时将被销毁的所有 AWS 资源。

kops delete cluster --name ${NAME}

当您确定要删除集群时,请使用 --yes 标志发出删除命令。请注意,此命令非常具有破坏性,将删除您的集群及其包含的所有内容!

kops delete cluster --name ${NAME} --yes

后续步骤

现在您已拥有一个可用的 kOps 集群,请阅读 生产环境设置指南中的建议

反馈

kops 背后有一个不可思议的团队,我们鼓励您在 Kubernetes Slack 上联系社区 (http://slack.k8s.io/)。提出您的问题、意见和请求,并结识项目背后的成员!

AWS 商标的使用是在 AWS 商标指南 下获得有限权限的。

Kubernetes 徽标的使用是在 Kubernetes 品牌指南 下获得许可的。