LoginSignup
1
3

More than 3 years have passed since last update.

Kubernetes RBAC(特定動作のみできるサーバを提供する)

Last updated at Posted at 2019-11-30

前提

今回なんでこんなことをするかという背景として、
社内ツールをkubernetes上で動かしていて、それをあるmasterとは別のサーバにNATすることで、NATサーバのIPからアプリケーションにアクセスできるようにしていたのですが、興味などでkubectlに触れてみたいと思う方もいらっしゃるかなと思いました。

そういう訳で、そのNATサーバーからkubectlを打てるようにしてあげようと思ったのですが、podに変更を加えられたくなかったので、Podの情報だけはを見れるようにしようということで、以下のことをしていくこととなりました。

まず初めに

提供するサーバに、kubernetesを操作するサーバの/root/.kube/configをコピーしておきます。

これで、そのサーバからkubernetesが操作できると思います。

ClusterRoleの準備

ClusterRoleのmanifestを作成します。

clusterRole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: confined-role
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list"]

適応します。

# kubectl apply -f clusterRole.yaml
clusterrole.rbac.authorization.k8s.io/confined-role created

# kubectl get clusterrole
NAME                                                                   AGE
admin                                                                  2d3h
cluster-admin                                                          2d3h
confined-role                                                          15s
edit                                                                   2d3h
<省略>

作成された事を確認できました。

ClusterRoleBinding

ClusterRoleBindingのmanifestを作成します。

clusterRoleBinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: confined-rolebinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: confined-role
subjects:
- apiGroup: ""
  kind: ServiceAccount
  name: confined-sa
  namespace: default

これで、下準備ができました。

Service Accountの作成

Service Accountを作成します。

# kubectl create sa confined-sa
serviceaccount/confined-sa created

# kubectl get sa
NAME                                   SECRETS   AGE
1cb2dc0b-0ae3-4d11-8be6-134366812874   1         2d3h
confined-sa                            1         15s
default                                1         2d3h


# kubectl get sa confined-sa -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: "2019-11-28T06:23:37Z"
  name: confined-sa
  namespace: default
  resourceVersion: "272115"
  selfLink: /api/v1/namespaces/default/serviceaccounts/confined-sa
  uid: faecd7c4-ffd9-4d8f-a080-55eff0b4dfa8
secrets:
- name: confined-sa-token-kfsn6

上の表示では secretの箇所に、confined-sa-token-kfsn6 と出てきました。
この表示されたSecretをyaml形式で取得し、Tokenを確認します。

