[OpenShift]projectについて確認する

#はじめに
OpenShiftではまず最初にprojectを作成します。projectはKubernetesだとnamespaceに当たるものだと思っていますが、今回詳しく調べてみました。

#contextの確認
##cluster-admin権限を持つユーザ
まず、cluster-admin権限を持つユーザ（admin）でログインします。

```
$ oc login -u admin -p redhat https://api.ocp4.example.com:6443
The server uses a certificate signed by an unknown authority.
You can bypass the certificate check, but any data you send to the server could be intercepted by others.
Use insecure connections? (y/n): y

Login successful.

You have access to 58 projects, the list has been suppressed. You can list all projects with 'oc projects'

Using project "default".
Welcome! See 'oc help' to get started.
```

contextを確認します。

```
$ kubectl config get-contexts
CURRENT   NAME                                      CLUSTER                     AUTHINFO   NAMESPACE
*         default/api-ocp4-example-com:6443/admin   api-ocp4-example-com:6443   admin      default
```
default namespaceのcontextがCurrentになっています。

##cluster-admin権限を持たないユーザ

次にcluster-admin権限を持たないユーザ（developer）でログインします。

```
$ oc login -u developer -p developer
Login successful.

You don't have any projects. You can try to create a new project, by running

    oc new-project <projectname>
```

contextを確認します。

```
$ kubectl config get-contexts
CURRENT   NAME                                      CLUSTER                     AUTHINFO    NAMESPACE
*         /api-ocp4-example-com:6443/developer      api-ocp4-example-com:6443   developer   
          default/api-ocp4-example-com:6443/admin   api-ocp4-example-com:6443   admin       default
```
developerユーザのcontextが新しく作成されています。


#project/namespaseの確認
##projectの作成
###contextの確認
projectを作成して、contextを確認します。

```
$ oc new-project sample-prj
Now using project "sample-prj" on server "https://api.ocp4.example.com:6443".

You can add applications to this project with the 'new-app' command. For example, try:

    oc new-app ruby~https://github.com/sclorg/ruby-ex.git

to build a new example application in Ruby. Or use kubectl to deploy a simple Kubernetes application:

    kubectl create deployment hello-node --image=gcr.io/hello-minikube-zero-install/hello-node

$ kubectl config get-contexts
CURRENT   NAME                                             CLUSTER                     AUTHINFO    NAMESPACE
          /api-ocp4-example-com:6443/developer             api-ocp4-example-com:6443   developer   
          default/api-ocp4-example-com:6443/admin          api-ocp4-example-com:6443   admin       default
*         sample-prj/api-ocp4-example-com:6443/developer   api-ocp4-example-com:6443   developer   sample-prj
```
新しくdeveloperユーザ/sample-prj namespaceのcontextが作成されて、Currentになっています。

###projectとnamespaceの比較
作成したsample-prjの設定をprojectとnamespaceで比較します。yaml形式でファイルにリダイレクトして、diffを取ってみます。

```
$ oc get project sample-prj -o yaml >project.yaml
$ oc get ns sample-prj -o yaml >ns.yaml
$ diff project.yaml ns.yaml 
1,2c1,2
< apiVersion: project.openshift.io/v1
< kind: Project
---
> apiVersion: v1
> kind: Namespace
48c48
<   selfLink: /apis/project.openshift.io/v1/projects/sample-prj
---
>   selfLink: /api/v1/namespaces/sample-prj
```

違いは以下の3つですね。

- apiVersion
- kind
- selfLink

apiVerisonとkindは違ってて当たり前かなと思います。
selfLinkはKubernetesのAPIリファレンスには以下のように書かれています。

> selfLink is a URL representing this object. Populated by the system. Read-only.

なので、オブジェクトとしては別物だけど、機能的には同じということになりますね。

projectとnamaspaceのyamlファイルはそれぞれ以下になります。

