DevOps
  • Introduction
  • Setting
    • Terminal
      • Tmux
    • WSL+Ubuntu
    • [NeoVIM]
      • install & 활용방법
      • error 처리
      • LazyVIM
        • install & 활용방법
    • ssh
    • mysql
    • package관리
  • Fundamental(basic)
    • Network
      • https
  • [GitOps]
    • [SCM]
      • [Github]
        • center-managed
      • bitbucket
      • AWS-codeCommit
  • roadmap
    • devops
    • kubernetes
    • AWS
    • MLOPS
  • Cloud
    • [AWS]
      • aws sso script
      • tagging 자동화
      • 동일cidr에서 VPC 연결
      • 무중단서비스를 위한 고려사항
    • [GCP]
      • [GCP] GCP의 VPC
      • [GCP] GCP의 ALB
      • [GCP] OIDC와 OAUTH를 활용한 github action
      • [GCP] Composer 설명
      • [GCP] gmail-api
      • [GCP] DataLake
      • [GCP] Cloud 관리형 계정&role
      • [[GCP] private환경
        • DNS 설정으로 google api 및 colab-notebook 사용 하기
        • intelligence 설정으로 google api 및 colab-notebook 사용 하기
  • [kubernetes]
    • [cloud 기반]
      • csr
  • InfraAsCode
    • terraform
  • 코드로 그리는 다이어그램
    • CodeAsDiagram
      • example
    • Mermaid
    • PDFtoImage
  • AutoMation
  • [ETC]
    • Magic_Trackpad Window설치
Powered by GitBook
On this page
  • eks csr, tls 인증 오류
  • 그래서 어떻게 하라고?
  • 마무리
  1. [kubernetes]
  2. [cloud 기반]

csr

eks csr, tls 인증 오류

부제 : cluster creator와 node role의 인증자를 동일하게 구성 시 일어나는 일에 대해서.

eks를 도입 하기 전에 사전 구축을 하고 테스트를 하는 과정에서 발생 된 일이다. 특정 상황에서 pod의 shell을 접속 하거나 로그를 보려고 하면 아래와 같은 TLS 오류가 발생 하였다.

Error from server: Get "https://10.10.20.xxx:10250/containerLogs/game-2048/deployment-2048-74cdf7657b-jshqz/app-2048": remote error: tls: internal error

csr을 확인 해보니 아래와 같이 csr 승인을 받으려고 대기 중이 었다.

> kubectl get csr -A |more
NAME        AGE     SIGNERNAME                      REQUESTOR          REQUESTEDDURATION   CONDITION
csr-22wz5   179m    kubernetes.io/kubelet-serving   kubernetes-admin   <none>              Pending
csr-268mq   12h     kubernetes.io/kubelet-serving   kubernetes-admin   <none>              Pending
csr-27jv2   3h30m   kubernetes.io/kubelet-serving   kubernetes-admin   <none>              Pending
csr-28z9s   163m    kubernetes.io/kubelet-serving   kubernetes-admin   <none>              Pending
csr-2925l   17h     kubernetes.io/kubelet-serving   kubernetes-admin   <none>              Pending
csr-299p4   14h     kubernetes.io/kubelet-serving   kubernetes-admin   <none>              Pending
csr-2b6m8   7h37m   kubernetes.io/kubelet-serving   kubernetes-admin   <none>              Pending

Approve,Issued 상태의 csr 상태 정보[정상]

  • kubectl get csr csr-ok -o json

    
    {
        "apiVersion": "certificates.k8s.io/v1",
        "kind": "CertificateSigningRequest",
        "metadata": {
            "creationTimestamp": "2023-06-15T08:42:56Z",
            "generateName": "csr-",
            "name": "csr-mwg9m",
            "resourceVersion": "1436",
            "uid": "60c56b9c-6d85-41f9-ae09-a242dbb76688"
        },
        "spec": {
            "extra": {
                "accessKeyId": [
                    "ASIA5ISTH5MDxxxxx"
                ],
                "arn": [
                    "arn:aws:sts::xxxxx:assumed-role/devops-role-20230614/i-0d53c8xxxxx3dd9"
                ],
                "canonicalArn": [
                    "arn:aws:iam::xxxx:role/devops-role-20230614"
                ],
                "principalId": [
                    "AROA5ISTH5MDNI6xxxxx"
                ],
                "sessionName": [
                    "i-0d53c871axxxxx"
                ]
            },
            "groups": [
                "system:bootstrappers",
                "system:nodes",
                "system:authenticated"
            ],
            "request": "LS0tLS1CRUdJTiBDRVJUSUZJxxxxxxJQmJEQ0NBUklDQVFBd1hURVZNQk1HQTFVRUNoTU1jM2x6ZEdWdE9tNXZaR1Z6TVVRd1FnWURWUVFERXp0egplWE4wWlcwNmJtOWtaVHBwY0MweE1DMHhNQzB4TmkweE1qRXVZWEF0Ym05eWRHaGxZWE4wTFRJdVkyOXRjSFYwClpTNXBiblJsY201aGJEQlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VIQTBJQUJQNjc4VFMrUTduVFlvdUUKcFpHQmxaYTRSR0puRlI0ZW9mZ29BTlZ0T1k3OG9SUkdyQ3p1OGZLYVpia09sNnpoU3RnVTYxTktLaHdWekhXSApJVDlHdlk2Z1V6QlJCZ2txaGtpRzl3MEJDUTR4UkRCQ01FQUdBMVVkRVFRNU1EZUNMMmx3TFRFd0xURXdMVEUyCkxURXlNUzVoY0MxdWIzSjBhR1ZoYzNRdE1pNWpiMjF3ZFhSbExtbHVkR1Z5Ym1Gc2h3UUtDaEI1TUFvR0NDcUcKU000OUJBTUNBMGdBTUVVQ0lRQ3RJaG85YzRhQlIrVVo0bnphY3AvZjhGNWtHSTgrOTViQU5ZWEVDMWYrWkFJZwpCa2VqWHNTVHNRcEJsalNieGJ6d3ZPY056SWQwVE9ST0M4OWhMR0UxZ0tJPQotLS0tLUVORCBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0K",
            "signerName": "kubernetes.io/kubelet-serving",
            "uid": "aws-iam-authenticator:xxxxx:AROA5ISTH5xxxx",
            "usages": [
                "digital signature",
                "key encipherment",
                "server auth"
            ],
            "username": "system:node:ip-10-10-xxx-xxxx.ap-northeast-2.compute.internal"
        },
        "status": {
            "certificate": "LS0tLS1CRUdJTiBDRVJxxxxxxx1JSUM3akNDQWRhZ0F3SUJBZ0lVYXg4OXo4VU5ueXJJOGl3NDZlaGJlVG0za0JZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZURVRNQkVHQTFVRUF4TUthM1ZpWlhKdVpYUmxjekFlRncweU16QTJNVFV3T0RNNE1EQmFGdzB5TkRBMgpNVFF3T0RNNE1EQmFNRjB4RlRBVEJnTlZCQW9UREhONWMzUmxiVHB1YjJSbGN6RkVNRUlHQTFVRUF4TTdjM2x6CmRHVnRPbTV2WkdVNmFYQXRNVEF0TVRBdE1UWXRNVEl4TG1Gd0xXNXZjblJvWldGemRDMHlMbU52YlhCMWRHVXUKYVc1MFpYSnVZV3d3V1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVQrdS9FMHZrTzUwMktMaEtXUgpnWldXdUVSaVp4VWVIcUg0S0FEVmJUbU8vS0VVUnF3czd2SHltbVc1RHBlczRVcllGT3RUU2lvY0ZjeDFoeUUvClJyMk9vNEc0TUlHMU1BNEdBMVVkRHdFQi93UUVBd0lGb0RBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFUQU0KQmdOVkhSTUJBZjhFQWpBQU1CMEdBMVVkRGdRV0JCVHBzeTBFdENkLzhmUEwzeTBUQWx4eTdpcm1XVEFmQmdOVgpIU01FR0RBV2dCUUhaeHREdnlzbEhYZURHaTY2SHNpV0VDb0cvakJBQmdOVkhSRUVPVEEzZ2k5cGNDMHhNQzB4Ck1DMHhOaTB4TWpFdVlYQXRibTl5ZEdobFlYTjBMVEl1WTI5dGNIVjBaUzVwYm5SbGNtNWhiSWNFQ2dvUWVUQU4KQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBTDhSQUlUM2JUZnRuWmwyUWhhTWlkRUdBWkRlbXYvVmhCVU9SMVdldQp5TGsvVEZCMFBTMkNqQjByVkc1blVTc21pK2VIa0huaE9pMEtFOGFmWVkzUi9SMWZCZnZDVEs2Q3JvdjM2OTBaCnV4U2dESklEeUhBSEk3YjNJTzhsVnJTd3J6VFphQUtZMytPNTA1U1FpYmNUY1VMNGk4UXJoWkZod1dpSGdhRUcKNTJvbkFkWVl0RUtBc3NBbGJXTWpKMnhZaW80M25nQmVsaGtUTzNFOFJhVmlzNDkwbllIZjRLUkdETDl0SytlUwpzdXpMYzZ0M1UwTU1NcFUzcWthYXl3cUg0ckdJMkVYdC8veTQ0WU1kVy8vSk5WYzdFYk1GaHR4ZW9BUVUxdjFiCmVNTGdBRmQzOHEyYzBER3NCZlJXQ21YV2pibCs2RWxVQ1NYeXpGbks4Mm1pcFE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==",
            "conditions": [
                {
                    "lastTransitionTime": "2023-06-15T08:43:13Z",
                    "lastUpdateTime": "2023-06-15T08:43:13Z",
                    "message": "Auto approving self kubelet server certificate after SubjectAccessReview.",
                    "reason": "AutoApproved",
                    "status": "True",
                    "type": "Approved"
                }
            ]
        }
    }

<Pending 상태의 csr 상태정보>

  • kubectl get csr csr-not-ok -o json

    
    {
        "apiVersion": "certificates.k8s.io/v1",
        "kind": "CertificateSigningRequest",
        "metadata": {
            "creationTimestamp": "2023-06-15T09:08:51Z",
            "generateName": "csr-",
            "name": "csr-7rnjv",
            "resourceVersion": "255226",
            "uid": "37395e40-caef-4d21-8ff2-1f132c5b040b"
        },
        "spec": {
            "extra": {
                "accessKeyId": [
                    "ASIA5ISTH5xxxxxx"
                ],
                "arn": [
                    "arn:aws:sts::xxxx:assumed-role/devops-role/i-xxxx"
                ],
                "canonicalArn": [
                    "arn:aws:iam::9117813xxxxxx:role/devops-role"
                ],
                "principalId": [
                    "AROA5ISTH5Mxxxx"
                ],
                "sessionName": [
                    "i-07c45ea1exxxxx"
                ]
            },
            "groups": [
                "system:masters",
                "system:authenticated"
            ],
            "request": "LS0tLS1xxxxxURSBSRVFVRVNULS0tLS0KTUlJQmFqQ0NBUkFDQVFBd1hERVZNQk1HQTFVRUNoTU1jM2x6ZEdWdE9tNXZaR1Z6TVVNd1FRWURWUVFERXpwegplWE4wWlcwNmJtOWtaVHBwY0MweE1DMHhNQzB4TmkwNU15NWhjQzF1YjNKMGFHVmhjM1F0TWk1amIyMXdkWFJsCkxtbHVkR1Z5Ym1Gc01Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRVo4SVNROFdwN0dkYjBpdjIKVGpSNkdBM0dxc1NCVXVDalllb0FqVWM2UmhSMUdLNDZrWEE4RW1lOUZQc0hTRWlZblZZcTU5Sk1BMnJHOWYyeQpPc25kSjZCU01GQUdDU3FHU0liM0RRRUpEakZETUVFd1B3WURWUjBSQkRnd05vSXVhWEF0TVRBdE1UQXRNVFl0Ck9UTXVZWEF0Ym05eWRHaGxZWE4wTFRJdVkyOXRjSFYwWlM1cGJuUmxjbTVoYkljRUNnb1FYVEFLQmdncWhrak8KUFFRREFnTklBREJGQWlFQXhWWUFrcVJCbFpKOEdjbmNhd2h3aWw5VE1ld3lrZnhaMVl6ZEk3dTZoeW9DSUZTawprZFdZN2MrUW5VaXVDZHhIUEdlU1czdCthbytmRER6N1JEUjB2VStTCi0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=",
            "signerName": "kubernetes.io/kubelet-serving",
            "uid": "aws-iam-authenticator:xxxx:AROA5ISTH5MDxxxxx",
            "usages": [
                "digital signature",
                "key encipherment",
                "server auth"
            ],
            "username": "kubernetes-admin"
        },
        "status": {}
    }

확인 결과 인증서의 내용은 모두 동일 하다 다른 점은 아래와 같다.

pending
        "usages": [
            "digital signature",
            "key encipherment",
            "server auth"
        ],
        "username": "kubernetes-admin"

-------------------------------------------------------------------------------

issued , aprover
        "usages": [
            "digital signature",
            "key encipherment",
            "server auth"
        ],
        "username": "system:node:ip-10-10-16-121.ap-northeast-2.compute.internal"

현상은 pending이 걸리는 csr은 devops-role로 만든 node의 것이고 issued , approver 로 잘 처리가 된 csr은 신규로 만든 iam role 정도의 차이밖에 없었다.

당연 하겠지만 두 role의 policy는 최대한 동일하게 셋팅 하였다.

그럼 여기서 부터 나오는 의문점이 몇 가지 생긴다.

  • role 외에는 같은 yaml파일로 install 하였는데 왜 csr의 username이 다른 것일까?

  • 같은 policy의 role을 사용 하였는데 왜 csr에서 이슈가 생긴 것일까?

하나씩 풀어보자

먼저 https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/add-user-role.html 공식 문서를 보면 아래와 같은 문구가 있다.

💡 Amazon EKS 클러스터를 생성할 경우 클러스터를 생성하는 [IAM 보안 주체](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html)에게는 Amazon EKS 제어 영역의 클러스터 역할 기반 액세스 제어(RBAC) 구성에 `system:masters` 권한이 자동으로 부여됩니다. 이 보안 주체는 표시되는 구성에 나타나지 않으므로 클러스터를 원래 생성한 보안 주체를 추적해야 합니다. 추가 IAM 보안 주체에 클러스터와 상호 작용할 수 있는 기능을 부여하려면 Kubernetes 내에서 `aws-auth` `ConfigMap`을 편집하고 `aws-auth` `ConfigMap`에 지정하는 `group`의 이름으로 Kubernetes `rolebinding` 또는 `clusterrolebinding`을 생성해야 합니다.

사실 이 문구도 많이 봤었지만 그렇게 크게 신경을 쓰고 있지 않았고 결국 이 문제로 인하여 이슈가 발생 되었다고 봐도 무방하다. 이에 원인파악에 시간을 많이 소모 하였고 문제를 찾지 못하고 있다가 우연히 원인을 찾게 되었다.

당시 devops 팀은 aws sso로 login을 한 뒤에 devops-role 을 assume 하여 클러스터를 생성한 상황 이었다. 그러다 eks & k8s 구축을 위해서 테스트 겸 다수의 cluster를 생성 & 삭제를 진행 하였고

우연히 configmap 에 등록이 안된 상태에서도 kubectl get pods 가 동작 되는 현상을 발견 하였다.

k get configmaps -n kube-system aws-auth -o yaml

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:masters
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::xxxxxx:role/eksFullAccessRole
      username: system:node:{{SessionName}}
      #username: system:node:{{EC2PrivateDNSName}}

    - groups:
      - system:masters
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::xxxxxxxxx:role/AWSReservedSSO_xxxx_devops_1c74128xxxx
      username: system:node:{{SessionName}}

위의 configmap을 보면 devops-role이 없는 상태임에도 불구하고 api 동작에 이상이 없었다.

그러고 원인을 찾던 도중 whoami라는 툴을 찾았다. 바로 시험 해보자

aws sts get-caller-identity |jq

{
  "UserId": "AROA5ISTH5xxxxxxx:xxxx@xxxxxx.co.kr",
  "Account": "91178xxxxx",
  "Arn": "arn:aws:sts::9117xxx:assumed-role/AWSReservedSSO_xxxxd_devops_xxxxx"
}
> kubectl rbac-tool whoami
{Username: "system:node:xxxxxx.co.kr",
 UID:      "aws-iam-authenticator:9117xxx:AROA5ISTH5Mxxxx",
 Groups:   ["system:masters",
            "system:bootstrappers",
            "system:nodes",
            "system:authenticated"],
 Extra:    {accessKeyId:  ["ASIA5Ixxxx"],
            arn:          ["arn:aws:sts::9117xxxxx:assumed-role/AWSReservedSSO_xxxx_devops_xxx3bb9822e/dorian@.co.kr"],
            canonicalArn: ["arn:aws:iam::9117xxxxx:role/AWSReservedSSO_xxxx_devops_1c74128b3bb9822e"],
            principalId:  ["AROAxxxDMSX3GGZA4"],
            sessionName:  ["dorian.kim@xxx.co.kr"]}}

aws sts get-caller-identity |jq

{
  "UserId": "AROA5ISTxxxxxVQHL:devops-session",
  "Account": "911xxxx",
  "Arn": "arn:aws:sts::9117xxxx:assumed-role/devops-role/devops-session"
}

> kubectl rbac-tool whoami
```json
{Username: "kubernetes-admin",
 UID:      "aws-iam-authenticator:9xxx110:AROA5ISTH5xxxxVQHL",
 Groups:   ["system:masters",
            "system:authenticated"],
 Extra:    {accessKeyId:  ["ASIA5ISTH5MDNL5UZ3KW"],
            arn:          ["arn:aws:sts::911xxx10:assumed-role/devops-role/devops-session"],
            canonicalArn: ["arn:aws:iam::911xxxx0:role/devops-role"],
            principalId:  ["AROA5IxxxxxxVQHL"],
            sessionName:  ["devops-session"]}}

내가 어떤 user로 접근 하고 있는지 상세 정보가 출력이 된다.

비교를 해 보면 Username: "kubernetes-admin” 의 원인과 configmap에 등록이 되어 있지 않은 role도 Groups: ["system:masters", "system:authenticated"] 권한을 부여

받아 api 동작이 잘 되었던 것이다.

참고로 eks생성자를 확인 하려면 aws cloud trail 을 확인 하자

일단 첫 번째 의문은 해소 되었다.

그럼 두번째 의문도 풀어보자

username과 csr은 무슨관계 일까?

일단 helm 으로 apache를 대충 설치 한 뒤에 pod 정보를 조금 살펴보자

k get po    apache-devopsrole-certm1-6d85486d-zpr6r  -o yaml | vi -

여러가지 설정이 있겠지만 먼저 봐야 할 것은 두 가지 이다.

volumes:
  - name: kube-api-access-w8q5s
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
-------------------------------------------------------------------
volumeMounts:
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-w8q5s
      readOnly: true

위의 설정은 k8s-api에서 인증서를 생성하고 생성한 인증서 secrtet에 보관 이후 node(kublet)가

볼륨 마운트를 하여 pod에도 동일한 인증서로 서명 하여 tls 통신을 시도 하기 위한 설정이다.

실제 node 서버에 ssh로 접속 해서 인증서가 제대로 있는지 확인해보자

[root@ip-10-xx-xx-13 kube-api-access-58vk5]# pwd
/var/lib/kubelet/pods/c2a616be-11a7-465b-93ae-609dffb18a51/volumes/kubernetes.io~projected/kube-api-access-58vk5
[root@ip-10-xx-xx-13 kube-api-access-58vk5]# ls
ca.crt  namespace  token

그럼 인증서도 완벽하게 다 있는데 kubernetes-api 놈이 승인을 안해주는 이유는 뭘까?

쿠버네티스 공식 문서의 인증서를 참조하면 인증서 및 인증서 서명 요청 | 쿠버네티스 (kubernetes.io) 아래와 같은 문구가있다.

💡 kubernetes.io/kubelet-serving: 유효한 kubelet 제공 인증서로 인정되는 인증서 제공에 서명합니다. API 서버에 의해 제공되지만 다른 보장은 없습니다. 자동 승인되지 않음 kube-controller-manager (쿠베 컨트롤러 매니저).


1. 신뢰 배포: kubelet에 대한 연결을 종료하려면 API 서버에서 서명된 인증서를 유효한 인증서로 인식해야 합니다. CA 번들은 다른 방법으로 배포되지 않습니다.
2. **허용되는 주제 - 조직은 정확히, 일반 이름은 ""로 시작합니다.**`["system:nodes"]system:node:`
3. 허용된 x509 확장 - 키 사용 및 DNSName/IPAddress subjectAltName 확장을 적용하고 EmailAddress 및 URI subjectAltName 확장은 다른 확장을 삭제합니다. 하나 이상의 DNS 또는 IP subjectAltName이 있어야 합니다.
4. 허용된 키 사용 - 또는 .`["key encipherment", "digital signature", "server auth"]["digital signature", "server auth"]`
5. 만료/인증서 수명 - 이 서명자의 kube-controller-manager 구현의 경우, 최소값으로 설정 옵션 또는 CSR 객체의 필드(지정된 경우)를 선택합니다.`-cluster-signing-durationspec.expirationSeconds`
6. CA 비트 허용/허용되지 않음 - 허용되지 않습니다.

허용되는 주제 - 조직은 정확히, 일반 이름은 ""로 시작합니다.["system:nodes"]system:node:

의 조건이 맞지 않아 결국 승인이 되지 않는 것으로 보인다.

그래서 어떻게 하라고?

cluster 생성자의 role과 다른 role로 node를 구성 하세요, 메뉴얼에 써 있습니다.

https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/create-node-role.html

마무리

삽질을 하긴 했지만 덕분에 IAM 으로 CSR을 발급 받는 과정과 원리를 알게 되어 유익한 경험을 한것 같다.

Previous[cloud 기반]NextInfraAsCode

Last updated 6 months ago

Untitled
Untitled