Swarm、Kubernetes、NomadでDocker投票を実行する方法

TL DR
この記事では、HashicorpのSwarm、Kubernetes、およびNomadに投票するDockerアプリケーションをデプロイします。 このすべてを試してみたのと同じくらい、この記事を読んで楽しんでください。

テクノロジーを使用する場合は、好奇心が必要です。 これは、現場で何が起こっているかを常に学び、最新の状態に保つために必要です。 すべてが非常に速く変化します。

コンテナオーケストレーションは議論の対象として非常にホットなトピックであるため、お気に入りの楽器があったとしても、他の楽器がどのように機能し、それらについて新しいことを学ぶのは興味深いことです。

投票アプリ


以前の記事で投票アプリを使用しました。 アプリケーションはマイクロサービスアーキテクチャで実行され、5つのサービスで構成されています。 画像


githubリポジトリにあるように、アプリケーションにはいくつかの構成ファイルがあります: https : //github.com/dockersamples/example-voting-app

Docker-stack.yml-アプリケーションの本番プレゼンテーションで使用する準備ができました。 ファイル自体は次のとおりです。

version: "3" services: redis: image: redis:alpine ports: - "6379" networks: - frontend deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure db: image: postgres:9.4 volumes: - db-data:/var/lib/postgresql/data networks: - backend deploy: placement: constraints: [node.role == manager] vote: image: dockersamples/examplevotingapp_vote:before ports: - 5000:80 networks: - frontend depends_on: - redis deploy: replicas: 2 update_config: parallelism: 2 restart_policy: condition: on-failure result: image: dockersamples/examplevotingapp_result:before ports: - 5001:80 networks: - backend depends_on: - db deploy: replicas: 1 update_config: parallelism: 2 delay: 10s restart_policy: condition: on-failure worker: image: dockersamples/examplevotingapp_worker networks: - frontend - backend deploy: mode: replicated replicas: 1 labels: [APP=VOTING] restart_policy: condition: on-failure delay: 10s max_attempts: 3 window: 120s placement: constraints: [node.role == manager] visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" stop_grace_period: 1m30s volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] networks: frontend: backend: volumes: db-data: 

通常、このファイルには6つのサービスがあり、アプリケーションアーキテクチャには5つのサービスしかありません追加のサービスは、サービスが展開されている場所を示すインターフェイスを提供する優れたツールであるビジュアライザーです。

Docker swarm


Docker Swarmは、Dockerコンテナーのクラスターを管理および作成するためのツールです。 管理者と開発者は、Swarmを使用して、ノードのクラスターを単一の仮想システムとして作成および管理できます。

Swarmコンポーネント


Swarmクラスターはいくつかのノードで構成され、一部はマネージャーとして機能し、他はエグゼキューターとして機能します。


画像

マネージャーは、内部分散ストレージを共有して、一貫したクラスター状態を維持します。 これは、Raftログによって確認されます。

Swarmでは、サービスはアプリケーションのデプロイ方法とコンテナ内での動作方法を定義します。

Dockerをインストールする


Dockerがまだインストールされていない場合は、OS用のDocker CE(Community Edition)ダウンロードできます

Swarmを作成する


Dockerをインストールすると、1つのチームだけがSwarmの実行から私たちを分離します

$ docker swarm init

Swarmクラスターに必要なのはこれだけです。 これは単一ノードのクラスターですが、関連するすべてのプロセスを持つクラスターのままです。

アプリケーションの展開


githubのアプリケーションリポジトリで利用可能な構成ファイルのうち、Swarmを介してアプリケーションをデプロイするにはdocker-stack.ymlが必要です。

 $ docker stack deploy -c docker-stack.yml app Creating network app_backend Creating network app_default Creating network app_frontend Creating service app_visualizer Creating service app_redis Creating service app_db Creating service app_vote Creating service app_result Creating service app_worker 

スタックはポピーのドッカーで実行されているため、ローカルマシンからすぐにアプリケーションにアクセスできます。 投票インターフェース(ポート5000)を使用して猫または犬を選択し、ポート5001で結果を確認できます。

画像画像

ここでは詳細に立ち入らず、Swarmを使用してアプリケーションを簡単にデプロイできることを示したかっただけです。

