Archive for November, 2012

OSX의 resolver의 기능은 dnsmasq로

dnsmasq는 dns forwarder가 기본입니다. 그리고 또 심플한 dns 기능을 가지고 있습니다. 이 기능을 모르고 이전에 twisted를 이용해서 dns proxy를 만들었지만, dnsmasq를 이용하면 보다 간단하게 설정이 가능하니 설명하지요.

첫번째는 특정 도메인을 특정 네임서버에 보내도록하는 예제입니다.

/etc/dnsmasq.d/company.zone:

server=/dev.company.com/192.168.1.199
server=/myteam.company.com/192.168.1.200

다음 예제는 local이라는 나만의 가상 도메인을 만들고 호스트를 지정하는 방법입니다. /etc/hosts에 설정하는 것과 비슷하죠.
/etc/dnsmasq/local.zone:

address=/local-db.local/10.20.1.4
address=/local-www.local/10.20.1.5

이렇게해서 dnspost는 역사속으로 사라지는군요.


OpenStack은 정말 복잡한 프로젝트다..

문득 얼마나 많은 패키지들이 OpenStack을 위해서 필요한지 단순하게 체크해밨다.

$ apt-get install mysql-server rabbitmq-server \
keystone glance-api glance-registry \
nova-api nova-scheduler nova-novncproxy nova-cert nova-consoleauth \
cinder-api cinder-scheduler cinder-volume \
nova-compute \
quantum-server quantum-plugin-openvswitch quantum-plugin-openvswitch-agent quantum-l3-agent quantum-dhcp-agent \
openstack-dashboard

단순하게 전체 구성하는 패키지를 설치하는 명령을 내리면...

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common augeas-lenses binutils bridge-utils cgroup-lite cinder-common cpp cpp-4.6 cpu-checker curl dbconfig-common dkms dnsmasq-base dnsmasq-utils ebtables
  erlang-asn1 erlang-base erlang-corba erlang-crypto erlang-dev erlang-diameter erlang-docbuilder erlang-edoc erlang-erl-docgen erlang-eunit erlang-ic erlang-inets erlang-inviso erlang-mnesia erlang-nox erlang-odbc
  erlang-os-mon erlang-parsetools erlang-percept erlang-public-key erlang-runtime-tools erlang-snmp erlang-ssh erlang-ssl erlang-syntax-tools erlang-tools erlang-webtool erlang-xmerl fakeroot gawk gcc gcc-4.6 git git-man
  glance-common kpartx kvm kvm-ipxe libaio1 libapache2-mod-wsgi libapparmor1 libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libasound2 libasyncns0 libaugeas0 libavahi-client3 libavahi-common-data libavahi-common3
  libc-dev-bin libc6-dev libcaca0 libconfig-general-perl libcurl3 libdbd-mysql-perl libdbi-perl liberror-perl libevent-2.0-5 libflac8 libgmp10 libgomp1 libhtml-template-perl libibverbs1 libjs-jquery libjs-sphinxdoc
  libjs-underscore libjson0 libltdl7 libmpc2 libmpfr4 libmysqlclient18 libnet-daemon-perl libnetcf1 libnetfilter-conntrack3 libnl-route-3-200 libnspr4 libnss3 libnuma1 libodbc1 libogg0 libplrpc-perl libpulse0 libquadmath0
  librados2 librbd1 librdmacm1 libsctp1 libsdl1.2debian libsgutils2-2 libsigsegv2 libsndfile1 libtidy-0.99-0 libvirt-bin libvirt0 libvorbis0a libvorbisenc2 libxenstore3.0 libxml2-utils libxslt1.1 libyajl1 libyaml-0-2
  linux-libc-dev lksctp-tools make manpages-dev memcached msr-tools mysql-client-5.5 mysql-client-core-5.5 mysql-common mysql-server-5.5 mysql-server-core-5.5 nova-common nova-compute-kvm open-iscsi open-iscsi-utils
  openstack-dashboard-ubuntu-theme openvswitch-common openvswitch-datapath-dkms openvswitch-switch patch python-amqplib python-anyjson python-appconf python-boto python-carrot python-cheetah python-cinder python-cinderclient
  python-cliff python-cloudfiles python-cmd2 python-compressor python-configobj python-crypto python-daemon python-dateutil python-decorator python-dingus python-django python-django-horizon python-eventlet python-feedparser
  python-formencode python-gevent python-gflags python-glance python-glanceclient python-greenlet python-httplib2 python-iso8601 python-jsonschema python-keyring python-keystone python-keystoneclient python-kombu python-ldap
  python-libvirt python-libxml2 python-lockfile python-lxml python-m2crypto python-memcache python-migrate python-mysqldb python-netaddr python-nose python-nova python-novaclient python-openid python-openssl
  python-openstack-auth python-pam python-paramiko python-passlib python-paste python-pastedeploy python-pastescript python-pkg-resources python-prettytable python-pycurl python-pyparsing python-pyudev python-quantum
  python-quantumclient python-requests python-routes python-scgi python-setuptools python-setuptools-git python-simplejson python-sqlalchemy python-sqlalchemy-ext python-stompy python-suds python-swiftclient python-tempita
  python-tz python-utidylib python-warlock python-webob python-xattr python-yaml qemu-common qemu-kvm qemu-utils quantum-common seabios sg3-utils ssl-cert tgt vgabios vlan
