google container engine (gke) & kubernetes のアーキテクチャ解説

Post on 21-Jan-2018

6.542 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Google Container Engine (GKE) & Kubernetes のアーキテクチャ解説九州インフラ交流勉強会 (Kixs) Vol.005

Proprietary + Confidential

Samir Hammoudi aka サミール クラウドカスタマエンジニア

SEPTEMBER 2, 2017

自己紹介

Samir Hammoudi(本イベントではサミえもんw)

クラウドカスタマエンジニア(セールスエンジニアね)

Twitter: @ksimirLinkedIn: https://www.linkedin.com/in/hammoudi/

→ スイスで7年間コンスタントとしてプライベートクラウド系のプロジェクトを担当

→ 3年半前に日本に移住、外資系大手 IT ベンダーに入社

→ 2017年11月にセールスエンジニアとして Google に入社

→ ゲーム会社を担当(ゲームが大好きなのでラッキー)

→ Cloud Spanner が大好き!

Copyright 2015 Google Inc

Googleでは10年間に渡り、すべてのサービスをコンテナで動かしてきた毎週20億以上のコンテナを立ち上げている

Images by Connie Zhou

コンテナとは?

コンテナはアプリケーションコードとその依存性を一

つのユニットとしてまとめる

これにより、アプリケーションとインフラを疎結合にする

ことができる

• コンテナはアプリケーションとその依存性がまとまっているので、例え

ば、開発環境、テスト環境、本番環境をまたいだデプロイが容易にな

• オンプレミス、プライベートクラウド、パブリッククラウド等ことなる実行

環境間の移動が容易になる

コンテナ イメージ

依存性

アプリケーション コード

VM vs ContainerVM

Container

なぜコンテナ?

軽量仮想マシンに比べて

軽量でシンプル。数十ミリ秒で起動

ポータブル様々な実行環境に対応し、

デプロイメントが容易

効率性リソース使用量が少なく、コンピュートリソースを細分化して効率的に利用可能

コンテナ管理の課題

Node Node

Cluster

Node

???

● 複数のノードに対するコンテナのデプロイは?

● ノード障害が発生した場合は?

● コンテナ障害が発生した場合は?

● アプリケーションのアップグレードはどうやって管理する?

Kubernetes κυβερνήτης: Greek for “pilot” or “helmsman of a ship”

the open source cluster manager from Google

Kubernetes (k8s) とは

● “コンテナオーケストレーション”

○ コンテナ中心のインフラ

● Googleの内部システムとコンテナの運用経験に

インスパイアされている

● Runs Anywhere

● 2014年にオープンソース化

● Kubernetes やクラウドネイティブエコシステムを

管理する CNCF に寄贈

Kubernetes のアーキテクチャ

Kubernetes のアーキテクチャ

API

UI

CLI

Master

Node 1

Node 2

Node 3

Node 4

Kubernetes Master

API

UI

CLI

APIServer Scheduler Controller

etcd

Master ノードのコンポーネント

API Server→ kubectl は API Server を REST API で叩くコマンドツール

Scheduler→ Pod をノードにスケジュールするコンポーネント

Controller→ クラスタの状態を常に監視しするバックグラウンドプロセス

→ 定義された状態と異なると、それを修正するコンポーネント

etcd→ 分散 KVS→ クラスタの全データを格納するデータストア

Kubernetes Node

Master

Docker Engine kubeletkube proxy

supervisord

fluentd

Pod

Pod Pod

Pod

Pod

Pod

AddonsDNS UI

Pod

Pod

Worker ノードのコンポーネント

kubelet→ ノードのエージェント

→ Pod の YAML ファイルに基づいて、定義されたコンテナを実行し、ストレージな

どをマウントし、正常に起動していることを担保

kube-proxy→ 各ノードで実行するネットワークプロキシ

→ サービスのIPアドレスを管理、コネクションフォワーディング

→ iptables を操作

Addons

DNS→ クラスタ内のDNSサービス

→ Kubernetes 1.3 からビルトインのサービス

→ Service や Pod は自動的にDNSに登録される

