[OpenShift]Security Context Constraintsの設定方法を確認する

#はじめに
今回はOpenShiftでのSecurity Context Constraints（SCC）の設定方法を確認します。

[第13章 SCC (SECURITY CONTEXT CONSTRAINTS) の管理](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.5/html/authentication_and_authorization/managing-pod-security-policies)

OpenShiftでは以下8つのSCCがデフォルトで定義されています。自分で個別に設定することもできます。

```
$ oc get scc
NAME               PRIV    CAPS         SELINUX     RUNASUSER          FSGROUP     SUPGROUP    PRIORITY     READONLYROOTFS   VOLUMES
anyuid             false   <no value>   MustRunAs   RunAsAny           RunAsAny    RunAsAny    10           false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
hostaccess         false   <no value>   MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            [configMap downwardAPI emptyDir hostPath persistentVolumeClaim projected secret]
hostmount-anyuid   false   <no value>   MustRunAs   RunAsAny           RunAsAny    RunAsAny    <no value>   false            [configMap downwardAPI emptyDir hostPath nfs persistentVolumeClaim projected secret]
hostnetwork        false   <no value>   MustRunAs   MustRunAsRange     MustRunAs   MustRunAs   <no value>   false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
node-exporter      true    <no value>   RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            [*]
nonroot            false   <no value>   MustRunAs   MustRunAsNonRoot   RunAsAny    RunAsAny    <no value>   false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
privileged         true    [*]          RunAsAny    RunAsAny           RunAsAny    RunAsAny    <no value>   false            [*]
restricted         false   <no value>   MustRunAs   MustRunAsRange     MustRunAs   RunAsAny    <no value>   false            [configMap downwardAPI emptyDir persistentVolumeClaim projected secret]
```

#環境の確認
今回使用したOpenShiftクラスタの構成です。

```
$ oc get node
NAME       STATUS   ROLES           AGE    VERSION
master01   Ready    master,worker   170d   v1.18.3+012b3ec
master02   Ready    master,worker   170d   v1.18.3+012b3ec
master03   Ready    master,worker   170d   v1.18.3+012b3ec
$ oc version
Client Version: 4.5.4
Server Version: 4.5.4
Kubernetes Version: v1.18.3+012b3ec
```

#アプリケーションのデプロイ
テスト用のアプリケーションとしてGitlabをデプロイします。

```
$ oc new-app --name gitlab --docker-image docker.io/gitlab/gitlab-ce:8.4.3-ce.0
--> Found container image a26371b (4 years old) from docker.io for "docker.io/gitlab/gitlab-ce:8.4.3-ce.0"

    * An image stream tag will be created as "gitlab:8.4.3-ce.0" that will track this image

--> Creating resources ...
    imagestream.image.openshift.io "gitlab" created
    deployment.apps "gitlab" created
    service "gitlab" created
--> Success
    Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
     'oc expose svc/gitlab' 
    Run 'oc status' to view your app.
```

##確認
しばらく待って確認すると、エラーになっています。

```
$ oc get pod
NAME                      READY   STATUS   RESTARTS   AGE
gitlab-6fbb9974cb-cvs98   0/1     Error    1          27s
```

ログを確認します。

```
$ oc logs gitlab-6fbb9974cb-cvs98 
Thank you for using GitLab Docker Image!
Current version: gitlab-ce=8.4.3-ce.0

Configure GitLab for your system by editing /etc/gitlab/gitlab.rb file
And restart this container to reload settings.
To do it use docker exec:

  docker exec -it gitlab vim /etc/gitlab/gitlab.rb
  docker restart gitlab

For a comprehensive list of configuration options please see the Omnibus GitLab readme
https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md

If this container fails to start due to permission problems try to fix it by executing:

  docker exec -it gitlab update-permissions
  docker restart gitlab

・・・省略・・・

================================================================================
Recipe Compile Error in /opt/gitlab/embedded/cookbooks/cache/cookbooks/gitlab/recipes/default.rb
================================================================================

Chef::Exceptions::InsufficientPermissions
-----------------------------------------
directory[/etc/gitlab] (gitlab::default line 26) had an error: Chef::Exceptions::InsufficientPermissions: Cannot create directory[/etc/gitlab] at /etc/gitlab due to insufficient permissions

Cookbook Trace:
---------------
  /opt/gitlab/embedded/cookbooks/cache/cookbooks/gitlab/recipes/default.rb:31:in `from_file'

Relevant File Content:
----------------------
/opt/gitlab/embedded/cookbooks/cache/cookbooks/gitlab/recipes/default.rb:

 24:  ENV['PATH'] = "#{install_dir}/bin:#{install_dir}/embedded/bin:#{ENV['PATH']}"
 25:  
 26:  directory "/etc/gitlab" do
 27:    owner "root"
 28:    group "root"
 29:    mode "0775"
 30:    action :nothing
 31>> end.run_action(:create)
 32:  
 33:  Gitlab[:node] = node
 34:  if File.exists?("/assets/gitlab.rb")
 35:    Gitlab.from_file("/assets/gitlab.rb")
 36:  end
 37:  node.consume_attributes(Gitlab.generate_config(node['fqdn']))
 38:  
 39:  if File.exists?("/var/opt/gitlab/bootstrapped")
 40:  	node.set['gitlab']['bootstrap']['enable'] = false

[2021-01-23T13:32:28+00:00] ERROR: Running exception handlers
[2021-01-23T13:32:28+00:00] ERROR: Exception handlers complete
[2021-01-23T13:32:28+00:00] FATAL: Stacktrace dumped to /opt/gitlab/embedded/cookbooks/cache/chef-stacktrace.out
[2021-01-23T13:32:28+00:00] ERROR: directory[/etc/gitlab] (gitlab::default line 26) had an error: Chef::Exceptions::InsufficientPermissions: Cannot create directory[/etc/gitlab] at /etc/gitlab due to insufficient permissions
[2021-01-23T13:32:29+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
```

権限不足（insufficient permissions）でエラーになっています。
このアプリケーションを起動するには、root権限が必要なのでエラーになっています。

Kubernetesだとデフォルトでroot権限でPodがデプロイされるのですが、OpenShiftはデフォルトではroot権限でデプロイされません。（だったと思います）

#SCCの設定
##設定するSCCの確認

どのSCCを使用すれば、パーミッションのエラーを解消できるか確認します。

```
$ oc get pod gitlab-6fbb9974cb-cvs98 -o yaml | oc adm policy scc-subject-review -f -
RESOURCE                      ALLOWED BY   
Pod/gitlab-6fbb9974cb-cvs98   anyuid
```
"anyuid"を設定すれば、解消できることがわかります。

##SCCの設定

Serviceaccountを作成し、そのServiceaccountにanyuidを割り当てます。

```
$ oc create sa gitlab-sa
serviceaccount/gitlab-sa created
$ oc adm policy add-scc-to-user anyuid -z gitlab-sa
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:anyuid added: "gitlab-sa"
```

Serviceaccountをdeploymentに割り当てます。

```
$ oc set sa deployment/gitlab gitlab-sa
deployment.apps/gitlab serviceaccount updated
```

しばらくすると、Podが再デプロイされています。

```
$ oc get pod
NAME                      READY   STATUS        RESTARTS   AGE
gitlab-57d6c798cd-hfmf4   1/1     Running       0          9s
gitlab-6fbb9974cb-cvs98   0/1     Terminating   6          8m43s
```