k8s에 대하여 - (PV,PVC) 9/13

양승현·2022년 9월 13일
0

kubernetes

목록 보기
9/18
post-thumbnail

PV, PVC

PV ReclaimPolicy

  • Retain : 삭제되지 않는다. pvc는 삭제되어도 pv 는 유지한다 (기본 값)
  • Delete: 볼륨 삭제 ,data 삭제
  • Recycle: data 삭제

PV

  • PV는 특정 namespace에 속하지 않기 때문에 다른 namespace에 PV를 제공할 수 있다

PVC

  • PVC는 namespace에 속한다.
  • PVC와 PV가 Bound 되서 바로 사용할 수는 없다 - Pod에서 해당 PVC를 volume 부분을 넣어주면 Pod와 PV가 mount되어 해당 PV를 사용할 수 있다.

StorageClassName

  • StorageClassName의 기본값은 null이다
  • StorageClassName가 없더라도 기본적인 연결은 가능하다.

리눅스 disk

  • 파티셔닝 종류로는 자동 파티셔닝과 수동 파티셔닝이 있다.
/boot -> 부팅을 위한 커널이 존재
swap -> 가상 메모리를 제공
/ -> / 디렉터리에 있는 디렉토리는 모두 / 용량을 공유한다. 각 디렉터리가 용량이 지정되지 않으면, 용량은 유동적이다. 이는 다른 디렉터리가 용량을 많이 사용할때 다른 디렉터리들은 용량을 적게 사용할 수 밖에 없다. 이때 수동 파티셔닝으로 디렉터리의 용량을 제한해야한다.

ResourceQuota

  • k8s 에서는 볼륨 용량을 제한하는 두 가지 방법이 있다
1. pvc 의 요청 용량을 제한하는 방법
2. 스토리지 리소스에 대한 사용량을 제한  
  • ResourceQuota 는 Namespace 에 속한다

스토리지 연결 방식 - Bind & Mount

  • 스토리지 연결 방식은 아래와 같다
NFS - Bind
IscsI - Mount
  • IscsI 방식을 많이 사용한다

AWS EBS

  • 위의 방법은 관리자(운영자)가 볼륨을 생성하고 이를 PV Pool에 미리 담아두고 사용자(게발자)는 PVC를 작성하여 둘을 bind하는 형태로 포드에 적용하는 방법이다.
  • 이 경우 개발자가 요청하는 볼륨은 미리 PV에 담겨있어야 하므로 반드시 관리자와의 커뮤니케이션이 필요하다. 하지만 갑작스럽게 볼륨이 필요하거나 잦은 볼륨 요청이 있을 경우에는 적절한 방법이 아니다.
  • 이를 해결하기 위하여 사용하는 것이 동적 프로비저닝이다.
  • 예제 aws에서 사용하게 될때)
    개발자, 사용자는 다음에 yaml 파일을 만들고 이를 배포해야 한다.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata: 
  name: fastdisk
provisioner: kubernetes.io/aws-ebs  # 온 프레미스 환경이나 다른 퍼블릭 클라우드에서 사용이 불가능 하다
  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
  • aws-ebs 는 aws 에서만 사용 가능한 프로비저닝이다. 이는 aws 에서 제공하는 PV 를 생성해주는 도구다.
온 프레미스 환경이나 다른 퍼블릭 클라우드에서 사용이 불가능 하다
프로비저너는 요청에 맞는 저장 공간을 생성해준다. 생성한 저장 공간은 Pool 에 담는다
  • ebs는 ssd와 hdd를 제공하는데
gp2 -> ssd를 의미
ext4 -> 포멧이다
zone 지정 -> block storage를 사용하는데 ssd 에 포멧은 ext4 이고, zone 이 ap-northeast-2a 임을 storageclass 에 정의하였다

동적 프로비저닝

  • Role는 namespace 내에 속하는 오브젝트에 대해 Role과 namespace에 속하지 않는 오브젝트에 대한 clusterRule이 있다.
SA 와 Role 을 연결하기 위해서는 RoleBinding 이 필요하다
SA 와 ClusterRole 을 연결하기 위해서는 ClusterRoleBinding 이 필요하다

SA(serviceAccount)

  • k8s는 다양한 오브젝트를 이용하는 것을 사용자(user)가 아닌 시스템 레벨에서 동작한다고 하여 useraccount 라는 개념보다는 serviceAccount를 사용한다. 단, 다른 서버에서 처럼 사용자를 이용하고 싶다면 별도로 UserAccount를 생성하여 사용할 수 있으나 이는 별도의 인증서버를 연결하여야 한다.
  • 일반적으로 SA를 이용한다.
  • 우리는 리눅스 root 사용자에게 k8s 전체 시스템에 대한 모든 권한을 갖는 cluster-admin 계정정보를 부여했다. default라는 이름의 secret을 이용하고 이 secret 내에 토큰을 이용하여 사용할 수 있다.
root@manager:~/0913/sa# kubectl get sa
root@manager:~/0913/sa# kubectl describe sa default

  • 우리 회사에 서비스를 요청한 사용자가 자신의 ns에 속한 포드들의 정보를 확인하고 싶다면?
    kubernetes -----------------> linux
    default(admin) root(~/.kube/conifg)에 k8s admin 정보를 포함하고 있다.
