본문 바로가기

컨테이너/Kubernetes

[Kubernetes] (20) Security

1.View Certificate Details ( Ceritificate & TLS )
2. Certificates API
3. KubeConfig
4. Role Based Access Controls (RBAC)
5. Cluster Roles
6. Service Accounts
7. image Security
 

1. Ceritificate & TLS 

 

* Authentication ( Who are you? )
  • Files: Username and Password
  • Files: Username and Tokens
  • Certificates
  • LDAP
  • SA (service accounts)
* Authorization ( What can you do? )
  • RBAC
  • ABAC
  • Node Authorization
  • Webhook

 

 

 

가장 첫번째로 보안을 생각할때 확인해야하는 쪽은 kube-api-server이다. 이는 모든 작업에 중심에 있다.

kube-api-server는 어떤식으로 권한제어를 할까?

 

1-1. 비대칭키 암호방식

 

API 서버는 비대칭키 암호방식을 통해 (Symnentic Encryption ) 호스트의 /etc/kubernetes/pki/ 내부에 

비밀키와 공개키를 저장해두고 TLS 인증을 통해 권한제어를 한다.

 

비대칭키 암호 방식


비대칭키 암호 방식은 암호화와 복호화에 사용하는 키가 서로 다른 암호화 방식을 의미합니다.
비대칭형 암호 방식을 이용하여 데이터를 전송하는 방식은 다음과 같습니다.
 
A는 공개키(public key)와 개인키(private key)를 생성한다. 생성된 공개키와 개인키는 수학적으로 다음과 같은 특성을 가집니다.

A의 공개키를 이용하여 암호화된 데이터는 A의 개인키로만 복호화가 가능하다.
A의 개인키를 이용하여 암호화된 데이터는 A의 공개키로만 복호화가 가능하다.

 

1-2. key, crt (Priavte Key, Public Key)

CA(ca-file)는 .crt 라는 파일 네이밍 형식을 따르는데 , Public key의 역할을 한다.
keyfile은 .key 라는 파일 네이밍 형식을 따르고, Private key의 역할을 한다. 

'KUBERNETES-CA'라는 Common Name을 갖고 있으며, etcd
를 제외한 모든 Component의 Certificate 서명에 사용된다.

  Master Node의 '/etc/kubernetes/pki' 디렉토리를 확인하면 위 그림에서 표현한 대부분의 파일이 존재하는 것을 확인할 수 있다.

 

 

다음은 kube-api server의 discription이다. 요약하면, 인증서의 주체는 kube-api server이며 crt,key를 가진다

 

1. client-ca-file : root ca파일

2. etcd에 접근할수 있는 componets는 api-server 뿐이다. 정보를 전달 하기때문에 cleint파일과 root crt를     가진다.

3. kubelet은 client 키만 가지고 있는데 정보를 가져오기만 하기 때문에 

4. tls-cert-file은 apiserver 자기자신의 공개키와 개인키를 가진다.


 

 

CA file decryption 

# openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout

# CA file을 decryption 해서 출력해줌.

 

로그 확인하는 방법

# journalctl -u etcd.service -l

# kubectl logs etcd-master


# kube-api 서버가 다운됬을떄 docker 명령어로 확인한다

# docker ps -a
# docker logs $container id

 

 


 


2. Certificate API

 

 

1. SSL Key 파일 및 CSR 파일 생성

# openssl genrsa -out myuser.key 2048
# openssl req -new -key myuser.key -out myuser.csr

2. K8s CertificateSigningRequest 리소스 생성

- vi csr.yaml

- 아래 형식의 CSR yaml 형식 복붙 

- reqeust: 부분에 cat myuser.csr | base64 | tr -d "\n" 해서 나온 결과값 복붙

# cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: myuser
spec:
  request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
  signerName: kubernetes.io/kube-apiserver-client
  usages:
  - client auth
EOF

 

3. CSR 확인 및 Approve

# kubectl get csr
# kubectl certificate approve myuser

3. KubeConfig

 

kubernetes utility의 인증방식은 kubectl option을 항상 명백히  typing 해줘야 한다. 

client CA, client Key, ceritificate-authority 를 항상 가지고 접근을 해야하는 인증절차를 가지기 때문에. 

 

이를 kubeConfig에 등록해놓고 사용

kubeConfig는 user의 $HOME/.kube/config 아래에 파일을 저장하는데, 이 파일을 읽어들여서 