Suggested packages:
  www-browser apache2-doc apache2-suexec apache2-suexec-custom augeas-doc binutils-doc python-ceph cpp-doc gcc-4.6-locales virtual-mysql-client mysql-client postgresql-client erlang erlang-manpages erlang-doc xsltproc fop
  erlang-ic-java erlang-observer gcc-multilib autoconf automake1.9 libtool flex bison gdb gcc-doc gcc-4.6-multilib libmudflap0-4.6-dev gcc-4.6-doc libgcc1-dbg libgomp1-dbg libquadmath0-dbg libmudflap0-dbg binutils-gold
  git-daemon-run git-daemon-sysvinit git-doc git-el git-arch git-cvs git-svn git-email git-gui gitk gitweb libasound2-plugins libasound2-python augeas-tools glibc-doc libipc-sharedcache-perl javascript-common libmyodbc
  odbc-postgresql tdsodbc unixodbc-bin pulseaudio policykit-1 pm-utils radvd make-doc libcache-memcached-perl libmemcached libterm-readkey-perl tinyca mailx novnc ethtool diffutils-doc python-amqplib-doc python-markdown
  python-pygments python-crypto-dbg python-crypto-doc python-psycopg2 python-psycopg python-flup python-sqlite geoip-database-contrib python-egenix-mxdatetime python-dns python-gevent-doc python-gevent-dbg python-greenlet-dbg
  python-greenlet-dev python-greenlet-doc python-couchdb python-kombu-doc python-pymongo python-ldap-doc python-lxml-dbg python-mysqldb-dbg ipython python-coverage python-nose-doc python-openssl-doc python-openssl-dbg
  python-pam-dbg python-pastewebkit libapache2-mod-python libapache2-mod-scgi python-pgsql libjs-mochikit python-cherrypy python-distribute python-distribute-doc libcurl4-gnutls-dev python-pycurl-dbg python-gobject python-qt4
  python-pyside.qtcore python-sqlalchemy-doc python-kinterbasdb python-pymssql mol-drivers-macosx openbios-sparc ubuntu-vm-builder uml-utilities openssl-blacklist
The following NEW packages will be installed:
  apache2 apache2-mpm-worker apache2-utils apache2.2-bin apache2.2-common augeas-lenses binutils bridge-utils cgroup-lite cinder-api cinder-common cinder-scheduler cinder-volume cpp cpp-4.6 cpu-checker curl dbconfig-common dkms
  dnsmasq-base dnsmasq-utils ebtables erlang-asn1 erlang-base erlang-corba erlang-crypto erlang-dev erlang-diameter erlang-docbuilder erlang-edoc erlang-erl-docgen erlang-eunit erlang-ic erlang-inets erlang-inviso erlang-mnesia
  erlang-nox erlang-odbc erlang-os-mon erlang-parsetools erlang-percept erlang-public-key erlang-runtime-tools erlang-snmp erlang-ssh erlang-ssl erlang-syntax-tools erlang-tools erlang-webtool erlang-xmerl fakeroot gawk gcc
  gcc-4.6 git git-man glance-api glance-common glance-registry keystone kpartx kvm kvm-ipxe libaio1 libapache2-mod-wsgi libapparmor1 libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap libasound2 libasyncns0 libaugeas0
  libavahi-client3 libavahi-common-data libavahi-common3 libc-dev-bin libc6-dev libcaca0 libconfig-general-perl libcurl3 libdbd-mysql-perl libdbi-perl liberror-perl libevent-2.0-5 libflac8 libgmp10 libgomp1
  libhtml-template-perl libibverbs1 libjs-jquery libjs-sphinxdoc libjs-underscore libjson0 libltdl7 libmpc2 libmpfr4 libmysqlclient18 libnet-daemon-perl libnetcf1 libnetfilter-conntrack3 libnl-route-3-200 libnspr4 libnss3
  libnuma1 libodbc1 libogg0 libplrpc-perl libpulse0 libquadmath0 librados2 librbd1 librdmacm1 libsctp1 libsdl1.2debian libsgutils2-2 libsigsegv2 libsndfile1 libtidy-0.99-0 libvirt-bin libvirt0 libvorbis0a libvorbisenc2
  libxenstore3.0 libxml2-utils libxslt1.1 libyajl1 libyaml-0-2 linux-libc-dev lksctp-tools make manpages-dev memcached msr-tools mysql-client-5.5 mysql-client-core-5.5 mysql-common mysql-server mysql-server-5.5
  mysql-server-core-5.5 nova-api nova-cert nova-common nova-compute nova-compute-kvm nova-consoleauth nova-novncproxy nova-scheduler open-iscsi open-iscsi-utils openstack-dashboard openstack-dashboard-ubuntu-theme
  openvswitch-common openvswitch-datapath-dkms openvswitch-switch patch python-amqplib python-anyjson python-appconf python-boto python-carrot python-cheetah python-cinder python-cinderclient python-cliff python-cloudfiles
  python-cmd2 python-compressor python-configobj python-crypto python-daemon python-dateutil python-decorator python-dingus python-django python-django-horizon python-eventlet python-feedparser python-formencode python-gevent
  python-gflags python-glance python-glanceclient python-greenlet python-httplib2 python-iso8601 python-jsonschema python-keyring python-keystone python-keystoneclient python-kombu python-ldap python-libvirt python-libxml2
  python-lockfile python-lxml python-m2crypto python-memcache python-migrate python-mysqldb python-netaddr python-nose python-nova python-novaclient python-openid python-openssl python-openstack-auth python-pam python-paramiko
  python-passlib python-paste python-pastedeploy python-pastescript python-pkg-resources python-prettytable python-pycurl python-pyparsing python-pyudev python-quantum python-quantumclient python-requests python-routes
  python-scgi python-setuptools python-setuptools-git python-simplejson python-sqlalchemy python-sqlalchemy-ext python-stompy python-suds python-swiftclient python-tempita python-tz python-utidylib python-warlock python-webob
  python-xattr python-yaml qemu-common qemu-kvm qemu-utils quantum-common quantum-dhcp-agent quantum-l3-agent quantum-plugin-openvswitch quantum-plugin-openvswitch-agent quantum-server rabbitmq-server seabios sg3-utils ssl-cert
  tgt vgabios vlan
