乐趣区

关于docker:在Kubernetes中访问IAM如何安装Kube2iam

IAM 是 AWS 的理论的受权办法。大部分针对 AWS 的 Kubernetes 的“疾速入门”指南并没有充沛笼罩如何在你的 Pod 中治理 IAM 拜访的相干内容。本系列文章讲探讨 Kubernetes 环境的 AWS IAM 特有的安全性问题,而后比照不同计划,并最终具体介绍如何抉择一种计划来设置集群。

在之前的文章中,咱们在生产 kubernetes 集群中装置了 kiam。在本文中,咱们将介绍在成产环境疾速装置 kube2iam 的过程.

概述

本文将蕴含你在身缠环境部署 kube2iamd 的以下 4 步:

  1. 创立 IAM roles
  2. 减少 Annotation 到 Pod
  3. 部署 kube2iam
  4. 测试
  5. 全副部署 kube2iam

浏览 kube2iam 详情及个性,请查看 Github Page。

1. 创立 IAM Roles

应用 kubeiam 的第一步是为你的 Pod 创立 IAM roles。kube2iam 的工作形式是须要一个 IAM 策略附加到集群中每个节点以容许其为 Pod 委派 roles。

创立为你的节点一个 IAM 策略并且附加到你的 kubernetes 节点的 role 上。

策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["sts:AssumeRole"],
      "Resource": "*"
    }
  ]
}

接下来为每个 pod 创立 role。每个 role 将须要一个策略,领有 Pod 性能所需的最小权限,例如:列出 S3 对象,写入 DynamoDB, 读取 SQS 等。你须要为每个所创立的 role 更新委派角色策略,以便使你的节点能够委派这些 role。用 kubernetes 节点所附加 role 的 arn 替换YOUR_NODE_ROLE

委派角色策略:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {"Service": "ec2.amazonaws.com"},
      "Effect": "Allow",
      "Sid": ""
    },
    {"Sid": "","Effect":"Allow","Principal": {"AWS":"YOUR_NODE_ROLE"},"Action":"sts:AssumeRole"
    }
  ]
}

2. 为 pod 减少Annotations

下一步将你的 pod 将用的 role 正文到 Pod。减少一个 annotation 到 pod 的 metadata.spec 即可,kube2iam 应用 IAM 对 Pod 进行身份认证时将应用这个 role。如此配置后,kube2iam 将为该 role 主动查看根底 arn,然而如果你须要委派角色给其余 AWS 账号也能够指定一个残缺的arn(以arn:aws:iam 开始)。kube2iam 文档有一些不同 pod 控制器的例子。

annotations:
   iam.amazonaws.com/role: MY_ROLE_NAME

3. 部署 kubeiam

当初能够部署 kube2iam。你能够参考 kube2iam github repo 获取 EKS 和 OpenShift 的例子,然而这里也也会介绍一些通用 deployment 办法。第一步时配置 RBAC:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: kube2iam
  namespace: kube-system
---
apiVersion: v1
items:
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: kube2iam
    rules:
      - apiGroups: [""]
        resources: ["namespaces","pods"]
        verbs: ["get","watch","list"]
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: kube2iam
    subjects:
    - kind: ServiceAccount
      name: kube2iam
      namespace: kube-system
    roleRef:
      kind: ClusterRole
      name: kube2iam
      apiGroup: rbac.authorization.k8s.io
kind: List

因为 kube2iam 批改了 kubernetes 节点上的 iptables 规定来劫持到 EC2 metadata 服务的流量,我倡议减少一个 tainted 的新节点到集群,这样你能够在确保不影响你生产环境 Pod 的前提下测试控制器来配置正确。为集群减少一个节点而后为其打上五点钟,这样其余 Pod 就不会被调度到该节点。

export ALICLOUD_ACCOUNT=""export ALICLOUD_ACCESS_KEY="your-access-key"export ALICLOUD_SECRET_KEY="your-secret-key"export ALICLOUD_REGION="cn-qingdao"
kubectl taint nodes NODE_NAME kube2iam=kube2iam:NoSchedule

接下来咱们能够在该节点上配置 agent。减少 nodeName: NEW_NODE_NAMEPod.spec,而后减少 tolerations 这样它就能够被调度到该节点。设置镜像版本为标记过的公布版本而非 latest。还须要设置--host-interface 命令参数来适配你的 CNI。kube2iam 页面有残缺的反对列表。我也倡议设置 --auto-discover-base-arn--auto-discover-default-role 参数来时配置和迁徙更容易。如果你的集群再单个可用区--use-regional-sts-endpoint 会很有用,然而你必须为其设置 AWS_REGION 环境变量。综上所述,配置大抵如下:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: kube2iam
  namespace: kube-system
  labels:
    app: kube2iam
spec:
  selector:
    matchLabels:
      name: kube2iam
  template:
    metadata:
      labels:
        name: kube2iam
    spec:
      nodeName: NEW_NODE_NAME
      tolerations:
       - key: kube2iam
         value: kube2iam
         effect: NoSchedule
      serviceAccountName: kube2iam
      hostNetwork: true
      containers:
        - image: jtblin/kube2iam:0.10.6
          imagePullPolicy: Always
          name: kube2iam
          args:
            - "--app-port=8181"
            - "--auto-discover-base-arn"
            - "--iptables=true"
            - "--host-ip=$(HOST_IP)"
            - "--host-interface=weave"
            - "--use-regional-sts-endpoint"
            - "--auto-discover-default-role"
            - "--log-level=info"
          env:
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: AWS_REGION
              value: "us-east-1"
          ports:
            - containerPort: 8181
              hostPort: 8181
              name: http
          securityContext:
            privileged: true

