Go勉強(2)　kubernetes client-goのexamplesをbuildする

# シリーズ
[Go勉強(1)　mac＋VSCode＋Go環境を設定](https://qiita.com/oruharo/items/545378eae5c707f717ed)
[Go勉強(2)　kubernetes client-goのexamplesをbuildする](https://qiita.com/oruharo/items/261d065340845149b4ce)
[Go勉強(3)　kubernetes client-goのexamplesを読んでみる](https://qiita.com/oruharo/items/8f98e75264b9d6c7df2a)
[Go勉強(4)　kubernetes client-goでPodのwatcher（TUI）を書いてみる]
(https://qiita.com/oruharo/items/668d708cead0ad261346)
[Go勉強(5)　kubernetes client-goでPodのwatcher（TUI）を書いてみる2]
(https://qiita.com/oruharo/items/b7a131bf3eda36dd08a3)

# はじめに

Kubernetes関連のツールを作成したいと思ってます。
[Kubernetes Reference Client Libraries](https://kubernetes.io/docs/reference/using-api/client-libraries/)によると、GoでKubernetesにアクセスするには[client-go](https://github.com/kubernetes/client-go/)を使います。

このライブラリを使ったサンプルをビルド＆実行してみます。


| 前提環境        |                            |
|----------------|----------------------------|
| クライアント     |macOS Mojava 10.14.6<br>Homebrew、Visual Studio Code 、go 1.13.1、kubectl 1.15|
|サーバ環境|AWS EKS|
■参考
・[client-go(github)](https://github.com/kubernetes/client-go/)

#サンプルコードをゲット

`client-go`を使ってKubernetesのクラスタの外からアクセスするサンプルコードがgithubに上がっているのでそれを使います。
■example：out-of-cluster-client-configuration
https://github.com/kubernetes/client-go/tree/master/examples/out-of-cluster-client-configuration

```console
$ mkdir $HOME/go/src/out-of-cluster-client-configuration
$ cd $HOME/go/src/out-of-cluster-client-configuration
$ curl -O https://raw.githubusercontent.com/kubernetes/client-go/master/examples/out-of-cluster-client-configuration/main.go
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2880  100  2880    0     0   6260      0 --:--:-- --:--:-- --:--:--  6260
$ ls -l
total 8
-rw-r--r--  1 xxxxx  staff  2880 10 19 00:58 main.go
```
成功です。

# build
[example：out-of-cluster-client-configuration](https://github.com/kubernetes/client-go/tree/master/examples/out-of-cluster-client-configuration)に従ってBuildしてみます。


```console
$ go build -o app .
main.go:27:2: cannot find package "k8s.io/apimachinery/pkg/api/errors" in any of:
        /usr/local/Cellar/go/1.13.1/libexec/src/k8s.io/apimachinery/pkg/api/errors (from $GOROOT)
        /Users/xxxxx/go/src/k8s.io/apimachinery/pkg/api/errors (from $GOPATH)
main.go:28:2: cannot find package "k8s.io/apimachinery/pkg/apis/meta/v1" in any of:
        /usr/local/Cellar/go/1.13.1/libexec/src/k8s.io/apimachinery/pkg/apis/meta/v1 (from $GOROOT)
        /Users/xxxxx/go/src/k8s.io/apimachinery/pkg/apis/meta/v1 (from $GOPATH)
main.go:29:2: cannot find package "k8s.io/client-go/kubernetes" in any of:
        /usr/local/Cellar/go/1.13.1/libexec/src/k8s.io/client-go/kubernetes (from $GOROOT)
        /Users/xxxxx/go/src/k8s.io/client-go/kubernetes (from $GOPATH)
main.go:30:2: cannot find package "k8s.io/client-go/tools/clientcmd" in any of:
        /usr/local/Cellar/go/1.13.1/libexec/src/k8s.io/client-go/tools/clientcmd (from $GOROOT)
        /Users/xxxxx/go/src/k8s.io/client-go/tools/clientcmd (from $GOPATH)
```
怒られました。 何やらModulesの設定をやらないといけないみたいです。

```console
$ go mod init
go: creating new go.mod: module out-of-cluster-client-configuration
Airine:out-of-cluster-client-configuration xxxxx$ ls -l
total 16
-rw-r--r--  1 xxxxx  staff    52 10 19 01:00 go.mod
-rw-r--r--  1 xxxxx  staff  2880 10 19 00:58 main.go
```
`go.mod`ファイルが追加されました。中身はこんな感じ。

```go.mod
module out-of-cluster-client-configuration

go 1.13
```

再度Buildします。

```console
$ go build -o app .
go: finding k8s.io/client-go v11.0.0+incompatible
go: finding k8s.io/apimachinery latest
go: downloading k8s.io/client-go v11.0.0+incompatible
go: downloading k8s.io/apimachinery v0.0.0-20191017185446-6e68a40eebf9
go: extracting k8s.io/apimachinery v0.0.0-20191017185446-6e68a40eebf9
go: extracting k8s.io/client-go v11.0.0+incompatible
go: downloading github.com/golang/protobuf v1.3.1
go: downloading k8s.io/klog v1.0.0
go: downloading github.com/spf13/pflag v1.0.3
go: downloading github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
go: extracting github.com/spf13/pflag v1.0.3
go: extracting k8s.io/klog v1.0.0
go: extracting github.com/golang/protobuf v1.3.1
go: finding golang.org/x/crypto latest
go: finding k8s.io/api latest
go: downloading github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
go: downloading golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
go: extracting github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
go: downloading k8s.io/api v0.0.0-20191016225839-816a9b7df678
go: extracting golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
go: extracting k8s.io/api v0.0.0-20191016225839-816a9b7df678
go: extracting github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
go: finding github.com/imdario/mergo v0.3.8
go: downloading github.com/imdario/mergo v0.3.8
go: extracting github.com/imdario/mergo v0.3.8
go: downloading github.com/modern-go/reflect2 v1.0.1
go: extracting github.com/modern-go/reflect2 v1.0.1
go: downloading github.com/json-iterator/go v1.1.7
go: extracting github.com/json-iterator/go v1.1.7
go: downloading sigs.k8s.io/yaml v1.1.0
go: extracting sigs.k8s.io/yaml v1.1.0
go: finding golang.org/x/time latest
go: downloading golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0
go: extracting golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0
go: downloading golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc
go: downloading gopkg.in/yaml.v2 v2.2.4
go: downloading github.com/davecgh/go-spew v1.1.1
go: extracting github.com/davecgh/go-spew v1.1.1
go: downloading gopkg.in/inf.v0 v0.9.0
go: extracting gopkg.in/yaml.v2 v2.2.4
go: extracting gopkg.in/inf.v0 v0.9.0
go: extracting golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc
go: downloading github.com/google/gofuzz v1.0.0
go: extracting github.com/google/gofuzz v1.0.0
go: downloading github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go: extracting github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go: downloading golang.org/x/text v0.3.2
go: extracting golang.org/x/text v0.3.2
go: finding k8s.io/utils latest
go: downloading k8s.io/utils v0.0.0-20191010214722-8d271d903fe4
go: finding golang.org/x/oauth2 latest
go: downloading golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
go: extracting golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
go: extracting k8s.io/utils v0.0.0-20191010214722-8d271d903fe4
go: downloading golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f
go: extracting golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f
go: finding github.com/golang/protobuf v1.3.1
go: finding github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d
go: finding github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d
go: finding github.com/spf13/pflag v1.0.3
go: finding github.com/google/gofuzz v1.0.0
go: finding golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f
go: finding gopkg.in/yaml.v2 v2.2.4
go: finding gopkg.in/inf.v0 v0.9.0
go: finding github.com/json-iterator/go v1.1.7
go: finding github.com/modern-go/reflect2 v1.0.1
go: finding k8s.io/klog v1.0.0
go: finding github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
go: finding golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc
go: finding sigs.k8s.io/yaml v1.1.0
go: finding golang.org/x/text v0.3.2
go: finding github.com/davecgh/go-spew v1.1.1
# k8s.io/client-go/rest
../../pkg/mod/k8s.io/client-go@v11.0.0+incompatible/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
        have (*versioned.Decoder)
        want (watch.Decoder, watch.Reporter)
```

いい感じに進んだように見えて最後にエラーが出ました。
`go.mod`の中身は以下のように変わりました。

```go.mod
module out-of-cluster-client-configuration

go 1.13

require (
        github.com/imdario/mergo v0.3.8 // indirect
        golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
        golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 // indirect
        golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
        k8s.io/api v0.0.0-20191016225839-816a9b7df678 // indirect
        k8s.io/apimachinery v0.0.0-20191017185446-6e68a40eebf9
        k8s.io/client-go v11.0.0+incompatible
        k8s.io/utils v0.0.0-20191010214722-8d271d903fe4 // indirect
)
```

エラー原因を探っているうちにgithubに[client-goのインストール方法](https://github.com/kubernetes/client-go/blob/master/INSTALL.md)が書かれていることに気付きました。。

```console
$ go get k8s.io/client-go@master
go: finding k8s.io/client-go master
go: downloading k8s.io/client-go v0.0.0-20191016230210-14c42cd304d9
go: extracting k8s.io/client-go v0.0.0-20191016230210-14c42cd304d9
```
ちゃんとインストールできた風です。
`go.mod`の内容がまた変わりました。 `k8s.io/client-go`のバージョンが変わって`golang.org/x/oauth2`と`k8s.io/utils`が無くなりました。

```go.mod
module out-of-cluster-client-configuration

go 1.13

require (
        github.com/imdario/mergo v0.3.8 // indirect
        golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
        golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
        k8s.io/api v0.0.0-20191016225839-816a9b7df678 // indirect
        k8s.io/apimachinery v0.0.0-20191017185446-6e68a40eebf9
        k8s.io/client-go v0.0.0-20191016230210-14c42cd304d9
)
```
再々度、buildします。

```console
$ go build -o app .
$ ls -l
total 68608
-rwxr-xr-x  1 xxxxx  staff  35096508 10 19 01:04 app
-rw-r--r--  1 xxxxx  staff       412 10 19 01:03 go.mod
-rw-r--r--  1 xxxxx  staff     18923 10 19 01:03 go.sum
-rw-r--r--  1 xxxxx  staff      2880 10 19 00:58 main.go
```
今度は通りました。
実行ファイルが出来上がりました。 35MBもあります。`client-go`が大きいんですかね？
実行してみます。

```console
$ ./app
There are 15 pods in the cluster
Pod example-xxxxx in namespace default not found
There are 15 pods in the cluster
Pod example-xxxxx in namespace default not found
^C
```
ソースに直書きされているPod名があれなんでnot foundになりましたが、Kubernetesのクラスターへはアクセスできてるようです。

# 一からBuildをやり直す

もう一度、ソース以外を消してやりなおします。

```console
$ ls -l
total 68608
-rwxr-xr-x  1 xxxxx  staff  35096508 10 19 01:04 app
-rw-r--r--  1 xxxxx  staff       412 10 19 01:03 go.mod
-rw-r--r--  1 xxxxx  staff     18923 10 19 01:03 go.sum
-rw-r--r--  1 xxxxx  staff      2880 10 19 00:58 main.go
$ rm app go.mod go.sum
$ ls -l
total 8
-rw-r--r--  1 xxxxx  staff  2880 10 19 00:58 main.go
```
モジュールを初期化してclient-goをゲットします。

```console
$ go mod init
go: creating new go.mod: module out-of-cluster-client-configuration
$ go get k8s.io/client-go@master
go: finding k8s.io master
go: finding k8s.io/client-go master
```
`go.mod`ファイルの中身です。

```go.mod
module out-of-cluster-client-configuration

go 1.13

require k8s.io/client-go v0.0.0-20191016230210-14c42cd304d9 // indirect
```
Buildします。

```console
$ go build -o app .
go: downloading k8s.io/apimachinery v0.0.0-20191016060620-86f2f1b9c076
go: downloading k8s.io/api v0.0.0-20191010143144-fbf594f18f80
go: downloading github.com/imdario/mergo v0.3.5
go: extracting github.com/imdario/mergo v0.3.5
go: extracting k8s.io/apimachinery v0.0.0-20191016060620-86f2f1b9c076
go: extracting k8s.io/api v0.0.0-20191010143144-fbf594f18f80
go: downloading golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
go: downloading golang.org/x/time v0.0.0-20181108054448-85acf8d2951c
go: extracting golang.org/x/time v0.0.0-20181108054448-85acf8d2951c
go: extracting golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
go: finding k8s.io/apimachinery v0.0.0-20191016060620-86f2f1b9c076
go: finding k8s.io/api v0.0.0-20191010143144-fbf594f18f80
go: finding github.com/imdario/mergo v0.3.5
go: finding golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
go: finding golang.org/x/time v0.0.0-20181108054448-85acf8d2951c
$ ls -l
total 68592
-rwxr-xr-x  1 xxxxx  staff  35088188 10 19 01:10 app
-rw-r--r--  1 xxxxx  staff       174 10 19 01:10 go.mod
-rw-r--r--  1 xxxxx  staff     18118 10 19 01:10 go.sum
-rw-r--r--  1 xxxxx  staff      2880 10 19 00:58 main.go
```
OKです。


```go.mod
module out-of-cluster-client-configuration

go 1.13

require (
        k8s.io/apimachinery v0.0.0-20191016060620-86f2f1b9c076
        k8s.io/client-go v0.0.0-20191016230210-14c42cd304d9
)
```
ん？ さっきやった時よりrequireが減りました。 
消えたは下の４つです。 全行`//indirec`ってコメントがついてます。

```
        github.com/imdario/mergo v0.3.8 // indirect
        golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 // indirect
        golang.org/x/time v0.0.0-20190921001708-c4c64cad1fd0 // indirect
        k8s.io/api v0.0.0-20191016225839-816a9b7df678 // indirect
```

できあがった実行ファイルはファイルサイズも同じだし、さっきと同じものができてそうです。

# おわりに

とりあえず触ってみる的に進めてます。
Modules関係とかちゃんと勉強しないといけないみたいですが、コード書きたいので先に進みます。