Amazon Web Services (AWS) 上的 Kubernetes#

AWS 本身不支持 Kubernetes,但许多组织已经构建了自己的解决方案和指南,用于在 AWS 上设置 Kubernetes。

本指南使用 kops 在 AWS 上设置集群。这应该被视为一个粗略的模板,您将使用它来设置和塑造您的集群。

步骤#

  1. 创建 IAM(身份和访问管理)角色。

    此角色将用于授予您的 CI 主机在 AWS 上创建和销毁资源的权限。有关创建角色的说明,请参见 此处。需要以下策略

    • AmazonEC2FullAccess

    • IAMFullAccess

    • AmazonS3FullAccess

    • AmazonVPCFullAccess

    • Route53FullAccess(可选)

  2. 创建一个新实例作为您的 CI 主机。此节点将处理集群的配置和拆卸。

    此实例可以很小(例如 t2.micro)。

    创建时,分配在步骤 1 中创建的 IAM 角色。

    创建后,下载 ssh 密钥(.pem 文件)。确保文件上的权限具有限制性

    chmod 400 name.pem
    
  3. SSH 到您的 CI 主机。有关如何执行此操作的说明,请参见 此处

  4. 在您的 CI 主机上安装 kops 和 kubectl

  5. 选择一个集群名称

    由于我们不使用预配置的 DNS,因此我们将使用后缀“.k8s.local”。根据文档,如果 DNS 名称以 .k8s.local 结尾,则集群将使用内部托管 DNS。

    export NAME=<somename>.k8s.local
    
  6. 设置一个 ssh 密钥对,用于与集群一起使用

    ssh-keygen
    
  7. 创建一个 S3 存储桶来存储您的集群配置

    由于我们在 AWS 上,因此我们可以使用 S3 作为后端存储。建议在 S3 存储桶上启用版本控制。我们不需要将其传递给 KOPS 命令。kops 工具会自动将其检测为环境变量。

    export KOPS_STATE_STORE=s3://<your_s3_bucket_name_here>
    
  8. 设置要部署的区域

    export REGION=`curl -s http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F\" '{print $4}'`
    
  9. 安装 AWS CLI

    sudo apt-get update
    sudo apt-get install awscli
    
  10. 设置节点的可用区

    在本指南中,我们将允许节点部署在所有可用区中

    export ZONES=$(aws ec2 describe-availability-zones --region $REGION | grep ZoneName | awk '{print $2}' | tr -d '"')
    
  11. 创建集群

    对于基本设置,请运行以下命令(所有大小均以 GB 为单位)

    kops create cluster $NAME \
    --zones "$ZONES" \
    --authorization RBAC \
    --master-size t3a.small \
    --master-volume-size 10 \
    --node-size t3.medium \
    --node-volume-size 10 \
    --yes
    

    对于更安全的设置,请将以下参数添加到 kops 命令中

    --topology private \
    --networking weave \
    

    这将创建一个集群,其中所有主节点和节点都在私有子网中,并且没有外部 IP 地址。配置错误的安全组或不安全的 ssh 配置不太可能危及集群。为了 SSH 到您的集群,您需要设置一个堡垒节点。确保您在下面执行该步骤。如果您拥有默认数量的弹性 IP(10 个),您可能需要向 AWS 支持提出请求以提高该限制。另一种方法是减少指定的区域数量。

    有关此主题的更多阅读内容:https://github.com/kubernetes/kops/blob/HEAD/docs/networking.md

    要考虑的设置(本指南中未涵盖)

    --vpc
      Allows you to use a custom VPC or share a VPC
      https://github.com/kubernetes/kops/blob/HEAD/docs/run_in_existing_vpc.md
    --master-count
      Spawns more masters in one or more VPCs
      This improves redudancy and reduces downtime during cluster upgrades
    --master-zones
      specify zones to run the master in
    --node-count
      Increases the total nodes created (default 2)
    --master/node-security-groups
      Allows you to specify additional security groups to put the masters and nodes in by default
    --ssh-access
      By default SSH access is open to the world (0.0.0.0).
      If you are using a private topology, this is not a problem.
      If you are using a public topology make sure your ssh keys are strong and you keep sshd up to date on your cluster's nodes.
    

    考虑 为您的 AWS 帐户设置云预算,以确保您不会意外支出超过您的意愿。

  12. 等待集群启动

    运行 kops validate cluster 命令将告诉我们当前的设置状态。如果您最初看到“无法获取节点”,请耐心等待,因为集群在一些基本服务启动并运行之前无法报告。

    持续运行 kops validate cluster,直到您在输出的末尾看到“您的集群 $NAME 已准备就绪”。

    time until kops validate cluster; do sleep 15; done
    

    可用于自动化等待过程。

    如果您在任何时候希望在此步骤后销毁您的集群,请运行 kops delete cluster $NAME --yes

  13. 确认 kubectl 已连接到您的 Kubernetes 集群。

    运行

    kubectl get nodes
    

    您应该看到两个节点的列表,每个节点都以 ip 开头。

    如果您想在本地使用 kubectl 和 helm

    • 在 CI 主机上运行以下命令:kops export kubecfg

    • ~/.kube/config 的内容复制到本地系统上的相同位置。

    如果您希望将 kube 配置文件放在其他位置,则需要运行

    export KUBECONFIG=<other kube config location>
    
  14. 配置 ssh 防御主机(如果您没有使用上面的 **–topology private** 选项,请跳过此步骤!)

    理想情况下,我们只需将 --bastion 标志传递到上面的 kops 命令中。但是,该标志目前无法按预期工作。 kubernetes/kops#2881

    相反,我们需要遵循本指南:kubernetes/kops

    此时,还有一些公开的端点需要解决。

    • 防御主机 ELB 安全组默认允许来自 0.0.0.0 的访问。

    • API ELB 安全组默认允许来自 0.0.0.0 的访问。

  15. 在您的 Kubernetes 集群上启用动态存储。

    在本地计算机上创建一个文件 storageclass.yml,并输入以下文本

    kind: StorageClass
    apiVersion: storage.k8s.io/v1
    metadata:
      annotations:
        storageclass.beta.kubernetes.io/is-default-class: "true"
      name: gp2
    provisioner: kubernetes.io/aws-ebs
    parameters:
      type: gp2
    

    接下来,运行以下命令

    kubectl apply -f storageclass.yml
    

    这将启用 动态配置 磁盘,允许我们在用户登录 JupyterHub 时自动为每个用户分配一个磁盘。

    注意

    EC2 实例元数据是详细说明正在运行的实例配置和运行的数据。这些数据可能很敏感,任何具有直接访问实例权限的人都可以看到这些数据。默认情况下,此元数据被一个 init 容器阻止,因为它们覆盖了用于设置实例的 iptables。通过在 init 容器中添加一个 iptables 规则,可以设置和保护对该元数据的访问,如云元数据安全部分所示 here <https://zero-to-jupyterhub.readthedocs.io/en/v0.5-doc/security.html>_。

