亚马逊AWS官方博客

OpenSource | 将 Heptio Authenticator 部署到 kops

Authenticator 工作流程

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

现在,我们已经创建文件并将其上传到状态库,接下来可以依次发出 updaterolling-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 的评述。