kubectl option을 명백히 타이핑 해주지 않아도 certificate들을 인식한다.

 

kubeConfig는 yaml파일 형식으로 되어 있으며, 3가지 영역이 있다. user / context / cluster 범위로 나뉘어져 있다.

 

$HOME/.kube/config 파일

# user
# context
# cluster 

1, How to get use-context 

# kubectl config --kubeconfig=### view

2. How to change use-context

# kubectl config --kubeconfig=### use-context ###

4. RBAC

 

RBAC란?

Role Based Access Control (RBAC)  : 쿠버네티스의 시스템 권한 관리 방법
Role 기반으로 User와 Role 두가지를 조합하여 사용자에게 특정 권한을 부여

롤바인딩이란? 

롤:  특정 API나 리소스(pod,deploy 등), 사용 권한(get, edit 등)을 매니페스트 파일에 명시해둔 규칙의 집합

특정 네임스페이스에 대한 권한을 관리 

롤바인딩:  위에 설명한 롤과 특정 사용자를 묶어주는 역할을 수행하고, 지정한 사용자들에 한해서 롤에 명시한 규칙들을 기준으로 권한을 사용할 수 있도록 권한을 관리

 

1. Role 만들기

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # 사용할 api들을 명시 합니다. 쿠버네티스 특정 버전 이상부터는 각각의 resources 들을 사용하기 위한 api를 모두 지정해주어야 한다고 합니다. 위의 코드에서 deployments를 사용하기 위해선 apps api가 필요 합니다.
  resources: ["pods"]
  verbs: ["get", "watch", "list"]

2. RoleBinding 만들기

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

5. Cluster Role

RoleBinding은 특정 네임스페이스 내에서 권한을 부여하는 반면 ClusterRoleBinding은 클러스터 전체에 액세스 권한을 부여합니다.

 

resources들은 storageclasses , persistencevolumes,  nodes, namespaces, certificatesigningrequests 등 있습니다.

Rolebinding 할떄 subjects의 type도 User,Group등 다양합니다.

 

# Cluster Role

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"]

 

# Cluster Role Binding

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 # User로 사용해도 무방함
  name: manager # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

 


6. Service Account

 

pod에 대한 서비스 계정 생성?

(사람이) 클러스터에 액세스할 때(예: 를 사용하여 kubectl) apiserver에 의해 특정 사용자 계정으로 인증됩니다( admin클러스터 관리자가 클러스터를 사용자 정의하지 않는 한 현재 일반적으로 입니다 ).

포드 내부의 컨테이너에 있는 프로세스도 apiserver에 연결할 수 있습니다. 그렇게 하면 특정 서비스 계정(예: default) 으로 인증됩니다

 

포드를 생성할 때 서비스 계정을 지정하지 않으면 default라는 이름으로  네임스페이스 마다 서비스 계정이 자동으로 할당됩니다 

 

1. service Account를 생성하는 definition file

apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa

 

2. kubectl describe pod 

Mounts: 

  /var/run/secrets/###/serviceaccount from ###

3. create secrets

#

4. allign serviceAccountName ( to Deploy, to Pod)

기본이 아닌 서비스 계정을 사용하려면 spec.serviceAccountName 팟(Pod)  필드를 사용하려는 서비스 계정의 이름으로 설정하십시오.

# kubectl edit deploy web-dashboard


### 

spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /var/run/secrets/tokens
      name: vault-token
  serviceAccountName: build-robot ### 여기 sa 를 바꿔넣으면 된다.
  volumes:
  - name: vault-token
    projected:
      sources:
      - serviceAccountToken:
          path: vault-token
          expirationSeconds: 7200
          audience: vault

7. image Security

 

이미지 접속 credential을 secret으로 관리하게 되면 상당히 편하다.

deploy나 pod를 만들때 sepc.imagePullSecrets에 secret을 등록해주면 된다.
 



 

1. 개인 레지스트리 접속 secert 만들기

# kubectl create secret docker-registry private-reg-cred2 --docker-server=myprivateregistry.com:5000\
 --docker-username=dock_user --docker-password=dock_password \
 --docker-email=dock_user@myprivateregistry.com

 

2. deployment/  POD 수정하기

apiVersion: v1
kind: Pod
metadata:
  name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: <your-private-image>
  imagePullSecrets:
  - name: regcred