[클라우드/K8S 기본(9) - 볼륨 동적 프로비저닝]

SooYeon Yeon·2022년 9월 14일
0

클라우드 K8S

목록 보기
11/18

볼륨 동적 프로비저닝

  • nfs, iscsi, glusterfs, ebs 등에게 명령을 전달하여 볼륨을 생성할 수 있도록 지시하는 역할을 수행하는데, 퍼블릭 환경은 해당 프로비저너가 이미 존재하고 있으므로 별도의 추가 작업 없이 개발자가 요청만 하면 볼륨을 생성하여 제공할 수 있다.
  • 가령 AWS의 경우, EKS GCP의 경우 GKE→ 동적 프로비저너가 있다.

예제 @ aws)

개발자, 사용자는 다음의 yaml 파일을 만들고 이를 배포해야 한다.

apiVersion: [storage.k8s.io/v1](http://storage.k8s.io/v1)
kind: StorageClass
metadata:
  name: fastdisk
provisioner: kubernetes.io/aws-ebs # 온프레미스나 다른 퍼블릭클라우드에서는 사용불가
parameters: 
  type: gp2
  fsType: ext4
  zones: ap-northeast-2a
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata: 
  name: pvc-fast-sc
spec: 
  storageClassName: fast
  accessModes: 
    - ReadWriteOnce
  resources: 
    requests: 
      storage: 1Gi

수동환경에서 PV,PVC를 필터링

  • PV와 PVC 필터링 요청한 개발자에게 정확히 제공하기 위해 아래와 같은 방법을 사용할 수 있다.
  1. storageclassname → 일종의 라벨과 같이 pv,pvc에 이름을 지정하고 동일한 이름일 경우 용량, 퍼미션 등을 비교하여 bind 시킨다.
    • 동적 프로비저닝에서는 반드시 필요
  2. 마치 로드밸런서에서 특정 포드로 트래픽을 전달하기 위해 사용했던 selector를 사용한다. PV에 라벨을 미리 부착해 두어야 한다.

storageclassname 이용하기

nfs 동작 확인 후 작성

pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: "100Mi"
  accessModes:
    - ReadWriteMany # r,w,여러사람동시접속가능, 혼자만 접속한다면 Once
  **storageClassName: testsc**
  persistentVolumeReclaimPolicy: Retain # PVC가 제거됐을 때 PV가 작동하는 방법정의(유지는 Retain, 삭제는 Delete)
  nfs:
    server: 211.183.3.100
    path: /shared
root@manager:~/k8slab/pvpvclab# kubectl apply -f pv.yaml
persistentvolume/nfs-pv created
root@manager:~/k8slab/pvpvclab# kubectl get pv
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
nfs-pv   100Mi      RWX            Retain           Available           testsc                  21s

pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
spec:
  accessModes:
    - ReadWriteMany
  **storageClassName: testsc**
  resources:
    requests:
      storage: 100Mi
root@manager:~/k8slab/pvpvclab# kubectl apply -f pvc.yaml

root@manager:~/k8slab/pvpvclab# kubectl get pv,pvc
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM         STORAGECLASS   REASON   AGE
persistentvolume/nfs-pv   100Mi      RWX            Retain           Bound    default/pvc   testsc                  4m25s

NAME                        STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc   Bound    nfs-pv   100Mi      RWX            testsc         24s

selector 이용하기 (라벨 부착)

pv.yaml 파일에 라벨 부착해두기

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
  **labels:
    dev: gildong**
spec:
  capacity:
    storage: "100Mi"
  accessModes:
    - ReadWriteMany # r,w,여러사람동시접속가능, 혼자만 접속한다면 Once
  persistentVolumeReclaimPolicy: Retain # PVC가 제거됐을 때 PV가 작동하는 방법정의(유지는 Retain, 삭제는 Delete)
  nfs:
    server: 211.183.3.100
    path: /shared

pvc.yaml 파일에는 selector을 이용해 뽑아내기

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc
spec:
  **selector:
    matchLabels:
      dev: gildong**
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Mi

배포 후 확인

root@manager:~/k8slab/pvpvclab# kubectl get pv,pvc
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM         STORAGECLASS   REASON   AGE
persistentvolume/nfs-pv   100Mi      RWX            Retain           Bound    default/pvc                           39s

NAME                        STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/pvc   Bound    nfs-pv   100Mi      RWX                           11s

동적 프로비저닝 구성하기

  • aws, gcp, azure의 경우에는 각 csp 에서 제공하는 블럭스토리지를 제어할 수 있는 동적 프로비저너가 이미 존재하기 때문에 각 csp에서 kubernetes 서비스를 제공하는 engine을 이용하여 손쉽게 볼륨을 제공 받을 수 있다.
  • 하지만 on-premise 에서 직접 클라우드 환경을 구성하여 운영한다면 직접 프로비저너를 준비해야 한다. 우리는 nfs를 이용하여 볼륨(디렉토리)를 제공하므로 nfs-provisioner 를 생성해야 한다. 이는 pod로 존재한다.

SA(Service Account)

kubernetes는 다양한 오브젝트를 이용하는 것을 사용자(user)가 아닌 시스템레벨에서 동작한다고 하여 useraccount라는 개념보다는 ServiceAccount를 사용한다. 단, 다른 서버에서처럼 사용자를 이용하고 싶다면 별도로 UserAccount를 생성해 사용할 수 있으나 이는 별도의 인증서버를 연결하여야 한다.

우리는 리눅스 root 사용자에게 k8s 전체 시스템에 대한 모든 권한을 갖는 cluster-admin 계정정보를 부여했다. default라는 이름의 secret을 이용하고, 이 secret 내에 토큰을 이용하여 이용할 수 있다.

우리 회사에 서비스를 요청한 사용자가 자신의 ns에 속한 포드들의 정보를 확인하고 싶다면?

kubernetes → linux

default(admin) root(~/.kube/config)에 k8s admin 정보를 포함하고 있다.

각 네임스페이스별로 별도의 SA를 생성하여 고객사에게 전달한다. 이때 고객사에서는 협의 사항에 있지 않은 서비스를 사용할 수 없도록 CREATE와 같은 명령은 제거한다.(GET과 같은 확인 명령만 허용)

SA

ROLE → 특정 네임스페이스에서만 동작

CLUSTERROLE → CLUSTER 전체에서 사용할 수 있는 것 지정

default는 모든 명령을 수행할 수 있으니, 별도의 SA를 제공해 제한을 두어야 한다.

Role (NS에 속함) : Rolebinding 필요

Cluster Role(node,NS,PV) : Cluster Rolebinding 필요

인증서가 필요하다.

동적 프로비저닝 실습

프로비저닝 준비하기

vi /etc/kubernetes/manifests/kube-apiserver.yaml

파일에서 - kube-apiserver 밑에

--feature-gates=RemoveSelfLink=false

추가

  • 211.183.3.100에 /shared 생성 후 nfs 서버 기동
mkdir shared
chmod 777 shared

vi /etc/exports에 /shared 211.183.3.0/24(rw,no_root_squash,sync)

Service Account 생성

  • NFS Provisioner 포드가 PV를 배포할 수 있는 Role 생성, 사용할 수 있다.

sa.yaml

kind: ServiceAccount
apiVersion: v1
metadata:
  name: nfs-pod-provisioner-sa
---
kind: ClusterRole # Role of kubernetes
apiVersion: rbac.authorization.k8s.io/v1 # auth API
metadata:
  name: nfs-provisioner-clusterRole
rules:
  - apiGroups: [""] # rules on persistentvolumes
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-provisioner-rolebinding
subjects:
  - kind: ServiceAccount
    name: nfs-pod-provisioner-sa # defined on top of file
    namespace: default
roleRef: # binding cluster role to service account
  kind: ClusterRole
  name: nfs-provisioner-clusterRole # name defined in clusterRole
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-pod-provisioner-otherRoles
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-pod-provisioner-otherRoles
subjects:
  - kind: ServiceAccount
    name: nfs-pod-provisioner-sa # same as top of the file
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: nfs-pod-provisioner-otherRoles
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f sa.yaml

Provisioner pod 배포

  • NFS 서버를 동적 프로비저닝으로 사용할 수 있게 한다.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-pod-provisioner
spec:
  selector:
    matchLabels:
      app: nfs-pod-provisioner
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-pod-provisioner
    spec:
      serviceAccountName: nfs-pod-provisioner-sa # name of service account created in rbac.yaml
      containers:
        - name: nfs-pod-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-provisioner-v
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME # do not change
              value: nfs-test # SAME AS PROVISONER NAME VALUE IN STORAGECLASS
            - name: NFS_SERVER # do not change
              value: 211.183.3.100 # Ip of the NFS SERVER
            - name: NFS_PATH # do not change
              value: /shared # path to nfs directory setup
      volumes:
       - name: nfs-provisioner-v # same as volumemouts name
         nfs:
           server: 211.183.3.100
           path: /shared
kubectl apply -f provisioner.yaml
  • 배포 확인
root@manager:~/k8slab/pvpvclab# kubectl get deploy
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
nfs-pod-provisioner   1/1     1            1           22s

Storage Class 생성

  • storageClass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storageclass # IMPORTANT pvc needs to mention this name
provisioner: nfs-test # name can be anything
parameters:
  archiveOnDelete: "false"
kubectl apply -f storageClass.yaml
  • 확인
root@manager:~/k8slab/pvpvclab# kubectl get Storageclass
NAME               PROVISIONER   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-storageclass   nfs-test      Delete          Immediate           false                  5s

PVC 생성

  • 자동으로 스토리지 클래스를 통해 PV와 바인딩 여부 확인
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc-test
spec:
  storageClassName: nfs-storageclass # SAME NAME AS THE STORAGECLASS
  accessModes:
    - ReadWriteMany #  must be the same as PersistentVolume
  resources:
    requests:
      storage: 50Mi
kubectl apply -f pvc.yaml
  • 확인하기
root@manager:~/k8slab/pvpvclab# kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS       REASON   AGE
persistentvolume/pvc-3cd03385-e8b4-4b0a-8c1a-e9afc0ce0d23   50Mi       RWX            Delete           Bound    default/nfs-pvc-test   nfs-storageclass            23s

NAME                                 STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS       AGE
persistentvolumeclaim/nfs-pvc-test   Bound    pvc-3cd03385-e8b4-4b0a-8c1a-e9afc0ce0d23   50Mi       RWX            nfs-storageclass   23s
  • nfs 서버 디렉토리에 생성된 것 확인
root@manager:~/k8slab/pvpvclab# ls /shared
default-nfs-pvc-test-pvc-3cd03385-e8b4-4b0a-8c1a-e9afc0ce0d23

PV 사용할 수 있는 pod 배포

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nfs-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      volumes:
      - name: nfs-test #
        persistentVolumeClaim:
          claimName: nfs-pvc-test  # same name of pvc that was created
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: nfs-test # name of volume should match claimName volume
          mountPath: /test # mount inside of contianer
kubectl apply -f deployment.yaml
root@manager:~/k8slab/pvpvclab# kubectl get deploy
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
nfs-nginx             1/1     1            1           16s
nfs-pod-provisioner   1/1     1            1           10m

생성한 pod에서 볼륨 사용 가능 여부 확인하기

  • nfs 서버에서 파일 생성
root@manager:/shared# ls
default-nfs-pvc-test-pvc-3cd03385-e8b4-4b0a-8c1a-e9afc0ce0d23  index.html
root@manager:/shared# cd default-nfs-pvc-test-pvc-3cd03385-e8b4-4b0a-8c1a-e9afc0ce0d23/
root@manager:/shared/default-nfs-pvc-test-pvc-3cd03385-e8b4-4b0a-8c1a-e9afc0ce0d23# ls
pvpvc_check.txt

default ~ 로 들어가서 touch로 pvpvc_check.txt 만들고 빠져나오기

  • pod 접근 해 디렉토리 확인
root@manager:~# kubectl get pod
NAME                                  READY   STATUS    RESTARTS   AGE
nfs-nginx-758d59b4c4-s4cpd            1/1     Running   0          3m11s
nfs-pod-provisioner-98bd4898f-4lvwq   1/1     Running   0          13m
root@manager:~# kubectl exec nfs-nginx-758d59b4c4-s4cpd -- ls /test
pvpvc_check.txt

Service Account와 RBAC(Role based Access Control)

UserAccount는 k8s 내에 있는 오브젝트들을 동작시키는 등은 k8s 시스템에서 제어한다는 의미에서 ServiceAccount를 사용한다. 우리가 알고 있는 일반적인 UserAccount의 개념도 있지만, 주로 SA를 사용하고 만약 UA를 사용하고 싶다면 이는 외부 인증 서버를 연결해야 한다.

자체 인증서

export KUBCONFIG=/etc/kubernetes/admin.conf 또는 cp -i /etc/kubernets/admin.conf ~/.kube/config

위의 과정을 통하면 api-server에 접속할 수 있는 권한을 현재 계정(root)에게 부여하게 된다(kubernetes-admin)

실제 환경이라면 적절한 권한을 부여한 SA를 별도로 생성하여 운영해야 한다. 만약 고객 관리가 필요하다면 고객에게는 해당 프로젝트(네임스페이스) 내에서 get 등을 할 수 있는 SA를 발행해서 제공해줄 수 있어야 한다.

각 네임스페이스별로 기본적으로 default 라는 SA가 있다.

SA 실습

root@manager:~# kubectl create sa user1
serviceaccount/user1 created
root@manager:~# kubectl get sa
NAME                     SECRETS   AGE
default                  1         26h
nfs-pod-provisioner-sa   1         149m
user1                    1         14s

secret이 하나 있다

root@manager:~# kubectl get secret
NAME                                 TYPE                                  DATA   AGE
default-token-sq587                  kubernetes.io/service-account-token   3      26h
nfs-pod-provisioner-sa-token-q4qwv   kubernetes.io/service-account-token   3      149m
user1-token-lqh4r                    kubernetes.io/service-account-token   3      53s

User1으로 명령을 실행 해볼것임

root@manager:~# kubectl get svc --as system:serviceaccount:default:user1
Error from server (Forbidden): services is forbidden: User "system:serviceaccount:default:user1" cannot list resource "services" in API group "" in the namespace "default"

user1으로 할 때 Forbidden 에러가 뜨는 것을 확인 할 수 있다.

401 error → 인증 에러(authentication) : username/pw

403 error → 인가 에러(authorization) : 인증에 성공한 사용자에게 부여된 권한

  • sa user 삭제
root@manager:~/k8slab# kubectl delete sa user1
serviceaccount "user1" deleted

RBAC

Role

  • pod, Deployment,svc 등과 같이 특정 네임스페이스에 포함되는 오브젝트에 대한 명령 실행
  • 해당 네임스페이스에만 제한적
  • Rolebinding 필요

ClusterRole

  • namespace, node, pv 등과 같이 특정 네임스페이스에 속하지 않는 오브젝트에 대한 명령 뿐만 아니라 클러스터 전반에 걸쳐 지정된 몇몇 네임 스페이스에게 반복적인 명령 등을 전달하고자 하는 경우에 활용한다.
  • ClusterRoleBinding 필요

인증서 없이 접속. 토큰 정보가 포함되지 않은 상태에서 api로 접속했을 경우 결과 내용을 확인할 수 없다. SA가 누구 인가를 알 수 없으므로

root@manager:~# curl https://localhost:6443
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

인증서 있게 접속

root@manager:~# curl https://localhost:6443 -k
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
  "reason": "Forbidden",
  "details": {

  },
  "code": 403
}
}root@manager:~# kubectl get secret
NAME                                 TYPE                                  DATA   AGE
default-token-sq587                  kubernetes.io/service-account-token   3      26h
nfs-pod-provisioner-sa-token-q4qwv   kubernetes.io/service-account-token   3      162m
user1-token-lqh4r                    kubernetes.io/service-account-token   3      13m
kubectl describe secret default-token-sq587

