brew installしたJenkinsから、docker-desktop上のKubernetesへアクセスする

# 動機

Kubernetesは便利だけれど結構作り直したり、マルチクラスタ管理してるので、Jenkinsはクラスタの外に立ててる。ローカルの開発環境を作っておくと、捗る。

# 準備

## Install Docker-Desktop

公式からインストーラーに従ってインストールする。
https://www.docker.com/products/docker-desktop

インストールしたら、設定→KubernetesからKubernetesを有効にする。
<img width="503" alt="Screen Shot 2019-07-08 at 21.55.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2826/40124dfe-b33f-6b27-f585-7b3a38968e7d.png">

## Install Java

Javaが入っていない人は、Javaから入れる。
ちなみに、いきなりJenkinsから入れようとしたら、まずはJavaをインストールしなよってインストールコマンド教えてくれた。親切。

```sh
$ brew cask install homebrew/cask-versions/adoptopenjdk8
```

## Install Jenkins

```sh
$ brew install jenkins
```

### Change listening port

デフォルトだと、localhostからしかアクセスできないので、Kubernetes上のPodからアクセスできるようにする。listenしてるアドレスを、0.0.0.0に変えるだけです。
**この変更を行うと、同じネットワーク上の任意のマシンからアクセスが可能になるので、Jenkins adminのパスワード管理はしっかりしましょう。**

```sh
$ sudo vi /usr/local/opt/jenkins/homebrew.mxcl.jenkins.plist
17c17
<       <string>--httpListenAddress=127.0.0.1</string>
---
>       <string>--httpListenAddress=0.0.0.0</string>
```

### Initialize Jenkins

```sh
$ brew services start jenkins
```

Jenkins立ち上げたら、http://localhost:8080 をブラウザで開き、初期化パスワードを入力して、オススメのPluginsをインストールする。

5分ほどかかるので、小休止する。

#### 余談

今後、困ったらとりあえず再起動する http://localhost:8080/safeRestart

Jenkinsがハングしたとしても、落ち着いてサービスを再起動する

```sh
$ brew services restart jenkins
```

### Integrate with a Kubernetes

#### Permit Agent → Jenkins Master

特に理由がなければ、Randomで大丈夫です。
http://localhost:8080/configureSecurity/
<img width="482" alt="Screen Shot 2019-07-08 at 22.17.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2826/60f89311-48b3-fbee-a9e7-618c49e7fe40.png">

#### Install Kubernetes plugin

kubernetes何ちゃら等々ヒットすると思いますが、そのものズバリ`kubernetes`ってのをインストールしてください。
http://localhost:8080/pluginManager/available

#### Configure Kubernetes info

一番下に、クラウドの追加というボタンが増えていると思うので、そこからKubernetesを選択する。
http://localhost:8080/configure

ひとまず、下記の３つを埋めておけば良いです。

##### Kubernetes URL

```sh
$ kubectl config view --flatten -o jsonpath='{.clusters[?(@.name=="docker-desktop")].cluster.server}'
https://127.0.0.1:6443
```

もしくは

```sh
$ kubectl config view --flatten -o jsonpath='{.clusters[?(@.name=="docker-for-desktop-cluster")].cluster.server}'
https://127.0.0.1:6443
```

##### Kubernetes server certificate key

```sh
$ kubectl config view --flatten -o jsonpath='{.users[?(@.name=="docker-desktop")].user.client-certificate-data}' | base64 --decode
-----BEGIN CERTIFICATE-----
xxx
xxx
xxx
-----END CERTIFICATE-----
```

もしくは

```sh
$ kubectl exec -it kube-apiserver-docker-for-desktop -n kube-system -- cat /run/config/pki/ca.crt
-----BEGIN CERTIFICATE-----
xxx
xxx
xxx
-----END CERTIFICATE-----
```

##### Jenkins URL

127.0.0.1だと、KubernetesのPodからJenkins Masterに繋ぎこみができなくなるので注意。

```sh
$ ip addr show en0
```

お疲れ様です、準備完了です。
小休止する。

# テスト

Kubernetes pluginのgithubに、いくつかサンプルがあるので、適当に選んで実行する。
https://github.com/jenkinsci/kubernetes-plugin/tree/master/examples

新規ジョブを、Pipelineとして作成する。
http://localhost:8080/view/all/newJob

Scriptに下記のコードをコピペする。

```groovy
pipeline {
  agent {
    kubernetes {
      //cloud 'kubernetes'
      label 'mypod'
      yaml """
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: maven
    image: maven:3.3.9-jdk-8-alpine
    command: ['cat']
    tty: true
"""
    }
  }
  stages {
    stage('Run maven') {
      steps {
        container('maven') {
          sh 'mvn -version'
        }
      }
    }
  }
}
```

初回実行時は、maven imageのダウンロード等で多少時間がかかりますが、２回目以降はすぐ終わりますのでご安心を。

成功した場合は、このような出力になるはずです。

```
Started by user takitake.job@gmail.com
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] podTemplate
[Pipeline] {
[Pipeline] node
Still waiting to schedule task
‘mypod-br97w-6pr07’ is offline
Agent mypod-br97w-6pr07 is provisioned from template Kubernetes Pod Template
Agent specification [Kubernetes Pod Template] (mypod): 
yaml:

apiVersion: v1
kind: Pod
spec:
  containers:
  - name: maven
    image: maven:3.3.9-jdk-8-alpine
    command: ['cat']
    tty: true


Running on mypod-br97w-6pr07 in /home/jenkins/workspace/maven
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Run maven)
[Pipeline] container
[Pipeline] {
[Pipeline] sh
+ mvn -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T16:41:47+00:00)
Maven home: /usr/share/maven
Java version: 1.8.0_121, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8-openjdk/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "4.9.125-linuxkit", arch: "amd64", family: "unix"
[Pipeline] }
[Pipeline] // container
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] }
[Pipeline] // podTemplate
[Pipeline] End of Pipeline
Finished: SUCCESS
```

失敗した場合は、ログを見てみましょう。
エラーメッセージでググれば、大抵は解決方法が見つかります。
http://localhost:8080/log/all

# 終わりに

Kubernetesクラスタを作り直した場合やPCを再起動した場合に、KubernetesやJenkinsのIPが変わることがあるので、その都度更新する必要があるのが玉に瑕ですが、やはりローカルで試せるとフィードバックサイクルが圧倒的に早いのでお試しくださいませ。