# kubectl get secret confined-sa-token-kfsn6 -o yaml
apiVersion: v1
data:
  ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrekNDQWVPZ0F3SUJBZ0lVVWdkdHNzcmxuTk5PRnZUdkpiamorbEdadjh3d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0RURUxNQWtHQTFVRUF4TUNZMkV3SGhjTk1Ua3hNVEkxTVRJd05qSTNXaGNOTWpNeE1USTFNVEl3TmpJMwpXakFOTVFzd0NRWURWUVFERXdKallUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCCkFOZGhFUzlobG81R2d4YUt3dWY1cmJlSTlYRTBJaVc0cWk5MkNUS1d5RmMxSXprV3FFRm40a0JYY1h3TlFJQ28KL09TdzJ1QTVGU0JJYzZyc3hSNjNiMVhEYjlDQWVWRkFGNG9XNXRWbW5qOW53cEMvVCtSZDFiMFFmMjZ3ckI4OQpQZmdqK0pod0UvUnBMc0tEUTJrQmkrUEpzbUlCTmpHdjAwMnNOTW9rYTVuNCtzU2ZGTkhkV2ErMUJGcWxGbUhiCmcxc0c3VEI5Y28yb25jTndabGxkemJKSUhYQXVRcC9RWkQ0QW9GRUhIRFZoMjBxZ1VXUFZBNkJlcklCaVorN28Ka0Z1eTdpcHB5RFdWSkhmTFBZRlF6MFppaHpkTkpCQkhKdDcvVFNNQTlidy9TZ0ZydUsrUXIzMUhaOXJpZ0M4TgpTU3B5djVIMjNmbG5HOE9ldHlIdkw5OENBd0VBQWFOVE1GRXdIUVlEVlIwT0JCWUVGTzIxT0I1TUtOZlhMWjRXClJKQnlkZVBacWpPSk1COEdBMVVkSXdRWU1CYUFGTzIxT0I1TUtOZlhMWjRXUkpCeWRlUFpxak9KTUE4R0ExVWQKRXdFQi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFIcTIrSVplOU41bzZYdWFCUUhKY29sTgpQc0RCS0lUTkxlWTJvaWpaQlBEVkhqanhnR2xHWTlKc2RWRzFITWNQc1lIVnd3bTljOTVEL1hnN1V4RWwvNVp4CkRkVDVDSnNLQWxlZGhsL3oxckFRZk9FN25HOU1FdU5oSFdKdTBTMXpQYVN0dElRVVhoU3drZ2MrcnQxMThPSFYKajdKc25lWEMrcVlTK0lEV09YWFI5S2VMRXJjc256eXBtVzE2bVRBTmtPblBlQzBTWlRzUWV0UDhORFBYRis0OAppMXlWL1A3WjZsaVl3TERPQlFJOFkwZzFJOEtCTTR2RXNQUlJOOStBbkg1OTAyNCtvNklnVnptQXhmT1RhSzVMCnN0M3cwSlJRYjVGcTIwaEYxK3NCZlNFdCttc2JnNmFCNmlaMlFCMWFSZm9LdnprSW1rOUVuZTlYZkNoVEo5dz0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
  namespace: ZGVmYXVsdA==
  token: ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WldOeVpYUXVibUZ0WlNJNkltTnZibVpwYm1Wa0xYTmhMWFJ2YTJWdUxXdG1jMjQySWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXpaWEoyYVdObExXRmpZMjkxYm5RdWJtRnRaU0k2SW1OdmJtWnBibVZrTFhOaElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WlhKMmFXTmxMV0ZqWTI5MWJuUXVkV2xrSWpvaVptRmxZMlEzWXpRdFptWmtPUzAwWkRobUxXRXdPREF0TlRWbFptWXdZalJrWm1FNElpd2ljM1ZpSWpvaWMzbHpkR1Z0T25ObGNuWnBZMlZoWTJOdmRXNTBPbVJsWm1GMWJIUTZZMjl1Wm1sdVpXUXRjMkVpZlEuRnZyV1hBUUMzVXJreG1IczM1SDlkbndUbUlJLWZoME1GTVJBbEVrZjNrdU1JVHFsbWl2VUMwLThORkdYdzMybDJrQm9TWmV0T18tNnlTbjZKSno3bk10cUZPVkZfMVpDZEtnZ2M5RE9xNkVueThSMnZYRWZPOFQ4YVhTMldfQ0Zza1lPVUttSjJFRkVTSU05RlNheXo0cHpkZU12RW5ObUw1dER3b1BXVHZGSU1TSjNtbDVNLUM0ZG9rWmtWSHB6RHQxLVRhMVR0emJlejFFRmNkb200blpyUTNLZWJ3cWx5MnhDeEg3YXdreldEbkdmSWtTVFVWRkRZWkk2SnBIMURxVVVYOXpxYzBCNW9XaVdVdzZucC1lRDFsWkMycXBUZVRTUGlyUUw0aE12dDVGUlNXdFByMlVOQXZDVENZeGNLSUl6Y2NIdXRzZklSaGJ6cVpYMzBB
kind: Secret
metadata:
  annotations:
    kubernetes.io/service-account.name: confined-sa
    kubernetes.io/service-account.uid: faecd7c4-ffd9-4d8f-a080-55eff0b4dfa8
  creationTimestamp: "2019-11-28T06:23:37Z"
  name: confined-sa-token-kfsn6
  namespace: default
  resourceVersion: "272114"
  selfLink: /api/v1/namespaces/default/secrets/confined-sa-token-kfsn6
  uid: aff16ff4-986b-40df-b3d4-51d300f0bb3a
type: kubernetes.io/service-account-token

このtokenの値はBase64でエンコードされているため、デコードしてあげます。