0 upgraded, 254 newly installed, 0 to remove and 0 not upgraded.
Need to get 124 MB of archives.
After this operation, 422 MB of additional disk space will be used.
Do you want to continue [Y/n]?

254개의 패키지가 필요하다. 물론 모든 full stack을 알아야할 필요는 없겠지만, 어느 정도 그들이 어떤 역할을 하는지는 알아 두는 것이 전체 시스템을 이해하는데 도움이 많이 되겠죠.

완전히 기술 분야가 다른 리눅스 네트워킹부터~ django까지... 후훗... 질릴정도가?


full stack

git, unit test, xp, scrum, gerrit, jenkins, chef, ci, cloud.... 프로젝트를 시작할라 치면 실제 삽을 들기도 전에 고려하고 생각하고 해야할 일들이 많다. 물론 여기에 빠진것도 많다.

요즈즘은 특히나 인터넷에 나와있는 유명한 회사, 유명한 오픈소스 플로젝트에서 말하는 best practice들을 보고 있노라면 각 단어 하나가 하나의 책으로 구성해도 부족한 것들인데, 이 모든것을 다 잘 해야만 프로젝트가 잘 될것 같은 생각이 들기도 하다. 실제로 그렇게 가야한다고 이야기도 많이 한다.

이 모든 것을 이미 경험해 본 사람이 있는 경우라면 그나마 좋은 경우겠지만, 구성원들의 지식 수준도 아주 다양하고, 게다가 프로젝트에서 풀어야할 문제 자체도 난감한데, 이를 수행하기 위해 기반을 갖추는 것도 아주 험난한 상황이 되는 것 뭐랄까... 열심히 뭔가를 했지만, 그 것을 사용할 사람에게는 뭔가 보여줄 게 없는 그런 이상한 상황이 오래 지속되는 것 같다.

몇주전에 들었던 야크 세이빙이 떠오르기도 한다....

프로젝트의 비전도 명확하고, 모든 구성원이 동의하고, 아주 열정이 있고, 배우려는 의지도 강하고, 프로젝트 일정도 여유가 있으면 하나씩 파면서 제대로 가겠지만, 그러기도 거시기한게.. 각자의 지식 수준도 다양하고, 그리고 각자에게 뭔가 프로젝트에서 자기 담당이라는 것도 암묵적으로 생기면서, 그 사람이 하겠지 하는 그런 생각도 들기도 하고 말이야... 흠.

내 스타일은 이 모든 것을 갗추어서 제대로 시작하기 보다는 우선은 조그만한 것부터, 작은 성공을 바탕으로 점점 큰 것을 가져나가는 것... 을 추구하고 계속 그렇게 가면서 새로운 것도 쉽게 쉽게 배우고, 그게 왜 필요한 지도 몸으로 느껴가면서 배웠는데 말이다.

만일 저 full stack을 딱 가져다 놓고, 이에 맞춰서 일 해야되.. 라고 한다면, 뭐랄까 답답함이 엄습해올 것 같다. 뭔가 내가 여기서 움직일 공간이 없이 저 틀에 박혀버리는 것 이 아닐까? 하다가 내가 관심있는 분야에 조금 더 뚝딱뚝딱해보려 하지만, 그를 위해서는 더 다른 부가 적인, 배보다 배꼼이 큰.. 그런 일들을 해야하는 상황들이 발생할 것 같다는 느낌도 들고 말이야... 후훗...

이제 혼자가 full stack을 이해하고, 모든 구성원이 케익을 세로롤 자를 수 있으련지.. 뭔가 그렇다...

그냥 넋두리입니다.. 😀

ps. 낼은 또 어떤 spike를 할까???


quantum: metadata overlapping patch 적용기

quantum의 문제중에 하나인 overlapping_ip을 사용할 때 metadata service가 작동하지 않는 문제에 대해서 이전에 언급했었고, 이에 대한 패치가 저번주에 올라왔습니다.

오늘 이를 테스트 해봤는데 대략 잘 동작합니다.

