rbac.authorization.k8s.io
API Group을 사용합니다.
kubectl get pods --all-namespaces
와 같은 커맨드를 실행할 때 필요한 권한apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
name: jane # "name" is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "dave" to read secrets in the "development" namespace.
# You need to already have a ClusterRole named "secret-reader".
kind: RoleBinding
metadata:
name: read-secrets
#
# The namespace of the RoleBinding determines where the permissions are granted.
# This only grants permissions within the "development" namespace.
namespace: development
subjects:
- kind: User
name: dave # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: example.com-superuser # DO NOT USE THIS ROLE, IT IS JUST AN EXAMPLE
rules:
- apiGroups: ["example.com"]
resources: ["*"]
verbs: ["*"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # The control plane automatically fills in the rules
K8s API에 접근 가능한 방법은 Users
와 Service Accounts
를 이용하는 방법이 있습니다.
sytem:masters
가 있습니다.{
"apiVersion": "authentication.k8s.io/v1",
"kind": "TokenReview",
"status": {
"authenticated": true,
"user": {
# Required
"username": "janedoe@example.com",
# Optional
"uid": "42",
# Optional group memberships
"groups": ["developers", "qa"],
# Optional additional information provided by the authenticator.
# This should not contain confidential data, as it can be recorded in logs
# or API objects, and is made available to admission webhooks.
"extra": {
"extrafield1": [
"extravalue1",
"extravalue2"
]
}
},
# Optional list audience-aware token authenticators can return,
# containing the audiences from the `spec.audiences` list for which the provided token was valid.
# If this is omitted, the token is considered to be valid to authenticate to the Kubernetes API server.
"audiences": ["https://myserver.example.com"]
}
}
Authenticator가 사용할 수 있도록 매핑을 만들어 주는 방식에는 두 가지가 있습니다.
다음과 같이 K8s resource 방식으로 만들어 주는 방법
---
apiVersion: iamauthenticator.k8s.aws/v1alpha1
kind: IAMIdentityMapping
metadata:
name: kubernetes-admin
spec:
# Arn of the User or Role to be allowed to authenticate
arn: arn:aws:iam::XXXXXXXXXXXX:user/KubernetesAdmin
# Username that Kubernetes will see the user as, this is useful for setting
# up allowed specific permissions for different users
username: kubernetes-admin
# Groups to be attached to your users/roles. For example `system:masters` to
# create cluster admin, or `system:nodes`, `system:bootstrappers` for nodes to
# access the API server.
groups:
- system:masters
kube-system/aws-auth
ConfigMap을 사용하는 방법
IAM User/Role 생성
resource "aws_iam_user" "lee-dev" {
name = "lee-dev"
path = "/test/"
}
resource "aws_iam_access_key" "lee-dev" {
user = aws_iam_user.lee-dev.name
}
output "aws_iam_smtp_password_v4" {
value = aws_iam_access_key.lee-dev.ses_smtp_password_v4
sensitive = true
}
resource "aws_iam_role" "eks-admin-role-test" {
name = "eks-admin-role-test"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::123123123123:root"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy" "eks-admin-role-test-policy" {
name = "eks-admin-role-test-policy"
description = "eks admin role 테스트 해보기 위한 정책입니다."
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"eks:DescribeCluster"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "eks-admin-role-test-attachment" {
role = aws_iam_role.eks-admin-role-test.name
policy_arn = aws_iam_policy.eks-admin-role-test-policy.arn
}
mapRoles 매핑
Role trust policy에 Principal 수정
Role에 사용할 IAM User를 trust policy에 추가해줍니다.
resource "aws_iam_role" "eks-admin-role-test" {
name = "eks-admin-role-test"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::123123123123:user/test/lee-dev"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
aws profile을 만들어 줍니다.
[profile eks-role]
source_profile = lee-test
role_arn = arn:aws:iam::123123123123:role/eks-admin-role-test
region = ap-northeast-2
[lee-test]
aws_access_key_id = {{access-key}}
aws_secret_access_key = {{secret-key}}
생성한 profile 사용해 K8s context 만들어 줍니다.
aws eks update-kubeconfig --region ap-northeast-2 --name your-cluster --profile eks-role
kube config에서 다음과 같이 eks-role 프로파일 사용하는 컨텍스트가 생성됩니다.
name: arn:aws:eks:ap-northeast-2:123123123123:cluster/your-cluster
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
args:
- --region
- ap-northeast-2
- eks
- get-token
- --cluster-name
- your-cluster
command: aws
env:
- name: AWS_PROFILE
value: eks-role
aws sts assume-role --role-arn "arn:aws:iam::123123123123:role/eks-admin-role-test" --role-session-name AWSCLI-Session --profile lee-test
위와 같이 생성한 유저에 assume-role을 적용하면 다음과 같은 credential을 얻을 수 있습니다.{
"Credentials": {
"AccessKeyId": "abcde",
"SecretAccessKey": "abcde+92dnq2d",
"SessionToken": "IQoJb3JpZ2luX2VjEC0aDmFwLW5vcnRoZWFzdC0yIkYwRAIgFeiUaQzjsktwHrVJGniPulHfQTy2HVK1tHqCo54NiY8CIAz3xOJJai7oQAjn7DekiZ2yMxcmjiLEGaPliag1WGyrKpsCCFcQAhoMODY2NjExNjI0MDgwIgx2VooXhS5gesQFN0sq+AHJi/EUNb2Jh9/3PIot66GqwW3Ik3fvw37oiyr20iNjw5pjuhgRTkbhTnvhbIV9y/zQfPvoOg+1BHpccV5D0Zlta/UZ0OUAHc+22vj4gmSvtYAlk2XH5pDTHeK9PZO5Qr0xxEIkNt2gTpxtZ6e/lROJtgbGHbK6cSwFcKMlufbBw9fjdt0sMltmkNUTKxZ/DgWhjAc79ONMUIqP0XPeuJCe4tqpi5wG+V0a+4Ezh3DH1ipviA/oAuKq/E2q9Q84djCc/Ev+saDUBbLYO7gNbEJyD4B2vagYBbRskm7xX/jOqFng3Qr4O3H3CIBdMbGQaPpiCZhkShk9oDDxi8ucBjqeAZYAa1yDZRAFWMCzGrd5R/X5fPb2XY49ZnpO/0p8tvT2Y+0iCPAsD4wrAcyCq3Y+G+nNrxk8vNTtWiEDFgDcZulNB4qNoW8vM5hIrFNrjvIV9D94ass0PKz6s3G+fS+10W0tpTun2KrA+DAZA7TyCglt5viElvsDw7gpnLBPMnB0gwz5BIBgNAIJrpjBU1HikLR0e5VYBkg4zSKRcJON",
"Expiration": "2022-12-09T06:21:53+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROA4TRQT7CIJ532MPACE:AWSCLI-Session",
"Arn": "arn:aws:sts::123123123123:assumed-role/eks-admin-role-test/AWSCLI-Session"
}
}
위에서 생성한 temporary security credential을 프로파일에 넣고 (혹은 AWS_ 환경변수에 넣어주어도 상관 없음) K8s 컨텍스트를 만들어 보겠습니다.[eks-role]
aws_access_key_id = abcde
aws_secret_access_key = abcde+92dnq2d
aws_session_token = IQoJb3JpZ2luX2VjEC0aDmFwLW5vcnRoZWFzdC0yIkYwRAIgFeiUaQzjsktwHrVJGniPulHfQTy2HVK1tHqCo54NiY8CIAz3xOJJai7oQAjn7DekiZ2yMxcmjiLEGaPliag1WGyrKpsCCFcQAhoMODY2NjExNjI0MDgwIgx2VooXhS5gesQFN0sq+AHJi/EUNb2Jh9/3PIot66GqwW3Ik3fvw37oiyr20iNjw5pjuhgRTkbhTnvhbIV9y/zQfPvoOg+1BHpccV5D0Zlta/UZ0OUAHc+22vj4gmSvtYAlk2XH5pDTHeK9PZO5Qr0xxEIkNt2gTpxtZ6e/lROJtgbGHbK6cSwFcKMlufbBw9fjdt0sMltmkNUTKxZ/DgWhjAc79ONMUIqP0XPeuJCe4tqpi5wG+V0a+4Ezh3DH1ipviA/oAuKq/E2q9Q84djCc/Ev+saDUBbLYO7gNbEJyD4B2vagYBbRskm7xX/jOqFng3Qr4O3H3CIBdMbGQaPpiCZhkShk9oDDxi8ucBjqeAZYAa1yDZRAFWMCzGrd5R/X5fPb2XY49ZnpO/0p8tvT2Y+0iCPAsD4wrAcyCq3Y+G+nNrxk8vNTtWiEDFgDcZulNB4qNoW8vM5hIrFNrjvIV9D94ass0PKz6s3G+fS+10W0tpTun2KrA+DAZA7TyCglt5viElvsDw7gpnLBPMnB0gwz5BIBgNAIJrpjBU1HikLR0e5VYBkg4zSKRcJON
[profile eks-role]
region = ap-northeast-2
update-kubeconfig 커맨드 실행aws eks update-kubeconfig --region ap-northeast-2 --name your-cluster --alias your-role --profile eks-role
리서치한 내용을 바탕으로 Readonly 계정을 관리하는 best practice를 작성해 보았습니다.
resource "aws_iam_user" "lee-dev" {
name = "lee-dev"
path = "/test/"
}
resource "aws_iam_access_key" "lee-dev" {
user = aws_iam_user.lee-dev.name
}
output "aws_iam_smtp_password_v4" {
value = aws_iam_access_key.lee-dev.ses_smtp_password_v4
sensitive = true
}
resource "aws_iam_role" "eks-admin-role-test" {
name = "eks-admin-role-test"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::123123123123:root"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_iam_policy" "eks-admin-role-test-policy" {
name = "eks-admin-role-test-policy"
description = "eks admin role 테스트 해보기 위한 정책입니다."
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"eks:DescribeCluster"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
EOF
}
resource "aws_iam_role_policy_attachment" "eks-admin-role-test-attachment" {
role = aws_iam_role.eks-admin-role-test.name
policy_arn = aws_iam_policy.eks-admin-role-test-policy.arn
}
resource "aws_iam_role" "eks-admin-role-test" {
name = "eks-admin-role-test"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"AWS": "arn:aws:iam::123123123123:user/test/lee-dev"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "kubernetes_cluster_role" "eks-readonly-role-test" {
metadata {
name = "eks-readonly-role-test"
}
rule {
api_groups = ["*"]
resources = ["*"]
verbs = ["get", "list", "watch"]
}
}
resource "kubernetes_cluster_role_binding" "eks-readonly-role-test" {
metadata {
name = "eks-readonly-role-test"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = "cluster-admin"
}
subject {
kind = "Group"
name = "eks-readonly-role-test"
api_group = "rbac.authorization.k8s.io"
}
}