SA → user1 현재 user1은 아무런 role 이 없는 상태이다.

role을 만들어 user1에게 제공할 예정

default - kubernetes-admin

user1 - 매핑된 권한(role)이 없는 상태

api 그룹은 apiversion에서 / 기준으로 구분한다.

v1 → group → “” : core group

apps/v1 → group → apps

만약 서비스에 대하여 명령을 실행할 계획이고, 리스트만 확인하고 싶다면

그룹 → “”

리소스 → service

verb(s) → get

role 만들기

root@manager:~/k8slab/0908# kubectl api-resources | grep -e ^role
rolebindings                                   rbac.authorization.k8s.io/v1           true         RoleBinding
roles                                          rbac.authorization.k8s.io/v1           true         Role

user1-role.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: user1role
rules: # 아래에 사용할 수 있는 api그룹, 리소스, 명령 작성
- apiGroups: [""] # "" : coregroup(Pod,service), Deploy/Replicaset은 X
  resources: ["services"] # pod도 하려면 , "pods"
  verbs: ["get","list"]

kubectl get svc : 서비스 전체 → list

옵션을 사용하여 pod 아닌 특정 pod, 서비스의 정보를 확인하고 싶다면

kubectl get svc testsvc → get

특정 pod 실시간으로 보고싶다면→ watch

  • Role binding하기

