본문 바로가기

kubernetes, helm, rancher

kubernetes config, Role, Rolebinding

기본적인 kubernetes resource, option 등을 설명한 블로그입니다. 추가적인 기능을 보고싶으시면 docs를 참고바랍니다.

https://kubernetes.io/docs/home/

 

Kubernetes Documentation

Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications. The open source project is hosted by the Cloud Native Computing Foundation.

kubernetes.io

  • 실제 서비스단계에서는 다양한 cluster, 다양한 context, 다양한 users가 있기 때문에, user와 cluster를 묶기 위해서 일단 config를 작성해야한다.
apiVersion: v1
kind: Config
current-context: [default context]
clusters:
- name: [cluster name]
  cluster:
    certificate-autority: ca.crt # or certificate-authority-data file 내용을 전달.
    server: https://[cluster-name]:6443
contexts:
- name: [context name]
  context:
    cluster: [cluster name]
    user: [user name]
    namespace: [ns]
# context는 cluster와 user를 묶어준다.

users:
- name: [user name]
  user:
    client-certificate: user.crt
    client-key: user.key
  • config 위치는 ~/.kube/config파일에 있으며, v1에 config라는 resource type은 없으므로, yaml 파일로 작성 후 create은 안된다.
  • kubectl config view -> config정보 보기.(context, user, cluster), 민감한 정보는 redacted되었다.
  • kubectl config set-context [name ex)test@kubernetes] --cluster [cluster name ex)kubernetes] --user [user name ex) kubernetes-admin] --namespace=[name] -> default가 아닌 다른 ns를 가진 context생성
    kubectl config current-context -> 현재 context
  • kubectl config use-context [context name] -> 해당 context로 switch하며, 해당 context가 가지는 ns 등의 설정을 가져온다.
  • 위의 방식 말고 kubectl config set-context $(kubectl config current-context) --namespace=[ns name]으로 기존 유저 default ns 를 바꿀 수 있다.
  • kubectl config set-context [context name] --cluster [cluster name] --user [user name] --namespace [namespace name] -> kubectl config use-context [context name] -> default namespace 바꾸는 방법
  • user를 새로만들었다면, password 혹은 certificate 등 authenticate 할수 있는 방법들을 적어야 한다.
  • pod가 실행될 때 ServiceAccount를 설정하지 않으면 같은 namespace에 default 라는 serviceaccount가 할당됨. 새로운 ns가 생성되면 항상 default serviceaccount가 생성된다.
  • kubectl get serviceaccounts를 하면 default라는 account를 볼 수 있다.
  • kubectl get secrets -> serviceaccount의 토큰을 볼 수 있다. 이러한 secret은 type이 kubernetes.io/service-account-token이며 account를 인증하기 위한 token이다. sa를 생성하면 자동으로 생성된다.
  • kubectl get pod [pod name] -o yaml 하면 serviceAccount: default를 볼 수 있다.
  • kubectl create serviceaccount(sa) [account name] -> serviceaccount 생성 -> kubectl get secrets -> 토큰 확인.
  • pod에서 serviceAccount를 설정할 수 있는데, 이는 pod 자원에 접근할 수 있는 권한을 의미한다. 즉, serviceAccount가 test라고 해보면, test이외의 user(serviceaccount)로 해당 pod(test를 service account로 가지는)를 삭제, 생성 등을 할 수 없는 뜻이 아니라, pod 자체의 권한이 test라는 것이다. test가 pod를 생성할 수 없다면 pod내에서 다른 pod를 생성할 수 없다는 뜻이다.

 

 

apiVersion: v1
kind: Pod
metadata:
  name: testpod
  namespace: deafult
spec:
  ...
  containers:
  - image: nginx
    name: testpod
  serviceAccount: [sa name]

 

  • ABAC(속성기반) -> 각각의 사용자에게 정책을 주는 것으로, 사용자가 많아지면 매번 관리하고 추가하기 힘들기 때문에 RBAC(정책기반)를 쓴다. ROLE을 만들어서 사용자에게 연결. 
  • 그 밖의 WEBHOOK(내부적으로 인증을 하는 것이 아니라 아웃소싱하여 third party가 해주는 경우), AlwaysAllow, AlwaysDeny, Node가 있다.
  • kube-apiserver에 --authorization-mode에 정의되어있으며, default로 node라고 되어있는데, node는 해당 노드에게 resource나 api 등을 제어할 수 있는 권한이다. 만약 admission plugin이 noderestriction이라고 한다면, 해당 노드는 노드 내의 자원밖에 제어하지 못한다.
  • 이러한 인증방식을 여러번 줄 수 있는데, node,rbac,webhook으로 주면 앞에서부터 차례대로 검사한다음 인증을 한곳이라도 받으면 통과.
  • 인증을 마치더라도(user의 인증서, pod의 sa) 요청을 수행할 권한을 확인하는 작업에서 필요한 Role, RoleBinding
  • Role -> 어떤 api를 이용할 수 있는지 정의. 지정된 namespace에서만 유효 ex)pod는 get, list, watch..., service는 get, list...를 할 수있다라는 role
  • RoleBinding -> 사용자/그룹 또는 sa와 role을 연결.

 

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namesapce: default
  name: pod_reader
rules:
- apiGroups: [""] # core라면 blank로 가능.
  resources: ["pods"]
  verbs: ["get","watch","list"]
