Kubernetes基礎(4)：Pod-Container, Label, Node Schedule

#1. Containerの特徴
![kubernetes_pod1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/23b7deb6-036b-4705-cb2f-c3c0498c8667.jpeg)
Podの中で、1つの独立したサービスとして駆動することができます。
単一のContainerはPortを1つ以上持つことはできますが、1つのPod内でContainer同士Portが重複してはなりません。

図のようにContainer1からContaner2(localhost：8080)へのアクセスは可能だが、Container2(localhost:8000)へのアクセスは出来ません。アクセスができないのではなくそもそも8000 Portを持っているContainerが既にPodの中に存在しているので作成すらできません。

Podが生成がされた時に固有IPアドレスが割り当てられるがこのIPアドレスはKubernetes Cluster内でのみアクセスできるIPアドレスであって、外部からはこのIPアドレスにアクセスすることができません。
Podに問題が発生した場合、システムがPodの削除及び再生成をしますがPodが再生成されると既存のIPアドレスが変わるので外部からの連携では使えません。

<b>Yaml：Pod Create</b>

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-1
spec:
  containers:
  - name: container1
    image: <image file name>
    ports:
    - containerPort: 8000
  - name: container2
    image: <image file name>
    ports:
    - containerPort: 8080
```
#2. Labelの属性
![kubernetes_label.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/f1ecea2b-8839-e637-fcb8-14463dfdcb48.jpeg)
LabelはPodだけでなく、全てのObjectに付与することができます。
Podで最も多く使われています。
Labelを使う理由は、目的に応じてObjectを分類し、分類されたObjectだけ繋げることができるからです。
Labelの構成はkey：valueになります。
1つのPodに複数のLabelを付与することができます。

上の図では、type：webのPodがdev環境、prod環境で2つありますが、type：db、serverも同じく2つあります。
このように定義されたLabelをServiceを生成するYamlファイルに指定することでPodとServiceの連携ができます。
使用目的に応じてLabelをよく設定して置くと使いたいPodの組み合わせなどが簡単にできます。

<b>2-1 Pod</b>

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-2
  labels:
    type: web
    lo: dev
spec:
  containers:
  - name: container
    image: <image file name>
```
<b>2-2 Service</b>

```Yaml
apiVersion: v1
kind: Service
metadata:
  name: svc-1
spec:
  selector:
    type: web
  ports:
  - port: 8080
```

#3. Node Scheduler
![kubernetes_node scheduler.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519254/33aeb4fc-db49-38bb-ff75-253d59fb4c27.jpeg)
Podは複数のNodeの中で必ず1つのNodeに属する。
Pod生成時、Nodeを選択する手動選択方法と、Kubernetes schedulerが自動に選択する自動選択方法があります。

<b>直接選択</b>
[3-1]のようにNodeにLabelを付与して、Podを生成するYamlファイルで「nodeSelector」属性にNodeに付与したLabelを設定します。

<b>3-1 Pod</b>

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-3
spec:
  nodeSelector:
    kubernetes.io/hostname: k8s-node1
  containers:
  - name: container
    image: <image file name>
```
<b>自動選択</b>
Nodeは利用可能なResource(Memory, CPU)とResourceのSizeを設定できます。
Node1は2つのPodがあって、Memoryが1Gが残っています。
Node2はPodがなく、3.7GのMemoryがあります。
Podを生成するときにPodで使うResourceとResourceのsizeを設定することができますが、[3-2]のPodは3GのMemoryを必要としているので
Kubernetes Schedulerが自動にNode2に属するよう設定をします。

ResourceのSizeを設定する大きな理由は、Pod内のApplicationで負荷が発生したとき、設定がないと無限にNodeのResourceを使用しようとするため、Node内の他のPodはresourceがなくPending状態になってしまいます。

<b>3-2 Pod</b>

```Yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-4
spec:
  containers:
  - name: container
    image: <image file name>
    resources:
      requests:
        memory: 2Gi
      limits:
        memory: 3Gi
```

<b>Yaml：request & limits</b>
Memoryはlimitを超えてしまうとすぐにPodを終了させます。
Cpuの場合は、limitを超えてもRequest数値まで下げるけどPodを終了させません。
このようにMemoryとCpuが異なる動作する理由は、各Resourceの特徴があるからです。

#Referenece
* Kubernetes Pod Overview : https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/
* Labels and Selectors : https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
* Assigning Pods to Nodes : https://kubernetes.io/docs/concepts/configuration/assign-pod-node/