간단한 구조는 다음과 같습니다.

  1. metadata request는 http://169.254.169.254/latest/metadata 형태로 router namespace로 들어온다.
  2. router namespace의 NAT rule에 의해서 localhost의 port 9697로 redirect 된다.
  3. 9696에서 listen하는 process(quantum-ns-metadata-proxy)는 l3_agent에서 network 생성에 맞춰 관리되며, namespace당 하나씩 생성된다.
  4. quantum-ns-metadata-proxy는 파라미터로 router_id를 가지므로 자신이 담당하는 network을 알 수 있다.
  5. quantum-ns-metadata-proxy는 nova-metadata-agent가 필요한 정보를 모아서(instance-id, router-id, network-id) http header에 포함하여 quantum-metadata-agent로 proxy request를 보낸다.
  6. quantum-metadata-agent는 ns-metadata-proxy에서 넘어온 전보를 바탕으로 instance-id를 확인하고 이를 http header에 포함하여 nova-metadata-api에 보낸다.
  7. nova-metadata-api는 X-Instace-ID가 있으면 이 아이디를 기준으로 메타데이터를 넘긴다.

대략 순서를 정리하면 이렇습니다. 마지막으로 quantum-metadata-agent를 upstart service로 등록하여 작업하는 것 까지하면 대략 쓸만할 것 같습니다.

지금은 우선 테스트라 quantum-metadata-agent가 같은 서버로 들어갔지만, metadata_ip를 줄 수 있으므로 별도의 서버에 운영할 수 있겠습니다.

삽질기

위 패치는 nova/ quantum 2개로 구성이 되어있으며, 당연히도 master 소스를 기준으로 작성이 되어있습니다. 그런데 저는 테스트 환경을 ubuntu folsom cloud archive를 사용하기 때문에 folsom 용으로 만들어야 했지요.. git에서 작업하기 위해 몇 가지 삽질을..

  1. master에 patch 적용하고 patch
  2. stable/folsom 기준으로 branch를 하나 만들고...
  3. master의 commit를 cherry picking...
  4. 다시 folsom에 맞게 소스 수정하고 commit...
  5. folsom과 변경된 부분으로 patch 생성...
물론 nova/ quantum도 같이요...
  • upstart-job service 등록

Side effect?

이전에 metadata 접속 방식은 l3 router namespace에서 metadata api로 요청하는 것이었습니다. 이 경우 l3 router namespace 부터는 public ip address이므로 결국 metadata api server의 주소도 public ip address를 가지게 됩니다.

그런데 이 metadata api server는 굳이 외부에서 접속할 필요가 없으므로 public ip를 가질 필요가 없습니다. 따라서 뭔가 꺼림직 했었는데, 이번 패치를 적용하면, quantum-metadata-agent를 내부망에서 운영할 수 있으므로 metadata api server가 내부망에서 운영이 가능합니다.


OpenStack: 가상머신의 네트워크가 안될 때 quantum의 체크 사항들

[toc]openstack에서 가상머신을 생성하기는 했는데, nova에서는 생성이 되었다고 리포트되지만 Quantum 네트워크 문제로 가상머신이 연결되지 않은 경우가 있다. 이러한 경우 몇가지 체크할 포인트를 정리해본다. 물론 여기는 모두 folsom에서 OpenVSwitch + GRE Tunneling을 사용할 경우를 가정한다.

증상들

quantum의 설정 문제라면 보통 아래의 증상이 나타난다.

  • nova list를 보면 가상머신에 ip는 할당이 되어 있지만, ping이 가지 않는다.
  • ping은 가는데 ssh 접속이 안된다.
  • vnc로 접속하면 접속은 된다.
nova list에서 가상머신의 ip address가 할당이 되지 않고 생성되는 문제가 있는데, 이는 대부분 quantum의 문제가 아니고 다른 문제였다. 이 경우는 nova-compute의 로그를 확인하면 된다.

physical network 확인

integration bridge가 설정 되어 있는지 확인

모든 l3-agent, dhcp-agent, ovs-plugin-agent가 동작하는 곳에 br-int bridge가 있는지 확인한다. quantum ovs plugin이 동작하기 위해서는 반드시 br-int bridge가 필요하다. agent가 자동으로 만들어 줄 만 한데 안만들어 주고 있다.(반면에 gre tunnel이 사용하는 br-tun은 알아서 만든다.)

이 경우는 quantum 로그 파일에 br-int bridge가 없다는 에러를 내기 때문에 찾아내기 아주 쉽다.

external bridge 확인

l3-agent가 동작하고 있는 곳에 br-ex bridge가 있는지 확인한다. 그리고 br-ex bridge에는 외부와 연결된 interface가 추가되어 있는지 확인한다.

테스트 환경에서의 bridge를 확인하면 아래와 같다. (qg-*는 tenant network의 gateway port다.)

    Bridge br-ex
        Port "qg-5376a58a-a7"
            Interface "qg-5376a58a-a7"
                type: internal
        Port "qg-8be78718-4b"
            Interface "qg-8be78718-4b"
                type: internal
        Port "eth2"
            Interface "eth2"
        Port br-ex
            Interface br-ex
                type: internal

그리고 여기에 연결된 eth2(external nic)에는 ip address가 설정하지 않는다.(물리적 연결을 확인하기 위해서 ip를 추가하고 테스트하기는 한다.)

datapath-dkms

openvswitch는 dynamic kernel module support를 사용한다. openvswitch-switch user space daemon과 커널 모듈이 동시에 사용되는 것이다. 의존성에 의해서 자동으로 설치되기는 하지만, 어떠한 경우에는 커널 모듈을 설치하지 않는 경우도 있기 때문에 한 번 쯤은 확인하는 것이 좋다.