# create: 리소스 생성
# get: 개별 리소스 조회
# list: 여러 건의 리소스 조회
# update: 기존 리소스 내용 전체 업데이트
# patch: 기존 리소스 중 일부 내용 변경
# delete: 개별 리소스 삭제
# deletecollection: 여러 리소스 삭제
  resourceNames: ["blue"] # 만약 pod 전부가 아니라, blue pod만 제한하고 싶다면

 

  • kubectl create role [role name] --verb=create --verb=get --verb=list --resource=pods -> 위 yaml을 cli로
  • kubectl get role -> 해당 ns에서만 적용되는 role 정보
  • kubectl create rolebinding [role binding name] --role=[role name] --user=[user name] ( --dry-run -o yaml 을 통해 yaml 파일을 볼 수 있다. 만약 user가 아니라 group에게 role을 주고 싶은 경우 --group이라고 하면 된다.)

 

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: developer-binding-myuser
  namespace: another
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: [role name]
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: [user name]

 

  • rolebinding된 role과 rolebinding을 보려면 config에 credential을 저장하고 context를 추가한다음 context를 바꿔줘야한다. 즉, rolebinding된 user가 포함된 context로 switch해줘야 보인다.
  • kubectl config set-credentials [user name] --client-key=[username].key --client-certificate=[username].crt --embed-certs=true -> user 정보를 config에 저장.
  • kubectl config set-context [user name] --cluster=kubernetes --user=[username] -> context 추가
  • kubectl config use-context [user name]
  • config파일은 .kube안에 있고 만약 다른 config file에 context를 정의했다면, kubectl config --kubeconfig=[config file] use-context 식으로 하면 된다.
  • 하지만 pods, rs, jobs, role, rolebinding 등등의 role resource들은 namespaced이며, namespace level이고, node, clusterroles, clusterrolebindings, PV, certificatesigningrequests, namespaces 등등은 cluster level이라서 cluster 범위로 접근가능.
  • ClusterRole & ClusterRoleBinding -> 전체 ns로 access 가능.
  • kubectl config current-context -> 현재 current-context user 확인
  • kubectl delete [role | rolebinding] [name]
  • kubectl create clusterrole [role name] --verb=create --verb=get --verb=list --resource=pods -> cluster만 붙이면 됨
  • kubectl create clusterrolebinding [role binding name] --clusterrole=[role name] --user=[user name] -> cluster만 붙이면 됨
  • cluster로 실행하면 kubectl get pods -n [전체 ns 이름]에 대한 권한을 얻을 수 있다.
  • kubectl config delete-context [user name]
  • kubectl config delete-user [user name]
  • kubectl describe clusterrole [cluster role]
  • kubectl auth can-i [create, delete 등] [deployments, nodes 등 resource] -> check access, 뒤에 --as [user name]으로 다른 user를 볼 수 있으며, -n 으로 ns 지정가능.
  • 보통 docker에서 image를 download할 때 nginx라고 해보면, library가 생략된 nginx만 써도된다. library는 default이며 user 혹은 repository 이름이 없다면 자동으로 library/nginx image가 pull하게 된다.
  • 하지만 private repository에서 image를 받고 싶다면 아래와 같이 secret을 만들어준다.
kubectl create secret docker-registry [secret name] \
--docker-server= private-registry.io \
--docker-username= registry-user \
--docker-password= registry-password \
--docker-email= registry@org.com

# 그 다음 yaml파일에
...
spec:
  containers:
  ...
  imagePullSecrets:
  - name: [secret name]
  • 보통 pod내에서의 command는 root가 실행하지만 특정 user id가 실행하고 싶다면 user id 지정
...
spec:
  securityContext:
    runAsUser: 1010
  containers:
  - image: ubuntu
    name: web
    command: ["sleep", "5000"]
    securityContext:
      runAsUser: 1011
  • 또한 특정 capability를 넣고싶다면.
spec:
  container:
  ...
    securityContext:
      capabilities:
        add: ["SYS_TIME"]

 

  • kubernetes는 core와 named group으로 나뉠 수 있으며, 그 안에 여러가지 groups들이 있는데 core는 /api그룹이며, core한 resource를 포함하며, named는 /apis로써 좀더 organized된 새로운 feature들이 있다.

 

  • kubernetes는 여러가지 groups이 있는데, /api, /apis, /metrics, /logs 등등이 있으며, /api에는 v1이있으며 그안에는 ns, pv, pvc, rc, rs secrets 등등이 있으며, /api/v1/secrets 이렇게 표시된다. /apis는 /apps, /extesions / networking.k8s.io, /certificates.k8s.io 등이 있으며, /apps안에는 /v1/deployments, /v1/replicasets, /v1/statefulsets 등이 있고 각각 list, delete, create, get, update, watch가 있다.
  • curl http://[kube-api server ip]:6443 -k 로 어떤 api group들이 있는지 알 수 있고, curl http://[kube-api server ip]:6443/apis -k는 apis 그룹에 대한 정보를 볼 수 있다. 또한 문서에 kubernetes api를 통해 알 수 있다.
  • curl로 보낼 때 인증해야한다면 certificate 인증 파라미터를 보낼 수 있고, kube config file에 작성하여, kubectl proxy를 실행하여 proxy를 시작하면 kube config file을 참조하여 인증 파라미터를 번거롭게 작성안해도 된다.
  • 여기서 kubectl proxy는 kube-proxy(service, pod, node간의 통신해주는 networking)하고는 다른 점은, kubectl로 인해 kube-api server로 통신을 위해 만들어진 http proxy service라는 것이다.