オンプレGitLabにMicroK8s接続してGitLabのAuto DevOpsを体験する(前半)

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

::: note alert
こちらの方法はGitLab v14.5から非推奨になり、GitLab v15.0で利用できなくなっています。

Certificate-based Kubernetes integration (DEPRECATED)
https://docs.gitlab.com/ee/user/infrastructure/clusters/#certificate-based-kubernetes-integration-deprecated

:::

::: note info

今後はGitLab Agent for Kubernetesをご利用ください。
利用方法は以下で記事を書きました。

GitLab Agent for Kubernetesを使ってみる(GitLab Kubernetes Agent改め) - Qiita 
https://qiita.com/ynott/items/35e9492d0681ea8ac60a
:::

# 0. はじめに

GitLabにはKubernetesを連携して便利にいろいろできる機能がついています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/c19bb980-af76-2d21-e1b9-4950f93be65d.png)

Kubernetes clusters | GitLab
https://docs.gitlab.com/ee/user/project/clusters/

しかし、問題があります。GKEにしてもEKSにしてもそれなりにいいお値段します。
アプリをちょっとデプロイする環境としては高価です。
しかし、本格的にKubernetesを立てるのも大変だし。。。。

そこで、仮想マシンにMicroK8sを動かして、それをオンプレのGitLabに連携してみます。

長くなったので前半と後半に分けました。後半はこちらです。

# 後半:[オンプレGitLabにMicroK8s接続してGitLabのAuto DevOpsを体験する(後半) - Qiita](https://qiita.com/ynott/items/46d4b2926afec0d788f2)

# 1. VMwareで仮想マシンを起動

mediumのインスタンスを適当に1つ動かします。
リソースは、CPU:4vCPU、Mem:4GBにしました。
OSは、Ubuntu 18.04 LTSにしました。

# 2. MicroK8sを動かす
## 2-1. MicroK8sをインストール

```bash
sudo update && sudo upgrade -y && sudo reboot
sudo install snap && sudo snap install microk8s --classic
sudo usermod -a -G microk8s ＜ユーザー名＞
```

## 2-2. MicroK8sの起動状況を確認する

```bash
$ microk8s.status
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    ha-cluster           # Configure high availability on the current node
  disabled:
    ambassador           # Ambassador API Gateway and Ingress
    cilium               # SDN, fast with full network policy
    dashboard            # The Kubernetes dashboard
    dns                  # CoreDNS
    fluentd              # Elasticsearch-Fluentd-Kibana logging and monitoring
    gpu                  # Automatic enablement of Nvidia CUDA
    helm                 # Helm 2 - the package manager for Kubernetes
    helm3                # Helm 3 - Kubernetes package manager
    host-access          # Allow Pods connecting to Host services smoothly
    ingress              # Ingress controller for external access
    istio                # Core Istio service mesh services
    jaeger               # Kubernetes Jaeger operator with its simple config
    keda                 # Kubernetes-based Event Driven Autoscaling
    knative              # The Knative framework on Kubernetes.
    kubeflow             # Kubeflow for easy ML deployments
    linkerd              # Linkerd is a service mesh for Kubernetes and other frameworks
    rbac                 # Role-Based Access Control for authorisation
    storage              # Storage class; allocates storage from host directory
    metallb              # Loadbalancer for your Kubernetes cluster
    metrics-server       # K8s Metrics Server for API access to service metrics
    multus               # Multus CNI enables attaching multiple network interfaces to pods
    portainer            # Portainer UI for your Kubernetes cluster
    prometheus           # Prometheus operator for monitoring and logging
    registry             # Private image registry exposed on localhost:32000
    traefik              # traefik Ingress controller for external access
```

kubectl でノードが取得できるか確認する

```
$ microk8s.kubectl get nodes
NAME            STATUS   ROLES    AGE   VERSION
ip-10-x-y-z   Ready    <none>   48m   v1.17.0
```

## 2-3. microk8sのaddonを動かす

必要なAddonは以下の通りです。
GitLab側でingress等は入れるのでAddonは最低限にしましょう。
Dashboardとかは問題ないと思います。

1. rbac
1. dns
1. storage
1. metallb

### 2-3-1. rbac,dns,storage を有効にする

rbac、dnsは、デフォルトで必要です。
storageは、pvが必要なアプリケーションの為に必要です。

```bash
$ sudo microk8s.enable rbac
$ sudo microk8s.enable dns storage
```

### 2-3-2. metallb

metallbは、ingressが利用するLoadBalancer用で必要です。
enable時に利用できるIPアドレスを`a.b.c.d-a.b.c.e`の形式で指定してください。