Web UI→ Kubernetes Dashboard

コンテナを使用するサンプルアプリ

Client PythonWeb App

RedisDatabase

Kubernetes Pod

1つか複数のコンテナをデプロイする単位

● 関連するコンテナ

● 同じコンテキストで実行するコンテナ

同じ Pod のコンテナは同じホスト名を持つ

各ポッドの隔離は:

● Namespace (process isolation)● Cgroups (リソース制御)

複数のプロセスを実行する VM の代替

Pod はデプロイ単位

Log Roller

Web Server

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

KubernetesMaster/Scheduler

コンテナ

コンテナ

ポッド

Labels & Selectors

● 各 Kubernetes のオブジェクトに紐付けられ

るキーバリューペア

● オブジェクトのフィルタリングに使用

● オブジェクトの作成の際に設定され、いつで

も変更可能

● ラベルは API オブジェクトを繋ぐ重要なのり

○ Deployment → Pods○ Service → Deployment

apiVersion: v1kind: Servicemetadata: name: web-svc labels: name: web app: demospec: selector: name: web type: LoadBalancer ports: - port: 80 targetPort: 5000 protocol: TCP

多数のポッドを識別するには?

FE

FE

FE

FE

FE

FE

BE

BE

BE BEBE

BEBE

BEBE

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

Kubernetes - Master/Scheduler

オブジェクトの識別 labels: role: frontend

FE

FE

FE

FE

FE

FE

BE

BE

BE BEBE

BE

BEBE

BE

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

Kubernetes - Master/Scheduler

オブジェクトの識別

labels: role: frontend stage: production

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

Kubernetes - Master/Scheduler

FE

FE

FE

FE

FE

FE

BE

BE

BE BEBE

BE

BEBE

BE

Pod をデプロイ

Master

Node

Docker kubeletkube proxy

supervisord

fluentd

WebPod

DBPod

Registry

pythonweb app

redisdb

Pod definitions (yaml)

Deployment

● YAML ファイルに設定されたポッドの数が

常に起動しているかを保証する

→ Pod をシャットダウンや起動する

● Deployment を replicas: 1 で作成すると、1つの Pod が常に起動していることを保証す

● デプロイするコンテナイメージと公開する

ポートを指定する

apiVersion: extensions/v1beta1kind: Deploymentmetadata: name: web-deployment labels: name: web app: demospec: replicas: 1 template: metadata: labels: app: demo spec: containers: - name: web image: asia.gcr.io/<projectid>/web-python:v1 ports: - containerPort: 5000 name: http protocol: TCP

Deployment で Pods をスケールする

Master

Docker kubeletkube proxy

supervisord

fluentd

WebPod

1

DBPod

Registry

replicas3

Deployment definitions (yaml)

WebPod

2

WebPod

3

replicas1

編集

Services

アプリケーションのエンドポイント

● TCP / UDP をサポート

● kube-proxy 経由で Iptables を操作

Types● ClusterIP (クラスタ内のみでアクセスできる VIP)● NodePort (クラスタ外からアクセス可能なサービス)● LoadBalancer (LB 経由でアクセス可能なサービス)● ExternalName (クラスタ外のサービスを指定可能)

apiVersion: v1kind: Servicemetadata: name: web labels: name: web app: demospec: selector: name: web type: LoadBalancer ports: - port: 80 targetPort: 5000 protocol: TCP

Service をデプロイ

Client

NodeWeb

Pod 1

DBPod

WebPod 2

WebPod 3

LB

ClusterIP

Port 6379

Port 80

エンドポイントを抽象化id: frontend-serviceport: 8080labels: role: frontend stage: productionType: LoadBalancer

Frontend Service

FE FE FE FE

MachineHost

MachineHost

MachineHost

MachineHost

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

port: 8080

Load-Balancing

Internet

エンドポイントを抽象化id: backend-serviceport: 9000labels: role: backend stage: productionType: ClusterIP

Backend Service

BE BE BE BE

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

MachineHost

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

ContainerAgent

FE

port: 9000

Load-Balancing

でも、FEはどうやってBEにアクセスするの?

