KubernetesのマニフェストをMagnumで実行する
![](https://thinkit.co.jp/sites/default/files/styles/main_image_730x/public/main_images/9378_main.png?itok=QaIop9Bw)
はじめに
2015年1月20日、コンテナサービスMagnumの最初のバージョンがリリースされました。Magnumは、Docker swarmやKubernetesなどのコンテナクラスタを提供するOpenStackのAPIサービスであり、これらの環境をコマンドで構築し、操作できます。本連載では、Fedora21とDevstackを用いてMagnum環境を構築し、Kubernetesの操作手順についてご紹介しています。
第3回では、Magnumの動作とKubernetesの概要を説明し、Magnumで構築したKubernetes上でnginxを動かします。
Magnumは何をしているのか
前回はMagnumをインストールして、Bayを作成しました。Bayを作る際にMagnumは下記のHeatのテンプレートを用いてKubernetes環境を作成しています。
$ ls /opt/stack/magnum/magnum/templates/heat-kubernetes/ COPYING kubemaster-coreos.yaml README.md kubemaster-fedora-ironic.yaml elements/ kubemaster.yaml fragments/ kubeminion-coreos.yaml kubecluster-coreos.yaml kubeminion-fedora-ironic.yaml kubecluster-fedora-ironic.yaml kubeminion.yaml kubecluster.yaml
これらのテンプレートは、Novaを呼び出して仮想マシンを作成し、Cinderを呼び出してdocker storageで必要になるボリュームを切り出し、Neutronを呼び出してネットワークを設定しています。そしてHeatのSoftwareConfig機能を用いてKubernetesに必要な設定を行っています。それらの設定は、fragmentsフォルダ以下のシェルスクリプトが行います。
$ ls /opt/stack/magnum/magnum/templates/heat-kubernetes/fragments/ add-proxy.sh kube-examples.yaml configure-docker-registry.sh kube-register.yaml configure-docker-storage.sh kube-user.yaml configure-etcd.sh make-cert-client.sh configure-flannel.sh make-cert.sh configure-kubernetes-master.sh network-config-service.sh configure-kubernetes-minion.sh network-service.sh coreos.params.yaml write-heat-params-master.yaml disable-selinux.sh write-heat-params.yaml enable-docker-registry.sh write-kube-os-config.sh enable-etcd.sh write-kubeconfig.yaml enable-services-master.sh write-network-config.sh enable-services-minion.sh
例えば、kubernetes masterの設定を行うconfigure-kubernetes-master.shは、以下のようになっています。
$ cat fragments/configure-kubernetes-master.sh #!/bin/sh . /etc/sysconfig/heat-params echo "configuring kubernetes (master)" sed -i ' /^ETCD_LISTEN_CLIENT_URLS=/ s/=.*/="http:\/\/0.0.0.0:2379"/ ' /etc/etcd/etcd.conf sed -i ' /^KUBE_ALLOW_PRIV=/ s/=.*/="--allow_privileged='"$KUBE_ALLOW_PRIV"'"/ ' /etc/kubernetes/config KUBE_API_ARGS="--runtime_config=api/all=true" if [ "$TLS_DISABLED" == "True" ]; then KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0 --insecure-port=$KUBE_API_PORT" else KUBE_API_ADDRESS="--bind_address=0.0.0.0 --secure-port=$KUBE_API_PORT" # insecure port is used internaly KUBE_API_ADDRESS="$KUBE_API_ADDRESS --insecure-port=8080" KUBE_API_ARGS="$KUBE_API_ARGS --tls_cert_file=/srv/kubernetes/server.crt" KUBE_API_ARGS="$KUBE_API_ARGS --tls_private_key_file=/srv/kubernetes/server.key" KUBE_API_ARGS="$KUBE_API_ARGS --client_ca_file=/srv/kubernetes/ca.crt" fi sed -i ' /^KUBE_API_ADDRESS=/ s/=.*/='"${KUBE_API_ADDRESS}"'/ /^KUBE_SERVICE_ADDRESSES=/ s|=.*|="--service-cluster-ip-range='"$PORTAL_NETWORK_CIDR"'"| /^KUBE_API_ARGS=/ s/KUBE_API_ARGS.// /^KUBE_ETCD_SERVERS=/ s/=.*/="--etcd_servers=http:\/\/127.0.0.1:2379"/ /^KUBE_ADMISSION_CONTROL=/ s/=.*/=""/ ' /etc/kubernetes/apiserver cat << _EOC_ >> /etc/kubernetes/apiserver #Uncomment the following line to disable Load Balancer feature KUBE_API_ARGS="$KUBE_API_ARGS" #Uncomment the following line to enable Load Balancer feature #KUBE_API_ARGS="$KUBE_API_ARGS --cloud_config=/etc/sysconfig/kube_openstack_config --cloud_provider=openstack" _EOC_ sed -i ' /^KUBELET_ADDRESSES=/ s/=.*/="--machines='""'"/ /^KUBE_CONTROLLER_MANAGER_ARGS=/ s/KUBE_CONTROLLER_MANAGER_ARGS.*/#Uncomment the following line to enable Kubernetes Load Balancer feature \n#KUBE_CONTROLLER_MANAGER_ARGS="--cloud_config=\/etc\/sysconfig\/kube_openstack_config --cloud_provider=openstack"/ ' /etc/kubernetes/controller-manager
configure-kubernetes-master.shが行っていることは、設定ファイルの作成と、magnumコマンドの引数をその設定ファイルに代入することです。代入には、sedコマンドが用いられています。
Magnumは特に難しいことをしているわけではなく、Heatのテンプレートとシェルスクリプトを活用してコンテナクラスタを構築しています。現時点でのゲストのイメージは、KubernetesやDockerがインストールされたAtomic-hostもしくはCoreOSを前提として動いています。
Kubernetesの概要
KubernetesはDockerコンテナのオーケストレーションシステムを管理します。PodやService、Replication Controllerといった概念があり、Magnumからそれらを作成することが可能です。作成するためには「マニフェスト」と呼ばれるファイル(jsonまたはyaml形式で記述)を用意し、Magnumのコマンドに与える必要があります。
Podのマニフェスト
Podは複数のDockerコンテナをまとめた単位です。Pod内のコンテナは、Linuxネームスペースの以下のコンテキストを共有します。
- PID名前空間
- Network名前空間
- IPC名前空間
- UTS名前空間
例えばNetwork名前空間がコンテナ同士で共有されているので、Pod内のコンテナ同士はIPアドレスを共有します。またそれぞれのコンテナが同じ共有ディスクにアクセスできるので、同じノードで実行するのに適したアプリケーションのコンテナ群は、同じPodに入れます。
ここでは実験のため、NginxのPodを作成するマニフェストを書いてみます。
$ cat pod.yaml apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
kindには作成したいPodやServiceなどのオブジェクトを記載します。metadataには、このPodの名前や、Podを特定するための付加情報のラベルを記載します。spec以下には、起動したいコンテナを記載します。上記の例ではimageにnginxを指定しています。この場合は「docker pull nginx」と同じ動作になるので、docker hubに登録されているnginxのdocker imageをpullして起動することを意味します。
Magnumで実行
上記のマニフェストを作成し、Magnumで実行してみます。
$ magnum pod-create --manifest pod.yaml --bay k8sbay
Nginxのdocker imageが起動したことを確認するためには、kubernetes masterのVMにログインしてkubectlコマンドを実行します。
$ nova list (見やすいように整形しています) |<ID1>|k8-aaa-kube_master-bbb|ACTIVE|Running|private=172.16.0.6, 10.0.0.26 | |<ID2>|k8-ccc-kube_minion-ddd|ACTIVE|Running|private=172.16.0.7, 10.0.0.27 | |<ID3>|k8-eee-kube_minion-fff|ACTIVE|Running|private=172.16.0.8, 10.0.0.28 | $ ssh minion@10.0.0.26 [minion]$ kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 6m
nginxのSTATUSがRunningになっていれば、Docker コンテナの立ち上げは成功です。
Replication Controllerのマニフェスト
Kubernetesには、Replication Controllerと呼ばれるPodの数を一定に保つようにする機能があります。この数は動的に変更可能なので、オートスケールにも使われます。またReplication ControllerはPodの数を維持するように動作するので、あるノードで障害が起きた際には、そのノード上のPodを他のノードで再度立ち上げてくれます。そのため、単一のPodを立ち上げる時もReplication Controllerの利用が推奨されています。
Replication Controller
http://kubernetes.io/v1.0/docs/user-guide/replication-controller.html
Replication Controller機能を試すために、まずは既存のPodを削除してから立ち上げます。現時点でPodを削除するmagnumコマンドのbayは、名前ではなくIDでPodを指定します。
$ magnum bay-list +--------------------------------------+--------+… | uuid | name | … +--------------------------------------+--------+… | 0c9e0d9d-0f2b-4a99-9160-1467c7f3e8ca | k8sbay |… +--------------------------------------+--------+… $ magnum pod-delete nginx 0c9e0d9d-0f2b-4a99-9160-1467c7f3e8ca
今回のReplication Controllerのマニフェストは、以下のものを使います。Podのものと似ていますが、specが入れ子になっており、最初の階層に複製数を指定するreplicasという項目があります。以下の例では3を指定しました。2段めの階層のspecは、Podで記述したものと同一です。
$ cat replication.yaml apiVersion: v1 kind: ReplicationController metadata: name: nginx spec: replicas: 3 selector: app: nginx template: metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx ports: - containerPort: 80
以下のように、MagnumでReplication Controllerを作成します。
$ magnum rc-create --manifest replication.yaml --bay k8sbay
先ほどと同じようにPodの起動を確認します。
$ ssh minion@10.0.0.26 [minion] $ kubectl get rc CONTROLLER CONTAINER(S) IMAGE(S) SELECTOR REPLICAS nginx nginx nginx app=nginx 3 [minion] $ kubectl get po NAME READY STATUS RESTARTS AGE nginx-1o41m 1/1 Running 0 9m nginx-wgnt4 1/1 Running 0 9m nginx-yor5x 1/1 Running 0 9m
「kubectl describe pod <pod name>」を各Podに対して実行すると、異なるNodeが表示されます。
Serviceのマニフェスト
最後に、他のPodや外部からアクセスするための抽象レイヤであるServiceを定義します。Podは作成時にIPアドレスが割り当てられますが、Replication ControllerによってPodは動的に作成・削除され、再作成の際には異なるIPアドレスが割り当てられます。そのため、IPアドレスでは安定的に通信を行うことができません。
そこでServiceという抽象レイヤをPodとセットにすることで、他のPodからはServiceにアクセスするだけで、安定的に通信が行えます。Serviceを作成すると、各Podに次の環境変数が追加されます。
- {service name}_SERVICE_HOST
- {service name}_SERVICE_PORT
この環境変数を使うことで、Podは他のPodと安定的に通信できるようになります。Serviceを作成するマニフェストは、以下のようになります。
$ cat service.yaml apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 8080 targetPort: 80 nodePort: 30080 selector: name: nginx type: LoadBalancer
このマニフェストは、名前がnginxのPodの80番ポートを外部のPodに8080で公開します。selectorは、Podを指定するために利用します。今回はnameで指定しましたが、Replication Controllerマニフェストのlabelsに「app:nginx」と記述したので「app: nginx」と指定することも可能です。このラベルは他のものから識別するためのもので、好きなラベルを付けることができます。詳しくは参考文献2を参照してください。
またこのマニフェストは、外部からのアクセスも許可しています。Nova listコマンドで表示された、kube-minionのVMのFloating IP(10.0.0.27)にnodePortのポート番号30080を加えてアクセスすると、Nginxのwelcomeページが表示されます。
今回は単純なマニフェストを書きましたが、複数のDockerイメージを用いた複雑なシステムを記述することも可能です。下記のリンクを参考に、ぜひマニフェストを書いてみてください。
Basics Tutorials
http://kubernetes.io/v1.0/basicstutorials.html
まとめ
3回にわたり、Magnumを紹介してきました。Magnumは現在とても注目されているプロジェクトであり、様々な機能が日々追加されており、執筆中にも増えています!Kubernetesだけでなく、Docker SwarmやMesosも構築できますし、VMではなくIronicも使えるよう、開発が勧められています。
Dockerを中心に多様なソフトウェアが増えています。今後さらにDocker関連のソフトウェアが増えたとしても、Magnumはそれらを吸収し統一されたAPIを提供していくでしょう。今後は、Dockerを中心にシステムが組まれることもあると思います。ぜひみなさんもMagnumを使ってみてください。
- Linuxは、Linus Torvalds氏の日本およびその他の国における登録商標または商標です。
- OpenStack?の文字表記とOpenStackのロゴは、米国とその他の国におけるOpenStack Foundationの登録商標/サービスマークまたは商標/サービスマークのいずれかであり,OpenStack Foundationの許諾を得て使用しています。日立製作所は,OpenStack FoundationやOpenStackコミュニティの関連企業ではなく、また支援や出資を受けていません。
- その他、記載の商標やロゴは、各社の商標または登録商標です。
参考文献
1.「Pods」Kubernetes
http://kubernetes.io/v1.0/docs/user-guide/walkthrough/README.html
2.「Labels」Kubernetes
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Dockerコンテナのオーケストレーション機能を実現するOpenStack Magnumを触ってみた
- NGINX Ingress Controllerの柔軟なアプリケーション制御、具体的なユースケースと設定方法を理解する
- Oracle Cloud Hangout Cafe Season5 #3「Kubernetes のセキュリティ」(2022年3月9日開催)
- Project CalicoをKubernetesで使ってみる:構築編
- Openstack Magnumの環境を構築する
- Kubernetesの基礎
- Oracle Cloud Hangout Cafe Season7 #1「Kubnernetes 超入門」(2023年6月7日開催)
- OpenStack Magnumとコンテナ
- Kubernetes環境を構築して、実際にコンテナを動かしてみよう
- RancherのCatalog機能を詳細に見てみる