root@net-l3:~# dpkg -l | grep datapath-dkms
ii  openvswitch-datapath-dkms        1.4.0-1ubuntu1.3             Open vSwitch datapath module source - DKMS version
root@net-l3:~# dkms status
openvswitch, 1.4.0, 3.2.0-33-generic, x86_64: installed

quantum-plugin-openvswitch-agent 동작 확인

nova-compute, quantum-l3-agent, quantum-dhcp-agent가 동작하는 노드에서는 quantum-plugin-openvswitch-agent가 동작하면서 지속적으로 quantum 서비스를 polling하면서 openvswitch의 설정들을 잡는다. database/ rabbitmq connection이나 keystone 설정들의 문제는 로그파일을 보면 바로 나오니 문제를 파악하기 쉽다. 하지만 gre tunneling을 맺는 것을 명시적으로 오류가 나지 않으므로 이 부분을 확인해야한다.

아래는 테스트 환경에서 gre tunneling 확인한 모습이다. remote_ip="10.130.1.101" 처럼 보이는 부분이 있어야하며, 기타 여러 다른 문제로 인해서 여기에 상대방의 ip가 정상적으로 나오지 않는 경우를 많이 경험했다.

root@net-dhcp:~# ovs-vsctl show
40a579fe-a5ae-4f63-b6ca-6967280a9893
    Bridge br-tun
        Port "gre-1"
            Interface "gre-1"
                type: gre
                options: {in_key=flow, out_key=flow, remote_ip="10.130.1.101"}
        Port patch-int
            Interface patch-int
                type: patch
                options: {peer=patch-tun}
        Port br-tun
            Interface br-tun
                type: internal
        Port "gre-4"
            Interface "gre-4"
                type: gre
                options: {in_key=flow, out_key=flow, remote_ip="10.130.1.11"}
        Port "gre-3"
            Interface "gre-3"
                type: gre
                options: {in_key=flow, out_key=flow, remote_ip="10.130.1.10"}
    Bridge br-int
        Port patch-tun
            Interface patch-tun
                type: patch
                options: {peer=patch-int}
        Port br-int
            Interface br-int
                type: internal
        Port "tap9dd6bf73-9a"
            tag: 2
            Interface "tap9dd6bf73-9a"
                type: internal
        Port "tap063f59a8-7b"
            tag: 1
            Interface "tap063f59a8-7b"
                type: internal
    ovs_version: "1.4.0+build0"

이런 문제가 있는 경우는 remote_ip가 나오지 않는 호스트의 ovs_quantum_plugin.ini의 local_ip 설정이 있는지 확인하고, 정확하게 gre tunneling으로 사용할 ip가 명시되어 있다면 단순히 quantum-plugin-openvswitch-agent 서비스를 재시작하면 대부분 해결 된다.

dhcp namespace에서 ping이 되는지

dhcp agent가 동작하는 곳에는 dhcp namespace가 생기고 여기에는 해당 네트워크에 동작하는 dhcp 서버가 동작하게 된다. 일만적으로 172.16.1.2처럼 2번의 ip를 가지게 되고 가상머신은 3번 아이피부터 시작한다. 여기는 외부 네트워크 연결과는 상관없이 내부 네트워크만 동작하면 되므로 우선 여기부터 확인한다.

root@net-dhcp:~# ip netns
qdhcp-9cbd5dd0-928a-4808-ae34-4cc2563fa619
qdhcp-55db86bf-7eee-4fac-a928-844218e88a11
root@net-dhcp:~# ip netns exec qdhcp-9cbd5dd0-928a-4808-ae34-4cc2563fa619 ip addr
8: tap9dd6bf73-9a: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether fa:16:3e:eb:c1:b3 brd ff:ff:ff:ff:ff:ff
    inet 172.16.2.2/24 brd 172.16.2.255 scope global tap9dd6bf73-9a
    inet6 fe80::f816:3eff:feeb:c1b3/64 scope link
       valid_lft forever preferred_lft forever
9: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
root@net-dhcp:~# ip netns exec qdhcp-9cbd5dd0-928a-4808-ae34-4cc2563fa619 ping -c 3 172.16.2.5
PING 172.16.2.5 (172.16.2.5) 56(84) bytes of data.
64 bytes from 172.16.2.5: icmp_req=1 ttl=64 time=8.82 ms
64 bytes from 172.16.2.5: icmp_req=2 ttl=64 time=3.98 ms
64 bytes from 172.16.2.5: icmp_req=3 ttl=64 time=2.17 ms

--- 172.16.2.5 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 2.179/4.996/8.823/2.804 ms

가상 머신의 ip로 ping이 간다면 우선 내부 네트워크는 정상적으로 작동한다는 말이다. 더불어 gre tunnel도 정상적으로 잘 된다는 이야기이다.

l3 namespace에서 네트워크 확인

l3 namespace는 해당 네트워크의 gateway가 위치(172.16.1.1)하는 곳이다. 당연히 여기서 네트워크가 문제없이 잘 되어야 외부로 나가는 길이 열리는 것이다.

l3 namespace에서 다음 사항을 확인해본다.

  • instance로의 ping
  • default gateway
root@net-l3:~# ip netns
qrouter-2c901c4d-eeb3-43b0-a84a-30da10fa74d7
qrouter-5fce397a-4e9d-4a42-8139-f7748a0f69b6
root@net-l3:~# ip netns exec qrouter-5fce397a-4e9d-4a42-8139-f7748a0f69b6 ip addr
8: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
9: qr-7b757ca9-3f: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether fa:16:3e:23:36:5b brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.1/24 brd 172.16.1.255 scope global qr-7b757ca9-3f
    inet6 fe80::f816:3eff:fe23:365b/64 scope link
       valid_lft forever preferred_lft forever