接下来你能够创立 agent 并确认该 agent 运行于你的新节点上。你其余节点上的 Pod 不会有变更。

4. 测试

在这一步,开始测试以冀望一切正常。你能够通过在该隔离节点部署一个 Pod,而后在该 POD 中应用 AWS CLI 拜访资源进行测试。当你做这些时,请查看 kube2iam agent 的日志来 debug 你遇到的的问题。这里有个 deployment 实例,你能够指定一个 role 而后用它进行拜访测试。

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: aws-iam-tester
  labels:
    app: aws-iam-tester
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: aws-iam-tester
  template:
    metadata:
      labels:
        app: aws-iam-tester
      annotations:
        iam.amazonaws.com/role: TEST_ROLE_NAME
    spec:
      nodeSelector:
        kubernetes.io/role: node
      nodeName: NEW_NODE_NAME
      tolerations:
       - key: kube2iam
         value: kube2iam
         effect: NoSchedule
      containers:
      - name: aws-iam-tester
        image: garland/aws-cli-docker:latest
        imagePullPolicy: Always
        command:
          - /bin/sleep
        args:
          - "3600"
        env:
          - name: AWS_DEFAULT_REGION
            value: us-east-1

Pod 将会在一个小时后退出,你能够应用 kubectl 获取一个 TTY 到 Pod。

kubectl exec -ti POD_NAME /bin/sh

一旦你确认你的 role 能够失常工作,并且 kube2iam agent 配置失常,你就能够部署 agent 到每个节点。

5. 全量部署 kube2iam

从 kube2iam Daemonset 删除 nodeNamekub2iam:kub2iam以容许它运行到每个节点。在每个节点装置实现当前,应该对要害 pod 进行更新,以这些 Pod 立刻应用 kube2iam 进行验证。其余已经应用 node role 进行认证的的 Pod 当其长期凭据过期后将开始应用 kube2iam 进行认证(通常是一个小时)。若 IAM 认证有错,请查看你的利用及 kubeiam 日志。

当所有运行失常,你就能够删除再次之前增加的隔离节点。

遇到问题时,你能够删除所有节点上的 agent,然而它不会主动清理它创立的 iptable 规定。这将导致所有发往 EC2 metada 的申请不起作用。你须要别离登录到每个节点并手动移除这些 iptables 规定。

首先列出 iptable 规定,找出 kube2iam 所创立的局部

sudo iptables -t nat -S PREROUTING | grep 169.254.169.254 

输入大略如下:

-A PREROUTING -d 169.254.169.254/32 -i weave -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.101.101:8181

如果你意外的应用不同的 --host-interface 选项部署 agent 你可能会看到多个后果。你能够一次删除他们。删除一条规定应用 iptables 的 -D 选项并指定 -A 选项输入的具体行号,例如:

sudo iptables -t nat -D PREROUTING -d 169.254.169.254/32 -i weave -p tcp -m tcp --dport 80 -j DNAT --to-destination 10.0.101.101:8181

当每个节点上都执行过后,EC2 metadta 申请将不在发往 kube2iam.

论断

当初有 kube2iam 运行于你的生产集群以及,并为 POD 创立独立的角色。
如果你的对其余阿计划看趣味,请查看我之前写的 [kiam 装置]() 一文。它更加简单,并且应用不同的办法解决 IAM 的问题。我也在关注 kube-aws-iam-controller 作为代替计划,然而该我的项目始终不太成熟不适宜生产环境。你可也能够查看本系列第一,第二篇文章来理解 kubernetes 中应用 AWS IAM 的问题,以及对 kiam 和 kube2iam 作为解决方案的深刻比拟。

因在下英文太烂,如果能够您浏览英文,强烈建议 查看原文

FAQ & Checklist

Question: Add support for Instance Metadata Service Version 2 (IMDSv2)

Question: 留神你的集群所应用的网络计划,比方:文中例子为weave,我的集群为Calico,所以应该批改为cali+。否则会报如下谬误:

$ k logs kube2iam-ltm7f -n kube-system
...
time="2020-07-17T10:47:30Z" level=fatal msg="route ip+net: no such network interface"

Question 2: 默认状况下 kube2iam 应用 8181 端口,因为我的 worker node 应用了 8181 端口,须要减少 2 个参数 --app-port=8182 --metrics-port=8183,否则会报如下谬误:

$ k logs kube2iam-bk59z -n kube-system
time="2020-07-18T03:42:04Z" level=info msg="Listening on port 8181"
time="2020-07-18T03:42:04Z" level=fatal msg="Error creating kube2iam http server: listen tcp :8181: bind: address already in use"

Question 3: 应用文中命令未找到相应的 iptables 规定

$ sudo iptables -t nat -S PREFOUTING | grep 169.254.169.254
iptables: No chain/target/match by that name.

# 尝试如下命令
sudo iptables -t nat -L | grep 169.254.169.254
退出移动版