序文
以下は、Kubernetesを経験豊富なKubernetesプラクティショナー向けのEdgio Delivery CDNサービスと統合した例である。 Kubernetesの知識のレベルと、TCP、DNS、HTTP/HTTPSなどの標準的なインターネットプロトコルの知識を前提としている。 最終的な目的は、Edgio Delivery CDNサービスを標準入力として表示する方法を示すことである。 KubernetesのユーザーはPortainerやTerraformのような使い慣れたシステムでIngressの設定を維持することができる。
Kubernetes
Kubernetes.ioは、Kubernetesを「コンテナ化されたアプリケーションのデプロイ、スケーリング、管理を自動化するためのオープンソースシステム」と定義している。 クラスタを起動する方法はいくつかある。 最も迅速かつ簡単な方法は、「ワンクリック」導入を可能にする多くのクラウドプロバイダーの1つを活用することである。
Kubernetesクラスタには多くの部分が含まれている。 デモでは、合計のサブセットに焦点を当てる。
Kubernetes Parts
- ノード:ワークロードとサービスをホストするマシンまたはVM。
- ワークロード:アプリケーションが単純または複雑
- ポッド:アプリケーションソフトウェアが実行されているコンテナ。 1つまたは複数のポッドがワークロードを構成する。
- サービス:ワークロードを他のワークロードまたはイングレスに公開するメカニズム
- Ingress:サービスを外部に公開するメカニズム
エドジオ
Edgioは、シームレスに統合された配信、アプリケーション、ストリーミングソリューションにより、エッジで比類のない速度、セキュリティ、シンプルさを実現し、コネクテッドライフをより速く、より安全に、より簡単に管理できるようにする。 世界規模のテクノロジーとエキスパートサービスは、世界のトップブランドに、最も速く、最もダイナミックで摩擦のない教育、エンターテインメント、イベント、アプリケーションをすべてのユーザーに提供する能力を与えている。 比類のない顧客の心配を提供し、道のあらゆるステップの価値を拡張することに捧げられて、Edgioは最も普及したショー、映画、スポーツ、ゲームおよび音楽を支えるために世界的なインターネット・トラフィックを運転し、そして即刻ロードのウェブサイトのパートナーである。
アーキテクチャ
Edgio Delivery CDN
このデモでは、GitHubのEdgio Python SDK–llnw/llnw-sdk-python: Limelight Networks Python SDKを使用する。 基本的な設定はシンプルにする。
CDNの設定には、認証以外に以下のデータが必要となる。
- Shortname: CDNルールを含むEdgio Delivery CDN内の一意の識別子。
- 公開ホスト名: CDNからインターネットに接続するホスト名。このデモの場合、ホスト名cstradtman.s.llnwi.netが以前に設定されている。
- 公開されたURLパス:問題の特定のルールにマップされたパス。
- Source Hostname:オリジンのホスト名。 この場合、ラウンドロビンレコードはKubernetesクラスタを指す。
- Source URL Path:ホスト名に関連付けられた宛先パス。 この場合は、後述するので空欄とする。 このデモでは、ワークロードはパスではなくポート番号で区別される。
DNS
このデモではVultr DNS APIを使用している。 オリジンとしてIPアドレスを使用してCDNを設定することはベストプラクティスではない。 このデモでは、APIを使用して、クラスタノードを指すラウンドロビンAレコードを作成または変更する。
クラスタ
デモは3ノードクラスタ上のVultrで行われている。
名前空間
このデモは、このクラスタ上で実行される唯一のものであるため、デフォルトの名前空間の下に存在する
ノード
- VKEクラスタ–各ノードが
- 4G RAM
- 80Gディスク
- 2 vCPU
- 1 Gネットワーク
ワークロード
ワークロードはHTTP接続に関する基本情報を返す単純なPythonプログラムである。 このデモをインラインでデプロイするが、これは一般的なデプロイ方法ではない。 しかし、これにより、コンテナを構築して格納するための外部依存関係を持つのではなく、デモを完全に自己完結させることができる。 ソースコードは付録1に記載されている。 実際のPythonコードはイタリック体であり、デプロイメントを記述するYAMLコードはイタリック体ではない。 ワークロードはTCPポート8000を使用する。
サービス
利用可能ないくつかのサービスタイプがある。 「NodePort」サービスタイプを使用している。 ランダムに選択された上位ポート番号のクラスタの外部IPアドレス上のサービスを公開する。 Kubernetesはワークロードが実行されるノードへの接続を処理する。
イングレス
Kubernetes Ingressは、クラスターの外部でKubernetesサービスを利用できるようにするリソースの集まりの動作を記述するソフトウェアオブジェクトである。
入力コントローラは、入力ソフトウェアオブジェクトをインスタンス化するソフトウェアまたはハードウェアを組み合わせたものである。
CDNは機能豊富な分散リバースプロキシであり、リバースプロキシ機能のほかに、CDNは通常、柔軟なキャッシュアルゴリズム、地理的多様性、セキュリティ機能(ACL(GEO、メソッド、regex)、Webアプリケーションファイアウォール、ウォーターマークなど、単純なリバースプロキシにはない高度な機能を備えている。
Kubernetesオブジェクト監視用のAPIは十分に定義されており、多くのHTTPリバースプロキシとロードバランサが入力コントローラとして動作するように拡張されている。 例えば、NGINXとHAProxyは古いプロキシであり、Ingressコントローラとして動作するよう拡張されており、TraefikやItsioのようなものがKubernetesと並行して開発されている。 CDNは単純な逆プロキシからの自然な次の進歩である。 このデモでは、Edgio Delivery CDNを制御するカスタムIngressコントローラを作成する。 通常、入力を記述するために必要なデータは
- パブリックホスト名:Kubernetesサービスが使用可能になるホスト名。
- パブリックパス:Kubernetesサービスが使用可能になるパブリックホスト名に関連付けられたパス
- バックエンドサービス名:Kubernetes servicesスタンザで定義されたservice-name
- Backend Port:サービス説明のポート説明と一致する名前
Edgio Delivery CDNアセットマッピング:
Kubernetes |
Edgio Delivery CDN |
パブリックホスト名 |
公開されているホスト名 |
パブリック・パス |
公開されたURLパス |
バックエンドサービス名 Kubernetesクラスタ内で一意 外部に知られていない/利用できない |
ソースホスト名 完全修飾ドメイン名 One to Oneではなく |
その背後にある論理:
- クラスタからの名前空間入力イベントをリッスンする
- イベントタイプが「追加」の場合。
- クラスタ内のノードのIPアドレスを取得する
- vultrでDNSレコードを作成する
- 作成されたDNSレコードとNodePortサービスによって割り当てられたポートを指すEdgio CDNでCDNルールを作成する。
- イベントタイプが「modified」の場合。
- Edgio CDNで既存の入力に一致するCDNルールを検索する
- イベントに新しいデータを反映するようにEdgio CDNのルールを変更する
- イベントタイプが「deleted」の場合。
- 削除された入力と一致するEdgio CDNのCDNルールを検索する
- この入力に関連付けられているVultrのDNSレコードを削除する
- 削除された入力と一致するEdgioのCDNルールを削除する
構成
オブジェクト
KubernetesオブジェクトはYAMLファイルに記述されている。 Kubernetesでは、すべての設定はオブジェクトである。 すべての配置構成を1つのファイルに格納できる。 導入のどの部分を説明しているかに基づいて、それらを分割するのが一般的な方法である。
展開
付録1には、PythonコードとYAMLを組み合わせた大きなYAMLファイルがある。 「spec.template.spec.containers.command”」の後のすべては、デプロイ中にコンテナに変換されるPythonコードである。 Kubernetesオブジェクトの観点から、デモで重要な行は次のとおりである。
- 種類:配置–オブジェクトを配置として記述する
- Metadata.name:nameはサービスオブジェクトによって2つの間のリンクを作成するために使用される。
- Spec.selector.matchlabels.app:は、デプロイがどのポッドに適用されるかを示す。
- Spec.template.spec.containers.image:DockerハブのPython 3公式イメージを指す
- Spec.template.spec.containers.ports.name:この場合、他のオブジェクトサービスで参照されるポートのラベル
- Spec.template.spec.containers.ports.containerport:実行中のコンテナから公開されたTCPポートを一覧表示する
サービス
- 種類:配置–オブジェクトを配置として記述する
- Metadata.name:nameは、2つの間のリンクを作成するためにIngressオブジェクトによって使用される。
- Spec.selector.app:は、デプロイメントオブジェクトで指定されたデプロイメントの名前–pywai-inline-serviceを指す。
- Spec.selector.type: NodePort上記のように、このサービスをNodePort型として定義する
- Spec.ports.name:他のオブジェクトによって参照されるポートのラベル(この場合はIngress)
- Spec.ports.protocol:は使用中のIPプロトコルを定義–TCP
- Spec.Ports.port:このサービスによって公開されるポートを定義する
- spec.ports.targetPort :デプロイによって公開されるポートを指す–pywai-inline-deploymentこの場合
イングレス
付録3では、Edgio IngressコントローラのKubernetesオブジェクトを記述したYAMLファイルを見る。 関連するオブジェクトは次のとおりである。
- Kind:Ingress–KubernetesにIngressオブジェクトであることを伝える
- Medatdata.name–Kubernetes内のすべてに名前が必要
- Metadata.labels.cdn–このタグは、このオブジェクトがedgio入力コントローラ用であることを入力コントローラに通知するために使用される
- Spec.rules.host–サービスを公開するためのパブリックホスト名。
- Spec.rules.http.paths.path–サービスに関連付けられたパス。
- Spec.rules.http.paths.backend.service.name–公開するサービスのラベル
- Spec.rules.http.paths.backend.service.port.name–公開するサービスのポートのラベル
設定マップ
秘密
Kubernetesには機密データの保存のための秘密の概念が組み込まれている。 このデモでは、Edgio SDKとVultr DNS APIの両方のユーザー名と共有キーにこれを活用
コード例
git reposに含まれているこのデモのコード
- Edgio Delivery Python SDK
- Kubernetesのデモデプロイメント
- https://github.com/llnw/edgio-delivery-k8s-demo
- これらはYAMLとして記述される一連のKubernetesオブジェクトであり、Edgio Delivery統合のデプロイ方法を示す
- Edgio Delivery入力コントローラのデモ
- https://github.com/llnw/edgio-delivery-k8s-ingress-demo
- これは、Edgio Delivery Ingressコントローラを実装する実際のコードである
- 長期的にはKubernetes内のサービスとして実行する必要があるが、デモをシンプルに保つためには、単に別のプロセスとして実行するだけでよい
現在の設計に対する将来の追加と拡張
今後の投稿では、アプリケーションなどの他のEdgioソリューションを活用する方法を示す。 Kubernetesクラスターを使用して、異なるワークフローのために複数のEdgio CDNオファリング間で構成を活用して同期する方法として使用できる。
付録1–pywai-inline-deployment.yaml
apiVersion:apps/v1
種類:展開
メタデータ:
名前:pywai-inline-deployment
仕様:
セレクター:
MatchLabels:
app:pywai-inline-deployment
レプリカ:1
テンプレート:
メタデータ:
ラベル:
app:pywai-inline-deployment
仕様:
コンテナ:
–name: Python
画像:Python:3
コマンド:
–/bin/sh
–“-c”
–|
>cat/ test.py <<EOF
#!/usr/bin/env python3
“”
リクエストをログに記録するためのPythonの非常に単純なHTTPサーバ
用途:
./ server.py [<ポート>]
“”
http.serverからBaseHTTPRequestHandler, HTTPServerをインポートする
インポートログ
インポートププリント
クラスS(BaseHTTPRequestHandler):
def_set_response(self):
self.send_response(200)
self.send_header(‘Content-type’、‘text/html’)
self.end_headers ()
def do_get(self):
logging.info(“GETリクエスト、\nパス:%s\nヘッダー:\n%s\n”、str(self.path)、str(pprint.pformat(self.headers))
self._set_response ()
headerinfo=pprint.pformat(self.headers.items)
clientinfo=pprint.pformat(self.client_address)
lineinfo=print.pformat(self.requestline)
versionInfo=pprint.pformat(self.request_version)
self.wfile.write(“<>pre{}/pre<>”.format(headerinfo).encode(‘UTF-8’))
self.wfile.write(“<>pre{}/pre<>”.format(clientinfo).encode(‘UTF-8’))
self.wfile.write(“<>pre{}/pre<>”.format(lineinfo).encode(‘UTF-8’))
self.wfile.write(“<>pre{}/pre<>”.format(versionInfo).encode(‘UTF-8’))
def run(server_class=HTTPServer, handler_class=S, port=8080):
logging.basicConfig(level=logging.INFO)
server_address=(“、ポート)
httpd= server_class(server_address、handler_class)
logging.info(‘Starting httpd…\n’)
試してみる:
httpd.serve_forever ()
KeyboardInterruptを除く:
合格
httpd.server_close ()
logging.info(‘Stopping httpd…\n’)
__name__==‘__main___’の場合:
sys import argvから
len(argv)== 2の場合:
run(port=int(argv[1]))
その他:
run ()
EOF
exec python/ test.py 8000
ポート:
–名前:http
containerPort:8000
付録2–pywai-inline-service.yaml
apiVersion: v1
種類:サービス
メタデータ:
名前:pywai-inline-service
仕様:
セレクター:
app:pywai-inline-deployment
タイプ:NodePort
ポート:
–名前:http
プロトコル:TCP
ポート:80
targetPort:8000
付録3–pywai-edgio-ingress.yaml
apiVersion: networking.k8s.io/v1
種類:入力
メタデータ:
名前:external-pywai-inline-ingress
注釈:
Kubernetes.io/ingress.class:edgio
ラベル:
cdn:edgio
仕様:
ルール:
–host:<一意のショートネーム>.s.llnwi.netを入力
http:
パス:
–path:/fred
パスタイプ:Exact
バックエンド:
サービス:
名前:external-pywai-inline-service
ポート:
名前:pywai-port