```project.yaml 
apiVersion: project.openshift.io/v1
kind: Project
metadata:
  annotations:
    openshift.io/description: ""
    openshift.io/display-name: ""
    openshift.io/requester: developer
    openshift.io/sa.scc.mcs: s0:c24,c19
    openshift.io/sa.scc.supplemental-groups: 1000590000/10000
    openshift.io/sa.scc.uid-range: 1000590000/10000
  creationTimestamp: "2020-11-19T13:17:32Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:openshift.io/sa.scc.mcs: {}
          f:openshift.io/sa.scc.supplemental-groups: {}
          f:openshift.io/sa.scc.uid-range: {}
    manager: cluster-policy-controller
    operation: Update
    time: "2020-11-19T13:17:32Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/description: {}
          f:openshift.io/display-name: {}
          f:openshift.io/requester: {}
      f:status:
        f:phase: {}
    manager: openshift-apiserver
    operation: Update
    time: "2020-11-19T13:17:32Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:finalizers: {}
    manager: openshift-controller-manager
    operation: Update
    time: "2020-11-19T13:17:32Z"
  name: sample-prj
  resourceVersion: "43190"
  selfLink: /apis/project.openshift.io/v1/projects/sample-prj
  uid: 7c2c46f0-68d3-4f94-816a-198d4cbae2c0
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
```
``` ns.yaml 
apiVersion: v1
kind: Namespace
metadata:
  annotations:
    openshift.io/description: ""
    openshift.io/display-name: ""
    openshift.io/requester: developer
    openshift.io/sa.scc.mcs: s0:c24,c19
    openshift.io/sa.scc.supplemental-groups: 1000590000/10000
    openshift.io/sa.scc.uid-range: 1000590000/10000
  creationTimestamp: "2020-11-19T13:17:32Z"
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:openshift.io/sa.scc.mcs: {}
          f:openshift.io/sa.scc.supplemental-groups: {}
          f:openshift.io/sa.scc.uid-range: {}
    manager: cluster-policy-controller
    operation: Update
    time: "2020-11-19T13:17:32Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:openshift.io/description: {}
          f:openshift.io/display-name: {}
          f:openshift.io/requester: {}
      f:status:
        f:phase: {}
    manager: openshift-apiserver
    operation: Update
    time: "2020-11-19T13:17:32Z"
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        f:finalizers: {}
    manager: openshift-controller-manager
    operation: Update
    time: "2020-11-19T13:17:32Z"
  name: sample-prj
  resourceVersion: "43190"
  selfLink: /api/v1/namespaces/sample-prj
  uid: 7c2c46f0-68d3-4f94-816a-198d4cbae2c0
spec:
  finalizers:
  - kubernetes
status:
  phase: Active
```

##projectの削除

projectを削除して、project/namespace/contextの状態を確認します。

```
$ oc delete project sample-prj 
project.project.openshift.io "sample-prj" deleted
$ oc get project sample-prj
Error from server (Forbidden): projects.project.openshift.io "sample-prj" is forbidden: User "developer" cannot get resource "projects" in API group "project.openshift.io" in the namespace "sample-prj"
$ oc get ns sample-prj
Error from server (Forbidden): namespaces "sample-prj" is forbidden: User "developer" cannot get resource "namespaces" in API group "" in the namespace "sample-prj"
```
projectを削除すると、namespaceも削除されています。

```
$ kubectl config get-contexts
CURRENT   NAME                                             CLUSTER                     AUTHINFO    NAMESPACE
          /api-ocp4-example-com:6443/developer             api-ocp4-example-com:6443   developer   
          default/api-ocp4-example-com:6443/admin          api-ocp4-example-com:6443   admin       default
*         sample-prj/api-ocp4-example-com:6443/developer   api-ocp4-example-com:6443   developer   sample-prj
```

contextは残ってますね。

logoutしてから、再度確認してみます。

```
$ oc logout 
Logged "developer" out on "https://api.ocp4.example.com:6443"
$ kubectl config get-contexts
CURRENT   NAME                                             CLUSTER                     AUTHINFO    NAMESPACE
          /api-ocp4-example-com:6443/developer             api-ocp4-example-com:6443   developer   
          default/api-ocp4-example-com:6443/admin          api-ocp4-example-com:6443   admin       default
*         sample-prj/api-ocp4-example-com:6443/developer   api-ocp4-example-com:6443   developer   sample-prj
```

logoutしてもcontextは残ってますね。projectを削除しただけでは、contextは削除してくれないようです。
contextを削除するには、`kubectl config delete-context`コマンドで削除しないといけないようです。contextも一緒に削除した方がいいように思えますが、きっと何か理由があるんでしょうね。

#まとめ
以下のことが確認できました。

- projectを作成すると、namespaceとcontextが作成される。
- projectを削除すると、namespaceは削除されるが、contextは削除されない。contextを削除する場合は、`kubectl config delete-context`コマンドで削除する。

※ `kubectl config`コマンドでcontextの確認操作をしていましたが、`oc config`コマンドでも同じことができました。まだocコマンドに慣れてないです。