加密#

有一些简单的方法可以加密您的 Kubernetes 集群。这里说明了在静止状态下加密和在传输过程中加密的简单方法。

静止状态下的加密

不要执行上面的步骤 13。在本地计算机上创建以下 storageclass.yml 文件

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  annotations:
    storageclass.beta.kubernetes.io/is-default-class: "true"
  name: gp2
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp2
  encrypted: "true"

主要区别在于添加了行 encrypted: "true",请注意 true 位于双引号中。

接下来运行以下命令

kubectl delete storageclass gp2
kubectl apply -f storageclass.yml

Kubernetes 不允许您修改 storageclass gp2 以添加 encrypted 标志,因此您必须先将其删除。这将加密 Kubernetes 创建的任何动态卷(例如您的笔记本),但不会加密 Kubernetes 节点本身的存储。

传输过程中的加密

在上面的步骤 9 中,通过在上面的 kops create 命令中包含 --networking weave 标志来使用 weave 设置集群。然后执行以下步骤

  1. 验证 weave 是否正在运行

    kubectl --namespace kube-system get pods
    

    您应该看到几个形式为 weave-net-abcde 的 pod。

  2. 使用足够强度的私有密码创建 Kubernetes 密钥。在本例中,使用随机的 128 字节

    openssl rand -hex 128 >weave-passwd
    kubectl create secret -n kube-system generic weave-passwd --from-file=./weave-passwd
    

    密钥名称及其值(取自文件名)必须相同。如果它们不匹配,您可能会收到 ConfigError

  3. 使用密码进行补丁编织

    kubectl patch --namespace=kube-system daemonset/weave-net --type json -p '[ { "op": "add", "path": "/spec/template/spec/containers/0/env/0", "value": { "name": "WEAVE_PASSWORD", "valueFrom": { "secretKeyRef": { "key": "weave-passwd", "name": "weave-passwd" } } } } ]'
    

    如果您想移除加密,可以使用以下补丁

    kubectl patch --namespace=kube-system daemonset/weave-net --type json -p '[ { "op": "remove", "path": "/spec/template/spec/containers/0/env/0"} ]'
    
  4. 检查 Pod 是否已重启。为了加快速度,您可以删除旧的 Pod。

  5. 您可以使用以下命令验证加密是否已开启

    kubectl exec -n kube-system weave-net-<pod> -c weave -- /home/weave/weave --local status
    

    您应该看到 encryption: enabled

    如果您真的想确保加密正常工作,可以在任何节点的端口 6783 上监听。如果流量看起来像乱码,那么您就知道它已开启。

共享存储#

共享卷应该被挂载到多个用户 Pod 上,因此我们不能使用 EBS。作为替代方案,可以使用 AWS EFS

  1. 在 AWS 上设置 EFS 存储

  2. 自定义用户存储

恭喜。现在您已经拥有了运行的 Kubernetes 集群,是时候开始 设置 helm 了。