Gitlab-runnerにてCIのテストにkubernetes(Kindを用いたテスト、及びKubernetes clusterにdeploy)

# Gitlab-Ruunerとは
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416540/774fe4c5-a151-feaf-989c-7891d6444da5.png)


https://docs.gitlab.com/runner/

gitlabと連携をして、CI/CDを行うためのツール。


# 環境
dockerホスト(gitlab-runnerコンテナがのっている)
kubernetes cluster × 1

# Step1 Kindのdeploy

https://qiita.com/ryojsb/items/e2146ad41005f536cf74
ここにまとめましたので、参照ください。

こちらは、docker host及びgitlab-runnerの両方にします。
## gitlab-runnerコンテナに関して

gitlab-runnerコンテナに関しては、kindのコマンドを打てるようにするとことまでで大丈夫です。

その際、以下を実行しその下にgoディレクトリを配置します。

```
# mkdir /home/gitlab-runner/lib/
```

そしてこの状態にしてください。

```
# ls -ltr
total 70248
-rwxr-xr-x 1 gitlab-runner gitlab-runner  3525802 Aug 15 18:50 gofmt
-rwxr-xr-x 1 gitlab-runner gitlab-runner 14613596 Aug 15 18:50 go
-rwxr-xr-x 1 gitlab-runner gitlab-runner 17422189 Aug 15 18:51 godoc
drwxr-xr-x 3 gitlab-runner gitlab-runner       17 Aug 28 06:34 pkg
-rwxr-xr-x 1 gitlab-runner gitlab-runner 36367031 Aug 28 07:01 kind
```


gitlab-runnerコンテナ内では、gitlab-runnerユーザに権限を与えてあげてください。

```
# chmod 777 /home/gitlab-runner/.docker
# chmod 777 /home/gitlab-runner/.docker/*
# chown gitlab-runner:gitlab-runner /home/gitlab-runner/.docker
# chown gitlab-runner:gitlab-runner /home/gitlab-runner/.docker/*
```

# Step2 docker buildテストのためにdockerのインストール

まず、gitlab-runnerコンテナにdockerをインストールして行きます。

```
# apt-get update

# apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common

# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -

# add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

# apt-get update

# apt-get install -y docker-ce
```

その後、kubectlを使えるように、セットアップをしてください。

https://kubernetes.io/docs/tasks/tools/install-kubectl/



# Step3 gitlab-runnerコンテナからKind及びkubernetes clusterの対してkubectlを実行

gitlab-runnerからkindとkubernetes clusterそれぞれにkubernetesを使えるようにしていきます。

kubernetesは`.kube/config`という,ファイルを参照して、kubectlを投げる先を特定しています。
つまり、これを持ってきて、`KUBECONFIG`にそのpathを指定してexportしてあげれば投げられるというわけです。

## kindの.kube/config
gitlab-runnerコンテナの載っているdockerホストにて、以下を実施します。

```
# ls /root/.kube/
cache  http-cache  kind-config-kind
```

kindに関しては、`kind-config-kind`という名前でconfigファイルが入っています。

ここで、kindのマスターの`containerに割り振られたIP`と`フォワーディングしているport`を確認しておきます。

```
# docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                                  NAMES
682857797af4        kindest/node:v1.15.0          "/usr/local/bin/entr…"   58 minutes ago      Up About an hour                                           kind-worker3
72b67c81ce82        kindest/node:v1.15.0          "/usr/local/bin/entr…"   58 minutes ago      Up About an hour    36996/tcp, 127.0.0.1:36996->6443/tcp   kind-control-plane
834a76c4bdb4        kindest/node:v1.15.0          "/usr/local/bin/entr…"   58 minutes ago      Up About an hour                                           kind-worker
143cf9312cf0        kindest/node:v1.15.0          "/usr/local/bin/entr…"   58 minutes ago      Up About an hour                                           kind-worker2
```

portは`6443`です。

```
# docker inspect kind-control-plane
(省略)
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.7",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:07",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "d57ec14a533f41659ffcb098ff46a9171f150845cbd52a67db3688f54e381a0b",
                    "EndpointID": "4d8aecd914a42e67c59554c441de1d3cf288e3ffd70ab02759bbb6af9a5da6c9",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.7",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:07",
                    "DriverOpts": null
                }
            }
        }
    }
]
```