10: qg-8be78718-4b: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN
    link/ether fa:16:3e:b7:bc:06 brd ff:ff:ff:ff:ff:ff
    inet 10.100.1.130/25 brd 10.100.1.255 scope global qg-8be78718-4b
    inet 10.100.1.131/32 brd 10.100.1.131 scope global qg-8be78718-4b
    inet6 fe80::f816:3eff:feb7:bc06/64 scope link
       valid_lft forever preferred_lft forever
root@net-l3:~# ip netns exec qrouter-5fce397a-4e9d-4a42-8139-f7748a0f69b6 ping -c 3 172.16.1.3
PING 172.16.1.3 (172.16.1.3) 56(84) bytes of data.
64 bytes from 172.16.1.3: icmp_req=1 ttl=64 time=10.4 ms
64 bytes from 172.16.1.3: icmp_req=2 ttl=64 time=0.563 ms
64 bytes from 172.16.1.3: icmp_req=3 ttl=64 time=0.541 ms

--- 172.16.1.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.541/3.851/10.450/4.666 ms
root@net-l3:~# ip netns exec qrouter-5fce397a-4e9d-4a42-8139-f7748a0f69b6 route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         10.100.1.129    0.0.0.0         UG    0      0        0 qg-8be78718-4b
10.100.1.128    *               255.255.255.128 U     0      0        0 qg-8be78718-4b
172.16.1.0      *               255.255.255.0   U     0      0        0 qr-7b757ca9-3f
root@net-l3:~# ip netns exec qrouter-5fce397a-4e9d-4a42-8139-f7748a0f69b6 ping -c 3 10.100.1.129
PING 10.100.1.129 (10.100.1.129) 56(84) bytes of data.
64 bytes from 10.100.1.129: icmp_req=1 ttl=64 time=22.1 ms
64 bytes from 10.100.1.129: icmp_req=2 ttl=64 time=0.423 ms
64 bytes from 10.100.1.129: icmp_req=3 ttl=64 time=0.339 ms

--- 10.100.1.129 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.339/7.622/22.105/10.241 ms

여기서 namespace의 gateway는 quantum을 이용해서 네트워크를 생성할때 만들어준 네트워크에서 알아서 잡는 것이다. 따라서 해당 주소는 미리 있어야한다. 위에서는 external network의 subnet을 10.100.1.128/25로 주었기 때문에 해당 네트워크의 첫번째 아이피인 10.100.1.129로 gateway가 자동으로 잡혔다.

또한 10.100.1.130은 해당 네트워크의 nat로 외부 접속할 대표 아이피이고 10.100.1.131은 floatingip로 설정된 것이다.

metadata

어쨌든 가상 머신으로 ping까지 잘 가지만 ssh로 로그인할 수 없는 경우가 있다. 이런 경우는 대부분 가상머신이 metadata를 가져오지 못해서 생기는 문제로 가상머신의 로그나 vnc로 접근해서 확인하면 확인할 수 있다.

ubuntu 가상 머신의 경우는 아래와 같은 메시지가 남는다.

root@c-01-01:~# tail /var/lib/nova/instances/instance-00000003/console.log
cloud-init start-local running: Thu, 22 Nov 2012 15:07:50 +0000. up 3.37 seconds
no instance data found in start-local
ci-info: lo    : 1 127.0.0.1       255.0.0.0       .
ci-info: eth0  : 1 172.16.2.4      255.255.255.0   fa:16:3e:78:fa:03^M
ci-info: route-0: 0.0.0.0         172.16.2.1      0.0.0.0         eth0   UG
ci-info: route-1: 172.16.2.0      0.0.0.0         255.255.255.0   eth0   U
cloud-init start running: Thu, 22 Nov 2012 15:07:54 +0000. up 7.01 seconds
2012-11-22 15:08:48,306 - util.py[WARNING]: 'http://169.254.169.254/2009-04-04/meta-data/instance-id' failed [51/120s]: url error [timed out]
2012-11-22 15:09:39,360 - util.py[WARNING]: 'http://169.254.169.254/2009-04-04/meta-data/instance-id' failed [102/120s]: url error [timed out]
2012-11-22 15:09:56,379 - util.py[WARNING]: 'http://169.254.169.254/2009-04-04/meta-data/instance-id' failed [119/120s]: url error [timed out]

로그를 보면 dhcp를 통해서 ip를 받아왔지만 cloud-init에서 metadata server롤 접속하지 못해서 ssh key를 받아오지 못해 ssh 인증키를 가상머신에 설치하지 못해서 이다. 이 문제에 관해서는 이전에 적었으니 참고하시면 되고, 간단하게 말한다면 l3 agent namespace에서도 metadata server에 접속할 수 있어야되고, 반대로 metadata server에서도 가상 머신에 접속할 수 있어야 합니다. management / data / external / tenant network을 모두 같은 네트워크에서 구성했다면 문제가 안생기겠지만, 별도의 분리된 네트워크나 private network을 사용했다면 직접 연결되는 경로가 없기 때문에 만들어 줘야 합니다.

간단하게 한다면 metadata api server에서 아래처럼 하면 됩니다.

