Kubernetesを勉強しつつ、用語を整理してみる
最近Kubernetesに興味をもっていろいろいじっている。
随時更新予定。
Kubernetesとは、、、
他のDockerにもオーケストラレーション機能はあることはあるが、 Kubernetesの特徴としては、
- 複数のノード(サーバ)を1つのコンテナサーバとしてみなすことができる
- スケールアウトが容易(ノード追加)
- サービスのローリングアップデートが可能
- アップデートしても、前のバージョンのコンテナが残っている(イミュータブル)なので、戻すことも容易
- 宣言的設定→望ましい状態に満たないときはKubernetesがうまいことやってくれる
とかですかね。
(このあたりはGoogleらしいというか、分散システム(YARNとかMesosとか)の感じを受けました)
kubectlインストール
brew install kubernetes-cli
minikubeインストール
curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.28.2/minikube-darwin-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/
他のインストール方法はこちら
YAML
Kubernetesでコンテナ起動等なんらかの定義をする際はYAMLで記述する
起動
定義を実行するときは、
kubectl apply -f <YAML定義>
で実行する。
それかkubectl runでもできる
Kubernetesの情報確認
kubectl get <項目>
で見れる
# Pod情報 kubectl get pods # Deployment情報 kubectl get deployments # Replicaset kubectl get rs
詳細情報の取得
kubectl describe <項目> <名前>
#特定の定義情報を取得
kubectl describe pod
Pod
- コンテナの塊
- Kubernetesで操作できる最小単位
- 基本的には1Podにつき1コンテナ
- 複数のコンテナが常に同期していないといけない場合は1Podにくるめる
- 入門Kubernetesによると「このコンテナはそれぞれ違うマシンに配置されても正常に動作するかどうか」がNoなら1つのPodにまとめるのがいいとのこと
- できるだけ疎結合であることを推奨 -> マイクロサービス化
- 入門Kubernetesによると「このコンテナはそれぞれ違うマシンに配置されても正常に動作するかどうか」がNoなら1つのPodにまとめるのがいいとのこと
Podを定義するときには、コンテナのポートとPodのポートのフォワーディングを設定する。
Label
- Podや後述するDeploymentやServiceなどにつけられるタグのようなもの
- Key/Value形式で設定
- app:tomcatというラベルがついているPodをすべて落とすみたいなラベル単位での操作が可能になる
apiVersion: v1 kind: Pod metadata: name: tomcat-pod labels: app: tomcat spec: containers: - name: tomcat image: tomcat:8.0 ports: - name: tomcat-port containerPort: 8080
- tomcat-podという名前のPodを作成
- app -> tomcatというラベルを作成
- コンテナの名前はtomcat、使用するコンテナイメージはtomcat:8.0
- Podの8080がコンテナポートの8080にフォワーディング
kubectl apply -f <コンテナイメージのyaml>
でクラスタにデプロイ
コンテナの起動を確認する場合は、
kubectl port-forward nodehelloworld.example.com <ローカルポート>:<Pod内のコンテナポート>
でポートフォワーディングするとlocalhost:<ローカルポート>でアクセスできる
livenessProbeとreadinessProbe
要はコンテナ生きてる?という確認を行うもの。(Hadoopでいうハートビートみたいなやつ)
LivenessとReadinessの違いは
Liveness -> コンテナが起動しているか Readiness -> コンテナが応答するか
apiVersion: v1 kind: Pod metadata: name: tomcat-pod labels: app: tomcat spec: template: metadata: labels: app: tomcat spec: containers: - name: tomcat image: tomcat:8.0 ports: - containerPort : 8080 livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 10 failureThreshold: 3 readinessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 15 periodSeconds: 3 timeoutSeconds: 10 failureThreshold: 3
- livenessProbe
- ReadinessProbe
Resource(requestとlimit)
コンテナに対して最低限要求するリソースと逆にこれ以上リソースをとるなというリミットを宣言できる
# 一部抜粋 spec: containers: - name: tomcat image: tomcat:9.0 resources: requests: cpu: "500m" memory: "128Mi" limits: cpu: "1000m" memory: "256Mi" ports: - containerPort: 8080
- cpu
- Min0.5コア、Max1コア
- メモリ
- Min128MB、Max256MB
Volume
Podが停止しても永続的に残るストレージのようなものを作成できる。
Volumeの定義はコンテナの定義を作る感覚で定義できる
(というよりストレージ用のコンテナを作る感覚に似ていると思う)
spec: volumes: - name: "kuard-data" nfs: server: my.nfs.server.local path: "/exports" containers: #以下にコンテナの定義を書いたり
でコンテナにVolumeをマウントするときは、
spec: containers: - name: tomcat image: tomcat:9.0 resources: requests: cpu: "500m" memory: "128Mi" limits: cpu: "1000m" memory: "256Mi" volumeMounts: - mountPath: "/data" name: "kuard-data" ports: - containerPort: 8080
- volumeMounts内で指定したnameのVolumeを/dataにマウント
ReplicasetとDeamonset
Podを複数立てます。
- 冗長化→負荷分散してくれる
- 耐障害性→1つPodが落ちても大丈夫
ReplicasetとDaemonsetの違いは、
Replicaset
- クラスタ全体内で決められた数のPodを生成
- 実際のノードのどこに配置するかは自由
- 定義を記述するときに、合わせてPod(コンテナ)の定義もできる
apiVersion: apps/v1beta2 kind: Replicaset metadata: name: tomcat spec: selector: matchLabels: app: tomcat replicas: 4 template: metadata: labels: app: tomcat spec: containers: - name: tomcat image: tomcat:9.0 ports: - containerPort : 8080
- Tomcatのコンテナが入っているPodを動かす
- PodのIP:8080でこのコンテナにアクセスできる
- PodはKubernetesクラスタ上に4つ複製される
これを実行した後、kubectl get rs
を動かすと
$ kubectl get rs NAME DESIRED CURRENT READY AGE tomcat-84bc588dcd 4 4 0 11s
こんな感じで結果が返ってくる。
Daemonset
- クラスタ内のすべてのノードに対して1つ以上Podを生成
- すべてのノードに対して監視用アプリケーションやログコレクタ(Fluentd等)のPodを配置したりできる
Service
外部から特定のPodにアクセスするための機能 ※本来はPod生成時に外部からアクセスできるIPが生成されるが、毎回調べるのが面倒なので、そこをServiceがうまい具合にやってくれる。
クラスタ内部はもちろん(TargetPort)、クラスタ外からのネットワークからのアクセスも可能(NodePort)
Deployment
- Pod(のReplicaを含む)をアップデートできる
- ローリングアップデート可能
- Deploymentの定義実行時にReplicasetならびにPodの定義も記述できる
Job
なんらかの処理やワークフローを実行したいときに一時的に立ち上がるPodの定義
なんとなく、サーバレスっぽいなと直感で思ったけど違ってたら教えて。
- 並列実行ができる
ConfigMap
- 環境変数を設定