IT」カテゴリーアーカイブ

ITに関するニュースの感想、または勉強した記録。

Configure pinniped supervisor with Keycloak

This article explains how to configure pinniped supervisor with Keycloak on Tanzu Kubernetes Grid.

Prerequisites

Software versions

  • vSphere 7.0.3
  • Tanzu kubernetes Grid 1.6.1
  • Avi 21.1.4 2p3
  • Keycloak: 21.0.0

Environment

  • bootstrap machine hostname: tkg161(bootstrap machine is used to run management cluster)
  • domain name: hidekazun.jp

Run Keycloak docker image on bootstrap machine

Keycloak must be running with TLS which is required at least for TKG.
Run docker if not running. Create work directory and move to it.

mkdir keycloak
cd keycloak

create self-signed certificate.

echo "subjectAltName = DNS:tkg161.hidekazun.jp" > san.txt
# create key
openssl genrsa 2048 > server.key
 
# create csr
openssl req -new -key server.key > server.csr
 
# self sign
cat server.csr | openssl x509 -req -signkey server.key -extfile san.txt > server.crt

create Dockerfile

FROM quay.io/keycloak/keycloak:21.0 as builder
 
# Enable health and metrics support
ENV KC_HEALTH_ENABLED=false
ENV KC_METRICS_ENABLED=false
 
# Configure a database vendor
# ENV KC_DB=postgres
 
WORKDIR /opt/keycloak
RUN /opt/keycloak/bin/kc.sh build
 
FROM quay.io/keycloak/keycloak:latest
COPY --from=builder /opt/keycloak/ /opt/keycloak/
 
ENV KC_HOSTNAME=tkg161.hidekazun.jp
 
COPY server.key /opt/keycloak/server.key
COPY server.crt /opt/keycloak/server.crt
 
ENV KC_HTTPS_CERTIFICATE_FILE=/opt/keycloak/server.crt
ENV KC_HTTPS_CERTIFICATE_KEY_FILE=/opt/keycloak/server.key
 
ENTRYPOINT ["/opt/keycloak/bin/kc.sh"]

Let’s build.

docker build . -t mykeycloak:21.0

Run docker image

docker run --name mykeycloak -p 8443:8443 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin mykeycloak:21.0 start --optimized

Open the URL https://tkg161.hidekazun.jp:8443/ , click Administrator console and login admin/admin.

Configure Keycloak

Create myrealm realm, and myclient client, hidekazun user for authentication. At this time, Root URL, Home URL, Valid redirect URLs, Web origins of myclient client are all blank.

Create management cluster

Update Cluster configuration file as the following and create management cluster as usual by tanzu mc create. preferred_username is the claim in the ID token correspond to the client name.

IDENTITY_MANAGEMENT_TYPE: oidc
...
OIDC_IDENTITY_PROVIDER_CLIENT_ID: "myclient"
OIDC_IDENTITY_PROVIDER_CLIENT_SECRET: "SIQxCyNlFlk02Smgkmit7ZugC6Lqxm92"
OIDC_IDENTITY_PROVIDER_ISSUER_URL: "https://tkg161.hidekazun.jp:8443/realms/myrealm"
OIDC_IDENTITY_PROVIDER_NAME: "keycloak"
OIDC_IDENTITY_PROVIDER_SCOPES: "openid"
OIDC_IDENTITY_PROVIDER_USERNAME_CLAIM: "preferred_username"

After management cluster is created, pinniped-post-deploy-job is completed.

hidekazun@tkg161:~/keycloak$ k get job pinniped-post-deploy-job -n pinniped-supervisor
NAME                       COMPLETIONS   DURATION   AGE
pinniped-post-deploy-job   1/1           7s         2d7h
hidekazun@tkg161:~/keycloak$

Update Keycloak setting

Confirm EXTERNAL_IP of pinniped-supervisor service

hidekazun@tkg161:~/keycloak$ k get svc -n pinniped-supervisor
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
pinniped-supervisor LoadBalancer 100.65.87.238 192.168.103.100 443:31639/TCP 3d2h
hidekazun@tkg161:~/keycloak$

Update Root URL, Home URL, Valid redirect URLs, Web origins of myclient client to  https://192.168.103.100/callback. This ip address is vary by the environment.

Update pinniped package configuration

As of now keycloak is running by self-signed certificate so that oidcidentityprovider resource ends with error. Pinniped package configuration must be updated to add self-signed certificate.

Get base64 encoded certificate.

hidekazun@tkg161:~/keycloak$ cat server.crt | base64 -w 0

Get values.yaml of pinniped-addon. mgmt1 is managment cluster’s name.

kubectl get secret mgmt1-pinniped-addon -n tkg-system -o jsonpath="{.data.values\.yaml}" | base64 -d > values.yaml

Update values .yaml to add upstream_oidc_tls_ca_data value.

pinniped:
  cert_duration: 2160h
  cert_renew_before: 360h
  supervisor_svc_endpoint: https://0.0.0.0:31234
  supervisor_ca_bundle_data: ca_bundle_data_of_supervisor_svc
  supervisor_svc_external_ip: 0.0.0.0
  supervisor_svc_external_dns: null
  upstream_oidc_client_id: myclient
  upstream_oidc_client_secret: SIQxCyNlFlk02Smgkmit7ZugC6Lqxm92
  upstream_oidc_issuer_url: https://tkg161.hidekazun.jp:8443/realms/myrealm
  upstream_oidc_tls_ca_data: LS0tLS......

Let’s apply.

kubectl patch secret/mgmt1-pinniped-addon -n tkg-system -p "{\"data\":{\"values.yaml\":\"$(base64 -w 0 < values.yaml)\"}}" --type=merge

After a while Pinniped package is reconciled and oidcidentityprovider becomes Ready status.

hidekazun@tkg161:~/keycloak$ kubectl get oidcidentityprovider -n pinniped-supervisor
NAME                              ISSUER                                            STATUS   AGE
upstream-oidc-identity-provider   https://tkg161.hidekazun.jp:8443/realms/myrealm   Ready    70s
hidekazun@tkg161:~/keycloak$

Confirm authentication is running

Execute the following due to running the command on the bootstrap machine.

export TANZU_CLI_PINNIPED_AUTH_LOGIN_SKIP_BROWSER=true

Get kubeconfig file. The point is that –admin option is not added.

tanzu mc kubeconfig get --export-file /tmp/mgmt1-kubeconfig

Let’s execute kubectl.

kubectl get pods -A --kubeconfig /tmp/mgmt1-kubeconfig

URL is shown like the following.

hidekazun@tkg161:~/keycloak$ kubectl get pods -A --kubeconfig /tmp/mgmt1-kubeconfig
Log in by visiting this link:
 
    https://192.168.103.100/oauth2/authorize?access_type=offline&client_id=pinniped-cli&code_challenge=LB5HqUDWH4Kuv58F3FLDcep8h827PVFJbjSmlOmrp6M&code_challenge_method=S256&nonce=385e448cc0071a83475620c4d0d20efa&redirect_uri=http%3A%2F%2F127.0.0.1%3A36991%2Fcallback&response_mode=form_post&response_type=code&scope=offline_access+openid+pinniped%3Arequest-audience&state=3b8edd9d472ef250da6a674e2d3a6a0b
 
    Optionally, paste your authorization code:

Open the URL. Additional operations would be needed due to self-signed authenticate.

Login by hidekazun user created on Keycloak.

Code is shown.

Copy the code and paste after Optionally, paste your authorization code:

hidekazun@tkg161:~/keycloak$ kubectl get pods -A --kubeconfig /tmp/mgmt1-kubeconfig
Log in by visiting this link:
 
    https://192.168.103.100/oauth2/authorize?access_type=offline&client_id=pinniped-cli&code_challenge=LB5HqUDWH4Kuv58F3FLDcep8h827PVFJbjSmlOmrp6M&code_challenge_method=S256&nonce=385e448cc0071a83475620c4d0d20efa&redirect_uri=http%3A%2F%2F127.0.0.1%3A36991%2Fcallback&response_mode=form_post&response_type=code&scope=offline_access+openid+pinniped%3Arequest-audience&state=3b8edd9d472ef250da6a674e2d3a6a0b
 
    Optionally, paste your authorization code: WegmTqpnyjleGPzW8xDFVkhTlJJHOdVEo2Yny4xDb00.iU5GK34xlVAGwmHSMEz6OHCINqfhP6Rv36zJWFg4ltM
 
Error from server (Forbidden): pods is forbidden: User "hidekazun" cannot list resource "pods" in API group "" at the cluster scope
hidekazun@tkg161:~/keycloak$

hidekazun user does not have any privileges so that the error is shown. If appropriate privilages are added, pods would be shown.

Certified Kubernetes Administrator (CKA) を更新しました

2019年1月6日に取得したCertified Kubernetes Administrator (CKA) が3年で期限切れになるため、2021年12月23日に再度合格して更新しました。更新後の期限は2024年12月23日になりました。3年前のKubernetesバージョンはv1.15でしたが、今回はv1.22でした。バージョンもありますが、2020年9月1日に試験が変更されたのもあり、同様にパフォーマンスベースといいつつ出題内容は別試験なくらい違う印象でした。

試験概要

Important Instructions: CKA and CKADFrequently Asked Questions: CKA and CKAD & CKSにあります。3年前と比べると、試験時間が3時間から2時間になりました。また、UIが若干変更されて使いやすくなっていました。

方法オンライン
時間2時間
形式パフォーマンスベース(Linuxのコマンドを実行して課題を解決する)
問題数15-20

出題範囲

Deploymentばかりいじっていた3年前とは異なり、出題範囲、割合が実践的になっていました。Certified Kubernetes Administrator (CKA)には下記のように書いてありました。IngressやNetwork PolicyはCKSで出たのでCKAでもでるのかな?と半信半疑でしたが、本当に出るんですね。

Storage10%
Troubleshooting30%
Workloads & Scheduling15%
Cluster Architecture, Installation & Configuration25%
Services & Networking20%

学習方法

UdemyのCertified Kubernetes Administrator (CKA) with Practice Testsをやりました。
2021年6月2日からExam Simulatorが試験に含まれるようになっていましたが、My Portalからアクセスする方法が試験の3時間前にわかったためほとんどやりませんでした。

所感

3年前とは違い、1回で89点で合格できたので成長したようでうれしかったです。

MetalLBでtype: LoadBalancerを使う

Kubernetesの説明を見るとtype: LoadBalancerのServiceばかり、NodePortにしてるけどなんか寂しい。そんなときRaspberry Piにインストール手順を調べていたら外部LBがなくてもtype: LoadBalancerが使えるようになるMetalLBを知りました。さっそくRaspberry Piにkubernetesクラスタをインストールするでインストールしたkubernetesに入れました。

インストールはapplyするだけ。

$ kubectl apply -f https://raw.githubusercontent.com/google/metallb/v0.7.3/manifests/metallb.yaml

インストールするとmetallb-system namespaceにいろいろできる。

$ kubectl get all -n metallb-system -o wide
NAME                            READY     STATUS    RESTARTS   AGE       IP           NODE      NOMINATED NODE
pod/controller-9c57dbd4-tnfrc   1/1       Running   0          14m       10.244.2.6   berry-3   <none>
pod/speaker-7wh84               1/1       Running   0          14m       10.0.0.53    berry-3   <none>
pod/speaker-xzbh7               1/1       Running   0          14m       10.0.0.52    berry-2   <none>

NAME                     DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE       CONTAINERS   IMAGES                   SELECTOR
daemonset.apps/speaker   2         2         2         2            2           <none>          14m       speaker      metallb/speaker:v0.7.3   app=metallb,component=speaker

NAME                         DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS   IMAGES                      SELECTOR
deployment.apps/controller   1         1         1            1           14m       controller   metallb/controller:v0.7.3   app=metallb,component=controller

NAME                                  DESIRED   CURRENT   READY     AGE       CONTAINERS   IMAGES                      SELECTOR
replicaset.apps/controller-9c57dbd4   1         1         1         14m       controller   metallb/controller:v0.7.3   app=metallb,component=controller,pod-template-hash=57138680

以下でConfigMapを作成して設定を入れます。protocolはlayer2とbgpとがありますが、BGPをはなすルーターは持ってないので今回はlayer2。

$ cat l2-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 10.0.0.151-10.0.0.200
$ kubectl apply -f l2-config.yaml

それではtype: LoadBalancerのServiceとDeploymentを作成しましょう。

$ cat armhf-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-hypriot-svc
  labels:
    app: hypriot
spec:
  type: LoadBalancer
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: hypriot
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-hypriot-deploy
  labels:
    app: hypriot
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hypriot
  template:
    metadata:
      labels:
        app: hypriot
    spec:
      containers:
      - name: hypriot 
        image: hypriot/rpi-busybox-httpd
        ports:
        - containerPort: 80
$ kubectl apply -f armhf-lb.yaml

ServiceにEXTERNAL-IPが付与されたのを確かめます。

$ kubectl get svc my-hypriot-svc -o wide
NAME             TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE       SELECTOR
my-hypriot-svc   LoadBalancer   10.102.222.71   10.0.0.151    80:31981/TCP   18s       app=hypriot

しばらくしてhttp://10.0.0.151 を開くと本当に表示されました。

Raspberry Piにkubernetesクラスタをインストールする

8月末に何気なくテレビを見ていたら夏休みの自由研究について話していたので自分も何かしたくなり、3台のRaspbrerry Pi 3 B+にkubeadmを使ってkubernetesクラスタシングル構成をインストールしてみました。

購入したハードウェア

kubernetesのラズパイ包みが美味しそうだったので、kubeadmを使って作ってみたを参考にし、Raspberry PiはRSコンポーネンツから、Raspberry Pi以外はAmazonで購入しました。Raspberry Piを入れるタワー状のケースもちゃんとAmazonで売っていました。

  • Raspberry Pi 3 Model B+ [137-3331] * 3
  • Samsung microSD card 32GB(B06XSV23T1) * 3
  • Micro USB cable Syncwire UNBREAKcable 20cm(B073WT6VJ5) * 3
  • UGREEN Micro USB cable 0.5m(B06VV6Z3L7)
  • LAN cable 0.3m(B00JEUSAR2) * 3
  • 6 port USB charger(B00QUS6AY6)
  • Switching hub 5 port(B00D5Q7V1M)
  • Raspberry Pi case(B01F8AHNBA)

ソフトウェア

    • 2018-06-27-raspbian-stretch-lite.img
    • Kubeadm
$ kubeadm version
kubeadm version: &amp;version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T17:59:42Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/arm"}
$ sudo dpkg -l |grep kube
ii kubeadm 1.11.3-00 armhf Kubernetes Cluster Bootstrapping Tool
ii kubectl 1.11.3-00 armhf Kubernetes Command Line Tool
ii kubelet 1.11.3-00 armhf Kubernetes Node Agent
ii kubernetes-cni 0.6.0-00 armhf Kubernetes CNI
    • Docker
$ sudo dpkg -l |grep docker-ce
ii docker-ce 18.06.1~ce~3-0~raspbian armhf Docker: the open-source application container engine
    • Flannel
$ kubectl describe ds kube-flannel-ds-arm -n kube-system | grep Image
Image: quay.io/coreos/flannel:v0.10.0-arm
Image: quay.io/coreos/flannel:v0.10.0-arm

インストール手順

3台すべてで行うもの、Master nodeで行うもの、Worker node(2台) で行うものからなります。以下の設定で実行したので適宜置き換えてください。

ノード IPアドレス ホスト名
Master node 10.0.0.51 berry-1
Worker node1台目 10.0.0.52 berry-2
Worker node2台目 10.0.0.53 berry-3

3台すべてで行うもの

Raspberry PiのOSを手持ちのMacBookでSDカードに書き込みます。Raspbian stretch lite をhttps://www.raspberrypi.org/downloads/raspbian/からダウンロードします。以下を実行します。

$ cd ~/Download
$ unzip 2017-09-07-raspbian-stretch-lite.zip
$ sudo diskutil umount /dev/disk2s1
$ sudo dd bs=1m if=2018-06-27-raspbian-stretch-lite.img of=/dev/rdisk2 conv=sync
$ sudo diskutil umountDisk /dev/disk2

sshを有効にします。

  $ cd /Volumes/boot
  $ touch ssh

SDカードをMacBookからとり、Raspberry Piに挿入し、電源のUSBケーブルを挿します。ログインプロンプトが出たら、pi/raspberryでログインします。raspi-configコマンドを実行し、キーボード設定とホスト名を変更します。
次に、/etc/dhcpcd.confに以下を追加し、IPアドレスを変更します。ip_addressの値はそれぞれの値とします。

  interface eth0
  static ip_address=10.0.0.53/24
  static routers=10.0.0.1
  static domain_name_servers=10.0.0.1

Dockerをインストールします。

$ curl -sSL get.docker.com | sh && \
sudo usermod pi -aG docker
newgrp docker

SWAPを無効にします。

$ sudo dphys-swapfile swapoff && \
sudo dphys-swapfile uninstall && \
sudo update-rc.d dphys-swapfile remove

/boot/cmdline.txtにあるテキストの最後に、スペースを空けて以下を追加します。

cgroup_enable=cpuset cgroup_enable=memory

一旦リブートします。
kubeadmをインストールします。

$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - && \
  echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list && \
  sudo apt-get update -q && \
  sudo apt-get install -qy kubeadm

Master node(1台)で実行する

下記のコマンドを実行し、Master nodeを初期化します。

$ sudo kubeadm init --token-ttl=0 --pod-network-cidr=10.244.0.0/16

初期化が終了したら、表示されたように以下を実行します。

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

初期化が終了したら、kubeadm join で始まるコマンドが表示されているのでそれを適当な場所に保存しておきます。

Flannel setup

Flannelをインストールしてカーネルを初期化します。

$ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
$ sudo sysctl net.bridge.bridge-nf-call-iptables=1

STATUSがRunningになっていることを確認します。

$ kubectl get po -n kube-system
NAME                              READY     STATUS    RESTARTS   AGE
coredns-78fcdf6894-shcnd          1/1       Running   1          2d
coredns-78fcdf6894-vzrp9          1/1       Running   1          2d
etcd-berry-1                      1/1       Running   1          2d
kube-apiserver-berry-1            1/1       Running   1          2d
kube-controller-manager-berry-1   1/1       Running   1          2d
kube-flannel-ds-arm-k7psp         1/1       Running   2          1d
kube-proxy-x58xl                  1/1       Running   1          2d
kube-scheduler-berry-1            1/1       Running   1          2d

Worker node(2台)で実行する

カーネルパラメータを変更します。

$ sudo sysctl net.bridge.bridge-nf-call-iptables=1

クラスタに参加します。Master nodeを初期化した時に表示されたコマンドを実行します。

  $ sudo kubeadm join 10.0.0.51:6443 --token wxxo84.rmbxfo2gprs91li7 --discovery-token-ca-cert-hash sha256:d76dede60db0a973b43628d59b82a139f5978469f5f2b743c419628a45fc1cc8

Master nodeから参加したノードで動作するpodのSTATUSがRunningであることを確認します。

   $ kubectl get po -n kube-system -o wide |grep berry-2
   kube-flannel-ds-arm-gq8bs         1/1       Running   2          9h        10.0.0.52     berry-2   <none>
   kube-proxy-zx4qq                  1/1       Running   0          9h        10.0.0.52     berry-2   <none>

動作確認

hello-worldを起動してもpodがCrashLoopBackOffになってしまったので、代わりに以下の方法で確認します。まず下記を実行します。

$ kubectl run hypriot --image=hypriot/rpi-busybox-httpd --replicas=3 --port=80
$ kubectl expose deployment hypriot --port 80 --target-port 80 --type NodePort
$ kubectl get svc hypriot

実行後、http://10.0.0.52:をブラウザから開きます。

参考

  • https://gist.github.com/alexellis/fdbc90de7691a1b9edb545c17da2d975
  • https://qiita.com/hatotaka/items/48a88ecb190e1f5e03c3
  • https://blog.hypriot.com/post/setup-kubernetes-raspberry-pi-cluster/

 

Cloud Foundry Container Runtime でk8s on OpenStack

Kubernetes Meetup Tokyo #8でCloud Foundry Container Runtime(CFCR)を使ってOpenStack Pikeにk8sをインストールできると聞いてインストールしてみました。OpenStackはもう何年も触っているし、BOSHは3年前に触ったことあるし、と始めましたがドキュメント通りコピペすればいい、というわけではないのでなかなか大変でした。

OpenStack環境

https://docs.openstack.org/install-guide/openstack-services.html#minimal-deployment のminimal deployment に加えてcinder も必要なのでインストールしました。この手順ではhostsファイルで名前解決していますが、後々BOSHで起動したVMが名前解決できる必要があるのでendpointはIPアドレスで再登録しておきました。

CFCR用プロジェクト、ユーザー、鍵、仮想ネットワーク、サブネット、セキュリティグループを作成します。自分は以下のように作りました。

  • プロジェクト名:k8s
  • ユーザー k8s
  • 仮想ネットワーク selfservice
  • サブネット selfservice, 172.16.1.0/24
  • 鍵 mykey
  • セキュリティグループ k8s

セキュリティグループのルールはCFCRの前提としてBOSHが使える必要があるため、8. Add the following rules to the BOSH Security Group: かつ 5. A network configured to allow the following: をとります。

以下はセキュリティグループルールの例。試行錯誤していたので正しくないかもしれませんが。。

$ openstack security group rule list k8s 
+--------------------------------------+-------------+-----------+-------------+--------------------------------------+
| ID                                   | IP Protocol | IP Range  | Port Range  | Remote Security Group                |
+--------------------------------------+-------------+-----------+-------------+--------------------------------------+ | 09268ad6-16e0-4679-b788-97ecca778679 | udp         | None      | 8285:8285   | 99d8ce43-f500-47ec-9cce-dd4b32f6ae76 |
| 1bf09b03-bfed-4bbf-a489-70babbbb44ec | None        | None      |             | None                                 |
| 2199df36-f76f-4946-8a81-d05cd20e8622 | tcp         | 0.0.0.0/0 | 30000:32765 | None                                 |
| 2f4a30e4-2038-4883-915f-3b63322ad040 | tcp         | 0.0.0.0/0 | 8443:8443   | None                                 |
| 54357d8f-88ea-4492-a183-1c53509aa70b | tcp         | None      | 1:65535     | 99d8ce43-f500-47ec-9cce-dd4b32f6ae76 |
| 9eca2f5e-6ae7-4d79-9d4b-93fd2b002596 | tcp         | 0.0.0.0/0 | 6868:6868   | None                                 | | b5f84e30-338c-42eb-a066-8ef808345d60 | tcp         | 0.0.0.0/0 | 25555:25555 | None                                 |
| e7655700-801b-477c-b2b7-af6fe5937afc | None        | None      |             | None                                 | | ebfc7a77-f808-4216-9f7f-297eb9efcaba | tcp         | None      | 53:53       | 99d8ce43-f500-47ec-9cce-dd4b32f6ae76 |
+--------------------------------------+-------------+-----------+-------------+--------------------------------------+

また、CFCR用フレーバーm1.large、m1.xlargeを作成します。名前が合っている必要があります。以下は作成後をリストした例。

$ nova flavor-list
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| ID | Name      | Memory_MB | Disk | Ephemeral | Swap | VCPUs | RXTX_Factor | Is_Public |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+
| 0  | m1.nano   | 64        | 1    | 0         |      | 1     | 1.0         | True      |
| 1  | m1.small  | 2048      | 10   | 0         |      | 1     | 1.0         | True      |
| 2  | m1.xlarge | 8192      | 20   | 0         |      | 4     | 1.0         | True      |
| 3  | m1.large  | 4096      | 20   | 0         |      | 2     | 1.0         | True      |
+----+-----------+-----------+------+-----------+------+-------+-------------+-----------+

Bastion VM作成

OpenStack でBOSHを使うときは踏み台としてVMを作成(Bastion VMという)してそこから操作するのが常道のようです。ここでもそれに習い作成します。上記で作成したユーザーで、作成した鍵、仮想ネットワーク、サブネットを指定します。イメージはubuntu xenialにしました。フレーバーはm1.small(メモリ2048、ディスク10GB)。

Bastion VMに入り、BOSH CLI v2とcredhub-cliをインストールします。credhub-cliはドキュメントにはありませんが後々インストールが必要になります。BOSH CLI v2のインストール手順はhttps://bosh.io/docs/cli-v2.html#installにあります。Goで書かれているので実行ファイルをダウンロード、実行権を付与しパスがあるディレクトリに置きます。このとき、ファイル名をboshではなくbosh-cliにします。なぜか、CFCRのシェルスクリプトではbosh-cliとなっているためです。その後書いてある通りに(Trustyではありませんが気にせず)OS依存パッケージをインストールします。credhub-cliはhttps://github.com/cloudfoundry-incubator/credhub-cli/releasesからダウンロードして解凍し実行権を付与し、パスがあるディレクトリに移動します。

以上でOpenStack環境と作業するVMの準備ができました。

BOSHのデプロイ

https://docs-cfcr.cfapps.io/installing/openstack/deploying-bosh-openstack/ の手順です。

設定ファイル生成

Step 1: Generate a Configuration Templateに書いてある通りにBastion VMに入って実行します。実行すると/home/ubuntu/kubo-env/kubo下にdirector.yml、director-secrets.ymlができます。

ロードバランサ作成

Step 2: Configure Routingに相当する手順です。ここはよくわからず合っているかわかりませんが、とりあえず動作したということで記録します。OpenStackではロードバランササービスが一般的ではないので、VMにHAProxyをインストールしてそれをロードバランサに使います。と言ってもFloatingIPにアクセスしたらkubernetesのマスターノードにある apiserverに通すだけ。。この次で設定ファイルにFloating IPを書くこともあり、この段階でFloating IPも付与して稼働させておきます。HAProxyパッケージをインストールした後にHAProxyの設定ファイル/etc/haproxy/haproxy/haproxy.cfgに以下を追加しました。

frontend web_proxy
        default_backend kubeapi
        bind *:8443
        mode tcp

backend kubeapi
        mode tcp
        server kubeapi 172.16.1.9:8443

172.16.1.9 はkubernetesのマスターノードのIPアドレスです。実はこれはデプロイしてみないとわからないので今は適当。

BOSH directorデプロイ

BOSH directorを構築するステップです。終わるとbosh/0という名前のVMが作成されます。

まず、/home/ubuntu/kubo-env/kubo/director.ymlを編集します。以下が例です。

internal_ip: 172.16.1.20 # Internal ip address of the BOSH director. Please select an available ip address in the network you wish to deploy into.

internal_cidr: 172.16.1.0/24 # CIDR range that BOSH will deploy to
internal_gw: 172.16.1.1 # internal gateway

director_name: k8director # user friendly Director name
dns_recursor_ip: 10.0.0.1 # DNS IP address for resolving non-BOSH hostnames

kubo_release_url: https://storage.googleapis.com/kubo-public/kubo-release-latest.tgz

worker_count: 3

# IaaS routing mode settings
# Comment this section when using CF routing mode
routing_mode: iaas
kubernetes_master_host: 10.0.0.202 # IP address that can be used to reach the Kubernetes API, usually the address of a load balancer or static IP
master_target_pool: # target pool that master nodes will be a part of

authorization_mode: abac # RBAC or ABAC authorization modes for the K8s cluster. Note: RBAC is not stable as of 0.8.x.

auth_url: 'http://10.0.0.11:5000/v3' # OpenStack authentication URL
az: nova # Availability zone
default_key_name: mykey # Name of the SSH key pair
default_security_groups:
# List of security groups for the instances
  - k8s
  - default
net_id: 57452a08-e50a-40a6-a25a-cb72e8b44ac5  # OpenStack network identifier
openstack_domain: default # OpenStack domain (optional)
openstack_project: k8s # Openstack project name
openstack_tenant: k8s # OpenStack tenant (required for multi-tenant environments)
region: RegionOne # OpenStack region (optional)
openstack_username: k8s # OpenStack admin username

internal_ipはBOSH directorのIPアドレスです。まだ使われていないサブネットのIPアドレスを指定します。internal_cidrは作成したサブネットのアドレス範囲です。internal_gwは作成したサブネットのゲートウェイです。dns_recursor_ipはDNSサーバのIPアドレスです。kubernetes_master_hostはHAProxyのVMにつけたFloatingIPです。

default_key_nameに指定したキーペアの秘密鍵を適当な場所に置きます。自分は/home/ubuntu/kubo-deployment下に置きました。

次に/home/ubuntu/kubo-env/kubo/director-secretes.ymlを編集します。openstack_passwordの値にadminのパスワードを書き込みます。

準備ができたので、kubo-deployment下から以下を実行します。

$ ./bin/deploy_bosh "${kubo_env_path}" id_rsa

しばらく待つとbosh/0というVMが作成されて終了します。

CFCRデプロイ

ここまで来ればあともう少しです。ここからが本番CFCRデプロイだろ、と思いますが本当です。これが良くも悪くもBOSHというもの。

私の環境はOpenStackかつノープロキシなので、Step 3: Deploy CFCRから始まります。以下を実行します。

$ ./bin/deploy_k8s ~/kubo-env/kubo my-cluster

成功すると、VMが4つできました。マスターノード1つとワーカーノード3つのようです。名前がmasterで始まっているVMのIPアドレスをひかえます。haproxy.cfgに適当に設定したIPをこのアドレスに変更し、HAProxyサービスを再起動します。はい終了。

Kubernetesクラスターにアクセス

Step 4: Access Kubernetesの手順です。用意されているシェルを実行してconfigを生成してapiserverにアクセスします。

以下を実行します。これで~/.kube が作成されます、たぶん。

./bin/set_kubeconfig ~/kubo-env/kubo my-cluster

以下を実行し動作確認します。

$ kubectl get pods --namespace=kube-system

以下のように出力されました。

ubuntu@bastion3:~$ kubectl get pods --namespace=kube-system
NAME                                    READY     STATUS    RESTARTS   AGE
heapster-5cd77b4fcb-gfcth               1/1       Running   0          6d
kube-dns-7468555786-qm47z               3/3       Running   0          6d
kubernetes-dashboard-85f6fc6c95-b74hv   1/1       Running   0          6d
monitoring-influxdb-679d8fc75c-lr5fs    1/1       Running   0          6d

めでたく終了。

keystone をリモートデバッグする

EclipseのPydevプラグインを使い、Keystoneをリモートデバッグできたので、記録を残します。Eclipseは以前Javaによる開発で使っていたので、Eclipseについては飛ばします。

環境

  • Ubuntu Desktop 14.04.3
  • Eclipse Mars (4.5)
  • Keystone Liberty 開発サイクル

Eclipseインストール

EclipseはJava 開発者向けなどインストールに際するの選択肢が多いですが、 Eclipse Platform でよいです。Eclipseインストール後、Egit plugin、Pydev plugin をインストールします。

Keystone プロジェクト作成

Egit にて、Keystone を clone します。cloneした プロジェクトの Working directory を右クリックして Import Projects… をクリックし Import as general project を選択し、とりあえずインポートします。インポートできたらプロジェクトを右クリックし、Pydev から Set as Pydev Project を選択します。Python not configured が出た場合は、一番左にある Quick Auto-Config をクリックします。

python_not_configured

Python package インストール

python-six アンインストール

debパッケージの six ではのちにエラーになるため、python-six パッケージを削除します。

$ sudo apt-get autoremove python-six

pip インストール

debパッケージでなく、最新の pip をインストールしないとのちにエラーになるため、最新の pip をインストールします。https://pip.pypa.io/en/stable/installing/から get-pip.py をダウンロードしてインストールします。

keystone の依存パッケージインストール

git がないとのちにエラーになるため、git をインストールします。

$ sudo apt-get install git

Keystone の開発ドキュメントに従い、以下を実行します。

$ sudo apt-get install python-dev python3-dev libxml2-dev libxslt1-dev libsasl2-dev libsqlite3-dev libssl-dev libldap2-dev libffi-dev
$ sudo pip installl -r requirements.txt
$ sudo pip installl -r test-requirements.txt
$ sudo pip setup.py develop

keystone 設定ファイルコピー

Keystone の開発ドキュメントに従い、以下を実行します。

$ cp etc/keystone.conf.sample etc/keystone.conf

Eclipse設定

pysrc を PYTHONPATH にいれる

デバッグに必要な pydevd を python のパスに含めるため、pysrc を PYTHONPATH に含めます。pysrc の場所は以下コマンドで探します。

$ find ~/ -name 'org.python.pydev_*'

たとえば ./.p2/pool/plugins/org.python.pydev_4.3.0.201508182223 のようなものです。

実際にPYTHONPATHに含めるには、プロジェクトを右クリックしてPropertiesを選択。Pydev – PYTHONPATH をクリックし、External Libraries タブをクリックします。。Add source folder をクリックし、pysrc を選び、OK をクリックします。pysrc が . から始まるフォルダにある場合は、ホームディレクトリをクリック後、左上にある鉛筆アイコンをクリックし、直に入力する必要があります。

PYTHONPATH

起動設定

プロジェクト – cmd – all.py を右クリックし、Run As – Run Configurations… を選択します。Name: を適切な名称に変更し、Main タブで Main Moduleに /usr/local/bin/keystone-all を入力し、Apply をクリックします。
Run Configurations - Main

Arguments タブをクリックし、Program arguments: に –standard-threads と入力し、Apply をクリックし OK をクリックします。
Run Configurations - Arguments

設定

デバッグが始まるように、keystone/controllers.pyのdef _get_versions_list(self, context):の下に以下のコードを入れます。

import pydevd
pydevd.settrace('127.0.0.1', port=5678, stdoutToServer=True, stderrToServer=True)

pydevd

デバッグサーバ起動

Debug Perspective に移動し、メニューからPydev – Start Debug Server をクリックします。左下の Console で Debug Server at port: 5678 と表示されたことを確認します。

Keystone 起動

Pydev Perspective に移動し、メニューから Run – Run Configurations を選択し、右下のRun をクリックします。Console に Started child が4行表示されたことを確認します。

デバッグ実行

ターミナルから以下を実行します。

$ curl http://127.0.0.1:35357/v3

戻り値がなく、Eclipse の画面を見ると、def _get_versions_list(self, context): の下に入れたコードのしたで止まっている(左側に右矢印が表示されてる)ことを確認します。
debug

あとは、Debug Perspective に移動し、ステップ実行などができます。

BOSH LiteでCloud Foundryをインストールする(3)

BOSH LiteはVagrnat boxにWardenコンテナを使ったBOSHのローカル開発環境です。BOSH Liteを使って、Vagrant boxにCloud Foundry実行環境を構築できます。手元のMacBook AirにBOSH Liteを使い、Cloud Foundryを構築します。これはBOSH LiteでCloud Foundryをインストールする(2)の続きです。

BOSH Liteを使いデプロイしたCloud Foundryを設定し、アプリケーションをアップロードします。

準備
Goインストール

Cloud Foundry CLIがGoでできているため、まずはGoをインストールします。http://golang.org/からGoのディストリビューションをダウンロードし、インストールします。最新は1.3でしたが、念のため1.2をインストールしました。

$ go version
$ go version go1.2 darwin/amd64

Go環境を設定します。

$ mkdir -p ~/go
$ export GOPATH=~/go

Cloud Foundry CLIインストール

http://github.com/cloudfoundry/cli
のDownloads下にある、Stable InstallersのMac OS X 64 bitをクリックして、ダウンロードし、インストールします。

以上で準備が終わりました。

Cloud Foundry設定

Cloud Foundryを設定します。

$ cf api --skip-ssl-validation https://api.10.244.0.34.xip.io
$ cf auth admin admin
$ cf create-org me
$ cf target -o me
$ cf create-space development
$ cf target -s development

アプリケーションのアップロード

cf-acceptance-testsにサンプルアプリケーションhello-worldが含まれているので、それをアップロードすることにします。アップロードするアプリケーションを取得します。

$ go get github.com/cloudfoundry/cf-acceptance-tests
$ cd $GOPATH/src/github.com/cloudfoundry/cf-acceptance-tests

.godirファイルがないとアップロードに失敗するため、空ファイルを作成します。

$ cd assets/hello-world
$ touch .godir

アップロードします。

$ cf push hello-world

hello-worldが返ってくることを確認します。

$ curl hello-world.10.244.0.34.xip.io
hello, world!

以上で、BOSH Liteをインストールし、Cloud Foundryをデプロイ、アプリケーションをアップロードできました。

BOSH LiteでCloud Foundryをインストールする(2)

BOSH LiteはVagrnat boxにWardenコンテナを使ったBOSHのローカル開発環境です。BOSH Liteを使って、Vagrant boxにCloud Foundry実行環境を構築できます。手元のMacBook AirにBOSH Liteを使い、Cloud Foundryを構築します。これはBOSH LiteでCloud Foundryをインストールする(1)の続きです。

BOSH Liteを使い、Cloud Foundryをデプロイします。シェルスクリプトで多くが自動化されているようですが、ここでは後学のため手順を追ってデプロイします。

準備

Spiffをインストール

$ brew tap xoebus/homebrew-cloudfoundry
$ brew install spiff
$ spiff -v
spiff version 1.0.3

cf-releaseをクローン

$ cd ~/workspace
$ git clone https://github.com/cloudfoundry/cf-release

これでデプロイする準備ができたので、デプロイします。

releaseのアップロード

releaseはBOSHがソフトウェアをデプロイするのに必要なパッケージやソースコード、設定ファイルの集まりで、ymlファイルで定義されています。一番新しいリリースをアップロードします。cf-release下にあるcf-<version>.ymlでversionが一番大きいものを確認します。今回は189でしたので、cf-189をアップロードします。

$ cd ~/workspace/cf-release
$ bosh upload release releases/cf-189.yml

Warden stemcellのアップロード

stemcellはBOSHがクローンして設定するVMのテンプレートです。BOSH LiteはWarden CPIを使うので、Warden Stemcell をダウンロードします。まず、公式にあるstemcellを確認してダウンロードします。

$ bosh public stemcells
+-----------------------------------------------------------------+
| Name                                                            |
+-----------------------------------------------------------------+
| ....                                                            |
| bosh-stemcell-370-warden-boshlite-ubuntu-trusty-go_agent.tgz    |
| bosh-stemcell-53-warden-boshlite-ubuntu.tgz                     |
| bosh-stemcell-370-warden-boshlite-centos-go_agent.tgz           |
| bosh-stemcell-64-warden-boshlite-ubuntu-lucid-go_agent.tgz      |
+-----------------------------------------------------------------+
$ bosh download public stemcell bosh-stemcell-370-warden-boshlite-ubuntu-trusty-go_agent.tgz

ダウンロードしたWarden Stemcellをアップロードします。

$ bosh upload stemcell bosh-stemcell-370-warden-boshlite-ubuntu-trusty-go_agent.tgz

manifest作成

manifestはreleaseとstemcellをどうデプロイするかを定義した設定ファイルです。spiffを使ってmanifestを作成します。

$ cd ~/workspace/bosh-lite
$ ./bin/make_manifest_spiff

manifests/cf-manifest.ymlが作成されます。作成したmanifestを使い、デプロイします。

$ bosh deployment manifests/cf-manifest.yml
$ bosh deploy

以上で、デプロイは終了です。

BOSH LiteでCloud Foundryをインストールする(1)

BOSH LiteはVagrnat boxにWardenコンテナを使ったBOSHのローカル開発環境です。BOSH Liteを使って、Vagrant boxにCloud Foundry実行環境を構築できます。手元のMacBook AirにBOSH Liteを使い、Cloud Foundryを構築します。MacBook Airの詳細なスペックは以下の通りです。

  • 11-inch, Mid 2012
  • プロセッサ 2GHz Intel Core i7
  • メモリ 8GB 1600 MHz DDR3
  • OS X 10.9.5

ここではVagrant providerはVirtualboxとします。GitHubにはVMware Fusion、AWSの手順も記載があります。

前提

以下のソフトウェアはインストール済みとします。

  • git
  • ruby
  • VirtualBox
  • Vagrant

手元のバージョンは以下の通りでした。

$ git --version
git version 1.8.5.2 (Apple Git-48)
$ ruby -v
ruby 2.0.0p247 (2013-06-27 revision 41674) [x86_64-darwin12.4.0]

なお、rubyはrbenvでインストールしました。

$ VBoxManage --version
4.3.16r95972
$ vagrant --version
Vagrant 1.6.5

また、MacBookはプロキシなしでインターネットにアクセスできます。

BOSH Liteインストール

bosh_cliをインストール

BOSHのクライアントをインストールします。

$ gem install bosh_cli
$ rbenv rehash
$ bosh -v
BOSH 1.2739.0

bosh-liteをクローン

BOSHは~/workspaceにインストールする慣習があるようなので、~/workspaceにクローンします。

$ mkdir ~/workspace
$ cd ~/workspace
$ git clone https://github.com/cloudfoundry/bosh-lite.git

Vagrant boxをupします。

$ cd bosh-lite
$ vagrant up --provider=virtualbox

BOSH Directorをtargetして、admin/adminでログインします。ここの192.168.50.4はVMに自動で割りあたるアドレスです。

$ bosh target 192.168.50.4 lite
$ bosh login

ローカルのルートテーブルにルートエントリセットを追加します。

$ bin/add-route

以上でBOSH Liteのインストールは終了です。

自宅のOpenStackを Grizzly から Havanaへバージョンアップ

Basic Installation Guide for Ubuntu 12.04 (LTS) and Debian WheezyをIPも含め、完全コピーして自宅で使っていたOpenStack(Grizzly)を、時間がある年末にHavanaにバージョンアップした。

バージョンアップの手順がないので、とりあえずパッケージをアップグレードして、後はインストールガイドを参考に試行錯誤。ダウンタイムは3日程度?。その間に睡眠や買い出し、窓ふきなどの大掃除とか。それでもなんとかバージョンアップ前のインスタンス、ネットワークは使えた。ボリュームは対応途中で削除してしまったけど、そのままで対応すれば動いたかも。せっかくなので、パッケージアップグレードし、設定ファイルを一通り編集して起動した後におこった障害を記録しておく。(いきあたりばったりで起きたものばかりだけど)

その前に、知っていればよかったこと。

パッケージのアップグレード

sudo add-apt-repository cloud-archive:havana
sudo apt-get update
sudo apt-get upgrade

とする。このあと保留になったパッケージをインストールするには

sudo apt-get dist-upgrade

とする。

sudo apt-get -s dist-upgrade

でテストできるのでやってみると便利。

データベースマイグレーション

いろいろ調べて直す前に知っておきたかったこととして、nova,cinder,glance,neutronはデータベースのマイグレーションが勝手に動かないので、パッケージインストールしたあと自分でやる必要がある。keystoneはパッケージ入れたら動いていたので、ほかも動くかと思ったら違う。neutronはリリースノートに書いてあり、アップグレードする前に

quantum-db-manage --config-file /path/to/quantum.conf --config-file /path/to/plugin/conf.ini stamp grizzly

アップグレードした後に

neutron-db-manage --config-file /path/to/quantum.conf --config-file /path/to/plugin/conf.ini upgrade havana

と書いてある。neutronだけはデータベースマイグレーションがalembicなので特別らしい。nova,cinder,glanceは

*-manage db sync

みたいなやつを単純に実行すればいい。

それでは以降でパッケージアップグレードし、設定ファイルを一通り編集して起動した後に起こった障害?を書いていく。

コマンドが実行できない

source openrc

したあとコマンド実行すると

'Client' object has no attribute 'service_catalog'

と表示されて、コマンドがいっさい実行できなかった。これはずばり、
http://abhisarswami.blogspot.jp/2013/01/openstack-keystone-client-object-has-no.html
に書いてあり、

export SERVICE_TOKEN=
export SERVICE_ENDPOINT=

とするなどして、SERVICE_TOKENとSERVICE_ENDPOINTを設定しないようにして解決した。

compute nodeのアップグレードが失敗

compute nodeでアップグレードしたら依存関係で正常終了せず、以下のメッセージが出た。

 以下のパッケージには満たせない依存関係があります:

kvm-ipxe : 依存: ipxe-qemu しかし、インストールされようとしていません

qemu-kvm : 依存: qemu-system-x86 (>= 1.5.0+dfsg-3ubuntu5~cloud0)

E: 問題を解決することができません。壊れた変更禁止パッケージがあります。

これは検索しても解決策が見当たらず。インストールガイドを見ると、compute nodeに明示的にqemu-kvmやkvm-ipxeなどをインストールしていなかったので、エラーになるパッケージをとことん削除する方針にした結果、以下を削除した。

qemu-system-x86 qemu-kvm kvm nova-compute-kvm nova-compute

そして、インストールガイドの通りに。

sudo apt-get install nova-compute-kvm python-guestfs

“Unknown column ‘services.disabled_reason’ in ‘field list'”

このあと、とりあえずHorizonにログインしてみたらエラーが出てた。どんなエラーか忘れてしまったけど、novaのどれかのログに以下のエラーが出ていた。

2013-12-29 22:40:53.848 2119 TRACE nova.api.openstack OperationalError: (OperationalError) (1054, "Unknown column 'services.disabled_reason' in 'field list'") 'SELECT services.created_at AS services_created_at, services.updated_at AS services_updated_at, services.deleted_at AS services_deleted_at, services.deleted AS services_deleted, services.id AS services_id, services.host AS services_host, services.`binary` AS services_binary, services.topic AS services_topic, services.report_count AS services_report_count, services.disabled AS services_disabled, services.disabled_reason AS services_disabled_reason \nFROM services \nWHERE services.deleted = %s' (0,)

検索するとhttps://bugs.launchpad.net/nova/+bug/1194792が出てきて、やはりデータベースマイグレーションが必要だった。

nova-manage db sync

を実行した。

VMにping失敗

novaを直したので、VMが気になりVMにnamespace内からpingしてみたら、まったく反応がなし。来たよneutron、と思ってログを見ると/var/log/neutron/openvswitch-agent.logに

ERROR neutron.plugins.openvswitch.agent.ovs_neutron_agent [-] No tunnel_type specified, cannot create tunnels

と出ていた。設定ファイルを見たところ、追加設定があった。
/etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini

[ovs]
tunnel_type=gre
.......
[agent]
tunnel_types = gre
.......

を追加した。

“Table ‘cinder.volume_admin_metadata’ doesn’t exist”

次にボリューム一覧が出なかった。そろそろデータベースマイグレーションを疑いつつログを見ると、

2013-12-30 15:01:32.872 30632 TRACE cinder.service ProgrammingError: (ProgrammingError) (1146, "Table 'cinder.volume_admin_metadata' doesn't exist") 'SELECT volumes.created_at AS volumes_created_at, volumes.updated_at AS volumes_updated_at, volumes.deleted_at AS volumes_deleted_at, volumes.id AS volumes_id, volumes._name_id AS volumes__name_id,

とあり、やはりマイグレーションが必要のようだったので、

cinder-manage db sync

を実行した。

GlanceでExit code: 127

ここまでくるとglanceも疑う。どこかのログに

Exit code: 127
Stdout: ''
Stderr: '/bin/sh: 1: collie: not found\n' Disabling add method.
2013-12-30 14:49:50.507 29642 WARNING glance.store.base [-] Failed to configure store correctly: Store cinder could not be configured correctly. Reason: Cinder storage requires a context. Disabling add method.
2013-12-30 14:49:50.514 29642 WARNING glance.api.v2.images [-] Could not find schema properties file schema-image.json. Continuing without custom properties

とあったので、いちおう

glance-manage db_sync

を実行した。

ルータ一覧がエラー

ネットワークの管理はネットワークトポロジーとネットワークは開けたが、ルーターがエラーになってしまった。ログを見ると

TRACE neutron.openstack.common.rpc.amqp OperationalError: (OperationalError) (1054, "Unknown column 'routers.enable_snat' in 'field list'")

とあった。すでにneutronにしていたので、適当に以下を(たぶん)実行した。

$ neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini stamp grizzly

$ neutron-db-manage --config-file /etc/neutron/neutron.conf --config-file /etc/neutron/plugins/openvswitch/ovs_neutron_plugin.ini upgrade havana

しかし、portbindingsテーブルはすでに存在する、というようなメッセージが出てマイグレーションが失敗してしまう。実際portbindingsテーブルは存在していて、データはない。やむを得ずテーブルを削除して再度upgradeするとまた別のテーブルがあるというエラーに。。やけになって失敗するたびに存在するテーブルを削除して再実行、何度かやって最終的には成功。(http://alembic.readthedocs.org/en/latest/tutorial.htmlみて、downgrade grizzlyのあとupgradeしても失敗)
最後に

INFO  [alembic.migration] Running upgrade 27ef74513d33 -> havana, havana

と出たのでたぶん成功。

ボリュームのアタッチができない

Horizonですべて表示できていそうだったので、うれしくて使い始めると、今度はボリュームのアタッチができない。Horizonで実行しても元通りになってしまい、コマンドで実行するとなにごともなく返ってくる割にavailableのまま。ログには

2013-12-30 23:11:04.581 31892 TRACE nova.openstack.common.rpc.amqp Command: sudo nova-rootwrap /etc/nova/rootwrap.conf iscsiadm -m node -T iqn.2010-10.org.openstack:volume-8978b858-22d9-4347-9690-0c2a6347d595 -p 10.0.0.10:3260 --rescan
2013-12-30 23:11:04.581 31892 TRACE nova.openstack.common.rpc.amqp Exit code: 255
2013-12-30 23:11:04.581 31892 TRACE nova.openstack.common.rpc.amqp Stdout: ''
2013-12-30 23:11:04.581 31892 TRACE nova.openstack.common.rpc.amqp Stderr: 'iscsiadm: No portal found.\n'

とあった。ここは何も変更してないはずなので、iSCSI周りをいろいろ調べた。10.0.0.10がよくないのかと思い、cinder.conf、nova.confに

iscsi_ip_address=10.10.10.10

を追加しても、状況は変わらず。かなり絶望しつつ検索すると、ずばりhttp://ubuntuforums.org/showthread.php?t=2045883にiscsitargetを削除しろとあった。ねんのため、

apt-get remove --purge iscsitarget

を実行後、リブートした。

以上、起こった障害を書いてみた。実際やってみた感想としては、思ったより難しくなく、かといって簡単でもない、といったところか。