# echo -n 'ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WldOeVpYUXVibUZ0WlNJNkltTnZibVpwYm1Wa0xYTmhMWFJ2YTJWdUxXdG1jMjQySWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXpaWEoyYVdObExXRmpZMjkxYm5RdWJtRnRaU0k2SW1OdmJtWnBibVZrTFhOaElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WlhKMmFXTmxMV0ZqWTI5MWJuUXVkV2xrSWpvaVptRmxZMlEzWXpRdFptWmtPUzAwWkRobUxXRXdPREF0TlRWbFptWXdZalJrWm1FNElpd2ljM1ZpSWpvaWMzbHpkR1Z0T25ObGNuWnBZMlZoWTJOdmRXNTBPbVJsWm1GMWJIUTZZMjl1Wm1sdVpXUXRjMkVpZlEuRnZyV1hBUUMzVXJreG1IczM1SDlkbndUbUlJLWZoME1GTVJBbEVrZjNrdU1JVHFsbWl2VUMwLThORkdYdzMybDJrQm9TWmV0T18tNnlTbjZKSno3bk10cUZPVkZfMVpDZEtnZ2M5RE9xNkVueThSMnZYRWZPOFQ4YVhTMldfQ0Zza1lPVUttSjJFRkVTSU05RlNheXo0cHpkZU12RW5ObUw1dER3b1BXVHZGSU1TSjNtbDVNLUM0ZG9rWmtWSHB6RHQxLVRhMVR0emJlejFFRmNkb200blpyUTNLZWJ3cWx5MnhDeEg3YXdreldEbkdmSWtTVFVWRkRZWkk2SnBIMURxVVVYOXpxYzBCNW9XaVdVdzZucC1lRDFsWkMycXBUZVRTUGlyUUw0aE12dDVGUlNXdFByMlVOQXZDVENZeGNLSUl6Y2NIdXRzZklSaGJ6cVpYMzBB' |base64 -d
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImNvbmZpbmVkLXNhLXRva2VuLWtmc242Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNvbmZpbmVkLXNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZmFlY2Q3YzQtZmZkOS00ZDhmLWEwODAtNTVlZmYwYjRkZmE4Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6Y29uZmluZWQtc2EifQ.FvrWXAQC3UrkxmHs35H9dnwTmII-fh0MFMRAlEkf3kuMITqlmivUC0-8NFGXw32l2kBoSZetO_-6ySn6JJz7nMtqFOVF_1ZCdKggc9DOq6Eny8R2vXEfO8T8aXS2W_CFskYOUKmJ2EFESIM9FSayz4pzdeMvEnNmL5tDwoPWTvFIMSJ3ml5M-C4dokZkVHpzDt1-Ta1Ttzbez1EFcdom4nZrQ3Kebwqly2xCxH7awkzWDnGfIkSTUVFDYZI6JpH1DqUUX9zqc0B5oWiWUw6np-eD1lZC2qpTeTSPirQL4hMvt5FRSWtPr2UNAvCTCYxcKIIzccHutsfIRhbzqZX30A

これを、configファイルに登録してあげます。

# kubectl config set-context confined-sa --token 'eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImNvbmZpbmVkLXNhLXRva2VuLWtmc242Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNvbmZpbmVkLXNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZmFlY2Q3YzQtZmZkOS00ZDhmLWEwODAtNTVlZmYwYjRkZmE4Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6Y29uZmluZWQtc2EifQ.FvrWXAQC3UrkxmHs35H9dnwTmII-fh0MFMRAlEkf3kuMITqlmivUC0-8NFGXw32l2kBoSZetO_-6ySn6JJz7nMtqFOVF_1ZCdKggc9DOq6Eny8R2vXEfO8T8aXS2W_CFskYOUKmJ2EFESIM9FSayz4pzdeMvEnNmL5tDwoPWTvFIMSJ3ml5M-C4dokZkVHpzDt1-Ta1Ttzbez1EFcdom4nZrQ3Kebwqly2xCxH7awkzWDnGfIkSTUVFDYZI6JpH1DqUUX9zqc0B5oWiWUw6np-eD1lZC2qpTeTSPirQL4hMvt5FRSWtPr2UNAvCTCYxcKIIzccHutsfIRhbzqZX30A'
Context "confined-sa" created.

ちゃんと作成されたかを確認します。

# kubectl config get-contexts
CURRENT   NAME            CLUSTER         AUTHINFO                               NAMESPACE
*         SampleCluster   SampleCluster   1cb2dc0b-0ae3-4d11-8be6-134366812874   default
          confined-sa

実際にこのcontextを使用します。

# kubectl config use-context confined-sa
Switched to context "confined-sa".

再度、get-contextを打つと*がついて、contextが切り替わったことがわかります。

podを見れるか確認します。

# kubectl get pods
The connection to the server localhost:8080 was refused - did you specify the right host or port?

これは、正しくconfigファイルが設定されていない場合に起こります。

configファイルに変更を加えます。

# vi .kube/config

編集
- context:
    cluster: SampleCluster
    user: confined-sa
  name: confined-sa

