kolla-openstack+opencontrail の組み合わせを試してみた

こまどりブログ (https://komadori-blog.blogspot.jp/2017/10/kolla-openstack-ocata-open-contrail40.html) の記載にしたがって、kolla-openstackとopenstackの組み合わせを試してみたので、まとめておく。
※ 先日からnested kvmが使用可能になった、gcp環境で実施
https://cloudplatform.googleblog.com/2017/09/introducing-nested-virtualization-for.html


事前準備として、GCPでnest環境を使う場合、以下のように、事前にカスタムイメージを作成しておく必要がある。
https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances#enablenestedvirt
※ また、最新のubuntu16.04.3 だと、vrouterの起動が上手くいかなかったため、2017/2 時点のイメージ(16.04.2に対応)を使用するようにしている

$ gcloud auth login
$ gcloud compute images create nested-vm-image \
 --project "プロジェクト名" \
 --source-image projects/ubuntu-os-cloud/global/images/ubuntu-1604-xenial-v20170220 \
  --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"

この後、
2vcpu, memory 7.5GB, disk 20GB (※ リージョンは us-central1-c を使用した)
で3台のinstance を作成し、ansible を順に実行することで、以下のように openstack/opencontrail が起動されることを確認できた。

f:id:aaabbb_200904:20171029191305p:plain
f:id:aaabbb_200904:20171029191317p:plain


なお、gcp の環境では以下の追加設定が必要だったため、念のため記載しておく。

  • ansible の設定記載時にnicが2本必要だったため、 以下のコマンドで ens4:0 を作成し、neutron_external_interface に指定した
ifconfig ens4:0 10.128.1.11 netmask 255.255.255.0
  • kolla-host.yml 実行時に "api_interface が未定義"、とのエラーが出たため、 ../etc/kolla/globals.yml で api_interface をコメントインした

ここまででhorizon, opencontrail は起動できたのだが、この後、cirros 起動、もしくはcompute上での169.254.0.3 (インスタンスに接続できるip) へのping、を実施したところ、computeへの疎通が取れなくなる、という事象が発生した。
原因不明なのだが、回避策として、以下を実施している。

  • configure > network > link-local services で metadata を削除(cirros起動時の疎通不可が改善した)
  • ping については手動で発行した場合のみ発生していたので、ログインはvncから行い、link-local アドレスは使わないようにする

最終的に、上記仮想ネットワーク2つにvm1/2 を作成、ルーターで接続し、pingが通ることを確認することが出来た。
f:id:aaabbb_200904:20171029191619p:plain

追記: ui確認のためのsshコマンドは以下を使用
$ ssh -L 8080:10.128.0.2:80 -L 6080:10.128.0.2:6080 ubuntu@(instance-1の外部ip)
$ ssh -L 8143:127.0.0.1:8143 ubuntu@(instance-2の外部ip)

補足: 元文書はこちら
http://www.opencontrail.org/opencontrail-containers-now-on-dockerhub/
https://gitlab.com/gokulpch/OpenContrail-Kolla/blob/master/README.md

opencontrail内のネットワークに外から疎通するには

前回の続きとなる。
http://aaabbb-200904.hatenablog.jp/entry/2017/10/24/232741

前回作成したk8s+contrail の環境を使用して、contrail 内部のネットワークから外に出る方法をまとめておく。

contrail のネットワークでは、他のノードと、MPLS over GRE で疎通する関係上、そのままだとcontrail内のvmは、お互いの間でしか疎通できない。
外に出るためには、MPLS over GREの通信を、通常のIP通信に変換する仕組みが必要となる。

今回は、aws上のvMXを使用して、変換を行うようにした。
vMXの起動方法については以下を参照。
https://www.juniper.net/documentation/en_US/vmx15.1f6/topics/concept/vmx-aws-overview.html

この後、MPLS over GREの通信を、vMXで終端するための設定を行うのだが、こちらはおおまかに、以下の4ステップで実施できる。
- BGPの設定
- GREの設定
- VRFの設定
- firewall filter の設定

コンフィグそのものは、多くの部分を、contrail の device-manager という機能を使って、自動生成できる。
device-manager の設定方法は、以下を参照。
https://www.juniper.net/documentation/en_US/contrail4.0/topics/concept/using-device-manager-netconf-contrail.html

※ ただし、今回は、'router' に対してroute-target設定を行っている関係で、VRF/firewall filterの設定は自動生成できなかったため、この部分は手動で記述している。

また、実際に試してみたところ、docker hub に上がっている 4.0.1.0 のイメージでは、そのままだとvMXに対してコンフィグ投入を行うことが出来なかった。
事前に以下の変更を行っておくことで、コンフィグ投入を行えることが確認できた。

マスター上で実施:
# kubectl exec -it contrail-controller-xxxxx -n kube-system bash
(controller)# vi /usr/lib/python2.7/dist-packages/device_manager/mx_conf.py
17行目
 -    _products = ['mx']
 +    _products = ['mx', 'vmx']
(controller)# systemctl restart contrail-device-manager.service

最終的なvMXコンフィグは以下となる。
https://github.com/tnaganawa/contrail-k8s-tutorial/blob/master/vmx-config/vmx-config

※ コンフィグ内のIPは、それぞれ以下の意味となる。
マスターノードのIP: 172.31.3.97
スレーブノードのIP: 172.31.6.143
vMX ge-0/0/0のIP: 172.31.10.57
稼働確認用ノードのIP: 172.31.9.34

設定実施後、以下のように各ノードのipが配布されてきていることと、稼働確認用ノードからのping, ssh疎通 (セキュリティグループで許可しているvm(office, mgmt)について) ができることが確認できた。

> show route
contrail-dc-router.inet.0: 4 destinations, 4 routes (4 active, 0 holddown, 0 hidden)
 + = Active Route, - = Last Active, * = Both

10.0.11.4/32       *[BGP/170] 00:07:49, MED 100, localpref 200, from 172.31.3.97
                      AS path: ?, validation-state: unverified
                    > via gr-0/0/0.32769, Push 34
10.0.12.4/32       *[BGP/170] 00:07:48, MED 100, localpref 200, from 172.31.3.97
                      AS path: ?, validation-state: unverified
                    > via gr-0/0/0.32769, Push 40
10.0.13.4/32       *[BGP/170] 00:07:49, MED 100, localpref 200, from 172.31.3.97
                      AS path: ?, validation-state: unverified
                    > via gr-0/0/0.32769, Push 51
10.0.14.4/32       *[BGP/170] 00:07:49, MED 100, localpref 200, from 172.31.3.97
                      AS path: ?, validation-state: unverified
                    > via gr-0/0/0.32769, Push 45

なお、vMXで終端しないといけないのは少々面倒に見えるが、例えば、openstackのml2プラグイン等では、bgp無しのvxlanを使用する関係上、networkノードという特別なノードを設置しないと終端が出来ない。
https://docs.openstack.org/liberty/ja/networking-guide/scenario-classic-ovs.html
contrailではbgp/mplsという標準的な仕組みを使っている関係で、ルーターで直接オーバーレイを終端出来る、というのは、メリットといえるのではなかろうか。

opencontrailで仮想ネットワーク間のルーティング、セキュリティポリシーを構成するには

概要

前回の続きとなる。
http://aaabbb-200904.hatenablog.jp/entry/2017/10/15/034243

前回作成した k8s+contrail の環境を使用して、web/db/mgmt等のセグメントを作成し、疎通確認を行ってみる。
作成するセグメントとセキュリティポリシーは以下とする。

(セグメント)
dc-web-network 10.0.11.0/24
dc-db-network 10.0.12.0/24
office-network 10.0.13.0/24
mgmt-network 10.0.14.0/24

(セキュリティポリシー)
dc-web-sg:
 mgmt: tcp/22
dc-db-sg:
 web: tcp/22 (tcp/5432の代わり)
 mgmt: tcp/22
office-sg:
 all: all
mgmt-sg:
 172.31.9.34/32: all (稼働確認用ノードのIP, 後述)

セグメントの使い分けとしては、以下を想定している。

  • web/dbのセグメントには、mgmtセグメントからだけssh可能
  • dbのpostgresqlには、webからのみアクセス可能
  • mgmt には稼働確認用ノードからだけssh可能

また、セグメント間は、互いにルーティングが出来るようにし、かつmgmtについては、稼働確認用のノード(contrail外)からも疎通が出来るようにしたい。

上記を実現するために、contrail 内では、'router'と、'security group'が使用できるので、以下にまとめていく。

router

contrail内のrouterは、定義した仮想ネットワーク(以下、vn)間に疎通を許可するための設定となる。
※ 内部的にはroute-targetの払い出しと、接続されたvnへの該当route-targetのインポート/エクスポート定義の追加、を実施している
上記の4つのvn間でルーティングを設定するためには、configure>networks>routersからルーターを作成(dc-routerとして作成)し、上記4つのネットワークを'connected networks'に追加すればよい。
f:id:aaabbb_200904:20171024231359p:plain

また、次回、vMXにも該当経路を配布するため、routerのroute-target を明示的に指定している(64512:201として指定)

仮想ネットワーク内へのコンテナ作成

なお、contrail内にvnを作る場合、configure>networks>network から作成可能となる。
また、該当vn内にk8sのコンテナを作る場合、以下のようにannotationを設定することで、該当vn内にコンテナを作ることができる。
※ contrail動作の説明用の使い方で、k8s の使い方としてはあまり一般的ではないので注意

https://github.com/tnaganawa/contrail-k8s-tutorial/blob/master/yml/2_dc/cirros-dc-web.yaml#L7

今回は、各vn内に1つずつ、containerを作っておく。

security group

security groupは、openstack等で使用できるものとほぼ同じで、各vmに疎通できる通信を設定するものとなる。
contrailでは、vmに接続されている'port'を提供しているため、こちらに対してsecurity groupを設定することになる。

security group(以下、sg)では、通信の許可、しか設定できないため、基本的には、デフォルトではsgには何も設定せず、許可する通信のみsg内に追加していくことになる。
今回は、各vnごとに1つずつsgを作成し、sg名単位で許可していくことにした。

設定例は以下となる。(例では、dc-web用のsgに mgmtからの疎通を許可している)
f:id:aaabbb_200904:20171024231640p:plain

※ ポートごとの定義は以下のように、該当ネットワーク内の各ポートに、セキュリティグループを設定していくことになる
f:id:aaabbb_200904:20171024232150p:plain

疎通確認

作成したそれぞれのコンテナにログインするには、以下のようなコマンドが使用できる

# kubectl exec -it cirros-mgmt sh

ログイン後、ping, ssh 等で、ルーティング、セキュリティポリシーが正しく設定されていることを確認していく。

# ping 10.0.11.4
# ssh cirros@10.0.11.4

ルーティングテーブルの確認

contrailの各vnのルーティングテーブルは、以下から確認できる。
monitor>control nodes>(コントロールノード名)>routes
f:id:aaabbb_200904:20171024231740p:plain

また、next-hop は、以下から確認できる。
monitor>virtual routers>(スレーブノード名)>interfaces
f:id:aaabbb_200904:20171024231817p:plain

※ 上記の例では、dc-web-networkのルーティングテーブルで 10.0.12.4の行き先が40のMPLSラベルであり、該当のラベルが cirros-dc-dbに対応することがわかる。


上記のように、contrail内ではルーティング、およびL4までのファイアウォールが設定できる。
上記の定義は、スレーブノードを追加すれば、そちらのvrouterにもそのまま適用される。
各スイッチやファイアウォール、ハイパーバイザ等で、順に作業していく必要がないので、だいぶ構築が楽になるのではなかろうか。

opencontrail4.0のdocker版を試してみた

概要

opencontrail から最新のdockerが公開されたため、そちらを試してみた際のまとめとなる。
http://www.opencontrail.org/opencontrail-containers-now-on-dockerhub/

opencontrail はオープンソースとして開発がすすめられているものの、バイナリファイルが定期的に公開されているわけではない、という制限があったため、手軽に試すのが難しかった。

今回久しぶりに新規のバイナリが公開されたため、そちらを試す、というのがこのブログの趣旨になる。

※ 公開されたバイナリは4.x 系なのだが、こちらは kubernetes 連携の機能が加わっている版なので、この機能を試している。

 

インストール方法

主な手順はこちらを参照。
https://github.com/Juniper/contrail-docker/wiki/Provision-Contrail-CNI-for-Kubernetes

まず、ubuntu16.04.2 の仮想マシンを3台用意する。
※ スレーブノードでは メモリ1GB程度でも大丈夫だが、マスターは8GB程度はほしい (検証時はawsでマスター: t2.large, スレーブ: t2.micro で実施)
※※ ローカルでインストールする場合、マスターノードでは、ホスト名が名前解決できるよう、/etc/hosts を設定する必要があった


その後、以下のコマンドを順に実施していく。

(1. 共通)
# sudo service ufw stop
# sudo iptables -F
# sudo apt-get install apt-transport-https ca-certificates curl -y

# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
# sudo bash -c 'cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF'
# sudo apt-get update -y
# sudo apt-get install -y kubectl=1.7.4-00 kubelet=1.7.4-00 kubeadm=1.7.4-00 docker-engine

(2-1. マスターのみ)
# sudo kubeadm init

# mkdir -p $HOME/.kube
# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# sudo chown $(id -u):$(id -g) $HOME/.kube/config

(2-2. スレーブのみ)
# sudo kubeadm join --token (kubeadm init実行時に表示されたtoken) (マスターのIP):6443

(3. マスターのみ)
# git clone https://github.com/Juniper/contrail-docker.git -b R4.0
# cd contrail-docker/kubernetes/manifests/
# sed -i 's/10.84.13.7/(マスターのIP)/' contrail-host-ubuntu.yaml
# kubectl apply -f contrail-host-ubuntu.yaml

この後、しばらく待つと、以下のURLでContrailの画面が表示されるはずである。
https://(マスターノードのIP):8143
aws の場合 $ssh -L 8143:127.0.0.1:8143 -i (aws用のpemファイル) ubuntu@(マスターのIP) などで確認する
※ ID/パスワードは admin:contrail123 となる

 

f:id:aaabbb_200904:20171015032251p:plainf:id:aaabbb_200904:20171015032304p:plainf:id:aaabbb_200904:20171015032309p:plain

 

 



動作確認

以下のyaml ファイルを使用して、podを2つ作成し、お互いにping が通れば、基本的な動作は okとなる
# kubectl create -f cirros1.yaml
# kubectl create -f cirros2.yaml
# kubectl exec -it cirros1 sh
# ping (cirros2のIP) # (kubectl get pod -o wide で確認)
※ cirrosがあがってこない場合、事前にスレーブノードを再起動する必要があるかもしれない

///
(cirros1.yaml)
apiVersion: v1
kind: Pod
metadata:
name: cirros1
labels:
name: cirros1
spec:
containers:
- name: cirros1
image: cirros
ports:
- containerPort: 22
///

うまくいかない場合

以下のコマンドを使って、contrail の各コンポーネントが起動しているかどうか、を順に見ていくことになる。

# kubectl get pod --all-namespaces
# kubectl exec -it <contrail-pod-name> -n kube-system -- contrail-status

※ 上手くいった場合、以下のように、各コンポーネントが active の状態になる。
root@ip-172-31-3-97:~/contrail-docker/kubernetes/manifests# kubectl exec -it contrail-controller-8hshr -n kube
-system -- contrail-status
== Contrail Control ==
contrail-control: active
contrail-named: active
contrail-dns: active
contrail-control-nodemgr: active
== Contrail Config ==
contrail-api: active
contrail-schema: active
contrail-svc-monitor: active
contrail-device-manager: active
contrail-config-nodemgr: active
== Contrail Config Database==
contrail-database: active

== Contrail Web UI ==
contrail-webui: active
contrail-webui-middleware: active
== Contrail Support Services ==
zookeeper: active
rabbitmq-server: active (disabled on boot)

root@ip-172-31-3-97:~/contrail-docker/kubernetes/manifests# kubectl exec -it -n kube-system contrail-agent-n4x
p5 contrail-status
== Contrail vRouter ==
contrail-vrouter-agent: active
contrail-vrouter-nodemgr: active


※ ログ確認が必要な場合、(主に) 以下で確認
# kubectl exec -it <contrail-pod-name> -n kube-system bash
# tail -n 100 -f /var/log/contrail/*

 


まとめ

Contrail は、MPLSベースのVPNオープンソースのみで動かせるようにした仕組みとなる。
※ 類似の仕組みについては以下、等を参照
https://forums.juniper.net/t5/Routing/Dymanic-GRE-Tunnel-VPN/td-p/92212
https://tools.ietf.org/html/draft-marques-l3vpn-end-system-07

上記の性質から、BGP(inet-vpn, evpn含む)にも対応しているので、ルーターと直接経路をやりとりし、GRE接続を張ることも出来る。

慣れるまで少々分かり辛いが、強力な割に使い方そのものはさほど難しくないので、この機会にトライしてみてもよいのではなかろうか

Jupyterベースでのアラート対応

execjson/applconn の実装を進めていくと、どうしても、間で人間の判断が必要な部分が出てくる。
こちらを上手く扱う方法を探していたのだが、最近Jupyter を使うのがよいのではないか、と思うようになった。
※ Jupyter についてはこちらなどを参照。
http://enakai00.hatenablog.com/entry/2016/04/22/204125
https://github.com/tnaganawa/jupyter-it-automation-notebook


この場合、フローとしては以下となる。
1. アラート発生
2. オペレーターがJupyter notebookを開く
3. 必要な作業をセルごとに実行
※ 現実的には、どうしても置き換えられない作業は、、ステークホルダー(サービスマネージャーなど)の判断をあおぐような場合だろうか。

また、アラートとnotebookのurlを紐付けておけば、アラート発生時に、自動でnotebookのurlにリダイレクトすることも出来る。
https://github.com/tnaganawa/open-alert-url

上記を踏まえると、アラート発生時の対応で間に人の判断が入るような場合には、Jupyterのセルの単位で区切って実装を進めていく、というのが一つの方法になるのではないかと思われる。

Docker上にOpenShotを導入して動画編集をしてみた

openshot (http://www.openshot.org/) はLinux上でも動く動画編集ソフトで、作ったogvファイルの連結、等が出来る。

openshot のような動画編集ソフトは、エンコードのライセンスの関係、等により、通常のcentosレポジトリには含まれていないものが多い。
このため、インストールしようとすると個別のyumレポジトリを定義する必要があるのだが、それをやると依存解決が煩雑になるため、可能であれば、vmやcontainer等に導入したかった。

今回は、上記ソフトウェアをdocker container上にいれて、動画編集を試してみた。
※ 2つのogv動画の連結、までは試したのだが、3D等の機能は試していないので、全ての機能がcontainer上で動くか、は未検証

インストール手番は以下となる。
※ Dockerfile形式で記述しているが、個別にコマンドを実行していっても作成は可能
///
FROM centos
RUN yum -y install openssh* epel-release xauth && sshd-keygen && rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-5.el7.nux.noarch.rpm && yum -y install openshot ladspa ipa*fonts && yum install -y mlt-ffmpeg
CMD ["/bin/bash", "-c", "/usr/sbin/sshd; bash"]
///

この後、
$ sudo docker run -it (image-id)
で、該当containerを起動した後、
$ ssh -X ip
でログインし、(事前に適当なユーザーを作成し、パスワードを設定しておく)
$ export LC_ALL=C
$ openshot
で、openshotが起動した。

運用ツール図を完成させるには

execjson / applconn 作成の経緯となった図について、まとめておこうと思う。

現状、ITILに準拠した ITオペレーションは、様々なソフトウェアによって、補助されながら実施されているが、環境によっては、導入されているツールの数が不足したりしていて、十分な自動化が進められないケースがある。

この場合、まずどのようなツールを導入するか、を確認し、それらの構築を進めていく必要があるのだが、それをまとめた図が以下になる。

f:id:aaabbb_200904:20170503072310j:plain


逆に、これらをオープンソースのみで達成できるようにしておけば、どんな環境であっても、ひとまずツールの問題は、解決できるものと考えられる。

上記について、オープンソースで対応するソフトウェアを追記した図は、以下となる。

f:id:aaabbb_200904:20170503072355j:plain
当時は、
 - ユーザー入力を、APIからアクセス可能にする仕組み
 - APIからの情報取得、更新が可能な構成管理DB(出来れば、検索、接続関係の可視化、も)
の2点が不足していたため、それぞれに対応するものとして、 execjson / applconn の作成に至った、という経緯になる。

現在の状況についてだが、上記2点については、あまり変化がない、、というより、上記2点については、他の部分と比べて環境依存が強い (それぞれサービスカタログ、CMDBの定義に対応) ので、個別に作り込む必要がある、部分になっていると思っている。

その意味では、'ソフトウェア開発のスキルがある、インフラエンジニア' の重要な仕事は、上記2点の実装、ということになるのではなかろうか。