Amazon Web Services (AWS) 上的 Kubernetes#
AWS 本身不支持 Kubernetes,但许多组织已经构建了自己的解决方案和指南,用于在 AWS 上设置 Kubernetes。
本指南使用 kops 在 AWS 上设置集群。这应该被视为一个粗略的模板,您将使用它来设置和塑造您的集群。
步骤#
创建 IAM(身份和访问管理)角色。
此角色将用于授予您的 CI 主机在 AWS 上创建和销毁资源的权限。有关创建角色的说明,请参见 此处。需要以下策略
AmazonEC2FullAccess
IAMFullAccess
AmazonS3FullAccess
AmazonVPCFullAccess
Route53FullAccess(可选)
创建一个新实例作为您的 CI 主机。此节点将处理集群的配置和拆卸。
此实例可以很小(例如 t2.micro)。
创建时,分配在步骤 1 中创建的 IAM 角色。
创建后,下载 ssh 密钥(.pem 文件)。确保文件上的权限具有限制性
chmod 400 name.pem
SSH 到您的 CI 主机。有关如何执行此操作的说明,请参见 此处。
在您的 CI 主机上安装 kops 和 kubectl
按照此处的说明操作:kubernetes/kops
选择一个集群名称
由于我们不使用预配置的 DNS,因此我们将使用后缀“.k8s.local”。根据文档,如果 DNS 名称以 .k8s.local 结尾,则集群将使用内部托管 DNS。
export NAME=<somename>.k8s.local
设置一个 ssh 密钥对,用于与集群一起使用
ssh-keygen
创建一个 S3 存储桶来存储您的集群配置
由于我们在 AWS 上,因此我们可以使用 S3 作为后端存储。建议在 S3 存储桶上启用版本控制。我们不需要将其传递给 KOPS 命令。kops 工具会自动将其检测为环境变量。
export KOPS_STATE_STORE=s3://<your_s3_bucket_name_here>
设置要部署的区域
export REGION=`curl -s http://169.254.169.254/latest/dynamic/instance-identity/document|grep region|awk -F\" '{print $4}'`
安装 AWS CLI
sudo apt-get update sudo apt-get install awscli
设置节点的可用区
在本指南中,我们将允许节点部署在所有可用区中
export ZONES=$(aws ec2 describe-availability-zones --region $REGION | grep ZoneName | awk '{print $2}' | tr -d '"')
创建集群
对于基本设置,请运行以下命令(所有大小均以 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 帐户设置云预算,以确保您不会意外支出超过您的意愿。
等待集群启动
运行
kops validate cluster
命令将告诉我们当前的设置状态。如果您最初看到“无法获取节点”,请耐心等待,因为集群在一些基本服务启动并运行之前无法报告。持续运行
kops validate cluster
,直到您在输出的末尾看到“您的集群 $NAME 已准备就绪”。time until kops validate cluster; do sleep 15; done
可用于自动化等待过程。
如果您在任何时候希望在此步骤后销毁您的集群,请运行
kops delete cluster $NAME --yes
确认
kubectl
已连接到您的 Kubernetes 集群。运行
kubectl get nodes
您应该看到两个节点的列表,每个节点都以
ip
开头。如果您想在本地使用 kubectl 和 helm
在 CI 主机上运行以下命令:
kops export kubecfg
将
~/.kube/config
的内容复制到本地系统上的相同位置。
如果您希望将 kube 配置文件放在其他位置,则需要运行
export KUBECONFIG=<other kube config location>
配置 ssh 防御主机(如果您没有使用上面的 **–topology private** 选项,请跳过此步骤!)
理想情况下,我们只需将
--bastion
标志传递到上面的 kops 命令中。但是,该标志目前无法按预期工作。 kubernetes/kops#2881相反,我们需要遵循本指南:kubernetes/kops
此时,还有一些公开的端点需要解决。
防御主机 ELB 安全组默认允许来自 0.0.0.0 的访问。
API ELB 安全组默认允许来自 0.0.0.0 的访问。
在您的 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 设置集群。然后执行以下步骤
验证 weave 是否正在运行
kubectl --namespace kube-system get pods
您应该看到几个形式为
weave-net-abcde
的 pod。使用足够强度的私有密码创建 Kubernetes 密钥。在本例中,使用随机的 128 字节
openssl rand -hex 128 >weave-passwd kubectl create secret -n kube-system generic weave-passwd --from-file=./weave-passwd
密钥名称及其值(取自文件名)必须相同。如果它们不匹配,您可能会收到
ConfigError
使用密码进行补丁编织
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"} ]'
检查 Pod 是否已重启。为了加快速度,您可以删除旧的 Pod。
您可以使用以下命令验证加密是否已开启
kubectl exec -n kube-system weave-net-<pod> -c weave -- /home/weave/weave --local status
您应该看到
encryption: enabled
如果您真的想确保加密正常工作,可以在任何节点的端口
6783
上监听。如果流量看起来像乱码,那么您就知道它已开启。