以下を追記
- name: confined-sa
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImNvbmZpbmVkLXNhLXRva2VuLWtmc242Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImNvbmZpbmVkLXNhIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiZmFlY2Q3YzQtZmZkOS00ZDhmLWEwODAtNTVlZmYwYjRkZmE4Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50OmRlZmF1bHQ6Y29uZmluZWQtc2EifQ.FvrWXAQC3UrkxmHs35H9dnwTmII-fh0MFMRAlEkf3kuMITqlmivUC0-8NFGXw32l2kBoSZetO_-6ySn6JJz7nMtqFOVF_1ZCdKggc9DOq6Eny8R2vXEfO8T8aXS2W_CFskYOUKmJ2EFESIM9FSayz4pzdeMvEnNmL5tDwoPWTvFIMSJ3ml5M-C4dokZkVHpzDt1-Ta1Ttzbez1EFcdom4nZrQ3Kebwqly2xCxH7awkzWDnGfIkSTUVFDYZI6JpH1DqUUX9zqc0B5oWiWUw6np-eD1lZC2qpTeTSPirQL4hMvt5FRSWtPr2UNAvCTCYxcKIIzccHutsfIRhbzqZX30A

ここでcontextsを確認します。

# kubectl config get-contexts
CURRENT   NAME            CLUSTER         AUTHINFO                               NAMESPACE
          SampleCluster   SampleCluster   1cb2dc0b-0ae3-4d11-8be6-134366812874   default
*         confined-sa     SampleCluster   confined-sa

情報が変わりました。

ここで、再度podの情報を確認していきます。

# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:confined-sa" cannot list resource "pods" in API group "" in the namespace "default"

しっかりブロックされました。

では、先ほど作成したClusterRoleを反映させていきます。

一旦、権限のあるContextに戻ります。

# kubectl config use-context SampleCluster
Switched to context "SampleCluster".

それでは、先ほど作っておいたclusterRoleBindingを適用します。

# kubectl apply -f clusterRoleBinding.yaml
clusterrolebinding.rbac.authorization.k8s.io/confined-rolebinding created

それでは、また先ほどのService AccountのContextに戻ります。

# kubectl config use-context confined-sa
Switched to context "confined-sa".

それでは、podが見れるかを確認します。

# kubectl get pods -n developing
NAME                                 READY   STATUS    RESTARTS   AGE
deploy-automation-54b5dd5779-wxnr4   1/1     Running   0          27h

できました!

ちなみに、podを作ったりはもちろんできません。

# kubectl run nginx --image nginx
kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.
Error from server (Forbidden): deployments.apps is forbidden: User "system:serviceaccount:default:confined-sa" cannot create resource "deployments" in API group "apps" in the namespace "default"

では最後に、全権限を持つユーザを消します。

# vi .kube/config
以下の2つを消す。
- context:
    cluster: SampleCluster
    namespace: default
    user: 1cb2dc0b-0ae3-4d11-8be6-134366812874
  name: SampleCluster

- name: 1cb2dc0b-0ae3-4d11-8be6-134366812874
  user:
    token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6IjFjYjJkYzBiLTBhZTMtNGQxMS04YmU2LTEzNDM2NjgxMjg3NC10b2tlbi04ZjdzbCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiIxY2IyZGMwYi0wYWUzLTRkMTEtOGJlNi0xMzQzNjY4MTI4NzQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI5OTc3NTI0MC1jZTQ0LTRhMjgtODNiYi04OGM2ZTNmMGI1NmMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDoxY2IyZGMwYi0wYWUzLTRkMTEtOGJlNi0xMzQzNjY4MTI4NzQifQ.Xo5MGt4Tk246lJyzoX4ZlFGuJuY8_d0V8STtA49oaUXpghA470n3CxAOjAvH0v5YCVA7iM7U1GZsvyEGXupO46jeRE0py3X3qLqAP02J8jSP5lodRfY5VoyUOgmOqcPcqRiOgYJvJLEafyANL8iRy4fB0MdxWSoczUIJWi8wZGymNbMQ7h9vwrbCRAef9k-TAmFojAFkAyckjEJ6g5mk8Hk8Tgv-SgIfd7iK8dRY6E6flghKMhRHbaq62bC6Pr2OKmHUMdp2GJrenZ04V-BGpmkf69qCiZg-fZ8seA0jO9_ri8Z65K2NjVaTeIO2My1a-7osFxdnajr6gOaWRAw_VQ

それでは、contextもきれいにします。

# kubectl config delete-context SampleCluster
deleted context SampleCluster from /root/.kube/config

# kubectl config get-contexts
CURRENT   NAME          CLUSTER         AUTHINFO      NAMESPACE
*         confined-sa   SampleCluster   confined-sa

これで、このサーバはpodしか見れないようになりました。

終わりに

こんな感じで、これ以外にも誰かにある権限をもったServerを提供することができると思いますので、参考にしていただけたら嬉しいです。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3