```
$ sudo microk8s.enable metallb
Enabling MetalLB
Enter each IP address range delimited by comma (e.g. '10.64.140.43-10.64.140.49,192.168.0.105-192.168.0.111'): 192.168.10.20-192.168.10.30
Applying Metallb manifest
namespace/metallb-system created
secret/memberlist created
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
daemonset.apps/speaker created
deployment.apps/controller created
configmap/config created
MetalLB is enabled
```

### 2-3-3. アドオンが有効になったか確認

```bash
$ microk8s.status
microk8s is running
high-availability: no
  datastore master nodes: 127.0.0.1:19001
  datastore standby nodes: none
addons:
  enabled:
    dns                  # CoreDNS
    ha-cluster           # Configure high availability on the current node
    metallb              # Loadbalancer for your Kubernetes cluster
    rbac                 # Role-Based Access Control for authorisation
    storage              # Storage class; allocates storage from host directory
<以下略>
```

## 2-5. (オプション)corednsを書き換える

社内のオンプレGitLabのIPアドレスを社内DNS側から取得したかったので、DNSサーバーの参照先を変更しました。

```bash
$ kubectl edit configmaps coredns -n kube-system -o yaml
```

あまりきれいな方法ではありませんが、直接書き換えました。

```
data:
  Corefile: ".:53 {\n    errors\n    health {\n      lameduck 5s\n    }\n    ready\n
    \   log . {\n      class error\n    }\n    kubernetes cluster.local in-addr.arpa
    ip6.arpa {\n      pods insecure\n      fallthrough in-addr.arpa ip6.arpa\n    }\n
    \   prometheus :9153\n    forward . <社内DNSサーバー> \n    cache 30\n    loop\n    reload\n
    \   loadbalance\n}\n"
```

以下のようにしてDNSが引けるか確認しておきましょう

```bash
$ kubectl run busybox --restart=Never --image=busybox:1.28 -- sleep 3600
$ kubectl exec busybox -- nslookup <オンプレGitLab FQDN>
```

## 2-6. (オプション)外部からkubectlで接続できるようにconfigを取得する
(GitLabから接続するためには必須ではない)

kubeconfigを取得します。

```
$ microk8s.config | tee gitlab-microk8s.config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
    server: https://10.x.y.z:16443
  name: microk8s-cluster
contexts:
- context:
    cluster: microk8s-cluster
    user: admin
  name: microk8s
current-context: microk8s
kind: Config
preferences: {}
users:
- name: admin
  user:
    username: admin
    password: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

# 3. GitLabと連携するために必要な情報を取得する

GitLabと連携するためには以下の情報が必要です。
1. API URL
2. CA証明書
3. サービストークン
それぞれ取得しておきます。

## 3-1. API URL

2-6で取得したkubeconfigの`server: https://10.x.y.z:16443`の`https://10.x.y.z:16443`部分です

## 3-2. CA証明書

`kubectl get secrets` で出てきたdefault-tokenから証明書を取得します。

```
$ kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-78r9t   kubernetes.io/service-account-token   3      46h
```

`default-token-78r9t`から証明書を取得します。

```
$ kubectl get secret default-token-78r9t -o jsonpath="{['data']['ca\.crt']}" | base64 --decode
-----BEGIN CERTIFICATE-----
MIIDATCCAemgAwIBAgIJANFqxpnmuSSZMA0GCSqGSIb3DQEBCwUAMBcxFTATBgNV
<中略>
-----END CERTIFICATE-----
```

## 3-3. サービストークン

サービストークンを取得するためにまず、サービスアカウントgitlabを以下のマニフェストで作成します。

```yaml:gitlab-admin-service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: gitlab
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: gitlab-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - kind: ServiceAccount
    name: gitlab
    namespace: kube-system
```

作ったファイルをkubectl applyします。

```
$ kubectl apply -f gitlab-admin-service-account.yaml
```

サービスアカウントができたので、トークンを取得します。
最後の`token:`以降の文字列(以下の例では、`eyJhbGciOiから最後`まで)をどこかに保存しておきます。

```
$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep gitlab | awk '{print$1}')
Name:         gitlab-token-dqjlx
Namespace:    kube-system
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: gitlab
              kubernetes.io/service-account.uid: 7e73e750-4bfc-4718-9ee0-ebe83da58c36

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1103 bytes
namespace:  11 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IjVURFF<以下略>
```

後半に続く

# 後半:[オンプレGitLabにMicroK8s接続してGitLabのAuto DevOpsを体験する(後半) - Qiita](https://qiita.com/ynott/items/46d4b2926afec0d788f2)