IPは、`172.17.0.7`です。


ではconfigファイルの内容をコピーしてください。

gitlab-runnerコンテナに入り、 `/home/gitlab-runner`下で.kube/kind-config-kindを作ります。

```
# mkdir /root/.kube

# vi /root/.kube/kind-config-kind

// コピーしたものをペーストする。「その際、server: の部分は先ほど調べたものに変える。」

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: dummy-key
    server: https://172.17.0.7:6443
  name: kind
contexts:
(省略)
```

user:groupを`chown`で`gitlab-runner`にすることや,
`chmod`による権限の変更をします。

そうしたら、`gitlab-runnerユーザ`kubectlが通るか確認する。

```
# export KUBECONFIG=/home/gitlab-runner/.kube/kind-config-kind

# kubectl get nodes
NAME                 STATUS   ROLES    AGE   VERSION
kind-control-plane   Ready    master   62m   v1.15.0
kind-worker          Ready    <none>   61m   v1.15.0
kind-worker2         Ready    <none>   61m   v1.15.0
kind-worker3         Ready    <none>   61m   v1.15.0
```

## kubernetes clusterの.kube/config

同様に、kubernetes clusterのmasterノードに入り、情報をコピーし、
gitlab-runnerコンテナの/root/.kube/下に新しくファイルを作成し、ペーストをする。
例としては、ファイル名を`verify-kube-config`とします。

同様に、user:groupを`chown`で`gitlab-runner`にすることや,
`chmod`による権限の変更をします。

そうしたら、`gitlab-runnerユーザ`でkubectlが通るか、確認してください。

```
# export KUBECONFIG=/home/gitlab-runner/.kube/verify-kube-config

# kubectl get nodes
NAME                      STATUS   ROLES    AGE   VERSION
kubemaster1.mydom.local   Ready    master   46d   v1.15.0
kubeworker1.mydom.local   Ready    <none>   46d   v1.15.0
kubeworker2.mydom.local   Ready    <none>   46d   v1.15.0
```

# Step4 gitlab-runnerを動かしてみる。

下準備をします。

```
# mkdir -p /home/gitlab-runner/config/manifest
```

この下に、manifestを用意します。
manifestはkustomizeで管理します。

kustomizeに関しては、以下に簡単な使い方を書いていますので、参照ください。
https://qiita.com/ryojsb/items/66fb5155cb3f908ffd07

構成としては、

```
manifest---------- base
             |
		     |---- verification
			 |
			 |---- production
```	 

gitlab-runnerを動かす、ymlファイルは以下です。
最小限のコマンドしか書いてません。

```.gitlab-ci.yml
stages:
  - build
  - test
  - deploy

docker-build:
  stage: build
  before_script:
    - sudo docker login -u $Registory_user -p $Registory_password <registry IP>
    - export GOROOT=/home/gitlab-runner/lib/go
    - export GOPATH=/home/gitlab-runner/lib/go/bin
    - export PATH=$PATH:$GOROOT/bin
  script:
    - sudo docker build -t <image 名> . --no-cache=true --force-rm=true
    - sudo docker push <image 名>
    - sudo /home/gitlab-runner/lib/go/bin/kind load docker-image <image 名>
    - sudo docker images

k8s-kind-test:
  stage: test
  before_script:
    - export KUBECONFIG=/home/gitlab-runner/.kube/kind-config-kind
  script:
    - cd /home/gitlab-runner/config/manifest
    - kubectl kustomize verification | kubectl apply -f -
    - sleep 1m
    - kubectl get pods
    - curl -I <application URL>
 
k8s-deploy:
  stage: deploy
  before_script:
    - export KUBECONFIG=/home/gitlab-runner/.kube/verify-kube-config
  script:
    - cd /home/gitlab-runner/config/manifest
    - kubectl kustomize production | kubectl apply -f -
    - sleep 1m
    - kubectl get pods
```


ここで、kind上にデプロイしたアプリケーションに`curl`する際は、
IPの部分を`containerのIP`にすることに注意してください。

あとは、`git push`をするのみです。

# 最後に
kubernetes meetup tokyo #22に参加してみて、最近よく聞く`Argo CD`をそろそろ使ってみなければという感じになりました。