GitHub Kubernetesのソースコードからビルドする方法のメモ

KubernetesをGitHubのソースコード https://github.com/kubernetes/kubernetes から実行形式のコマンドをビルドする方法についてのメモです。このメモでは、次の３種類のバージョンについてビルド方法を書き残しておきます。

1. リリース前の開発中のソースコードからビルド
2. 既にリリースされサポート期間中の最新コードからビルド
3. 既にリリース済み(GA)のコードからビルド


## ビルド環境の準備

日々使用しているMacやWindowsなどの仕事環境に影響を与えたく無いので、Vagrant + VirtualBox の仮想マシンの上で、Kubernetesをソースコードからバイナリへビルドします。VagrantやVirtualBoxのインストール方法はこの記事では取り上げないので、それぞれのソフトウェアのホームページなどを参考にインストールしてくださいね。

以下は、ビルド用仮想マシンのVagrantfileにリストです。仮想マシンを起動するディレクトリを作成して、このファイルをおいて、vagrant up する事で ビルド環境は構築完了です。

このファイルでは、`vb.memory = "16384"`で 16GBのメモリを割り当て、`vb.cpus = 16` によって 仮想CPUを16個割り当てています。時間の節約になるので、仮想マシンのホストのリソースが許すかぎり大きな値を設定しておくと良いと思います。


~~~file:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"
  config.vm.synced_folder ".", "/vagrant"
  config.vm.provider "virtualbox" do |vb|
     vb.gui = false
     vb.memory = "16384"
     vb.cpus = 16
  end
  config.vm.provision "shell", inline: <<-SHELL
     apt-get update
     apt-get install -y build-essential
     export GO_VER="1.14.2"
     curl -s -O https://dl.google.com/go/go${GO_VER}.linux-amd64.tar.gz
     tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz
     echo "export PATH=$PATH:/usr/local/go/bin" > /home/vagrant/.profile
     echo "export GOPATH=/home/vagrant" >> /home/vagrant/.profile
  SHELL
end
~~~

起動までのコマンドを列挙しておきます。 viなどのエディタを使用して上記のファイルを準備しておき、`vagarnt up` によって起動します。

~~~
mkdir k8s-build
cd k8s-build
vi Vagrantfile
vagrant up
~~~

## リリース前の開発中のソースコードからビルド

この方法は、GitHub https://github.com/kubernetes/kubernetes に記述された方法とほぼ同じで、`vagrant ssh`で仮想マシンにログインしたあとの作業を書いておきます。

仮想マシンの起動段階で既にGo言語のソースコードをコンパイルとリンクする環境はできていますから、環境変数`GOPATH`を設定して、ディレクトリを作成後に移動して、GitHubからコードをクローンして、コンパイルを開始するだけです。

~~~
vagrant@ubuntu-bionic:~$ export GOPATH=`pwd`/v1.19.x
vagrant@ubuntu-bionic:~$ mkdir -p $GOPATH/src/k8s.io
vagrant@ubuntu-bionic:~$ cd $GOPATH/src/k8s.io
vagrant@ubuntu-bionic:~/v1.19.x/src/k8s.io$ git clone https://github.com/kubernetes/kubernetes
...

vagrant@ubuntu-bionic:~/v1.19.x/src/k8s.io$ cd kubernetes/
vagrant@ubuntu-bionic:~/v1.19.x/src/k8s.io/kubernetes$ make
...

~~~

ビルドが完了したバイナリファイルは、カレントディレクトリの`_output/bin/*`にありますから、この仮想マシンの外で利用できるように、仮想化のホストマシンとの共有ディレクトリ `/vagrant` へコピーする。