user-rolebinding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: default
  name: user1-rolebinding
subjects:
- kind: ServiceAccount
  name: user1
  namespace: default
roleRef:
  kind: Role
  name: user1role
  apiGroup: rbac.authorization.k8s.io
kubectl apply -f user-rolebinding.yaml
root@manager:~/k8slab/0908# kubectl get pod --as system:serviceaccount:default:user1
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:user1" cannot list resource "pods" in API group "" in the namespace "default": RBAC: role.rbac.authorization.k8s.io "user1role" not found

Quiz.

다음 중 정상 동작 하는 것은? 1번

kubectl get deployment —as list-only : list만 추가

kubectl get deployment —as get-only : get만 추가 → 되게 하려면 list추가해서 해야함

kubectl get deplolyment —as watch-only : watch만 추가 → 되게 하려면 list, get 추가해서 해야함

Quiz.

현재 상태에서 user1이 deployment에 대하여 get 가능하도록 해보자

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: user1role
rules: # 아래에 사용할 수 있는 api그룹, 리소스, 명령 작성
- apiGroups: ["","apps"]
  resources: ["services","deployments"]
  verbs: ["get","list"]
root@manager:~/k8slab/0908# kubectl get deploy --as system:serviceaccount:default:user1
NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
nfs-nginx             1/1     1            1           3h34m
nfs-pod-provisioner   1/1     1            1           3h45m

