訳しながら理解していくKubernetes_Share a Cluster with Namespaces編

# はじめに
Kubernetesのドキュメントって英語だし、英検3級レベルで英語力のない私にはつらい・・・
そして、一回(google翻訳を使って)訳しながら読んでまた忘れてまた(google翻訳を使って)訳すを繰り返すのをやめたい。
調べるときは全文を見ずに、必要な部分だけを見てたりするので、公式ドキュメントを訳しながら全体を理解していこうと思う。

英語読むのめんどくせーーーとなっている人の助けになればと思い公開した

今回は [Share a Cluster with Namespaces](https://kubernetes.io/docs/tasks/administer-cluster/namespaces/)


## 注意事項
* 基本的にGoogle翻訳のまんまです。
* 一応、意味が分かるようには訳してるつもりですが、ちょいちょい意味分からない部分もあります。  
誤訳がある可能性があるので、最後はちゃんと公式ドキュメントを読みましょう
* 私の知りたい部分からやるので、訳す部分はバラバラになります。
* 公式ドキュメントに記載されていない部分(自分で調べた部分とか)は_italic_で記載しています。
* V1.11でのドキュメントを記載

## Share a Cluster with Namespaces
このページでは、名前空間を表示、操作、および削除する方法を示します。このページでは、Kubernetesネームスペースを使用してクラスタを細分する方法も示しています。

## Before you begin

* 既存のKubernetesクラスターを持つ
* Kubernetes [Pods](https://kubernetes.io/docs/concepts/workloads/pods/pod/)、[Services](https://kubernetes.io/docs/concepts/services-networking/service/)、および[Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)について基本的な知識を持っていること

## Viewing namespaces

次のコマンドを使用して、クラスタ内の現在の名前空間を一覧表示します。

```shell
$ kubectl get namespaces
NAME          STATUS    AGE
default       Active    11d
kube-system   Active    11d
```

Kubernetesは2つの初期名前空間から始まります：

* `default` 他の名前空間を持たないオブジェクトのデフォルト名前空間
* `kube-system` Kubernetesシステムによって作成されたオブジェクトの名前空間

特定の名前空間の要約を得るには、次のようにします。

```shell
$ kubectl get namespaces <name>
```

または、次の情報で詳細情報を入手できます。

```shell
$ kubectl describe namespaces <name>
Name:           default
Labels:         <none>
Annotations:    <none>
Status:         Active

No resource quota.

Resource Limits
 Type       Resource    Min Max Default
 ----               --------    --- --- ---
 Container          cpu         -   -   100m
```

これらの詳細は、リソース制限（存在する場合）とリソース制限範囲の両方を示しています。

リソースクォータは、ネームスペース内のリソースの総使用量を追跡し、クラスタオペレータは、ネームスペースが消費するハードリソース使用制限を定義することができます。

制限範囲は、単一のエンティティが名前空間で消費できるリソースの量に対する最小/最大の制約を定義します。

[Admission control: Limit Range](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/resource-management/admission_control_limit_range.md)を確認

名前空間は、次の2つの段階のいずれかになります。

* `Active` 名前空間が使用中
* `Terminating ` 名前空間が削除されているため、新しいオブジェクトには使用できません

詳細については、[設計文書](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/namespaces.md#phases)を参照してください。

## Creating a new namespace
次の内容の`my-namespace.yaml`という新しいYAMLファイルを作成します。

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: <insert-namespace-name-here>
```

次に

```shell
$ kubectl create -f ./my-namespace.yaml
```

名前空間の名前はDNS互換のラベルでなければならないことに注意してください。

オプションのフィールド `finalizers`があり、オブザーバブルが名前空間が削除されるたびにリソースをパージすることができます。存在しないファイナライザを指定すると、名前空間が作成されますが、ユーザが削除しようとすると`Terminating`状態になることに注意してください。

`finalizers`の詳細については、ネームスペースの[設計ドキュメント](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/namespaces.md#finalizers)を参照してください。

## Deleting a namespace

名前空間を削除する

```shell
$ kubectl delete namespaces <insert-some-namespace-name>
```

***警告、これは名前空間の下のすべてを削除します！***

この削除は非同期なので、しばらくの間、名前空間は`Terminating`になります。

## Subdividing your cluster using Kubernetes namespaces
デフォルトの名前空間を理解する

デフォルトでは、Kubernetesクラスタは、クラスタで使用されるデフォルトのPod、Service、およびDeploymentのセットを保持するようにクラスタをプロビジョニングするときに、デフォルトのネームスペースをインスタンス化します。

新しいクラスタがあると仮定すると、次のようにして、使用可能な名前空間を調べることができます。

```shell
$ kubectl get namespaces
NAME      STATUS    AGE
default   Active    13m
```

新しい名前空間を作成する

この演習では、コンテンツを保持するために2つのKubernetes名前空間を追加作成します。

組織が開発および実運用のユースケースに共有Kubernetesクラスタを使用しているシナリオでは、次のようになります。

開発チームは、アプリケーションを構築して実行するために使用するPods、Services、およびDeploymentsのリストを表示できるスペースをクラスタ内に維持したいと考えています。この領域では、Kubernetesのリソースが出入りし、アジャイル開発を可能にするために、リソースを変更できる人または変更できない人の制限が緩和されます。

オペレーションチームは、本番サイトを実行するPods、Services、およびDeploymentsのセットを操作できる人または操作できない人に関する厳格な手順を実行できるスペースをクラスタ内で維持したいと考えています。

この組織が従うパターンの1つは、Kubernetesクラスターをdevelopmentとproductionという2つのネームスペースに分割することです。

私たちの作業を保持するために2つの新しい名前空間を作成しましょう。

開発ネームスペースを記述するファイル`namespace-dev.json`を使用します。

```json:admin/namespace-dev.json
{
  "kind": "Namespace",
  "apiVersion": "v1",
  "metadata": {
    "name": "development",
    "labels": {
      "name": "development"
    }
  }
}
```

kubectlを使用して開発ネームスペースを作成します。

`$ kubectl create -f https://k8s.io/examples/admin/namespace-dev.json`

そして、kubectlを使ってプロダクションネームスペースを作りましょう。

`$ kubectl create -f https://k8s.io/examples/admin/namespace-prod.json`

状況が正しいことを確認するには、クラスタ内のすべてのネームスペースを一覧表示します。

```shell
$ kubectl get namespaces --show-labels
NAME          STATUS    AGE       LABELS
default       Active    32m       <none>
development   Active    29s       name=development
production    Active    23s       name=production
```

各ネームスペースにポッドを作成する
Kubernetesネームスペースは、クラスタ内のPods、Services、およびDeploymentsの範囲(scope)を提供します。
ある名前空間と対話するユーザーは、別の名前空間のコンテンツを参照しません。
これを実証するために、開発ネームスペースで簡単なDeploymentとPodsを作成しましょう。
最初に現在のコンテキストが何かを確認します。

```yaml
$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://130.211.122.180
  name: lithe-cocoa-92103_kubernetes
contexts:
- context:
    cluster: lithe-cocoa-92103_kubernetes
    user: lithe-cocoa-92103_kubernetes
  name: lithe-cocoa-92103_kubernetes
current-context: lithe-cocoa-92103_kubernetes
kind: Config
preferences: {}
users:
- name: lithe-cocoa-92103_kubernetes
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
    token: 65rZW78y8HbwXXtSXuUw9DbP4FLjHi4b
- name: lithe-cocoa-92103_kubernetes-basic-auth
  user:
    password: h5M0FtUUIflBSdI7
    username: admin

$ kubectl config current-context
lithe-cocoa-92103_kubernetes
```

次のステップは、各ネームスペースでkubectlクライアントが動作するためのコンテキストを定義することです。 "cluster"と "user"フィールドの値は、現在のコンテキストからコピーされます。

```shell
$ kubectl config set-context dev --namespace=development --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes
$ kubectl config set-context prod --namespace=production --cluster=lithe-cocoa-92103_kubernetes --user=lithe-cocoa-92103_kubernetes
```

上記のコマンドは、あなたが対処したいネームスペースに応じて交代できる2つの要求コンテキストを提供しています。

開発ネームスペースで操作するように切り替えましょう。

`$ kubectl config use-context dev`

次のようにして、現在のコンテキストを確認できます。

```shell
$ kubectl config current-context
dev
```

この時点で、コマンドラインからKubernetesクラスタに対して行うすべてのリクエストは、開発ネームスペースにスコープされます。 
いくつかのコンテンツを作りましょう。

`$ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2`

レプリカサイズが2のデプロイメントを作成しました。このデプロイメントでは、ホスト名だけを提供する基本的なコンテナでsnowflakeというポッドを実行しています。`kubectl run`は、Kubernetes cluster> = v1.2でのみdeploymentsが作成されます。古いバージョンを実行している場合は、代わりにreplication controllerが作成されます。古い動作を取得する場合は、`--generator=run/v1`を使用してreplication controllersを作成します。詳細については、[kubectl run](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#run)を参照してください。

```shell
$ kubectl get deployment
NAME        DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
snowflake   2         2         2            2           2m

$ kubectl get pods -l run=snowflake
NAME                         READY     STATUS    RESTARTS   AGE
snowflake-3968820950-9dgr8   1/1       Running   0          2m
snowflake-3968820950-vgc4n   1/1       Running   0          2m
```

これは素晴らしいことです。開発者は自分が望むことをすることができ、プロダクションネームスペースのコンテンツに影響を与えることを心配する必要はありません。
本番用のネームスペースに切り替えて、ある名前空間内のリソースが他のネームスペースからどのように隠されているかを示しましょう。

`$ kubectl config use-context prod`

プロダクションネームスペースは空でなければならず、次のコマンドは何も返しません。

```shell
$ kubectl get deployment
$ kubectl get pods
```

本番は牛(cattle)を走らせる好きなので、いくつかの牛(cattle)のpodsを作りましょう。

```shell
$ kubectl run cattle --image=kubernetes/serve_hostname --replicas=5

$ kubectl get deployment
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
cattle    5         5         5            5           10s

kubectl get pods -l run=cattle
NAME                      READY     STATUS    RESTARTS   AGE
cattle-2263376956-41xy6   1/1       Running   0          34s
cattle-2263376956-kw466   1/1       Running   0          34s
cattle-2263376956-n4v97   1/1       Running   0          34s
cattle-2263376956-p5p3i   1/1       Running   0          34s
cattle-2263376956-sxpth   1/1       Running   0          34s
```

この時点で、ユーザーが1つのネームスペースで作成するリソースは、他のネームスペースから隠されていることが明らかです。

Kubernetesにおけるポリシーのサポートが進展するにつれて、このシナリオを拡張して、各ネームスペースに対して異なる認可ルールを提供する方法を示します。

## Understanding the motivation for using namespaces
単一のクラスタは、複数のユーザーまたはユーザーグループ（以後「ユーザーコミュニティ」）のニーズを満たすことができる必要があります。
Kubernetesネームスペースは、さまざまなプロジェクト、チーム、または顧客がKubernetesクラスタを共有するのに役立ちます。
これは、以下を提供することで行います。

1. [Names](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/)のスコープ。
2. 承認およびポリシーをクラスタのサブセクションに付加するメカニズム。

複数のネームスペースの使用はオプションです。
各ユーザーコミュニティは、他のコミュニティとは隔離して作業できるようにしたいと考えています。
各ユーザーコミュニティにはそれぞれ独自のものがあります。

1. リソース（ポッド、サービス、レプリケーションコントローラなど）
2. ポリシー（コミュニティで誰がアクションを実行できる、できない）
3. 制約（このコミュニティにはこのように多くの割り当て(quota)が許可されています）

クラスタオペレータは、一意のユーザコミュニティごとに名前空間を作成することができます。
ネームスペースは、次のような独自のスコープを提供します。

1. 名前付きリソース（基本的な名前付けの衝突を避けるため）
2. 信頼できるユーザーへの委任された管理権限
3. コミュニティのリソース消費を制限する機能

ユースケースには、

1. クラスタオペレータとして、私は単一のクラスタ上で複数のユーザコミュニティをサポートしたいと考えています。
2. クラスターオペレータとして、クラスターのパーティションに権限を委任し、それらのコミュニティ内の信頼できるユーザーに委託したいと考えています。
3. クラスタオペレータとして、クラスタを使用する他のコミュニティへの影響を制限するために、各コミュニティが消費できるリソースの量を制限したいと考えています。
4. クラスタユーザーとして、他のユーザーコミュニティがクラスタ上で行っていることとは別に、自分のユーザーコミュニティに関係するリソースとやりとりしたい。

## Understanding namespaces and DNS
[Service](https://kubernetes.io/docs/concepts/services-networking/service/)を作成すると、対応する[DNSエントリ](https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/)が作成されます。このエントリの形式は`<service-name>.<namespace-name> .svc.cluster.local`です。つまり、コンテナが単に`<service-name>`を使用する場合、ネームスペースのローカルなサービスに解決されます。これは、開発、ステージング、プロダクションなどの複数のネームスペースで同じ構成を使用する場合に便利です。ネームスペースをまたぐ場合は、完全修飾ドメイン名（FQDN）を使用する必要があります。