複数のノードを使用してSwarmを介してアプリケーションをデプロイする方法の詳細な説明が必要な場合は、 この記事を読むことができます。

クベルネテス


Kubernetesは、コンテナ化されたアプリケーションの展開、スケーリング、および管理を自動化するためのオープンソースプラットフォームです。

Kubernetes Concept


Kubernetesクラスターは、1つ以上のマスターとノードで構成されます。


画像

コマンドを入力するには、kubectl CLIを使用します。 以下では、いくつかの使用例を検討します。

アプリケーションのデプロイ方法を理解するには、いくつかの高レベルのKubernetesオブジェクトについて知る必要があります。


このパートでは、アプリケーションサービスごとに展開とサービスを使用します。

kubectlをインストールする


Kubectlは、Kubernetesでアプリケーションを展開および管理するためのコマンドラインです。


インストールには、公式ドキュメント(https://kubernetes.io/docs/tasks/tools/install-kubectl/)を使用します。 たとえば、Macにインストールするには、次のコマンドを入力します。

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/darwin/amd64/kubectl
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl


ミニキューブのインストール


MinicubeはKubenetesの包括的な設定です。 ローカルVMを作成し、すべてのKubernetesプロセスが実行されているノードクラスターを起動します。 間違いなく、これは運用クラスタをインストールするために使用すべきツールではありませんが、開発とテストに使用すると本当に便利です。

Minicubeをインストールすると、1つのノードでクラスターをインストールするために必要なコマンドは1つだけです。

$ minikube start
Starting local Kubernetes v1.7.0 cluster…
Starting VM…
Downloading Minikube ISO
97.80 MB / 97.80 MB [==============================================] 100.00% 0s
Getting VM IP address…
Moving files into cluster…
Setting up certs…
Starting cluster components…
Connecting to cluster…
Setting up kubeconfig…
Kubectl is now configured to use the cluster.


記述子Kubernetes


Kubernetesでは、 Deploymentによって制御されるReplicaSetを介してコンテナーが起動されます。
以下はDeploymentを説明する.ymlファイルの例です。 ReplicaSetは、2つのNginxレプリカの起動を提供します。

 // nginx-deployment.yml apiVersion: apps/v1beta1 kind: Deployment metadata: name: nginx-deployment spec: replicas: 2 # tells deployment to run 2 pods matching the template template: # create pods using pod definition in this template metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 

展開を作成するには、kubectl CLIを使用する必要があります。

マイクロサービスで構成されるアプリケーションを作成するには、サービスごとに展開ファイルを作成する必要があります。 これは手動で行うことも、 Komposeを使用することもできます。

Komposeを使用してデプロイメントとサービスを作成する


Komposeは、Docker構成ファイルをKubernetesが使用する記述子ファイルに変換するツールです。 このサービスの方が便利で、移行プロセスを高速化します。

注:
Komposeはオプションで、すべてを手動で作成できますが、展開プロセスを大幅に高速化します


# Linux
$ curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-linux-amd64 -o kompose
# macOS
$ curl -L https://github.com/kubernetes/kompose/releases/download/v1.0.0/kompose-darwin-amd64 -o kompose

$ chmod +x kompose
$ sudo mv ./kompose /usr/local/bin/kompose


Komposeでdocker -stack.ymlを開始する前に、少し変更して各サービスのデプロイキーを削除します。 このキーは認識されないため、記述子ファイルの生成時にエラーが発生する場合があります。 ネットワークに関する情報を削除することもできます。 Komposeでは、docker -stack-k8s.ymlを呼び出す新しいファイルを提供します。

 version: "3" services: redis: image: redis:alpine ports: - "6379" db: image: postgres:9.4 volumes: - db-data:/var/lib/postgresql/data vote: image: dockersamples/examplevotingapp_vote:before ports: - 5000:80 depends_on: - redis result: image: dockersamples/examplevotingapp_result:before ports: - 5001:80 depends_on: - db worker: image: dockersamples/examplevotingapp_worker visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" stop_grace_period: 1m30s volumes: - "/var/run/docker.sock:/var/run/docker.sock" volumes: db-data: 

docker-stack-k8s.ymlファイルから、次のコマンドを使用してアプリケーションの記述子生成します。

$ kompose convert --file docker-stack-k8s.yml
WARN Volume mount on the host "/var/run/docker.sock" isn't supported - ignoring path on the host
INFO Kubernetes file "db-service.yaml" created
INFO Kubernetes file "redis-service.yaml" created
INFO Kubernetes file "result-service.yaml" created
INFO Kubernetes file "visualizer-service.yaml" created
INFO Kubernetes file "vote-service.yaml" created
INFO Kubernetes file "worker-service.yaml" created
INFO Kubernetes file "db-deployment.yaml" created
INFO Kubernetes file "db-data-persistentvolumeclaim.yaml" created
INFO Kubernetes file "redis-deployment.yaml" created
INFO Kubernetes file "result-deployment.yaml" created
INFO Kubernetes file "visualizer-deployment.yaml" created
INFO Kubernetes file "visualizer-claim0-persistentvolumeclaim.yaml" created
INFO Kubernetes file "vote-deployment.yaml" created
INFO Kubernetes file "worker-deployment.yaml" created


各サービスについて、展開ファイルとサービスが作成されることがわかります。
警告は1つだけ受け取りました。 Dockerソケットに接続できないため、 ビジュアライザーと接続されます。 このサービスの開始は試みませんが、残りに焦点を合わせます。

アプリケーションの展開


kubectlを使用して、記述子ファイルで指定されたすべてのコンポーネントを作成します。 ファイルが現在のフォルダーにあることを示します。

$ kubectl create -f .
persistentvolumeclaim "db-data" created
deployment "db" created
service "db" created
deployment "redis" created
service "redis" created
deployment "result" created
service "result" created
persistentvolumeclaim "visualizer-claim0" created
deployment "visualizer" created
service "visualizer" created
deployment "vote" created
service "vote" created
deployment "worker" created
service "worker" created
unable to decode "docker-stack-k8s.yml":...


注:変更した構成ファイルを現在のフォルダーに残したため、解析できないためエラーが発生しました。 しかし、この間違いはリスクなしで無視できます。

これらのコマンドを使用すると、作成されたサービスデプロイメントを確認できます。
画像

外の世界からアプリケーションにアクセスできるようにします


投票結果のインターフェースにアクセスするには、それらのために作成されたサービスをわずかに変更する必要があります。

投票用に生成された記述子は次のとおりです。

 apiVersion: v1 kind: Service metadata: creationTimestamp: null labels: io.kompose.service: vote name: vote spec: ports: - name: "5000" port: 5000 targetPort: 80 selector: io.kompose.service: vote status: loadBalancer: {} 

サービスのタイプを変更し、 ClusterIPNodePortに置き換えます。 ClusterIPはサービスを内部で利用可能にし、 NodePortはポートをクラスターの各ノードで公開し、世界中で利用できるようにします。 投票結果の両方に外部からアクセスできるようにするためresultに対しても同じことを行います。

 apiVersion: v1 kind: Service metadata: labels: io.kompose.service: vote name: vote spec: type: NodePort ports: - name: "5000" port: 5000 targetPort: 80 selector: io.kompose.service: vote 

両方のサービス( 投票結果 )に変更を加えたら、それらを再作成できます。

$ kubectl delete svc vote
$ kubectl delete svc result
$ kubectl create -f vote-service.yaml
service "vote" created
$ kubectl create -f result-service.yaml
service "result" created


アプリケーションへのアクセス


次に、 投票および結果サービスの詳細を取得し、それらが提供するポートを取得します。
画像

投票はポート30069で利用でき、 結果は31873です。今度は投票して結果を確認します。
画像画像

Kubernetesの基本コンポーネントを理解した後、アプリケーションを簡単にデプロイできました。 Komposeは私たちを大いに助けてくれました。

ハシコープの遊牧民


Nomadは、マシンのクラスターを管理し、それらでアプリケーションを実行するためのツールです。 マシンとアプリケーションホストを抽象化し、ユーザーが実行したいことを言うことができるようにします。 そして、Nomadは、それがどこでどのように起動されるかについて責任を負います。

ノマドコンセプト


Nomadクラスターは、 サーバー (サーバー)モードまたはクライアント (クライアント)モードで動作できるエージェントで構成されています。


画像

Nomadクラスターでは、いくつかのタイプのタスクを起動できます。

アプリケーションをデプロイするには、Nomadの基本概念を理解する必要があります。


設置


この例では、Docker Machineを使用して作成されたDockerホストでアプリケーションを実行します。 ローカルIP-192.168.1.100。 まず、Consulを実行します。Consulは、サービスの検出と登録に使用されます。 Nomadを起動し、アプリケーションをJob in Nomadとしてデプロイします。

サービスの登録と発見のための領事


サービスを検出して登録するには、NomadのJobのように機能しないConsulなどのツールをお勧めします。 領事はリンクからダウンロードできます。

このコマンドは、Consulサーバーをローカルで起動します。

$ consul agent -dev -client=0.0.0.0 -dns-port=53 -recursor=8.8.8.8

使用されるオプションを詳しく見てみましょう。

Nomadはこのリンクからダウンロードできます。

ノードを持つクラスターを作成する


Nomadをダウンロードしたら、次の設定でエージェントを起動できます。

 // nomad.hcl bind_addr = "0.0.0.0" data_dir = "/var/lib/nomad" server { enabled = true bootstrap_expect = 1 } client { enabled = true network_speed = 100 } 

エージェントはサーバーとクライアントの両方として機能します。 bind_addrは、タスクを外部から受け入れることができるように、どのインターフェイスでも動作する必要があることを指摘します。 次の設定でNomad Agentを起動します。

$ nomad agent -config=nomad.hcl
==> WARNING: Bootstrap mode enabled! Potentially unsafe operation.
Loaded configuration from nomad-v2.hcl
==> Starting Nomad agent...
==> Nomad agent configuration:
Client: true
Log Level: INFO
Region: global (DC: dc1)
Server: true
Version: 0.6.0
==> Nomad agent started! Log data will stream in below:


注:デフォルトでは、NomadはローカルのConsulインスタンスに接続します。
単一ノードクラスターをインストールしました。 一意のメンバーに関する情報は次のとおりです。

$ nomad server-members
Name Address Port Status Leader Protocol Build Datacenter Region
neptune.local.global 192.168.1.100 4648 alive true 2 0.6.0 dc1 global


アプリケーションの展開


Swarmを使用してアプリケーションをデプロイするには、すぐに構成ファイルを使用できます。 Kubernetesを介してデプロイするには、同じ構成ファイルからの記述子が必要です。 これはすべて、Nomadを通じてどのように行われますか?

まず、Kompose for Hashicorpに似たツールはありません。そのため、コンマのNomadへの移行を簡単にすることができます(ちなみに、オープンソースプロジェクトにとっては良い考えです)。 Jobsgroupstasksを記述するファイルは手動で作成する必要があります。

これについては、 RedisおよびVoteサービスのジョブについて説明する際に詳しく見ていきます。 他のサービスについては、このようになります。

Redisのジョブの定義


このファイルは、アプリケーションのRedisの一部を定義します。

 // redis.nomad job "redis-nomad" { datacenters = ["dc1"] type = "service" group "redis-group" { task "redis" { driver = "docker" config { image = "redis:3.2" port_map { db = 6379 } } resources { cpu = 500 # 500 MHz memory = 256 # 256MB network { mbits = 10 port "db" {} } } service { name = "redis" address_mode = "driver" port = "db" check { name = "alive" type = "tcp" interval = "10s" timeout = "2s" } } } } } 

ここに何が書かれているか見てみましょう:


ジョブが正しく実行されるかどうかを確認するには、 planコマンドを使用します。

 $ nomad plan redis.nomad + Job: "nomad-redis" + Task Group: "cache" (1 create) + Task: "redis" (forces create) Scheduler dry-run: - All tasks successfully allocated. Job Modify Index: 0 To submit the job with version verification run: nomad run -check-index 0 redis.nomad When running the job with the check-index flag, the job will only be run if the server side version matches the job modify index returned. If the index has changed, another user has modified the job and the plan's results are potentially invalid. 

すべてが機能しているようです。 次に、このジョブを使用してタスクを展開します。

 $ nomad run redis.nomad ==> Monitoring evaluation "1e729627" Evaluation triggered by job "nomad-redis" Allocation "bf3fc4b2" created: node "b0d927cd", group "cache" Evaluation status changed: "pending" -> "complete" ==> Evaluation "1e729627" finished with status "complete" 

プレースメントが作成されたことがわかります。 彼のステータスを確認してください:

 $ nomad alloc-status bf3fc4b2 ID = bf3fc4b2 Eval ID = 1e729627 Name = nomad-redis.cache[0] Node ID = b0d927cd Job ID = nomad-redis Job Version = 0 Client Status = running Client Description = <none> Desired Status = run Desired Description = <none> Created At = 08/23/17 21:52:03 CEST Task "redis" is "running" Task Resources CPU Memory Disk IOPS Addresses 1/500 MHz 6.3 MiB/256 MiB 300 MiB 0 db: 192.168.1.100:21886 Task Events: Started At = 08/23/17 19:52:03 UTC Finished At = N/A Total Restarts = 0 Last Restart = N/A Recent Events: Time Type Description 08/23/17 21:52:03 CEST Started Task started by client 08/23/17 21:52:03 CEST Task Setup Building Task Directory 08/23/17 21:52:03 CEST Received Task received by client 

コンテナは正しく起動されています。 Consul DNSサーバーをチェックして、サービスも正しく登録されていることを確認しましょう。

 $ dig @localhost SRV redis.service.consul ; <<>> DiG 9.10.3-P4-Ubuntu <<>> @localhost SRV redis.service.consul ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35884 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;redis.service.consul. IN SRV ;; ANSWER SECTION: redis.service.consul. 0 IN SRV 1 1 6379 ac110002.addr.dc1.consul. ;; ADDITIONAL SECTION: ac110002.addr.dc1.consul. 0 IN A 172.17.0.2 ;; Query time: 0 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Wed Aug 23 23:08:36 CEST 2017 ;; MSG SIZE rcvd: 103 

タスクはIP 172.17.0.2によってホストされ、そのポートは先に示したように6379です。

投票のための仕事の定義


投票サービスのジョブを定義します。 次のファイルを使用します。

 // job.nomad job "vote-nomad" { datacenters = ["dc1"] type = "service" group "vote-group" { task "vote" { driver = "docker" config { image = "dockersamples/examplevotingapp_vote:before" dns_search_domains = ["service.dc1.consul"] dns_servers = ["172.17.0.1", "8.8.8.8"] port_map { http = 80 } } service { name = "vote" port = "http" check { name = "vote interface running on 80" interval = "10s" timeout = "5s" type = "http" protocol = "http" path = "/" } } resources { cpu = 500 # 500 MHz memory = 256 # 256MB network { port "http" { static = 5000 } } } } } } 

ただし、Redisに使用したファイルとはいくつかの違いがあります。


 // app.py def get_redis(): if not hasattr(g, 'redis'): g.redis = Redis(host="redis", db=0, socket_timeout=5) return g.redis 

この場合、 redisを使用してIPコンテナーを取得するには投票の あるコンテナーがConsul DNSサーバーを使用する必要があります。 コンテナからのDNSクエリは、Dockerブリッジ(172.17.0.1)を介して実行されます。 dns_search_domainsは、サービスXがConsul内のX.service.dc1.consulとして登録されていることを判別します


他のサービスに対して同じ設定を行うことができます:worker、postgres、result。

アプリケーションへのアクセス


すべてのジョブが実行されている場合、ジョブのステータスを確認し、すべてが機能することを確認できます。

画像

これは、Consulインターフェースでも見ることができます。

画像

IPノード(この例では192.168.1.100) によりvoteおよびresultを使用してインターフェースにアクセスできます。

まとめ


ここに、そのような投票投票がデモンストレーションの面で素晴らしいアプリケーションです。 オーケストラを使用してコードを変更せずに展開できるかどうかを知りたいと思いました。 はい、タンバリンとの特別なダンスがなくてもできます。

この記事がSwarm、Kubernetes、Nomadの基本を理解するのに役立つことを願っています。 また、Dockerで起動しているものとオーケストラの使用方法を知ることも興味深いでしょう。

Source: https://habr.com/ru/post/J339508/


All Articles