k8s는 각 오브젝트에 대한 접근이 가능하도록 RestAPI가 제공된다. 접근을 위해서는 헤더에 별도의 토큰을 첨부해 접근해야 한다. 접근 경로를 먼저 확인해보고, 생성한 SA의 토큰을 이용하여 웹으로 접근했을 때, svc, pod는 웹상에서 결과를 확인할 수 있는 지 여부를 살펴보자

root@manager:~/k8slab/sa# kubectl proxy
Starting to serve on 127.0.0.1:8001
  • 토큰 뽑아 접속하기
root@manager:~/k8slab/0908# kubectl get secret
NAME                                 TYPE                                  DATA   AGE
default-token-sq587                  kubernetes.io/service-account-token   3      28h
nfs-pod-provisioner-sa-token-q4qwv   kubernetes.io/service-account-token   3      4h18m
user1-token-lqh4r                    kubernetes.io/service-account-token   3      109m
root@manager:~/k8slab/0908# export SECNAME=user1-token-lqh4r

전역변수로 선언해서 사용하기

root@manager:~/k8slab/0908# kubectl get secret $SECNAME -o jsonpath='{.data.token}'

토큰 정보 뽑아오기

export DTKN=$(kubectl get secret $SECNAME -o jsonpath='{.data.token}' | base64 -d)