root@api $ route add -net <tenant subnet> gw <tenant default public ip>;
root@api $ route add -net 172.16.1.0/24 gw 10.100.1.130

참고로 metadata_ip는 external network에서 접근 가능한 ip여야 합니다. metadata server를 접근하는 곳이 l3 namespace인데 여기는 이미 external network 영역이기 때문입니다. 여기서 management나 기타 다른 영역으로 들어가는 것은 구성상 바람직 하지 않습니다.

기타 다른 이유들...

  • keystone
    • 설정 오류
    • quantum user의 권한 문제: quantum user는 admin role이 있어야 한다.
  • glance 이미지 설정 오류
    • glance의 설정이 잘못되어 있으면 가상 머신의 상태가 build에서 멈춰있습니다. nova-compute 쪽 로그를 보면 이미지를 찾을 수 없다고 나옵니다.
    • glace 이미지 오류: glance에서 이미지를 추가할 때 뭔가 잘못하여 active가 아닌 queued 상태인 이미지가 만들어 질 수 있는데, 이 이미지로 가상머신을 만들면 역시 build 상태에서 멈춰 있습니다.
  • quantum-service startup error
  • 가끔 nova-network을 설치해놓고선 quantum service가 왜 안뜨냐고 투덜인 분이 있습니다. 녜.... quantum은 nova-network을 완전해 대체할 목적으로 만들어 졌기에 같이 공존할 수 없습니다. nova-volume과 cinder와의 관계와 같습니다.  /etc/nova/nova.conf에 enabled_apis=ec2,osapi_compute,metadata 처럼 몇몇 서비스를 내리세욧

.....

quantum은 openstack의 마지막에 있습니다. 무슨 말이냐 keystone, glance, nova-* 등 여러 openstack 요소들이 동작을 제대로 한 이후에 quantum의 동작을 확인할 수 있습니다. 네트워크가 안된다는 것은 단순 네트워크 문제로 보이지만 다른 여러 요인들이 겹쳐서 생기는 문제가 더 많습니다. 경험상 정작 quantum 자체의 문제보다는 다른쪽의 문제가 더 많았습니다.

감이 오시나요? quantum을 하려면 다른 것도 어느 정도 대충 알아야한다는 이야기입니다. 그러지 않고서는 quantum은 문제 없어!! 라고 끝내버리는 경우가 생길 수 있는데, 이건 팀워크에서는 하면 안되는 것이죠.. 음.. 이상한..

어쨌든 끝~


bash: simple job control

bash에서 child process를 돌릴 필요가 생겨서 잠깐 테스트 삼아 작성해본 background로 프로세스 돌리고, 죽이기 스크립트

#!/bin/bash
set -m

function sig_int(){
        echo "sig_int"

        kill `jobs -p`
}

function child_process() {
        echo "enter child pid:$$, $1"
        sleep 5
        echo "exit someting $1"
}

# run several jobs
for x in {1..3}; do
        #(something $x &) # parallel executation
        child_process $x & # background executation
done

trap sig_int SIGINT

wait

* $$는 shell의 pid로 child process에서 같은 값이 나온다.
* parallel executation은 child process가 아닌 현재 스크립트와 동일한 레벨로 생성된다.


metadata_overlapping_networks에 대한 패치가 올라와 벼렸군

일전에 지금의 Quantum 구현에 overlapping networks에서 metadata를 가져오는 문제가 있고, 이에 대한 해결책에 대해서 이야기한 적이 있었죠. 시간내서 이 것을 제대로 정리해서 패치를 보낼 생각이었는데... 허걱 오늘 Dream Host에서 이 문제에 대한 패치를 보냈군요.

기본 구현을 보면 기본적인 아이디어는 제 아이디어와 비슷합니다. 역시나 namespace에서 agent를 router_id, network_id를 가지고 있는 agent를 띄우고, 다시 agent가 proxy 역할을 해서 실제 metadata로 proxy 형태로 request를 보내는 겁니다.

소스를 보니 깔끔하군요. 지금 적용해도 큰 무리는 없겠습니다. 다음주에 시도해봐야 겠습니다.

역시.. 빨리 했어야 하는건데. ㅡㅡ;


fork(?) in bash

shell script에서 fork와 비슷한 같은 작업을 하는 것은 간단하다. 함수를 호출뒤에 &를 넣어주면 되니깐... 이게 정확하게 fork와 같은 역할을 하는 지는 잘 모르겠지만, 비슷한 역할을 한다.

#!/bin/bash
function foo() {
    echo "function foo $1"
    sleep 5
    echo "exiting foo $1"
}

for x in {1..5}; do
    foo $x &
done

echo 'waiting...'
wait

foo 함수를 5개 호출하면서 child process로 호출하고, parent에서는 child process가 종료할 때 까지 기다린다. 다음은 실행 결과

$ bash fork.sh
function foo 1
function foo 2
waiting...
function foo 3
function foo 5
function foo 4
exiting foo 1
exiting foo 4
exiting foo 3
exiting foo 5
exiting foo 2

이걸 어디에 사용하냐구요? 그래요 snapshot를 뜨는데, 하나하나 하기가 너무 느려서 백그라운드로 돌릴려구요.. 잘 될려나..


ubuntu repository mirror

간단하게 apt-mirror를 이용해서 apt repository mirror를 구축하는 것에 대해 정리해본다. OpenStack을 설치하는데, 원격으로 패키지를 가져오는 것이 영 맘에 안들어 간단히 구축해본 것이다.

