亚马逊AWS官方博客
OpenSource | 将 Heptio Authenticator 部署到 kops
Kubernetes 1.10 版本为 client-go 软件包提供了 alpha 支持,以处理外部
ExecCredential
提供程序。这将用于在仍然遵循 AWS Elastic Container Service for Kubernetes (EKS) 核心原则之一的同时为针对 EKS 集群的身份验证提供支持;还将提供一个 100% 的上游 Kubernetes。为了实现所有这些功能,我们将使用 Heptio Authenticator。本博文将向您介绍如何在 kops 集群中部署 Authenticator,从而让您使用 AWS Identity & Access Management (IAM) 来对以下工具进行身份验证:kubectl
管理身份验证协议通常是一项繁重的任务,需要管理员去维护可接受用户的列表、持续验证每个用户的权限、删除不需要访问权限的用户,甚至定期对令牌和基于证书的访问权限进行回收再利用。需要管理的系统越多,这些任务就越复杂。正因如此,Heptio(AWS 在 Amazon 合作伙伴网络中的合作伙伴)与 AWS 合作开发了 Heptio Authenticator,它支持您使用 AWS IAM 进行联合身份验证。
入门
要开始使用,我们需要一个 Kubernetes 集群,最简单的实现方法就是使用 kops。首先,您需要安装 kops
二进制文件。kops 文档中对不同的安装选项进行了说明。如果您使用的是 macOS,可按此处说明操作。
brew update && brew install kops
安装完成后,请运行此二进制文件以进行验证。
$ kops version
Version 1.9.0
此外,您还需要 Kubernetes 命令行工具 kubectl
;您同样可以使用 Homebrew 进行安装。
brew install kubernetes-cli
接下来,我们需要一个具有以下权限的 IAM 用户:
AmazonEC2FullAccess
AmazonRoute53FullAccess
AmazonS3FullAccess
IAMFullAccess
AmazonVPCFullAccess
或者,您可以创建一个新的 IAM 用户,相关创建策略的说明请参阅:https://github.com/kubernetes/kops/blob/master/docs/aws-china.md。最后一个需要安装的依赖项是 Heptio Authenticator。目前,最简单的安装方法是使用 go get
。前提是您的设备上已安装 Golang。如果尚未安装,请按照此处的指示,根据您的操作系统进行安装。安装好 Golang 之后,就可以安装 Authenticator 了。
go get -u -v github.com/heptio/authenticator/cmd/heptio-authenticator-aws
请通过尝试运行二进制文件确保 heptio-authenticator-aws
位于您的 $PATH
中。
heptio-authenticator-aws help
如果失败,并显示 -bash: heptio-authenticator-aws: command not found
,则您需要 export
一个 PATH
,且其中要包括 $GOPATH/bin
目录。否则,请继续创建集群。
创建集群
现在所有依赖项均已安装完毕,让我们开始创建 kops
集群。只需运行一个命令即可:
export NAME=authenticator.$(cat /dev/random | LC_ALL=C tr -dc "[:alpha:]" | tr '[:upper:]' '[:lower:]' | head -c 10).k8s.local
export KOPS_STATE_STORE=s3://${NAME}
aws s3 mb $KOPS_STATE_STORE
kops create cluster \
--zones us-west-1a \
--name ${NAME} \
--yes
如果您想将集群部署在
us-west-1
区域之外,请确保将--zones
键更改为您区域中的可用区。
这些命令将生成一个随机的可用于存储桶和集群的 $NAME
,创建 Amazon S3 存储桶来存储集群状态,最后,创建相应集群。现在,您可以运行验证命令来验证集群状态。
kops validate cluster
此过程可能需要 5 到 10 分钟的时间才能完成。当响应内容以 Your cluster {{NAME}} is ready
结尾时,您就可以开始使用集群了。要安装 Heptio Authenticator,我们需要先修改 kops
配置:
kops edit cluster
这会将您的 $EDITOR
打开至 kops
集群清单文件。在此文件的 .spec.api
下,我们需要添加以下内容。
# ...
kubeAPIServer:
authenticationTokenWebhookConfigFile: /srv/kubernetes/heptio-authenticator-aws/kubeconfig.yaml
hooks:
- name: kops-hook-authenticator-config.service
before:
- kubelet.service
roles: [Master]
manifest: |
[Unit]
Description=Download Heptio AWS Authenticator configs from S3
[Service]
Type=oneshot
ExecStart=/bin/mkdir -p /srv/kubernetes/heptio-authenticator-aws
ExecStart=/usr/local/bin/aws s3 cp --recursive {{KOPS_STATE_STORE}}/{{NAME}}/addons/authenticator /srv/kubernetes/heptio-authenticator-aws/
请确保将 {{KOPS_STATE_STORE}}
和 {{NAME}}
替换为您创建的集群中的值。这样将新增一个 systemd
单元文件,它将从您的 KOPS_STATE_STORE
Amazon S3 存储桶下载所有配置;我们将在下一步添加这些文件。此外,这还会通知 apiserver 来使用我们即将提供的 Webhook 身份验证配置。
如果要将其添加到现有集群并且您使用的是非默认 AMI,则需要验证 AWS 命令行界面是否可用。否则,您可以更改
ExecStart
,改用 Docker。
ExecStart=/usr/bin/docker run --net=host --rm -v /srv/kubernetes/heptio-authenticator-aws:/srv/kubernetes/heptio-authenticator-aws quay.io/coreos/awscli@sha256:7b893bfb22ac582587798b011024f40871cd7424b9026595fd99c2b69492791d aws s3 cp --recursive {{KOPS_STATE_STORE}}/{{NAME}}/addons/authenticator /srv/kubernetes/heptio-authenticator-aws/
在完成这些操作后,请保存并关闭此文件。接下来,我们将创建身份验证配置所需的文件。
heptio-authenticator-aws init -i $NAME
aws s3 cp cert.pem ${KOPS_STATE_STORE}/${NAME}/addons/authenticator/cert.pem
aws s3 cp key.pem ${KOPS_STATE_STORE}/${NAME}/addons/authenticator/key.pem
aws s3 cp heptio-authenticator-aws.kubeconfig ${KOPS_STATE_STORE}/${NAME}/addons/authenticator/kubeconfig.yaml
现在,我们已经创建文件并将其上传到状态库,接下来可以依次发出 update
和 rolling-update
,以便发布新映像。执行这些命令可能需要 5 到 10 分钟的时间。
kops update cluster --yes
kops rolling-update cluster --yes
创建策略
现在,我们可以通过以下方法测试默认的 KubernetesAdmin
用户仍然可以访问集群:运行 kubectl get nodes
– 此命令应该会返回连接至您集群的节点。在赋予任何人访问集群的权限之前,我们首先需要为附加的 admin
用户创建 AWS IAM 角色和信任策略。这可以通过 AWS 控制台或者使用 AWS CLI 来完成。
# Get your account ID
ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account')
# Define a role trust policy that opens the role to users in your account (limited by IAM policy)
POLICY=$(echo -n '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::'; echo -n "$ACCOUNT_ID"; echo -n ':root"},"Action":"sts:AssumeRole","Condition":{}}]}')
# Create a role named KubernetesAdmin (will print the new role's ARN)
aws iam create-role \
--role-name KubernetesAdmin \
--description "Kubernetes administrator role (for Heptio Authenticator for AWS)." \
--assume-role-policy-document "$POLICY" \
--output text \
--query 'Role.Arn'
现在,我们可以创建一个 ConfigMap
,用以定义可以访问集群的 AWS IAM 角色。
# authenticator.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
namespace: kube-system
name: heptio-authenticator-aws
labels:
k8s-app: heptio-authenticator-aws
data:
config.yaml: |
clusterID: {{NAME}}
server:
mapRoles:
- roleARN: arn:aws:iam::{{ACCOUNT_ID}}:role/KubernetesAdmin
username: kubernetes-admin
groups:
- system:masters
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
namespace: kube-system
name: heptio-authenticator-aws
labels:
k8s-app: heptio-authenticator-aws
spec:
updateStrategy:
type: RollingUpdate
template:
metadata:
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ""
labels:
k8s-app: heptio-authenticator-aws
spec:
# run on the host network (don't depend on CNI)
hostNetwork: true
# run on each master node
nodeSelector:
node-role.kubernetes.io/master: ""
tolerations:
- effect: NoSchedule
key: node-role.kubernetes.io/master
- key: CriticalAddonsOnly
operator: Exists
# run `heptio-authenticator-aws server` with three volumes
# - config (mounted from the ConfigMap at /etc/heptio-authenticator-aws/config.yaml)
# - state (persisted TLS certificate and keys, mounted from the host)
# - output (output kubeconfig to plug into your apiserver configuration, mounted from the host)
containers:
- name: heptio-authenticator-aws
image: gcr.io/heptio-images/authenticator:v0.1.0
args:
- server
- --config=/etc/heptio-authenticator-aws/config.yaml
- --state-dir=/var/heptio-authenticator-aws
- --generate-kubeconfig=/etc/kubernetes/heptio-authenticator-aws/kubeconfig.yaml
resources:
requests:
memory: 20Mi
cpu: 10m
limits:
memory: 20Mi
cpu: 100m
volumeMounts:
- name: config
mountPath: /etc/heptio-authenticator-aws/
- name: state
mountPath: /var/heptio-authenticator-aws/
- name: output
mountPath: /etc/kubernetes/heptio-authenticator-aws/
volumes:
- name: config
configMap:
name: heptio-authenticator-aws
- name: output
hostPath:
path: /srv/kubernetes/heptio-authenticator-aws/
- name: state
hostPath:
path: /srv/kubernetes/heptio-authenticator-aws/
现在,我们可以将这一配置 apply
至我们的集群,以便部署服务和允许进行身份验证的角色:
kubectl apply -f authenticator.yaml
部署完成后,我们需要在 kubeconfig
中创建一个新用户。为此,您可以使用自己常用的编辑器打开 ~/.kube/config
。然后,创建一个用户,将 {{NAME}}
替换为您的集群名称,将 {{ACCOUNT_ID}}
替换为您的 AWS 账户 ID。
# ...
users:
- name: {{NAME}}.exec
user:
exec:
apiVersion: client.authentication.k8s.io/v1alpha1
command: heptio-authenticator-aws
args:
- "token"
- "-i"
- "{{NAME}}"
- "-r"
- "arn:aws:iam::{{ACCOUNT_ID}}:role/KubernetesAdmin"
然后,我们需要修改 context
,以引用这个新用户:
kubectl config set-context {{NAME}} --user={{NAME}}.exec
完成所有这些操作后,我们可以测试针对集群进行的身份验证:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
ip-172-20-39-241.us-west-1.compute.internal Ready node 5h v1.9.3
ip-172-20-39-253.us-west-1.compute.internal Ready master 3h v1.9.3
ip-172-20-48-164.us-west-1.compute.internal Ready node 5h v1.9.3
如果您看到所列出的集群节点,则说明 Authenticator 已正确部署,并且正在使用 STS 来验证用户的身份。
清除
如果您想继续使用此集群,可以让它一直运行。如果您想关闭实例,可以调用 kop delete cluster
命令来完成:
kops delete cluster --name ${NAME} --yes
结论
借助 Heptio Authenticator,您能将 Kubernetes apiserver 身份验证与 AWS IAM 联合,从而使您您能够设置基于精细 IAM 角色的组,并赋予精细的 Kubernetes RBAC 规则。您无需再发出复杂的命令来管理授予 kubectl
访问权限的密钥和证书。感谢 Peter Rifel 对 Github Heptio Authenticator 的评述。