root@manager:~/0913/sa# kubectl describe secret default-token-fmftn

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

SA & Role

ROLE -> 특정 네임스페이스에서만 동작 + ROLEBINDIG(롤과 서비스어카운트를 연결)
CLUSTERROLE -> CLUSTER 전체에서 사용할 수 있는 것 지정(클러스터 롤과 서비스어카운트 연결)

SA 생성하기 및 삭제하기

  • testuser 생성
root@manager:~/0913# kubectl create sa testuser
  • SA 확인
root@manager:~/0913# kubectl get sa
NAME       SECRETS   AGE
default    1         5d23h
testuser   1         27s
  • SA 삭제하기
root@manager:~/0913# kubectl delete sa testuser

에러
401 error -> 인증에러(authentication)
403 error -> 인가에러(authentication)

실습 SA 권한

    1. kubectl create sa testuser
    1. role 생성하기
root@manager:~/0913/sa# cat role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: testuser
rules:
- apiGroups: [""]     # 코어 그룹에 포함 되는 것들 Pod, Service, Deployment(x), replicaset(x)
  resources: ["services", "pods"]
  verbs: ["get", "list", "watch"]
    1. role과 sa 연결하기(rolebinding)
root@manager:~/0913/sa# cat rolebinding.yaml
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
    1. 확인
root@manager:~/0913/sa# kubectl get svc --as system:serviceaccount:default:testuser
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   5d23h
  • k8s 는 각 오브젝트에 대한 접근이 가능하도록 RestAPI 가 제공된다. 접근을 위해서는 헤더에 별도의 토큰을 첨부하여 접근해야 한다. 접근 경로를 먼저 확인해 보고 생성한 SA 의 token 을 이용하여 웹으로 접근했을 때, svc,pod 는 웹상에서 결과를 확인할 수 있는지 여부를 살펴보자

Api Server 접속

  • K8S 는 각 오브젝트에 대한 접근이 가능하도록 Rest Api가 제공되는데, 이곳에 접근하기 위해서는 Header 에 별도의 Token 을 첨부하여야 한다.
  • 접근 경로를 먼저 확인해보고, 생성한 SA 의 Token 을 이용하여 웹으로 접근했을 때, svc 와 pod 는 웹 상에서 결과를 확인할 수 있다.

Token 없이 Api Server 접속

  • https://211.183.3.100:6443
  • 웹 브라우저에서 Api Server 에 접속해보면 권한 문제가 생긴다. 이유는 토큰의 정보가 없기 때문이다
root@manager:~/k8slab# 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
}
  • 로컬 환경에서 접속하면 https 인증을 위한 공인 인증서가 없으므로, -k 옵션을 통해 접속해본다.
  • 지금은 토큰 정보를 전달하지 않았기 때문에 403 error 가 발생한다.

Proxy 를 통한 Api Server 접속

  • 아래 명령어를 통해 proxy를 열어둔다.
kubectl proxy 
  • 해당 주소 접속시 proxy를 열면 누구나 해당 주소에 인증 정보 상관없이 접근할 수 있다
root@manager:~/k8slab/sa# curl http://localhost:8001/apis/node.k8s.io
{
  "kind": "APIGroup",
  "apiVersion": "v1",
  "name": "node.k8s.io",
  "versions": [
    {
      "groupVersion": "node.k8s.io/v1",
      "version": "v1"
    },
    {
      "groupVersion": "node.k8s.io/v1beta1",
      "version": "v1beta1"
    }
  ],
  "preferredVersion": {
    "groupVersion": "node.k8s.io/v1",
    "version": "v1"
  }
}
  • 이것으로 인증 정보 없이 api server 의 정보를 불러올 수 있다
  • 누구나 접근할 수 있기 때문에 이 방법은 보안상 좋지 않다.

Token 을 통한 Api Server 접속

  • 아래 명령어를 통해 secret 리스트를 확인한다.
kubectl get secret 
  • 해당하는 secret의 상세 정보를 확인하여 token 정보를 확인하고 base64로 암호화 된 토큰이기 때문에 복호화를 하고 사용한다.
export SEC=testuser-token-7vgq4  kubectl get secret $SEC -o jsonpath='{.data.token}'
kubectl get secret $SEC -o jsonpath='{.data.token}' | base64 -d
export SECTOEKN=$(kubectl get secret $SEC -o jsonpath='{.data.token}' | base64 -d )
  • secret의 토큰을 복호화하고 전역 변수에 저장하여 api server에 접속한다.
curl https://localhost:6443/apis --header "Authorization: Bearer $SECTOEKN" -k
  • 헤더에 토큰을 넣어주게 되면 접속이 가능하며 토큰 타입을 Bearer로 지정 해주면 pod list와 service list가 확인 가능하다.
curl https://localhost:6443/api/v1/namespace/defaultpods -- header "Authoriz00ation: Bearer $SECTOKEN" -k
curl https://localhost:6443/api/v1/namespace/default/services -- header "Authoriz00ation: Bearer $SECTOKEN" -k

0개의 댓글