디코딩 되어 있는 값이 필요하기 때문에 해당 명령어를 실행 = 실제 토큰의 값을 전역변수에 넣는다.

셀프 인증서를 사용하기 때문에 -k 옵션을 사용해야 한다.

curl 이용시 -k 옵션을 사용할 경우 공인 인증서 여부 확인 하지 않는다.

root@manager:~/k8slab/0908# curl https://211.183.3.100:6443/apis --header "Authorization: Bearer $DTKN" -k
{
  "kind": "APIGroupList",
  "apiVersion": "v1",
  "groups": [
    {
      "name": "apiregistration.k8s.io",
      "versions": [
        {
          "groupVersion": "apiregistration.k8s.io/v1",
          "version": "v1"
...

다음과 같이 정상적으로 결과를 볼 수 있다.

root@manager:~/k8slab/0908# curl https://localhost:6443/api/v1/namespaces/default/services -k --header "Authorization: Bearer $DTKN"
{
  "kind": "ServiceList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces/default/services",
    "resourceVersion": "95389"
  },
  "items": [
    {
      "metadata": {
        "name": "kubernetes",
...

= kubectl get svc 정보

curl https://localhost:6443/apis/apps/v1/namespaces/default/deployments -k --header "Authorization: Bearer $DTKN"

= kubectl get deployment 정보

root@manager:~/k8slab/0908# curl https://localhost:6443/api/v1/namespaces/default/services/kubernetes -k --header "Authorization: Bearer $DTKN"

kubectl get svc의 kubernetes 까지 들어갈 수 있음

실습2

kubectl create sa testuser
  • role 생성
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: testuser
rules:
- apiGroups: [""]       # Pod, Service, Deploy/RS(X)
  resources: ["services", "pods"]
  verbs: ["get", "list", "watch"]
  • rolebinding
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: testuserrb
# 서비스 어카운트 지정
subjects:
- kind: ServiceAccount
  name: testuser
  namespace: default
# 연결할 Role 지정
roleRef:
  kind: Role
  name: testuser
  apiGroup: rbac.authorization.k8s.io
  • 배포 후 확인
kubectl get svc --as system:serviceaccount:default:testuser
kubectl get pod --as system:serviceaccount:default:testuser
kubectl get deploy --as system:serviceaccount:default:testuser # deploy는 Forbidden
  • 토큰 전역변수로 지정
export SECNAME=testuser-token-zpfsx
export SECTOKEN=$(kubectl get secret $SECNAME -o jsonpath='{.data.token}' | base64 -d)
  • role 변경 후 배포
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: testuser
rules:
- apiGroups: [""]       # Pod, Service, Deploy/RS(X)
  resources: ["services", "pods", "namespaces"]
  verbs: ["get", "list", "watch", "delete"]
  • 모니터링
curl https://localhost:6443/api/v1/namespaces/default/pods?watch=true --header "Authorization: Bearer $SECTOKEN" -k
  • 테스트용 포드 생성
kubectl run testpod --image nginx --restart Never
  • api를 통해 포드 삭제
curl -X DELETE https://localhost:6443/api/v1/namespaces/default/pods/testpod1 --header "Authorization: Bearer $SECTOKEN" -k
  • watch 중인 curl 의 pid 를 찾기
ps -ef | grep curl
kill -9 'curl 의 PID'

위의 내용이 가능하기 위해서는 testuser 가 watch, delete 가 가능해야 한다

0개의 댓글