물론 현재는 squid를 이용한 proxy를 apt-get에서 이용하도록 하고 있지만, 그래도 외부로 나가는 traffic이 있으니.. 그것을 완전히 없애려고 하는 것이다.

rsync를 이용하는 방법도 있으나, 이것은 전체를 통체로 가져오는 것이라 크기가 너무 크다. 물론 필요한 것만 가져온다고 하지만, 그게 실상 쉽지 않다. ubuntu의 경우는 .pool에 실제 파일이 들어가 있는데, 여기서 구분하기가 만만치 않아서...

$ apt-get install apt-mirror

/etc/apt/mirror.list 파일은 적당히 편집하여 미러링 원하는 레포지트리를 선택한다.

deb-amd64 http://apt.opscode.com precise-0.10 main testing
deb-amd64 http://apt.opscode.com quantal-0.10 main testing
deb-i386 http://apt.opscode.com precise-0.10 main testing
deb-i386 http://apt.opscode.com quantal-0.10 main testing
clean http://apt.opscode.com

deb-amd64 http://ubuntu-cloud.archive.canonical.com/ubuntu/ precise-updates/folsom  main
deb-amd64 http://ubuntu-cloud.archive.canonical.com/ubuntu/ precise-proposed/folsom  main
deb-i386 http://ubuntu-cloud.archive.canonical.com/ubuntu/ precise-updates/folsom  main
deb-i386 http://ubuntu-cloud.archive.canonical.com/ubuntu/ precise-proposed/folsom  main
clean http://ubuntu-cloud.archive.canonical.com/ubuntu
  • apt-mirror는 기본으로 구동되는 OS의 arch에 맞춰서 해당 패키지만 가져오도록 되어있다. 따라서 deb-[amd64|i386]처럼 직접 아키텍쳐를 지정한다.

OpenStack을 chef로 자동하하기 때문에 chef repository를... OpenStack은 cloud-archive를 가져오기로 했다.

choe@choe-pc:~/public_html$ du -sh /var/spool/apt-mirror/mirror/*
22M	/var/spool/apt-mirror/mirror/apt.opscode.com
357M	/var/spool/apt-mirror/mirror/ubuntu-cloud.archive.canonical.com

설정이 되었으면 미러링이 잘 되는지 테스트 해본다.

$ sudo apt-mirror

별 문제 없다면 주기적으로 미러링을 하기 위해서 crontab 파일을 수정한다. apt-mirror 패키지에서 기본적인 crontab 파일을 만들어 놨지만, 주석처리되어서 실제로 미러링되지 않는다.

$ sudo vi /etc/cron.d/apt-mirror

참고로 ubuntu 공식 패키지 미러링은 하루에 4번 하는 것을 권장하고 있다. 따라서 crontab도 6시간 간격으로 지정해 놓으면 되겠다.
이제 미러링 된 파일을 웹 서버에 링크하면 된다.

$ ln -s /var/spool/apt-mirror/mirror ~/public_html/apt-mirror

ps. precise의 전체 패키지(precise, precise-updates, precise-security, precise-proposed, precise-backports/ main, multiverse, universe, restricted)는 약 80G 정도 소요된다.


OpenStack: allow_overlapping_ip의 해결 아이디어 간단 구현

quantum 제한사항에서 allow_overlapping_ip 기능이 안된다고 이전에 포스트 했었고, 이에 대해서 잠깐 생각을 하다가 아이디어가 떠올라서 몇 가지 작업했더니 대충은 동작합니다.

안되는 근본 원인은 instance의 ip를 가지고 어떤 instance인지 특정할 수 없다는 것이었는데, 여기다 tenant-id를 같이 조합하면 된다는 것이죠. 문제는 어떻게 tenant-id를 넘기느냐 였는데, http를 사용하니 header에 집어넣고, 이 header를 집어 넣는 역할을 하는 proxy를 l3 router namespace에서 동작하면 되는 것입니다.

이제 아래처럼 metadata 요청 흐름이 바뀌는 것이죠.

  • instance --> DNAT --> metadata server
  • instance --> proxy in router namespace --> metadata server

prox 서버는 간단히 twisted를 이용해서 만들었습니다.

적용 순서는...

  1. metadata patch 적용: https://github.com/whitekid/nova/commit/de9b371a4667dd66f510093a1e207bc7f9e02c6d
  2. metadata api restart

router name space에서

  1. lo device에 metadata ip 추가
    $ ip netns exec qrouter-XXXX ip addr add 169.254.169.254/32 device lo
  2. DNAT하는 iptables rule 삭제
    $ ip netns exec qrouter-XXXX
    $ iptables -t nat -L quantum-l3-agent-PREROUTING | grep 169.254.169.254 > /dev/null && iptables -t nat -D quantum-l3-agent-PREROUTING 1
    $ exit
  3. metadata proxy 실행
    $ ip netns exec qrouter-XXX python metadata-proxy [real-metadata-api-server-ip] [tenant-id]

그냥 단순히 아이디어 검증 차원이라, 실제로 쓰고자 한다면 많은 추가 작업이 필요할 것 같습니다.

https://github.com/whitekid/metadata_proxy

ps. 아.. 영어 어렵다.. ㅡㅡ


  • Copyright © 1996-2010 Your wish is my command. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress