#chiroito ’s blog

Java を中心とした趣味の技術について

Windows 上で CoreOS Container Linux を使用した k8s を構築

Container Linux 上に Kubernetes の環境を作るcoreos-kubernetesというツールが用意されています。 Windows で以下のようにこのツールを実行するとエラーで停止してしまいます。このエラーメッセージは failed generating SSL artifactsfailed generating admin SSL artifactsというメッセージだけなのでよく分かりません。

> git clone https://github.com/coreos/coreos-kubernetes.git
> cd coreos-kubernetes\multi-node\vagrant
> vagrant up

これらの問題はシェルをちょっと変えるだけで動くようになります。 vagrant, ruby, Container Linux, k8s のどれも詳しくないのですが、はまっている人が多かったのでメモとして記録しておきます。

環境

エラーの原因と解決方法

実行時に以下のが原因でエラーが発生します。

  • シェルの起動方法が誤っている
  • SSL のサブジェクトの指定方法が誤っている

シェルの起動方法

既存のコードでは vagrantfile 内にある system 関数へ指定したスクリプトを実行できないためエラーが発生します。

There was an error loading a Vagrantfile. The file being loaded
and the error message are shown below. This is usually caused by
a syntax error.

Path: C:/Users/chito/.babun/cygwin/home/chito/coreos-kubernetes/multi-node/vagrant/Vagrantfile
Line number: 0
Message: Errno::ENOEXEC: Exec format error - ./../../lib/init-ssl-ca ssl

coreos-kubernetes\multi-node\vagrant内のsystem("mkdir -p ssl && ./../../lib/init-ssl-ca ssl")system("./../../lib/init-ssl ssl admin kube-admin")system("./../../lib/init-ssl ssl #{certBaseName} #{cn} #{ipString}") の'‘内の先頭に、それぞれbashを追加します。

SSLのサブジェクトの指定方法

スクリプトが実行できるようになると、OpenSSL がエラーを出力します。サブジェクトに/CN=を設定していますが、Windows では /C で始まるためエラーになっています。

"Generating RSA private key, 2048 bit long modulus\n"
"...+++\n"
"...........+++\n"
"e is 65537 (0x10001)\n"
"Subject does not start with '/'.\n"
"problems making Certificate Request\n"
failed generating SL artifacts

coreos-kubernetes\lib\init-sslcoreos-kubernetes\lib\init-ssl-ca内のコードをそれぞれ/CN=ではなく//CN=へ修正します。

この 2 つを修正することでvagrant upで起動できるようになります。

差分

変更の差分は以下の通りです。

diff --git a/lib/init-ssl b/lib/init-ssl
index 7f1e0c0..77ef156 100755
--- a/lib/init-ssl
+++ b/lib/init-ssl
@@ -66,7 +66,7 @@ CONTENTS="${CAFILE} ${KEYFILE} ${PEMFILE}"
 echo "$CNF_TEMPLATE$(echo $SANS | tr ',' '\n')" > "$CONFIGFILE"

 $OPENSSL genrsa -out "$KEYFILE" 2048
-$OPENSSL req -new -key "$KEYFILE" -out "$CSRFILE" -subj "/CN=$CN" -config "$CONFIGFILE"
+$OPENSSL req -new -key "$KEYFILE" -out "$CSRFILE" -subj "//CN=$CN" -config "$CONFIGFILE"
 $OPENSSL x509 -req -in "$CSRFILE" -CA "$CAFILE" -CAkey "$CAKEYFILE" -CAcreateserial -out "$PEMFILE" -days 365 -extensions v3_req -extfile "$CONFIGFILE"

 tar -cf $OUTFILE -C $OUTDIR $(for  f in $CONTENTS;do printf "$(basename $f) ";done)
diff --git a/lib/init-ssl-ca b/lib/init-ssl-ca
index 57e43ac..26e984a 100755
--- a/lib/init-ssl-ca
+++ b/lib/init-ssl-ca
@@ -30,6 +30,6 @@ fi

 # establish cluster CA and self-sign a cert
 openssl genrsa -out "$OUTDIR/ca-key.pem" 2048
-openssl req -x509 -new -nodes -key "$OUTDIR/ca-key.pem" -days 10000 -out "$OUTFILE" -subj "/CN=kube-ca"
+openssl req -x509 -new -nodes -key "$OUTDIR/ca-key.pem" -days 10000 -out "$OUTFILE" -subj "//CN=kube-ca"

diff --git a/multi-node/vagrant/Vagrantfile b/multi-node/vagrant/Vagrantfile
index feabf95..63613e4 100644
--- a/multi-node/vagrant/Vagrantfile
+++ b/multi-node/vagrant/Vagrantfile
@@ -50,15 +50,15 @@ initial_etcd_cluster = etcdIPs.map.with_index{ |ip, i| "e#{i+1}=http://#{ip}:238
 etcd_endpoints = etcdIPs.map.with_index{ |ip, i| "http://#{ip}:2379" }.join(",")

 # Generate root CA
-system("mkdir -p ssl && ./../../lib/init-ssl-ca ssl") or abort ("failed generating SSL artifacts")
+system("mkdir -p ssl && bash ./../../lib/init-ssl-ca ssl") or abort ("failed generating SSL artifacts")

 # Generate admin key/cert
-system("./../../lib/init-ssl ssl admin kube-admin") or abort("failed generating admin SSL artifacts")
+system("bash ./../../lib/init-ssl ssl admin kube-admin") or abort("failed generating admin SSL artifacts")

 def provisionMachineSSL(machine,certBaseName,cn,ipAddrs)
   tarFile = "ssl/#{cn}.tar"
   ipString = ipAddrs.map.with_index { |ip, i| "IP.#{i+1}=#{ip}"}.join(",")
-  system("./../../lib/init-ssl ssl #{certBaseName} #{cn} #{ipString}") or abort("failed generating #{cn} SSL artifacts")
+  system("bash ./../../lib/init-ssl ssl #{certBaseName} #{cn} #{ipString}") or abort("failed generating #{cn} SSL artifacts")
   machine.vm.provision :file, :source => tarFile, :destination => "/tmp/ssl.tar"
   machine.vm.provision :shell, :inline => "mkdir -p /etc/kubernetes/ssl && tar -C /etc/kubernetes/ssl -xf /tmp/ssl.tar", :privileged => true
 end

この原因を突き止めるためにエラーログが出力されるように修正したので、プルリクとしてこの修正を送ってみました。

multi-node: printing error of openssl by chiroito · Pull Request #894 · coreos/coreos-kubernetes · GitHub