~~~
vagrant@ubuntu-bionic:~/v1.19.x/src/k8s.io/kubernetes$ mkdir /vagrant/v1.19.x
vagrant@ubuntu-bionic:~/v1.19.x/src/k8s.io/kubernetes$ cp _output/bin/* /vagrant/v1.19.x/
vagrant@ubuntu-bionic:~/v1.19.x/src/k8s.io/kubernetes$ exit
~~~

動作確認として kubectl コマンドでバージョンを表示してみる。以下のように、v1.19.0 のアルファ・バージョンである事が判ります。

~~~
tkr@hibiki:~/build-k8s/v1.19.x$ ./kubectl version --client --short
Client Version: v1.19.0-alpha.3.84+a3cf6fc0aae6be
~~~

仮想マシンごとクリーンナップするには、`vagrant destroy` を利用します。



## 既にリリースされサポート期間中の最新コードからビルド

例えば Kubernetes v1.18.2 までのパッチ・リリース済みで、v1.18.3 のパッチのリリース準備が進んでいる状況で、最新コードでビルドの方法です。

~~~
vagrant@ubuntu-bionic:~$ export GOPATH=`pwd`/v1.18.x
vagrant@ubuntu-bionic:~$ mkdir -p $GOPATH/src/k8s.io
vagrant@ubuntu-bionic:~$ cd $GOPATH/src/k8s.io
vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io$ git clone https://github.com/kubernetes/kubernetes
vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io$ cd kubernetes/
~~~

上記まで共通で、次にブランチをリストして、ビルドしたブランチへ切り替えます。

~~~
vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io/kubernetes$ git branch -a
* master
...
  remotes/origin/release-1.16
  remotes/origin/release-1.17
  remotes/origin/release-1.18
  remotes/origin/release-1.2
  remotes/origin/release-1.3
...
~~~

ブランチを切り替えた後は同じ手順で、v1.18.xの最新パッチリリースを入手できます。

~~~
vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io/kubernetes$ git checkout release-1.18
...

vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io/kubernetes$ make
~~~

上記でビルドされたバイナリを共有ディレクトリにコピーします。

~~~
vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io/kubernetes$ mkdir /vagrant/v1.18.x
vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io/kubernetes$ cp _output/bin/* /vagrant/v1.18.x
vagrant@ubuntu-bionic:~/v1.18.x/src/k8s.io/kubernetes$ exit
~~~

仮想マシンからログアウトして、kubectl コマンドでバージョンをみると、GA前のコードである事が確認できました。

~~~
tkr@hibiki:~/build-k8s$ cd v1.18.x
tkr@hibiki:~/build-k8s/v1.18.x$ ./kubectl version --client --short
Client Version: v1.18.3-beta.0.26+058eecbfefc296
~~~



## リリース済みのKubernetesをビルドする方法

リリース済みの Kubernetes のバージョンは、このURL https://github.com/kubernetes/kubernetes/releases から参照でき、ソースコードのダウンロードリンクも掲示されています。このセクションでは、URLからソースコードをダウンロードして、バイナリを作リます。

具体的には、ビルド用の仮想マシンにログインした後は、前述のURLからバージョンを選んでソースコードのtarファイルをダウンロードして、後は同じ手順です。

~~~
curl -OL https://dl.k8s.io/v1.18.2/kubernetes-src.tar.gz
export GOPATH=`pwd`/v1.18.2
mkdir $GOPATH
tar -C $GOPATH -xzf kubernetes-src.tar.gz
cd $GOPATH
make
~~~

ビルド用仮想マシンから、ホストマシンへ、バイナリをコピーします。

~~~
vagrant@ubuntu-bionic:~/v1.18.2$ mkdir /vagrant/v1.18.2
vagrant@ubuntu-bionic:~/v1.18.2$ cp _output/bin/* /vagrant/v1.18.2/
vagrant@ubuntu-bionic:~/v1.18.2$ exit
~~~


## まとめ

Kubernetesのソースコードから、実行形式のバイナリファイルをビルドする方法について調べてみた。Go言語の開発環境が準備できていれば、バイナリをビルドすることは簡単な事がわかった。また、GitHubのコードは、各リリースの最新コードとなっているので、リリース済み(GA)のソースを使いたい場合は、Releases https://github.com/kubernetes/kubernetes/releases から入手できる。

次は、こうして作った実行形式でK8sクラスタを稼働させるまでについて、取り組んでみたい。