k8s node

今までのまとめServiceport : 80

name : web

Deployment replicas=1

Podname : web

作成

公開

API Server

Pod にアクセス

管理者開発者

ユーザー

Service Discovery

Kuberenetes は2つのモードをビルトインでサポート

環境変数

→ Pod が実行すると、kubelet は自動的にクラスタ上で実行している各サービス

の環境変数を追加します

DNS→ 新しいサービスが作成されると、自動的に Service の DNS レコードが作成され

Service Discovery - 環境変数(例)

サービス名: ”redis-master”ポート: TCP 6379クラスタ内のIP: 10.0.0.11

REDIS_MASTER_SERVICE_HOST=10.0.0.11REDIS_MASTER_SERVICE_PORT=6379REDIS_MASTER_PORT=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_MASTER_PORT_6379_TCP_PROTO=tcpREDIS_MASTER_PORT_6379_TCP_PORT=6379REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11

Dev と Prod の差異は環境変数で解決

Dev 環境のクラスタ

サービス名:Web

サービス名:Redis Redis

Webredis_host = os.environ.get('REDIS_SERVICE_HOST', '')redis_port = os.environ.get('REDIS_SERVICE_PORT', 6379)

Prod 環境のクラスタ

Redis

Webredis_host = os.environ.get('REDIS_SERVICE_HOST', '')redis_port = os.environ.get('REDIS_SERVICE_PORT', 6379)

環境変数(自動生成)

REDIS_SERVICE_HOST=10.0.0.11REDIS_SERVICE_PORT=6379REDIS_PORT=tcp://10.0.0.11:6379REDIS_PORT_6379_TCP=tcp://10.0.0.11:6379REDIS_PORT_6379_TCP_PROTO=tcpREDIS_PORT_6379_TCP_PORT=6379REDIS_PORT_6379_TCP_ADDR=10.0.0.11

REDIS_SERVICE_HOST=10.0.1.11REDIS_SERVICE_PORT=6379REDIS_PORT=tcp://10.0.1.22:6379REDIS_PORT_6379_TCP=tcp://10.0.1.11:6379REDIS_PORT_6379_TCP_PROTO=tcpREDIS_PORT_6379_TCP_PORT=6379REDIS_PORT_6379_TCP_ADDR=10.0.1.11

コード変更不要

ConfigMap/Secret

コンテナイメージからアプリケーションの設定・パスワードを切り離してデプロイ可能とするリソース

ConfigMap → プレインテキスト

Secret → 暗号化可能(Alpha、k8s 1.7 以降)

2つの使い方:

1. Volume としてマウント

○ ConfigMap/Secret のキーがファイル名で、値がファイルの内容

○ nginx の設定ファイルを読み込む場合、この方法がオススメ

2. 環境変数に設定

○ Pod の定義に環境変数を指定することが可能

ConfigMap のファイルマウント(例)

コンテナイメージ コンテナイメージ

nginx nginx

nginx.conf

ConfigMap

nginx.conf

マウント

⭕�

メリット:ConfigMapのような外部リソースをマウントすると、設定を変更する際にイメージ自体を変更する必要がなくなる

Secret の環境変数(例)

$ kubectl get secret mysecret -o yamlapiVersion: v1data: username: YWRtaW4= password: MWYyZDFlMmU2N2Rmkind: Secret...type: Opaque

apiVersion: v1kind: Podmetadata: name: secret-env-podspec: containers: - name: mycontainer image: redis env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password restartPolicy: Never

$ echo -n "admin" > ./username.txt$ echo -n "1f2d1e2e67df" > ./password.txt$ kubectl create secret generic mysecret --from-file=./username.txt --from-file=./password.txtsecret "mysecret" created

Secret の作成

Secret の確認

環境変数経由でSecret の利用

Kubernetes での役割のサマリー

Kubernetes Master の役割は以下となる

→ API Server / Scheduler / Replication Controller各 Node は Pod を実行する役割

Pod は Kubernetes のデプロイ単位で、1か複数のコンテナを含む

Label は Kubernetes のオブジェクト間を紐付ける役割

Selector は Kubernetes のオブジェクトをフィルターする役割

Deployment は Pod の可用性を担保する役割

Service は Pod を内部、又は外部に公開する役割

Service Discovery はサービスを環境変数やDNSで解決する役割

ConfigMap/Secret は設定やパスワードをイメージから切り離す機能

Minikube - ローカル環境

サポートされている Kubernetes の機能

● DNS● NodePorts● ConfigMaps and Secrets● Dashboards● Container Runtime: Docker, and rkt● Enabling CNI (Container Network

Interface)● Ingress

サポートされている VM Drivers● virtualbox● vmwarefusion● kvm (driver installation)● xhyve (driver installation)

Google Container Engine (GKE)vs Kubernetes

Kubernetes は Google の Borg からインスパイア

Google は Kubernetes の複数の SIG をリードしたり、積極的に開発にも参加して

います。

→ Kubernetes は Google が論文で出した Borg (社内コンテナオーケストレーショ

ンシステム) からインスパイアーされている

GKE は Kubernetes の新しいバージョンや機能をより早くかつ自動的に対応

Private Container Registry→ Google Container Registry (GCR)

One click で k8s クラスタを作成

Kubernetes クラスタを手動で作る必要はない

普通だと、全てを手動でインストールする必要がある

● 例えば、ネットワーク:クラスタ間で Pod はどのように通信するのか? flannel や weave を使う? → GKE ではフルマネージド

● インストールが必要のバイナリー:

○ マスタ:etcd, kube-apiserver, kube-controller-manager, kube-scheduler○ 各ノード:docker, kubelet, kube-proxy

● API Server を HTTPS で設定するなら、証明書が必要

● Addonのインストール:DNS, Logging, Dashboard などなど

GKE が全部やってくれます!

Master はマネージドサービス

● Master は Google により管理されており、自動的に更新される

→ Node はユーザによってコントロール

→ ノードのマイナー バージョン(x.X.x)がマスターのバージョンより 3 つ以上

古くなると、そのノードは正しく動作しない場合がある

例: マスタが1.3 になると 1.0 が実行しているノードは動作しない場合がある

● クラスタの設定を持つ etcd の自動バックアップ

● Google の SRE が面倒見てくれます!

Node もマネージドモデルにオプトイン可能

● Node の自動アップグレード

→ Node を1by1:unschedulable → drain → 古いバージョンのNodeを削除 → 新しいバージョンのNodeを作成 → schedulable● Node の自動修復

→ Node が10分ほど応答しない場合、新しいNodeを作成する

● Node の自動スケール

→ Scheduler が Pod を既存の Node にスケジュールできない場合、新しい Node を作成し、Pod をその Node にスケジュールする(リソース不足の場合)

● 1 クラスタは 5,000 以上の Node をサポート

GCP とのネイティブ連携

● Cloud IAM→ クラスタのアクセス制御、クラスタ内は RBAC で

● Stackdriver Monitoring & Logging→ One click で Monitoring と Logging を設定

● Network Route , FW & Load Balancers (ingress)→ HTTP LB, TCP/UDP LB, Route & FW ルールを自動的に作成

● Persistent Disk (PDHDD & PDSSD)→ Stateful アプリケーションも PDHDD & PDSSD でサポート

→ ReplicaSet でも自動 PD のプロビジョニング

● GCP コンソールに Dashboard インテグレーション

GCP の Preemptible VM との連携

● Preempitble VM って何者?

→ 超安いVM!普通の VM の7割以上安い!

● おいしすぎる話なんすけど、デメリットはなに??

→ VM は Max 24 時間起動する。その後、シャットダウンされる。

● GKE と Preemptible VM との相性はなぜ?

→ GKE の自動修復機能で Preemptible VM のシャットダウンを修復する

● 使い分けが重要

Container-Optimized OS (COS)

● 高速なブート

→ スケールアウトが早い

● セキュリティ

→ コンテナに必要なコンポーネントだけを持つOS→ Verified boot

● Open Source→ https://cloud.google.com/container-optimized-os/

Thank you!

top related