| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

「Kubernetes」の版間の差分

提供: MyMemoWiki
ナビゲーションに移動 検索に移動
 
(同じ利用者による、間の117版が非表示)
1行目: 1行目:
==[[Kubernetes]]==
+
| [[Docker]] |  [[Docker コマンド]] | [[Docker ネットワーク]] | [[WSL]] | [[MicroK8s]] | [[Multipass]] |
| [[Docker]] |  
+
==[https://kubernetes.io/ja/ Kubernetes]==
 
 
 
{{amazon|4873118409}}
 
{{amazon|4873118409}}
 
{{amazon|B07HFS7TDT}}
 
{{amazon|B07HFS7TDT}}
 
+
*https://kubernetes.io/ja/
 
*コンテナ化されたアプリケーションのデプロイ、スケーリングなどの管理を自動化するプラットフォーム(コンテナオーケストレーションエンジン)
 
*コンテナ化されたアプリケーションのデプロイ、スケーリングなどの管理を自動化するプラットフォーム(コンテナオーケストレーションエンジン)
 
*https://knowledge.sakura.ad.jp/20955/
 
*https://knowledge.sakura.ad.jp/20955/
12行目: 11行目:
 
**Microsoft:Azure Container Ser[[vi]]ce
 
**Microsoft:Azure Container Ser[[vi]]ce
 
**Google:Google [[Kubernetes]] Engine
 
**Google:Google [[Kubernetes]] Engine
 +
===[https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/ チートシート]===
 +
*[https://kubernetes.io/ja/docs/reference/kubectl/cheatsheet/ チートシート]
 +
===コンポーネント構成===
 +
*https://kubernetes.io/docs/concepts/overview/components/
 +
*https://www.slideshare.net/yokawasa/istio-114360124 から引用
 +
[[File:kubernetes_component.png|600px]]
  
 
===宣言的なコードによる管理===
 
===宣言的なコードによる管理===
41行目: 46行目:
 
*kubectlは、マニフェストファイルの情報を元にKubernetes MasterのAPIにリクエストを送り、Kubernetesの操作を行う
 
*kubectlは、マニフェストファイルの情報を元にKubernetes MasterのAPIにリクエストを送り、Kubernetesの操作を行う
 
*Kubernetes の API は一般的な RESTful API として実装されている
 
*Kubernetes の API は一般的な RESTful API として実装されている
===Kubernetes とリソース===
+
 
 +
==構成==
 +
===クラスタ===
 +
*Kubernetesクラスターは以下の2種類のリソースで構成
 +
**マスターがクラスターを管理する、マスターはクラスターの管理を担当
 +
**ノードがアプリケーションを動かすワーカーとなる、ノードは、Kubernetesクラスターのワーカーマシンとして機能するVMまたは物理マシン
 +
====Kubelet====
 +
*各ノードにはKubeletがあり、これはノードを管理し、Kubernetesマスターと通信するためのエージェント
 +
 
 +
====デプロイ====
 +
Kubernetesにアプリケーションをデプロイするときは、
 +
#マスターにアプリケーションコンテナを起動するように指示
 +
#マスターはコンテナがクラスターのノードで実行されるようにスケジュール
 +
#ノードは、マスターが公開しているKubernetes APIを使用してマスターと通信
 +
##エンドユーザーは、Kubernetes APIを直接使用して対話することもできます
 +
 
 +
 
 +
 
 +
 
 +
====Kubernetes とリソース====
 
*Kubernetesでは、リソースを登録することで、コンテナの実行やロードバランサの作成が非同期に行われる
 
*Kubernetesでは、リソースを登録することで、コンテナの実行やロードバランサの作成が非同期に行われる
====Workloadsリソース====
+
 
 +
==Workloadsリソース==
 
*クラスタ上にコンテナを起動するために利用する
 
*クラスタ上にコンテナを起動するために利用する
 
*内部的に利用されているものをのぞき、直接操作するものとしては、以下のリソースがある
 
*内部的に利用されているものをのぞき、直接操作するものとしては、以下のリソースがある
54行目: 79行目:
 
**Job
 
**Job
 
**CronJob
 
**CronJob
 +
===Pod===
 +
*Workloadsリソースの最小単位
 +
*一つ以上のコンテナから構成され、ネットワーク的に隔離されておらず、IPアドレスを共有する
 +
*2つのコンテナが入ったPodを作成した場合、同一IPアドレスを持ち、お互い、localhostで通信できる
 +
*多くの場合は、1つのPodに1つのコンテナを含めるが、補助するサブコンテナを複数含めることもある
  
====Discovery & LBリソース====
+
==Discovery & LBリソース==
 
*コンテナサービスディスカバリやクラスタの外部からもアクセス可能なエンドポイントなどを提供する
 
*コンテナサービスディスカバリやクラスタの外部からもアクセス可能なエンドポイントなどを提供する
 
*利用者が直接利用するものとしては、Service と Ingress があり、Serviceは複数タイプが用意されている
 
*利用者が直接利用するものとしては、Service と Ingress があり、Serviceは複数タイプが用意されている
 
*Service
 
*Service
**ClusterIP
+
{| class="wikitable"
**ExternalIP (ClusterIPの一種)
+
|-
**NodePort
+
! scope="col"| Service
**LoadBalancer
+
! 内容
**Headless (None)
+
|-
**ExternalName
+
| ClusterIP
**None-Selector
+
|
 +
|-
 +
| ExternalIP (ClusterIPの一種)
 +
|
 +
|-
 +
| NodePort
 +
|
 +
|-
 +
| LoadBalancer
 +
|
 +
|-
 +
| Headless (None)
 +
|
 +
|-
 +
| ExternalName
 +
|
 +
|-
 +
| None-Selector
 +
|
 +
|-
 +
|}
 
*Ingress
 
*Ingress
 +
===KubernetesクラスタのネットワークとService===
 +
====Kubernetesが構成するネットワーク====
 +
*Pod内には複数のコンテナを内包できるが、同じPodであれば、同一IPが割り振られている
 +
*同一Podコンテナへ通信を行う場合は、localhostあてに通信を行い、Podのコンテナから別Podコンテナへ通信を行う場合には、PodのIPアドレス宛に通信を行う
 +
*Kubernetesクラスタは、クラスタを構成するとノードにPodのための内部ネットワークを自動的に構成する
 +
*基本的にはノードごとに異なるネットワークセグメントを互いに通信できるよう構成する
 +
*このような内部ネットワークが自動構成されるため、PodはServiceを利用しなくてもPod間通信を行うことが可能
 +
====Serviceを利用することによるメリット====
 +
*Podあてトラフィックのロードバランシング
 +
*サービスディスカバリとクラスタ内DNS
 +
*これらは、上記のどのService Typeからも利用できる
 +
====Pod宛トラフィックのロードバランシング====
 +
*Serviceは、複数のPodにロードバランシングを行う
 +
*Serviceを利用すると、各PodのIPを毎回調べたり、宛先を設定するなど独自に実現しなくても、自動的に構成することができる
 +
*Serviceは、ロードバランシングのエンドポイントも提供する
 +
**外部ロードバランサーが払い出す仮想IP(Virtual IPアドレス)、クラスタ内のみで利用可能な仮想IPアドレス(ClusterIP)など
  
====Config & Storage リソース====
+
==Config & Storage リソース==
 
*設定や機密データをコンテナに埋め込んだり、永続ボリュームを提供する
 
*設定や機密データをコンテナに埋め込んだり、永続ボリュームを提供する
 
*Secret と ConfigMap は Key-Value のデータ構造を持ち保存データが機密か一般化によって使い分ける
 
*Secret と ConfigMap は Key-Value のデータ構造を持ち保存データが機密か一般化によって使い分ける
75行目: 141行目:
 
*PersistentVolumeClaim
 
*PersistentVolumeClaim
  
====Cluster リソース====
+
==Cluster リソース==
 
*クラスタ自体の振る舞いを定義
 
*クラスタ自体の振る舞いを定義
 
*Node
 
*Node
88行目: 154行目:
 
*NetworkPolicy
 
*NetworkPolicy
  
====Metadataリソース====
+
==Metadataリソース==
 
*クラスタ内の他のリソースの動作を制御する
 
*クラスタ内の他のリソースの動作を制御する
 
*LimitRange
 
*LimitRange
94行目: 160行目:
 
*PodDisruptionBudget
 
*PodDisruptionBudget
 
*CustomResourceDefinition
 
*CustomResourceDefinition
==[[Kubernetes]]クライアント==
+
==[[Minikube]]==
*公式なクライアントは、kubectl
+
*[[Minikube]]
*kubectlを使用してクラスターと対話できるようになります
+
 
*[[Kubernetes]] APIと連携するコマンドラインツール
+
==[[MicroK8s]]==
*minikube から利用する場合
+
*[[MicroK8s]]
> minikube kubectl version
+
==[[Kubectl]]==
===kubectlコマンド===
+
*[[Kubectl]]
*Kubernetesでは、クラスタの操作は全て、Kubernetes Masterの APIを介して行われる
+
 
*手動で操作する場合には、CLIツールの kubectl を利用するのが一般的
+
==[https://kubernetes.io/ja/docs/concepts/overview/working-with-objects/namespaces/ Namespace]==
*Kubectl が Kubernetes Master と通信するには、接続先サーバー情報や認証情報が必要となる
+
*Kubernetesは、同一の物理クラスター上で複数の仮想クラスターの動作をサポートします。 この仮想クラスターをNamespaceと呼びます
*デフォルトでは、~/.kube/config に書かれている情報を使用して接続を行う
+
*作成:kubectl create namespace <名称>
===kubectlインストール===
+
*削除:kubectl delete namespace <名称>
 
<pre>
 
<pre>
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl
+
$ kubectl create namespace sample
$ sudo chmod +x ./kubectl
+
namespace/sample created
$ sudo install kubectl /usr/local/bin
+
$ kubectl get namespaces
 +
NAME              STATUS  AGE
 +
kube-system      Active  66d
 +
kube-public      Active  66d
 +
kube-node-lease  Active  66d
 +
default          Active  66d
 +
sample            Active  4s
 
</pre>
 
</pre>
 +
 +
==[https://kubernetes.io/ja/docs/concepts/workloads/pods/ Pod]==
 +
*https://kubernetes.io/ja/docs/concepts/workloads/pods/
 +
*同じ実行環境上で動くアプリケーションコンテナとストレージボリュームの集まりのこと
 +
*Kubernetesクラスタ上では、コンテナではなくPodがデプロイの最小単位
 +
*1つのPodないのコンテナは全て同じマシン上に配置される
 +
*同じPod内のアプリケーションは、ネイティブなプロセス間通信チャネルで通信できるが、異なるPodのアプリケーションからは分離されている
 +
===Pod単位で考える===
 +
*WordPressとMySQLを同じPodに入れれば良いと考えるのはアンチパターンの1つ
 +
*それぞれ別マシンで通信できればよく、WordPressとDBが同じ単位としてスケールする可能性も低い
 +
*WordPress自体はステートレスなため、負荷が増大した場合、WordPressのPodを増やしてスケールさせれば良い
 +
*通常は、Podを作る際に、コンテナが異なるマシンに配置されても正常に動作するかという点が判断基準
 +
 
===設定===
 
===設定===
 
*設定を行う箇所は、clusters,contexts,users
 
*設定を行う箇所は、clusters,contexts,users
152行目: 237行目:
 
*apply コマンドを利用すると、存在しなければ生成、更新があれば更新、変更なければ何もしないという挙動
 
*apply コマンドを利用すると、存在しなければ生成、更新があれば更新、変更なければ何もしないという挙動
 
<pre>
 
<pre>
$ kubectl create -f sample-pod.yaml  --save-config
+
$ kubectl create -f sample-pod.yaml   
 
pod/sample-pod created
 
pod/sample-pod created
 
</pre>
 
</pre>
158行目: 243行目:
 
<pre>
 
<pre>
 
$ kubectl get pod
 
$ kubectl get pod
NAME                             READY  STATUS             RESTARTS  AGE
+
NAME         READY  STATUS   RESTARTS  AGE
hello-minikube-64b64df8c9-jzm5v   1/1    Running           6          7d19h
+
sample-pod   1/1    Running  0          42s
sample-pod                        0/1    ImagePullBackOff   0          2m17s
 
 
</pre>
 
</pre>
*nginx のバージョンを 1.12 -> 1.19に変更して更新
+
 
 
<pre>
 
<pre>
 
$ kubectl apply -f sample-pod.yaml  
 
$ kubectl apply -f sample-pod.yaml  
 
pod/sample-pod configured
 
pod/sample-pod configured
 
</pre>
 
</pre>
 +
 
===アノテーションとラベル===
 
===アノテーションとラベル===
 
*各リソースに対してアノテーションとラベルというメタデータを付与することができる
 
*各リソースに対してアノテーションとラベルというメタデータを付与することができる
208行目: 293行目:
 
</pre>
 
</pre>
  
==minikube==
+
*表示の拡張
*https://github.com/kubernetes/minikube
+
<pre>
*ローカル開発や学習、テスト用のシンプルな[[Kubernetes]]シュミレータ
+
$ kubectl get pod --output wide
*シングルノードクラスタで、インストールには、ローカルマシンにハイパーバイザーがインストールされていること
+
NAME        READY  STATUS    RESTARTS  AGE  IP          NODE      NOMINATED NODE  READINESS GATES
*VT-x/AMD-v [[仮想化]]がBIOSで有効化されていること。
+
sample-pod  1/1    Running  2          24h  172.17.0.minikube   <none>          <none>
*[https://kubernetes.io/ja/docs/setup/learning-environment/minikube/ Minikubeを使用してローカル環境でKubernetesを動かす]
+
</pre>
===インストール===
+
*ダッシュボードに表示された
*https://kubernetes.io/docs/tasks/tools/install-minikube/
+
[[File:Kubernetes_label.png|600px]]
  
====Ubuntu + 仮想環境====
+
====Podの削除====
*[https://www.typea.info/blog/index.php/2020/08/22/ubuntu-kvm-bridge-network/ Ubuntu 仮想環境(KVM)構築]
+
<pre>
 +
$ kubectl delete -f sample-pod.yaml
 +
pod "sample-pod" deleted
 +
</pre>
 +
===2つのコンテナを内包したPod===
 +
*マニフェスト sample-2pod.yaml
 +
<pre>
 +
apiVersion: v1
 +
kind: Pod
 +
metadata:
 +
  name: sample-2pod
 +
spec:
 +
  containers:
 +
    - name: nginx-container
 +
      image: nginx:1.19
 +
    - name: radis-container
 +
      image: redis:6.0.7
 +
</pre>
 +
*適用
 +
<pre>
 +
$ kubectl apply -f sample-2pod.yaml
 +
pod/sample-2pod created
 +
</pre>
 +
*結果確認
 +
<pre>
 +
$ kubectl get pod --output wide
 +
NAME          READY  STATUS    RESTARTS  AGE    IP          NODE      NOMINATED NODE  READINESS GATES
 +
sample-2pod  2/2    Running  0          7m40s  172.17.0.6  minikube  <none>          <none>
 +
sample-pod    1/1    Running  2          2d      172.17.0.3  minikube  <none>          <none>
 +
</pre>
  
====入手====
+
===コンテナへのログインとコマンド実行===
 +
*-t 疑似端末(TTY)を生成し、-i 標準入力をコンテナに渡す
 +
* /bin/bashコマンドを実行する
 
<pre>
 
<pre>
$ curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
+
$ kubectl exec sample-pod -i -t -- /bin/bash
$ sudo +x minkube
+
root@sample-pod:/#
 
</pre>
 
</pre>
  
====インストール====
+
==[https://kubernetes.io/ja/docs/concepts/workloads/controllers/replicaset/ ReplicaSet]==
 +
*https://kubernetes.io/ja/docs/concepts/workloads/controllers/replicaset/
 +
*Podのレプリカを作成するリソース
 +
*レプリカ数=3でスケールさせたReplicaSet
 
<pre>
 
<pre>
$ sudo install minikube /usr/local/bin
+
apiVersion: apps/v1
 +
kind: ReplicaSet
 +
metadata:
 +
  name: sample-rs
 +
spec:
 +
  replicas: 3
 +
  selector:
 +
    matchLabels:
 +
      app: sample-app
 +
  template:
 +
    metadata:
 +
      labels:
 +
        app: sample-app
 +
    spec:
 +
      containers:
 +
        - name: nginx-container
 +
          image: nginx:1.19
 +
          ports:   
 +
          - containerPort: 80
 
</pre>
 
</pre>
 +
*作成
 +
<pre>
 +
$ kubectl apply -f sample-rs.yaml
 +
replicaset.apps/sample-rs created
 +
</pre>
 +
*確認
 +
**Podが3つ起動していることが確認できる
 +
<pre>
 +
$ kubectl get pods --output wide
 +
NAME              READY  STATUS    RESTARTS  AGE    IP          NODE      NOMINATED NODE  READINESS GATES
 +
sample-2pod      2/2    Running  0          26h    172.17.0.6  minikube  <none>          <none>
 +
sample-pod        1/1    Running  2          3d2h    172.17.0.3  minikube  <none>          <none>
 +
sample-rs-9gxzs  1/1    Running  0          3m14s  172.17.0.7  minikube  <none>          <none>
 +
sample-rs-nsn86  1/1    Running  0          3m14s  172.17.0.9  minikube  <none>          <none>
 +
sample-rs-wcjsv  1/1    Running  0          3m14s  172.17.0.8  minikube  <none>          <none>
 +
</pre>
 +
*ダッシュボードで確認
 +
[[File:kubernetes_replicaset.png|600px]]
  
===利用===
+
==[https://kubernetes.io/ja/docs/concepts/workloads/controllers/deployment/ Deployment]==
====ローカルクラスタの作成====
+
*https://kubernetes.io/ja/docs/concepts/workloads/controllers/deployment/
*ローカル仮想マシンを作成
+
*複数のReplicaSetを管理することで、ローリングアップデートやロールバックを実現するリソース
*[[Kubernetes]]を設定
+
*Kubernetesで最も推奨されるコンテナの起動方法
*kubectlを設定
+
*1つのコンテナでもDeploymentを使用すべき
&gt; minikube start
+
*Deploymentは新しいバージョンのリリースを管理する仕組み
*VirtualBox
+
*デプロイされたアプリケーションをバージョンをまたいで表現する
[[File:0753_minikube.png|400px]]
+
**Pod単体では自動で再起動されないし、ReplicaSetでは、ローリングアップデートが利用できない
*Ubuntu+KVM
+
**PodもReplicaSetも変更されないコンテナイメージを取り扱うために作られている
[[File:Minikube_kvm.png|400px]]
+
*フロー
 +
*#新しいReplicaSetを作成
 +
*#新しいReplicaSetのPod数を徐々に増やす
 +
*#古いReplicaSetのPod数を徐々に減らす
 +
*#上記を繰り返す
 +
*#古いReplicaSetのレプリカ数を0で保つ
 +
<pre>
 +
apiVersion: apps/v1
 +
kind: Deployment
 +
metadata:
 +
  name: sample-deploy
 +
spec:
 +
  replicas: 3
 +
  selector:
 +
    matchLabels:
 +
      app: sample-app
 +
  template:
 +
    metadata:
 +
      labels:
 +
        app: sample-app
 +
    spec:
 +
      containers:
 +
        - name: nginx-container
 +
          image: nginx:1.19
 +
          ports:
 +
          - containerPort: 80
 +
</pre>
 +
*作成
 +
<pre>
 +
$ kubectl apply -f sample-deploy.yaml
 +
deployment.apps/sample-rs created
 +
</pre>
  
====停止====
+
*確認(Pod)
&gt; minikube stop
 
====クラスタを削除====
 
&gt; minikube delete
 
===ダッシュボード===
 
 
<pre>
 
<pre>
$ minikube dashboard
+
$ kubectl get pod --output wide
 +
NAME                            READY  STATUS    RESTARTS  AGE  IP          NODE      NOMINATED NODE  READINESS GATES
 +
sample-deploy-5cc5cfccd7-6vq65  1/1    Running  0          33s  172.17.0.6  minikube   <none>          <none>
 +
sample-deploy-5cc5cfccd7-qjtbx  1/1    Running  0          33s  172.17.0.7  minikube  <none>          <none>
 +
sample-deploy-5cc5cfccd7-szcx5  1/1    Running  0          33s  172.17.0.3  minikube  <none>          <none>
 
</pre>
 
</pre>
[[File:Minikube_dashboard.png | 400px]]
+
*確認(ReplicaSet)
===Kubernetes Deploymentを作る===
 
*単純なHTTPサーバーであるechoserverという既存のイメージを使用して、Kubernetes Deploymentを作る
 
*--portを使用して8080番ポートで公開
 
 
<pre>
 
<pre>
$ kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
+
$ kubectl get replicaset --output wide
deployment.apps/hello-minikube created
+
NAME                      DESIRED  CURRENT  READY  AGE    CONTAINERS        IMAGES      SELECTOR
 +
sample-deploy-5cc5cfccd7  3        3        3      2m34s  nginx-container  nginx:1.19  app=sample-app,pod-template-hash=5cc5cfccd7
 
</pre>
 
</pre>
[[File:K8s_deploy.png | 400px]]
 
  
===Deploymentに接続するために、Serviceとして公開===
+
*ダッシュボード
 +
[[File:kubernetes_deployment.png|600px]]
 +
 
 +
==[https://kubernetes.io/ja/docs/concepts/workloads/controllers/daemonset/ DaemonSet]==
 +
*https://kubernetes.io/ja/docs/concepts/workloads/controllers/daemonset/
 +
*ReplicaSetでは、Podの数が一致するとも確実に配置されるとも保証されない
 +
*DaemonSetは、ReplicaSetの特殊な形、各ノードにPodを一つづつ配置するリソース
 +
*各ノード上で必ず動作させたいプロセスのために利用することが多い
 +
 
 
<pre>
 
<pre>
$ kubectl expose deployment hello-minikube --type=NodePort --port=8080
+
apiVersion: apps/v1
service/hello-minikube exposed
+
kind: DaemonSet
 +
metadata:
 +
  name: sample-ds
 +
spec:
 +
  selector:
 +
    matchLabels:
 +
      app: sample-app
 +
  template:
 +
    metadata:
 +
      labels:
 +
        app: sample-app
 +
    spec:
 +
      containers:
 +
        - name: nginx-container
 +
          image: nginx:1.19
 
</pre>
 
</pre>
[[File:K8s_service.png | 400px]]
+
*作成
===Podが起動しているか確認===
 
 
<pre>
 
<pre>
$ kubectl get pod
+
$ kubectl apply -f sample-ds.yaml
NAME                              READY  STATUS    RESTARTS  AGE
+
daemonset.apps/sample-ds created
hello-minikube-64b64df8c9-jzm5v  1/1    Running  0          11m
 
 
</pre>
 
</pre>
===公開サービスのURLを確認===
+
*確認
 
<pre>
 
<pre>
$ minikube service hello-minikube --url
+
$ kubectl get daemonset --output wide
http://192.168.39.214:31429
+
NAME        DESIRED  CURRENT  READY  UP-TO-DATE  AVAILABLE  NODE SELECTOR  AGE  CONTAINERS        IMAGES      SELECTOR
 +
sample-ds  1        1        1      1            1          <none>          98s  nginx-container  nginx:1.19  app=sample-app
 
</pre>
 
</pre>
[[File:K8s_service_run.png | 400px]]
 
  
===クラスタのステータス===
+
==[https://kubernetes.io/ja/docs/concepts/workloads/controllers/statefulset/ StatefulSet]==
*Serverとクライアントのバージョン
+
*https://kubernetes.io/ja/docs/concepts/workloads/controllers/statefulset/
 +
*データベースなどステートフルなワークロードに対応するためのリソース
 +
*ReplicaSetの特殊な形
 +
**作成されるPodのサフィックスは数字のインデックスが付与
 +
**データを永続化する仕組みを持つ
 +
**Pod名が変わらない
 
<pre>
 
<pre>
$ kubectl version
+
apiVersion: apps/v1
Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.8", GitCommit:"9f2892aab98fe339f3bd70e3c470144299398ace", GitTreeState:"clean", BuildDate:"2020-08-13T16:12:48Z", GoVersion:"go1.13.15", Compiler:"gc", Platform:"linux/amd64"}
+
kind: StatefulSet
Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.3", GitCommit:"2e7996e3e2712684bc73f0dec0200d64eec7fe40", GitTreeState:"clean", BuildDate:"2020-05-20T12:43:34Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"}
+
metadata:
 +
  name: web
 +
spec:
 +
  selector:
 +
    matchLabels:
 +
      app: sample-app
 +
  serviceName: sample-stateful
 +
  replicas: 3
 +
  template:
 +
    metadata:
 +
      labels:
 +
        app: sample-app
 +
    spec:
 +
      terminationGracePeriodSeconds: 10
 +
      containers:
 +
      - name: nginx
 +
        image: nginx:1.19
 +
        ports:
 +
        - containerPort: 80
 +
          name: web
 +
        volumeMounts:
 +
        - name: www
 +
          mountPath: /usr/share/nginx/html
 +
  volumeClaimTemplates:
 +
  - metadata:
 +
      name: www
 +
    spec:
 +
      accessModes:  
 +
      - ReadWriteOnce
 +
      resources:
 +
        requests:
 +
          storage: 1G
 
</pre>
 
</pre>
*クラスタを構成しているコンポーネントを確認
+
*作成
 
<pre>
 
<pre>
$ kubectl get componentstatus
+
$ kubectl apply -f sample-stateful.yaml
NAME                STATUS    MESSAGE            ERROR
+
statefulset.apps/web created
controller-manager  Healthy  ok                 
 
scheduler            Healthy  ok                 
 
etcd-0              Healthy  {"health":"true"} 
 
 
</pre>
 
</pre>
====ワーカーノードの表示====
+
*確認
*クラスタ上の全のノードを表示
 
 
<pre>
 
<pre>
$ kubectl get nodes
+
$ kubectl get statefulset --output wide
NAME       STATUS   ROLES    AGE    VERSION
+
NAME  READY  AGE    CONTAINERS  IMAGES
minikube  Ready   master  3h13m   v1.18.3
+
web   0/3    2m19s   nginx        nginx:1.19
 
</pre>
 
</pre>
 +
<q>running "VolumeBinding" filter plugin for pod "web-0": pod has unbound immediate PersistentVolumeClaims</q>
 +
*https://qiita.com/silverbirder/items/d3522237b28703a9adb6
 +
*PersistentVolumeは、データを永続的に保存しておく場所のリソース。マネージドサービスを利用すると、デフォルトでPresistentVolumeが用意されている
 +
*PersistentVolumeClaimsは、「PresistentVolumeを使わせて」というリソース
 +
*PresistentVolumeのnameを指定し、applyすることで、初めてマウントができる
  
====ノードの詳細情報====
+
<pre>
*kubectl describe nodes [ノード名]
+
$ kubectl get pv
 +
No resources found in default namespace.
 +
</pre>
  
=====基本情報が最初に表示される=====
+
==[https://kubernetes.io/ja/docs/concepts/storage/persistent-volumes/ 永続ボリューム(PersistentVolume)]==
Name:              minikube
+
*https://kubernetes.io/ja/docs/concepts/storage/persistent-volumes/
[[R]]oles:             master
+
*ストレージが何から提供されているか、どのように消費されているかをユーザーと管理者から抽象化するAPIを提供
Labels:            beta.kubernetes.io/arch=amd64
+
===PersistentVolume(PV)===
                    beta.kubernetes.io/os=linux
+
*ストレージクラスを使って管理者もしくは動的にプロビジョニングされるクラスターのストレージの一部
                    kubernetes.io/arch=amd64
+
*Nodeと同じようにクラスターリソースの一部
                    kubernetes.io/hostname=minikube
+
*PVを使う個別のPodとは独立したライフサイクルを持っている
                    kubernetes.io/os=linux
+
===PersistentVolumeClaim(PVC)===
                    node-role.kubernetes.io/master=
+
*ユーザーによって要求されるストレージ
Annotations:       kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
+
*Podと似ています。PodはNodeリソースを消費し、PVCはPVリソースを消費します
                    node.alpha.kubernetes.io/ttl: 0
+
*クレームは特定のサイズやアクセスモード(例えば、1ノードからのみ読み書きマウントができるモードや、複数ノードから読み込み専用マウントができるモードなどです)を要求することができます
                    volumes.kubernetes.io/controller-managed-attach-detach: true
+
===実例===
CreationTimestamp:  Mon, 05 Aug 2019 23:17:24 +0900
+
*https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
Taints:            &lt;none&gt;
+
====index.htmlをノード上に生成====
Unschedulable:      false
+
<pre>
=====ノード上で動いているオペレーションの情報が表示される=====
+
$ minikube ssh
*それぞれのノードが十分なディスクとメモリを持っているか
+
$ sudo mkdir /mnt/data
*Kubernatesマスターに対して正常であるか
+
$ sudo sh -c "echo 'Hello from kubernetes storage' > /mnt/data/index.html"
Conditions:
+
$ cat /mnt/data/index.html
  Type            Status  LastHeartbeatTime                LastTransitionTime                [[R]]eason                      Message
+
Hello from kubernetes storage
  ----            ------  -----------------                ------------------                ------                      -------
+
</pre>
  MemoryPressure  False  Tue, 13 Aug 2019 01:01:05 +0900  Mon, 05 Aug 2019 23:17:15 +0900  KubeletHasSufficientMemory  kubelet has sufficient memory available
+
====PersistentVolumeの生成====
  DiskPressure    False  Tue, 13 Aug 2019 01:01:05 +0900  Mon, 05 Aug 2019 23:17:15 +0900  KubeletHasNoDiskPressure    kubelet has no disk pressure
+
*ホストパスのPersistentVolumeを作成
  PIDPressure      False  Tue, 13 Aug 2019 01:01:05 +0900  Mon, 05 Aug 2019 23:17:15 +0900  KubeletHasSufficientPID      kubelet has sufficient PID available
+
*Kubernetesは単一クラスターで、ホストパスを開発とテストでサポートする
  [[R]]eady            True    Tue, 13 Aug 2019 01:01:05 +0900  Mon, 05 Aug 2019 23:17:15 +0900  Kubelet[[R]]eady                kubelet is posting ready status
+
*ホストパスPersistentVolumeは、ファイルやディレクトリをネットワークアタッチストレージをエミュレートしたものとして使用する
Addresses:
+
*プロダクションのクラスターでは、ホストパスは使用すべきでなく、クラスタ管理者により、用意されたネットワークリソース(Google Compute Engine persistent disk) などを使用する
  InternalIP:  10.0.2.15
+
*クラスタ管理者は、StorageClassesも動的プロビジョニングに使用することができる
  Hostname:    minikube
+
*ホストパスPersistentVolumeの例
=====マシンのキャパシティ情報の表示=====
+
<pre>
Capacity:
+
apiVersion: v1
  cpu:                2
+
kind: PersistentVolume
  ephemeral-storage:  17784772Ki
+
metadata:
  hugepages-2Mi:      0
+
   name: sample-pv
  memory:            2038624Ki
+
   labels:
  pods:              110
+
    type: local
Allocatable:
+
spec:
  cpu:               2
+
   storageClassName: manual
  ephemeral-storage: 16390445849
+
   capacity:
  hugepages-2Mi:     0
+
    storage: 1Gi
   memory:             1936224Ki
+
   accessModes:
   pods:               110
+
    - ReadWriteOnce
=====ノード上のソフトウェアバージョンの表示=====
+
   hostPath:
System Info:
+
    path: "/mnt/data"
  [[Mac]]hine ID:                 7ec5a55cfdc14693866eccf4e9a1228f
+
</pre>
   System UUID:               2C88347D-32CC-4F26-9AEE-1FED259A233C
+
*生成
   Boot ID:                   1da81daa-4519-4f04-afe0-64efecedd7e7
+
<pre>
  Kernel Version:             4.15.0
+
$ kubectl apply -f sample-pv.yaml
   OS Image:                   Buildroot 2018.05.3
+
persistentvolume/sample-pv created
  Operating System:          linux
+
</pre>
   Architecture:               amd64
+
*確認
  Container [[R]]untime Version:  docker://18.9.6
+
<pre>
  Kubelet Version:            v1.15.0
+
$ kubectl get pv --output wide
  Kube-Proxy Version:        v1.15.0
+
NAME       CAPACITY  ACCESS MODES  RECLAIM POLICY  STATUS     CLAIM  STORAGECLASS  REASON  AGE  VOLUMEMODE
=====ノード上で動いているPod情報の表示=====
+
sample-pv  1Gi       RWO            Retain           Available           manual                  12s  Filesystem
Non-terminated Pods:        (9 in total)
+
</pre>
  Namespace                  Name                                CPU [[R]]equests  CPU Limits  Memory [[R]]equests  Memory Limits  AGE
+
====PersistentVolumeClaimの作成====
  ---------                  ----                                ------------  ----------  ---------------  -------------  ---
+
<pre>
  kube-system                coredns-5c98db65d4-j24hp            100m (5%)    0 (0%)      70Mi (3%)        170Mi (8%)    7d1h
+
apiVersion: v1
  kube-system                coredns-5c98db65d4-phtm8            100m (5%)    0 (0%)      70Mi (3%)        170Mi (8%)    7d1h
+
kind: PersistentVolumeClaim
  kube-system                etcd-minikube                      0 (0%)       0 (0%)     0 (0%)          0 (0%)        7d1h
+
metadata:
  kube-system                kube-addon-manager-minikube        5m (0%)      0 (0%)      50Mi (2%)       0 (0%)        7d1h
+
   name: sample-pvc
  kube-system                kube-apiserver-minikube            250m (12%)    0 (0%)      0 (0%)           0 (0%)        7d1h
+
spec:
  kube-system                kube-controller-manager-minikube    200m (10%)    0 (0%)      0 (0%)           0 (0%)        7d1h
+
  storageClassName: manual
  kube-system                kube-proxy-wrgp5                    0 (0%)        0 (0%)      0 (0%)          0 (0%)        7d1h
+
  accessModes:
  kube-system                kube-scheduler-minikube            100m (5%)    0 (0%)      0 (0%)          0 (0%)        7d1h
+
     - ReadWriteOnce
  kube-system                storage-pro[[vi]]sioner                0 (0%)        0 (0%)      0 (0%)          0 (0%)        7d1h
+
  resources:
Allocated resources:
+
     requests:
  (Total limits may be over 100 percent, i.e., overcommitted.)
+
      storage: 1Gi
  [[R]]esource          [[R]]equests    Limits
+
</pre>
  --------          --------    ------
+
*生成
  cpu                755m (37%)   0 (0%)
+
<pre>
  memory            190Mi (10%)  340Mi (17%)
+
$ kubectl apply -f sample-pvc.yaml
  ephemeral-storage  0 (0%)      0 (0%)
+
persistentvolumeclaim/sample-pvc created
Events:
+
</pre>
  Type    [[R]]eason                  Age                  From                  Message
+
*確認
  ----    ------                  ----                ----                  -------
+
<pre>
  Normal  NodeHasSufficientMemory  7d1h (x8 over 7d1h)  kubelet, minikube    Node minikube status is now: NodeHasSufficientMemory
+
$ kubectl get pvc --output wide
  Normal  NodeHasNoDiskPressure    7d1h (x8 over 7d1h)  kubelet, minikube    Node minikube status is now: NodeHasNoDiskPressure
+
NAME        STATUS    VOLUME      CAPACITY  ACCESS MODES  STORAGECLASS      AGE  VOLUMEMODE
  Normal  NodeHasSufficientPID     7d1h (x7 over 7d1h)  kubelet, minikube    Node minikube status is now: NodeHasSufficientPID
+
sample-pvc  Bound    sample-pv  1Gi        RWO            manual            52s  Filesystem
  Normal  Starting                7d1h                kube-proxy, minikube  Starting kube-proxy.
+
</pre>
  Normal  Starting                12m                  kubelet, minikube    Starting kubelet.
 
  Normal  NodeHasSufficientMemory  12m (x8 over 12m)    kubelet, minikube     Node minikube status is now: NodeHasSufficientMemory
 
  Normal  NodeHasNoDiskPressure    12m (x8 over 12m)    kubelet, minikube    Node minikube status is now: NodeHasNoDiskPressure
 
  Normal  NodeHasSufficientPID    12m (x7 over 12m)    kubelet, minikube    Node minikube status is now: NodeHasSufficientPID
 
  Normal  NodeAllocatableEnforced  12m                  kubelet, minikube    Updated Node Allocatable limit across pods
 
  Normal  Starting                11m                  kube-proxy, minikube  Starting kube-proxy
 
 
 
===クラスタのコンポーネント===
 
*[[Kubernetes]]クラスタを構成する多くのコンポーネントが、[[Kubernetes]]自体を使ってデプロイされる
 
*kube-system Namesspace内で動作
 
====[[Kubernetes]] proxy====
 
*クラスタ内のロードバランスされたSer[[vi]]ceにネットワークトラフィックをルーティング
 
*クラスタ内の各ノードで動いている必要がある
 
*DaemonSetというAPIオブジェクトが多くのクラスタではノードでプロキシを動作させるために利用される
 
 
 
===Namespace===
 
*クラスタ内のオブジェクトを構造化
 
*kubectlはデフォルトではdefaultというNamespaceとやり取り
 
*--namespace で指定できる
 
===Context===
 
*デフォルトのNamespaceを恒久的に変更したい場合
 
*$HOME/.kube/config に保存される
 
===[[Kubernetes]] APIオブジェクトの参照===
 
*[[Kubernetes]]上にあるものは、すべてRESTFulリソースであらわされる
 
*[https://kubernetes.io/ja/docs/concepts/overview/kubernetes-api/ Kubernetes API]
 
*[https://kubernetes.io/docs/reference/ Kubernetes API Reference]
 
  
==Pod==
 
*同じ実行環境上で動くアプリケーションコンテナとストレージボリュームの集まりのこと
 
*Kubernetesクラスタ上では、コンテナではなくPodがデプロイの最小単位
 
*1つのPodないのコンテナは全て同じマシン上に配置される
 
*同じPod内のアプリケーションは、ネイティブなプロセス間通信チャネルで通信できるが、異なるPodのアプリケーションからは分離されている
 
===Pod単位で考える===
 
*WordPressとMySQLを同じPodに入れれば良いと考えるのはアンチパターンの1つ
 
*それぞれ別マシンで通信できればよく、WordPressとDBが同じ単位としてスケールする可能性も低い
 
*WordPress自体はステートレスなため、負荷が増大した場合、WordPressのPodを増やしてスケールさせれば良い
 
*通常は、Podを作る際に、コンテナが異なるマシンに配置されても正常に動作するかという点が判断基準
 
 
==[[Docker]]==
 
==[[Docker]]==
 +
*[[Docker]]
 +
*[[Docker コマンド]]
 +
*[[Docker ネットワーク]]
 
===Dockerデーモンの再利用によるローカルイメージの使用===
 
===Dockerデーモンの再利用によるローカルイメージの使用===
 
*[https://kubernetes.io/ja/docs/setup/learning-environment/minikube/#docker%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3%E3%81%AE%E5%86%8D%E5%88%A9%E7%94%A8%E3%81%AB%E3%82%88%E3%82%8B%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E4%BD%BF%E7%94%A8 Dockerデーモンの再利用によるローカルイメージの使用]
 
*[https://kubernetes.io/ja/docs/setup/learning-environment/minikube/#docker%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3%E3%81%AE%E5%86%8D%E5%88%A9%E7%94%A8%E3%81%AB%E3%82%88%E3%82%8B%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E4%BD%BF%E7%94%A8 Dockerデーモンの再利用によるローカルイメージの使用]
455行目: 664行目:
  
 
https://hub.docker.com/
 
https://hub.docker.com/
 +
 +
==Tips==
 +
*[[WSL|WSL2でKubernetes/Dockerを動かす]]
 +
 +
 +
===クイックスタート===
 +
*https://kubernetes.io/ja/docs/setup/learning-environment/minikube/
 +
<pre>
 +
piroto@jinmu:~$ kubectl get node
 +
NAME      STATUS  ROLES    AGE  VERSION
 +
minikube  Ready    master  14m  v1.18.3
 +
piroto@jinmu:~$ kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
 +
deployment.apps/hello-minikube created
 +
piroto@jinmu:~$ kubectl get pod
 +
NAME                              READY  STATUS              RESTARTS  AGE
 +
hello-minikube-64b64df8c9-42s98  0/1    ContainerCreating  0          11s
 +
piroto@jinmu:~$ kubectl expose deployment hello-minikube --type=NodePort --port=8080
 +
service/hello-minikube exposed
 +
piroto@jinmu:~$ minikube service hello-minikube --url
 +
http://192.168.39.238:30523
 +
</pre>
 +
*ローカル環境のクラスターについて詳細を確認するには、出力から得たURLをブラウザー上でコピーアンドペースト
 +
[[File:Kubernetes quick start 01.png|600px]]
 +
*Service,Deploymentの削除、クラスター停止、クラスター削除
 +
<pre>
 +
piroto@jinmu:~$ kubectl delete services hello-minikube
 +
service "hello-minikube" deleted
 +
piroto@jinmu:~$ kubectl delete deployment hello-minikube
 +
deployment.apps "hello-minikube" deleted
 +
piroto@jinmu:~$ minikube stop
 +
ノード "minikube" を停止しています...
 +
1台のノードが停止しました。
 +
piroto@jinmu:~$ minikube delete
 +
kvm2 の「minikube」を削除しています...
 +
クラスタ "minikube" の全てのトレースを削除しました。
 +
</pre>
 +
===NodeでHello World===
 +
*https://kubernetes.io/ja/docs/tutorials/hello-minikube/

2021年5月20日 (木) 13:59時点における最新版

| Docker | Docker コマンド | Docker ネットワーク | WSL | MicroK8s | Multipass |

目次

Kubernetes

  • https://kubernetes.io/ja/
  • コンテナ化されたアプリケーションのデプロイ、スケーリングなどの管理を自動化するプラットフォーム(コンテナオーケストレーションエンジン)
  • https://knowledge.sakura.ad.jp/20955/
  • 信頼性が高くスケーラブルな分散システムを上手に構築してデプロイするために必要なソフトウェアを提供
  • 分散システムとは、異なるマシンで動作するAPIを実装する部品の集まり
  • マネージドKubernetesサービス(KaaS:Kubernates-as-a-Service)

チートシート

コンポーネント構成

Kubernetes component.png

宣言的なコードによる管理

  • YAMLやJSONの宣言的なマニフェストで、コンテナやリソースを管理できる

スケーリング/オートスケーリング

  • コンテナクラスタを形成して、複数のKubernetes Nodeを管理できる

スケジューリング

  • コンテナを Kubernetes Nodeにデプロイする際に、どのNodeに配置するかを決定するスケジューリングというステップがある
  • コンテナのワークロードの特徴、Kubernetes Nodeの性能差を意識してスケジューリングを行うことができる

リソース管理

  • コンテナ配置に特別指定がない場合、自動スケジューリングが行われるため、管理する必要がない
  • オートスケール機能により、Kubernetesクラスタの、Kubernetes Nodeの増減も自動で行われる

セルフヒーリング

  • 標準でコンテナのプロセス管理を行っており、プロセス停止を検知すると、再度コンテナのスケジュールを行うことで自動的にコンテナを再デプロイする
  • プロセス監視以外にも、HTTP・TCPや、シェルスクリプトによるヘルスチェックも可能

サービスディスカバリーとロードバランシング

  • ロードバランシング機能(Service)を持っており、事前に指定した条件に合致するコンテナ群に対してルーティングを行う機能を提供する
  • コンテナスケール時や、障害時のサービスへの追加、切り離しも自動で行うため、エンドポイント管理をKubernetesに任せることが可能
  • コンテナを使用したシステム構築では、マイクロサービスアーキテクチャ採用が一般的、マイクロサービスが相互参照するために、サービスディスカバリー機能が有用
  • マイクロサービスを定義されたマニフェストを元にシステム全体を連携させることが可能

データ管理

  • バックエンドのデータ管理にetcdを利用している

基礎

  • Kubernetes は、Kubernetes Master と Kubernetes Node の2種類のノードからから成り立っている
  • Kubernetes Master は、APIエンドポイントの提供コンテナのスケジューリング、コンテナのスケーリングなどを担う
  • Kubernetes Node は、Docker ホストに相当し実際にコンテナが稼働するノード
  • Kubernetes クラスタを操作するには、kubectl と YAML か JSON 形式のマニフェストファイルを用いて、Kuebrnetes Masterにリソースの登録を行う
  • kubectlは、マニフェストファイルの情報を元にKubernetes MasterのAPIにリクエストを送り、Kubernetesの操作を行う
  • Kubernetes の API は一般的な RESTful API として実装されている

構成

クラスタ

  • Kubernetesクラスターは以下の2種類のリソースで構成
    • マスターがクラスターを管理する、マスターはクラスターの管理を担当
    • ノードがアプリケーションを動かすワーカーとなる、ノードは、Kubernetesクラスターのワーカーマシンとして機能するVMまたは物理マシン

Kubelet

  • 各ノードにはKubeletがあり、これはノードを管理し、Kubernetesマスターと通信するためのエージェント

デプロイ

Kubernetesにアプリケーションをデプロイするときは、

  1. マスターにアプリケーションコンテナを起動するように指示
  2. マスターはコンテナがクラスターのノードで実行されるようにスケジュール
  3. ノードは、マスターが公開しているKubernetes APIを使用してマスターと通信
    1. エンドユーザーは、Kubernetes APIを直接使用して対話することもできます



Kubernetes とリソース

  • Kubernetesでは、リソースを登録することで、コンテナの実行やロードバランサの作成が非同期に行われる

Workloadsリソース

  • クラスタ上にコンテナを起動するために利用する
  • 内部的に利用されているものをのぞき、直接操作するものとしては、以下のリソースがある
    • Pod
    • ReplicationController
    • ReplicaSet
    • Deployment
    • DaemonSet
    • StatefulSet
    • Job
    • CronJob

Pod

  • Workloadsリソースの最小単位
  • 一つ以上のコンテナから構成され、ネットワーク的に隔離されておらず、IPアドレスを共有する
  • 2つのコンテナが入ったPodを作成した場合、同一IPアドレスを持ち、お互い、localhostで通信できる
  • 多くの場合は、1つのPodに1つのコンテナを含めるが、補助するサブコンテナを複数含めることもある

Discovery & LBリソース

  • コンテナサービスディスカバリやクラスタの外部からもアクセス可能なエンドポイントなどを提供する
  • 利用者が直接利用するものとしては、Service と Ingress があり、Serviceは複数タイプが用意されている
  • Service
Service 内容
ClusterIP
ExternalIP (ClusterIPの一種)
NodePort
LoadBalancer
Headless (None)
ExternalName
None-Selector
  • Ingress

KubernetesクラスタのネットワークとService

Kubernetesが構成するネットワーク

  • Pod内には複数のコンテナを内包できるが、同じPodであれば、同一IPが割り振られている
  • 同一Podコンテナへ通信を行う場合は、localhostあてに通信を行い、Podのコンテナから別Podコンテナへ通信を行う場合には、PodのIPアドレス宛に通信を行う
  • Kubernetesクラスタは、クラスタを構成するとノードにPodのための内部ネットワークを自動的に構成する
  • 基本的にはノードごとに異なるネットワークセグメントを互いに通信できるよう構成する
  • このような内部ネットワークが自動構成されるため、PodはServiceを利用しなくてもPod間通信を行うことが可能

Serviceを利用することによるメリット

  • Podあてトラフィックのロードバランシング
  • サービスディスカバリとクラスタ内DNS
  • これらは、上記のどのService Typeからも利用できる

Pod宛トラフィックのロードバランシング

  • Serviceは、複数のPodにロードバランシングを行う
  • Serviceを利用すると、各PodのIPを毎回調べたり、宛先を設定するなど独自に実現しなくても、自動的に構成することができる
  • Serviceは、ロードバランシングのエンドポイントも提供する
    • 外部ロードバランサーが払い出す仮想IP(Virtual IPアドレス)、クラスタ内のみで利用可能な仮想IPアドレス(ClusterIP)など

Config & Storage リソース

  • 設定や機密データをコンテナに埋め込んだり、永続ボリュームを提供する
  • Secret と ConfigMap は Key-Value のデータ構造を持ち保存データが機密か一般化によって使い分ける
  • Secret
  • ConfigMap
  • PersistentVolumeClaim

Cluster リソース

  • クラスタ自体の振る舞いを定義
  • Node
  • Namespace
  • PersistentVolume
  • ResourceQuote
  • ServiceAccount
  • Role
  • ClusterRole
  • RoleBinding
  • ClusterRoleBinding
  • NetworkPolicy

Metadataリソース

  • クラスタ内の他のリソースの動作を制御する
  • LimitRange
  • HorizontalPodAutoscaler
  • PodDisruptionBudget
  • CustomResourceDefinition

Minikube

MicroK8s

Kubectl

Namespace

  • Kubernetesは、同一の物理クラスター上で複数の仮想クラスターの動作をサポートします。 この仮想クラスターをNamespaceと呼びます
  • 作成:kubectl create namespace <名称>
  • 削除:kubectl delete namespace <名称>
$ kubectl create namespace sample
namespace/sample created
$ kubectl get namespaces
NAME              STATUS   AGE
kube-system       Active   66d
kube-public       Active   66d
kube-node-lease   Active   66d
default           Active   66d
sample            Active   4s

Pod

  • https://kubernetes.io/ja/docs/concepts/workloads/pods/
  • 同じ実行環境上で動くアプリケーションコンテナとストレージボリュームの集まりのこと
  • Kubernetesクラスタ上では、コンテナではなくPodがデプロイの最小単位
  • 1つのPodないのコンテナは全て同じマシン上に配置される
  • 同じPod内のアプリケーションは、ネイティブなプロセス間通信チャネルで通信できるが、異なるPodのアプリケーションからは分離されている

Pod単位で考える

  • WordPressとMySQLを同じPodに入れれば良いと考えるのはアンチパターンの1つ
  • それぞれ別マシンで通信できればよく、WordPressとDBが同じ単位としてスケールする可能性も低い
  • WordPress自体はステートレスなため、負荷が増大した場合、WordPressのPodを増やしてスケールさせれば良い
  • 通常は、Podを作る際に、コンテナが異なるマシンに配置されても正常に動作するかという点が判断基準

設定

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/piroto/.minikube/ca.crt
    server: https://192.168.39.214:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /home/piroto/.minikube/profiles/minikube/client.crt
    client-key: /home/piroto/.minikube/profiles/minikube/client.key

マニフェストとリソースの作成

  • sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
spec:
  containers:
    - name: nginx-container
      image: nginx:1.12

実行

  • apply コマンドを利用すると、存在しなければ生成、更新があれば更新、変更なければ何もしないという挙動
$ kubectl create -f sample-pod.yaml  
pod/sample-pod created
  • 確認
$ kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
sample-pod   1/1     Running   0          42s
$ kubectl apply -f sample-pod.yaml 
pod/sample-pod configured

アノテーションとラベル

  • 各リソースに対してアノテーションとラベルというメタデータを付与することができる
名称 概要
アノテーション システムコンポーネントが使用するメタデータ.アノテーションを元に処理するシステムコンポーネントが存在しない場合は単なるメモ
ラベル リソース管理に利用するメターデータ.リソースを分別するための情報
  • ユーザーがアノテーションを付与せず作成したリソースでも、下記のように様々なアノテーションが付与される
$ kubectl get deployments -o yaml hello-minikube
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2020-08-22T08:02:54Z"
         :
  • アノテーションとラベルをマニフェストに追記
apiVersion: v1
kind: Pod
metadata:
  name: sample-pod
  annotations:
    annotation1: val1 
    annotation2: val2
  labels:
    label1: lab1
    label2: lab2
spec:
  containers:
    - name: nginx-container
      image: nginx:1.19
  • 表示の拡張
$ kubectl get pod --output wide
NAME         READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
sample-pod   1/1     Running   2          24h   172.17.0.3   minikube   <none>           <none>
  • ダッシュボードに表示された

Kubernetes label.png

Podの削除

$ kubectl delete -f sample-pod.yaml 
pod "sample-pod" deleted

2つのコンテナを内包したPod

  • マニフェスト sample-2pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: sample-2pod
spec:
  containers:
    - name: nginx-container
      image: nginx:1.19
    - name: radis-container
      image: redis:6.0.7
  • 適用
$ kubectl apply -f sample-2pod.yaml 
pod/sample-2pod created
  • 結果確認
$ kubectl get pod --output wide
NAME          READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
sample-2pod   2/2     Running   0          7m40s   172.17.0.6   minikube   <none>           <none>
sample-pod    1/1     Running   2          2d      172.17.0.3   minikube   <none>           <none>

コンテナへのログインとコマンド実行

  • -t 疑似端末(TTY)を生成し、-i 標準入力をコンテナに渡す
  • /bin/bashコマンドを実行する
$ kubectl exec sample-pod -i -t -- /bin/bash
root@sample-pod:/# 

ReplicaSet

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: sample-rs
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.19
          ports:    
           - containerPort: 80

*作成

$ kubectl apply -f sample-rs.yaml 
replicaset.apps/sample-rs created
  • 確認
    • Podが3つ起動していることが確認できる
$ kubectl get pods --output wide
NAME              READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATES
sample-2pod       2/2     Running   0          26h     172.17.0.6   minikube   <none>           <none>
sample-pod        1/1     Running   2          3d2h    172.17.0.3   minikube   <none>           <none>
sample-rs-9gxzs   1/1     Running   0          3m14s   172.17.0.7   minikube   <none>           <none>
sample-rs-nsn86   1/1     Running   0          3m14s   172.17.0.9   minikube   <none>           <none>
sample-rs-wcjsv   1/1     Running   0          3m14s   172.17.0.8   minikube   <none>           <none>
  • ダッシュボードで確認

Kubernetes replicaset.png

Deployment

  • https://kubernetes.io/ja/docs/concepts/workloads/controllers/deployment/
  • 複数のReplicaSetを管理することで、ローリングアップデートやロールバックを実現するリソース
  • Kubernetesで最も推奨されるコンテナの起動方法
  • 1つのコンテナでもDeploymentを使用すべき
  • Deploymentは新しいバージョンのリリースを管理する仕組み
  • デプロイされたアプリケーションをバージョンをまたいで表現する
    • Pod単体では自動で再起動されないし、ReplicaSetでは、ローリングアップデートが利用できない
    • PodもReplicaSetも変更されないコンテナイメージを取り扱うために作られている
  • フロー
    1. 新しいReplicaSetを作成
    2. 新しいReplicaSetのPod数を徐々に増やす
    3. 古いReplicaSetのPod数を徐々に減らす
    4. 上記を繰り返す
    5. 古いReplicaSetのレプリカ数を0で保つ
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-deploy
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.19
          ports:
           - containerPort: 80
  • 作成
$ kubectl apply -f sample-deploy.yaml 
deployment.apps/sample-rs created
  • 確認(Pod)
$ kubectl get pod --output wide
NAME                             READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
sample-deploy-5cc5cfccd7-6vq65   1/1     Running   0          33s   172.17.0.6   minikube   <none>           <none>
sample-deploy-5cc5cfccd7-qjtbx   1/1     Running   0          33s   172.17.0.7   minikube   <none>           <none>
sample-deploy-5cc5cfccd7-szcx5   1/1     Running   0          33s   172.17.0.3   minikube   <none>           <none>
  • 確認(ReplicaSet)
$ kubectl get replicaset --output wide
NAME                       DESIRED   CURRENT   READY   AGE     CONTAINERS        IMAGES       SELECTOR
sample-deploy-5cc5cfccd7   3         3         3       2m34s   nginx-container   nginx:1.19   app=sample-app,pod-template-hash=5cc5cfccd7
  • ダッシュボード

Kubernetes deployment.png

DaemonSet

  • https://kubernetes.io/ja/docs/concepts/workloads/controllers/daemonset/
  • ReplicaSetでは、Podの数が一致するとも確実に配置されるとも保証されない
  • DaemonSetは、ReplicaSetの特殊な形、各ノードにPodを一つづつ配置するリソース
  • 各ノード上で必ず動作させたいプロセスのために利用することが多い
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: sample-ds
spec:
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - name: nginx-container
          image: nginx:1.19
  • 作成
$ kubectl apply -f sample-ds.yaml 
daemonset.apps/sample-ds created
  • 確認
$ kubectl get daemonset --output wide
NAME        DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE   CONTAINERS        IMAGES       SELECTOR
sample-ds   1         1         1       1            1           <none>          98s   nginx-container   nginx:1.19   app=sample-app

StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: sample-app
  serviceName: sample-stateful 
  replicas: 3 
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: nginx:1.19
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: 
      - ReadWriteOnce
      resources:
        requests:
          storage: 1G
  • 作成
$ kubectl apply -f sample-stateful.yaml 
statefulset.apps/web created
  • 確認
$ kubectl get statefulset --output wide
NAME   READY   AGE     CONTAINERS   IMAGES
web    0/3     2m19s   nginx        nginx:1.19

running "VolumeBinding" filter plugin for pod "web-0": pod has unbound immediate PersistentVolumeClaims

  • https://qiita.com/silverbirder/items/d3522237b28703a9adb6
  • PersistentVolumeは、データを永続的に保存しておく場所のリソース。マネージドサービスを利用すると、デフォルトでPresistentVolumeが用意されている
  • PersistentVolumeClaimsは、「PresistentVolumeを使わせて」というリソース
  • PresistentVolumeのnameを指定し、applyすることで、初めてマウントができる
$ kubectl get pv
No resources found in default namespace.

永続ボリューム(PersistentVolume)

PersistentVolume(PV)

  • ストレージクラスを使って管理者もしくは動的にプロビジョニングされるクラスターのストレージの一部
  • Nodeと同じようにクラスターリソースの一部
  • PVを使う個別のPodとは独立したライフサイクルを持っている

PersistentVolumeClaim(PVC)

  • ユーザーによって要求されるストレージ
  • Podと似ています。PodはNodeリソースを消費し、PVCはPVリソースを消費します
  • クレームは特定のサイズやアクセスモード(例えば、1ノードからのみ読み書きマウントができるモードや、複数ノードから読み込み専用マウントができるモードなどです)を要求することができます

実例

index.htmlをノード上に生成

$ minikube ssh
$ sudo mkdir /mnt/data
$ sudo sh -c "echo 'Hello from kubernetes storage' > /mnt/data/index.html"
$ cat /mnt/data/index.html
Hello from kubernetes storage

PersistentVolumeの生成

  • ホストパスのPersistentVolumeを作成
  • Kubernetesは単一クラスターで、ホストパスを開発とテストでサポートする
  • ホストパスPersistentVolumeは、ファイルやディレクトリをネットワークアタッチストレージをエミュレートしたものとして使用する
  • プロダクションのクラスターでは、ホストパスは使用すべきでなく、クラスタ管理者により、用意されたネットワークリソース(Google Compute Engine persistent disk) などを使用する
  • クラスタ管理者は、StorageClassesも動的プロビジョニングに使用することができる
  • ホストパスPersistentVolumeの例
apiVersion: v1
kind: PersistentVolume
metadata:
  name: sample-pv
  labels:
    type: local
spec:
  storageClassName: manual
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"
  • 生成
$ kubectl apply -f sample-pv.yaml 
persistentvolume/sample-pv created
  • 確認
$ kubectl get pv --output wide
NAME        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
sample-pv   1Gi        RWO            Retain           Available           manual                  12s   Filesystem

PersistentVolumeClaimの作成

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sample-pvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  • 生成
$ kubectl apply -f sample-pvc.yaml 
persistentvolumeclaim/sample-pvc created
  • 確認
$ kubectl get pvc --output wide
NAME         STATUS    VOLUME      CAPACITY   ACCESS MODES   STORAGECLASS       AGE   VOLUMEMODE
sample-pvc   Bound     sample-pv   1Gi        RWO            manual             52s   Filesystem

Docker

Dockerデーモンの再利用によるローカルイメージの使用

$ minikube docker-env
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.39.214:2376"
export DOCKER_CERT_PATH="/home/piroto/.minikube/certs"
export MINIKUBE_ACTIVE_DOCKERD="minikube"

# To point your shell to minikube's docker-daemon, run:
# eval $(minikube -p minikube docker-env)
$ docker ps
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/containers/json: dial unix /var/run/docker.sock: connect: permission denied
$ sudo groupadd docker
$ sudo gpasswd -a `id -un` docker
$ sudo chgrp docker /var/run/docker.sock 
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

https://hub.docker.com/

Tips


クイックスタート

piroto@jinmu:~$ kubectl get node
NAME       STATUS   ROLES    AGE   VERSION
minikube   Ready    master   14m   v1.18.3
piroto@jinmu:~$ kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.10
deployment.apps/hello-minikube created
piroto@jinmu:~$ kubectl get pod
NAME                              READY   STATUS              RESTARTS   AGE
hello-minikube-64b64df8c9-42s98   0/1     ContainerCreating   0          11s
piroto@jinmu:~$ kubectl expose deployment hello-minikube --type=NodePort --port=8080
service/hello-minikube exposed
piroto@jinmu:~$ minikube service hello-minikube --url
http://192.168.39.238:30523
  • ローカル環境のクラスターについて詳細を確認するには、出力から得たURLをブラウザー上でコピーアンドペースト

Kubernetes quick start 01.png

  • Service,Deploymentの削除、クラスター停止、クラスター削除
piroto@jinmu:~$ kubectl delete services hello-minikube
service "hello-minikube" deleted
piroto@jinmu:~$ kubectl delete deployment hello-minikube
deployment.apps "hello-minikube" deleted
piroto@jinmu:~$ minikube stop
 ノード "minikube" を停止しています...
 1台のノードが停止しました。
piroto@jinmu:~$ minikube delete
 kvm2 の「minikube」を削除しています...
 クラスタ "minikube" の全てのトレースを削除しました。

NodeでHello World