kubernetes cluster의 보안에 있어서 가장 핵심이 되어야하는 곳은 바로 kubernetes api server이다. kubernetes api server는 user로부터 요청을 받아 cluster의 object들을 제어하고 관리해주며, cluster에 필요한 workload들을 실행하기 때문이다.
kubernetes api server에 보안을 제공하는 데에는 두 가지 측면이 있는데, 다음과 같다.
'누가 접근하는가?'에 대한 문제는 인증을 받은 사람만이 접근하도록 하면 된다. 가령 username, password를 통한 인증이나, 토큰, certificate, LDAP, Service Accounts 등이 있다.
'어떤 것을 하용하는가?'에 대한 문제는 인가에 대한 문제이기 때문에 필요한 부분만 열어주고 동작시킬 수 있도록 해야한다. 가령, object생성은 할 수 있지만 삭제는 못하게 할 수 있다. 이를 가능하게 해주는 것이 RBAC
, ABAC
, Node Authorization
, Webhook
이 있다.
또한, kube api server와 통신하는 kube controller manager, kube proxy, kubelet, kube scheculder, etcd cluster 모두 TLS를 통한 안전한 통신을 보장하도록 한다.
서로 다른 pod들끼리의 통신 역시도 보안을 적용할 수 있는데, 이를 가능하게 해주는 것이 바로 network policies이다.
이제 위의 내용들에 대해서 하나씩 배워보도록 하자.
kubernetes cluster에 다음의 참여자들이 있다고 하자.
1. admin
2. 개발자
3. 유저
4. bots(CI,CD tool)
먼저 유저의 경우는 kubernetes cluster내부의 application 자체에서 user의 접근에 대해서 보안을 제공해야 한다. 따라서, 우리의 현재 고려대상이 아니다.
bots의 경우는 kubernetes cluster에 접근하기위해서는 ServiceAccount
라는 것을 만들어 접근하도록 허용하면 된다. 이에 대해서는 추후에 이야기할 예정이므로, 논의에서 잠시 제쳐두도록 하자.
메인이 되는 것은 admin
과 개발자
인데, admin의 경우는 kubectl
을 통해서 kube-apiserver에 쉽게 접근이 가능하다. 그러나 개발자의 경우는 kubectl
을 사용할 수 없는 환경에 있기 때문에 curl
을 통해서 kube-apiserver
에 요청을 보낼 수 있다.
curl -v -k https://master-node-ip:6443/api/v1/pods
위와 같이 요청을 보낼 수 있다.
이때 kube-apiserver
가 개발자로부터 인증을 요청할 수 있는데, 다음의 방법들이 있다.
static password file과 static token file을 먼저보도록 하자.
password123, user1, u0001
password123, user2, u0002
password123, user3, u0003
순서대로 password, id, 식별자이다.
다음의 static password file을 kube-apiserver
에 --basic-auth-file
로 제공하는 것이다.
apiVersion: v1
kind: Pod
metadata:
name: kube-apiserver
namespace: kube-system
labels:
tier: control-plane
component: kube-apiserver
spec:
containers:
- command:
- kube-apiserver
- --authorization-mode=Node,RBAC
...
- --basic-auth-file=user-details.csv
이렇게 수정하면 자동으로 실행될 것이다.
이렇게 적용되었다면, curl
옵션을 통해서 user-details.csv
에 명시된 아이디, 패스워드를 사용하면 된다.
curl -v -k https://master-node-ip:6443/api/v1/pods -u "user1:password123"
이렇게 요청하면 인증에 성공할 것이다.
토큰 역시도 마찬가지의 방법이다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c,user10,u0010,group1
다음의 file을 --token-auth-file
옵션에 전달해주면 된다.
- --token-auth-file=user-token-details.csv
요청할 때는 header
로 Authorization: bearer ${token}
을 사용하면 된다.
curl -v -k https://master-node-ip:6443/api/v1/pods --header "Authorization: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
위와 같이 요청하면 접근에 성공할 것이다. 그러나 사실 위의 두 방법은 추천되지 않는다. 왜냐하면 무분별하게 user들이 kubernetes apiserver에 접근할 수 있기 때문이고, 해당 file이 유출되면 그로인한 여파가 너무 크기 때문이다. 때문에 일부 기능들은 현재는 사용불가로 deprecated되었거나, 더 많은 단계들이 추가되었다.
이보다 더 안전하고 user가 더 사용하기 쉬운 Role base의 인증 방식을 통해 kubernetes apiserver에 접근하는 방식을 배워보도록 하자.