任意のNamespaceにMicroclimate 1.3.0をデプロイする

Microclimateのチャートのバージョンが1.3.0になり、default以外のNamespaceへのデプロイが可能になったようなので試す。

詳細な手順が以下にあるのでこれに従って実施。

https://microclimate-dev2ops.github.io/installndnamespace

## Namespaceの作成

MicroclimateをデプロイするNamespaceを作成する。アプリケーションのデプロイ先のNamespaceはチャートの`jenkins.Pipeline.TargetNamespace`で指定するので、ここで作成するNamespaceとは限らない。

```
kubectl create namespace ns2
```

## ServiceAccountの作成

作成したNamespaceに、Jenkins用のServiceAccountを作成する。
このServiceAccountがJenkinsとDevOpsのPodを実行する。

```
kubectl create serviceaccount ns2-devops-sa --namespace ns2
```

作成したNamespaceに、Microclimate用のServiceAccountを作成する。
このServiceAccountがedito、file-watcher、portalのPodを実行する。

```
kubectl create serviceaccount ns2-micro-sa --namespace ns2
```

## Docker Registry用のSecretの作成

作成したNamespaceに、Docker Registry用のSecretを作成する。

```
kubectl create secret docker-registry microclimate-registry-secret \
  --docker-server mycluster.icp:8500 \
  --docker-username admin \
  --docker-password admin \
  --docker-email null \
  --namespace ns2
```

## Helm用のSecretの作成

作成したNamespaceに、Helm用のSecretを作成する。

```
kubectl create secret generic microclimate-helm-secret \
  --from-file=cert.pem=$HOME/.helm/cert.pem \
  --from-file=ca.pem=$HOME/.helm/ca.pem \
  --from-file=key.pem=$HOME/.helm/key.pem \
  --namespace ns2
```

## ServiceAccountの修正

作成したServiceAccountに先ほど作成したSecretをimagePullSecretとして追加する。

```
kubectl patch serviceaccount ns2-devops-sa \
  -p '{"imagePullSecrets": [{"name": "microclimate-registry-secret"}, {"name": "microclimate-helm-secret"}, {"name": "anyothersecret..."} ]}' \
  --namespace ns2
```

```
kubectl patch serviceaccount ns2-micro-sa \
  -p '{"imagePullSecrets": [{"name": "microclimate-registry-secret"}, {"name": "microclimate-helm-secret"}, {"name": "anyothersecret..."} ]}' \
  --namespace ns2
```

```shell-session
root@myicp01:~# kubectl get sa -n ns2 ns2-devops-sa -o yaml --export
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: ns2-devops-sa
  selfLink: /api/v1/namespaces/ns2/serviceaccounts/ns2-devops-sa
secrets:
- name: ns2-devops-sa-token-kthfd
root@myicp01:~# kubectl patch serviceaccount ns2-devops-sa \
>   -p '{"imagePullSecrets": [{"name": "microclimate-registry-secret"}, {"name": "microclimate-helm-secret"}, {"name": "anyothersecret..."} ]}' \
>   --namespace ns2
serviceaccount "ns2-devops-sa" patched
root@myicp01:~# kubectl get sa -n ns2 ns2-devops-sa -o yaml --export
apiVersion: v1
imagePullSecrets:
- name: microclimate-registry-secret
- name: microclimate-helm-secret
- name: anyothersecret...
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: ns2-devops-sa
  selfLink: /api/v1/namespaces/ns2/serviceaccounts/ns2-devops-sa
secrets:
- name: ns2-devops-sa-token-kthfd
root@myicp01:~#
```

```shell-session
root@myicp01:~# kubectl get sa -n ns2 ns2-micro-sa -o yaml --export
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: ns2-micro-sa
  selfLink: /api/v1/namespaces/ns2/serviceaccounts/ns2-micro-sa
secrets:
- name: ns2-micro-sa-token-lxwmj
root@myicp01:~# kubectl patch serviceaccount ns2-micro-sa \
>   -p '{"imagePullSecrets": [{"name": "microclimate-registry-secret"}, {"name": "microclimate-helm-secret"}, {"name": "anyothersecret..."} ]}' \
>   --namespace ns2
serviceaccount "ns2-micro-sa" patched
root@myicp01:~# kubectl get sa -n ns2 ns2-micro-sa -o yaml --export
apiVersion: v1
imagePullSecrets:
- name: microclimate-registry-secret
- name: microclimate-helm-secret
- name: anyothersecret...
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: ns2-micro-sa
  selfLink: /api/v1/namespaces/ns2/serviceaccounts/ns2-micro-sa
secrets:
- name: ns2-micro-sa-token-lxwmj
root@myicp01:~#
```

## ロールとバインディングの作成

以下の内容のyamlファイルを作成する。

```yaml:devops.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: cr-devops
rules:
- apiGroups: ["extensions", ""]
  resources: ["ingresses", "ingresses/status"]
  verbs: ["delete", "create", "patch", "get", "list", "update", "watch"]

- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["delete", "create", "patch", "get", "list"]

- apiGroups: [""]
  resources: ["pods", "pods/portforward", "pods/log", "pods/exec"]
  verbs: ["get", "list", "create", "delete", "watch"]

- apiGroups: ["mc.ibm.com"]
  resources: ["projects", "releases"]
  verbs: ["get", "list", "create", "delete", "watch"]

- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create", "watch"]

- apiGroups: [""]
  resources: ["serviceaccounts"]
  verbs: ["get", "patch"]

- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list"]

- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list"]

- apiGroups: ["apiextensions.k8s.io"]
  resources: ["customresourcedefinitions"]
  verbs: ["get", "list", "create", "delete"]

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: crb-devops
roleRef:
  kind: ClusterRole
  name: cr-devops
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: ns2-devops-sa
  namespace: ns2
```

```yaml:micro.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: cr-micro
rules:
- apiGroups: [""]
  resources: ["namespaces"]
  verbs: ["delete", "create", "patch", "get", "list"]

- apiGroups: [""]
  resources: ["pods", "pods/portforward", "pods/log", "pods/exec"]
  verbs: ["get", "list", "create", "delete", "watch"]

- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get", "list", "create"]

- apiGroups: [""]
  resources: ["serviceaccounts"]
  verbs: ["get", "patch"]

- apiGroups: [""]
  resources: ["services"]
  verbs: ["get", "list", "create", "delete"]

- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "list"]

- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]

- apiGroups: ["extensions"]
  resources: ["ingresses"]
  verbs: ["get", "patch"]

- apiGroups: ["apps", "extensions"]
  resources: ["deployments"]
  verbs: ["get", "list", "create", "update", "delete"]

- apiGroups: ["extensions"]
  resources: ["replicasets"]
  verbs: ["get", "list", "update", "delete"]

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: crb-micro
roleRef:
  kind: ClusterRole
  name: cr-micro
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: ns2-micro-sa
  namespace: ns2
```

yamlファイルをapplyする。

```
kubectl apply -f devops.yaml
kubectl apply -f micro.yaml
```

## PersistentVolumeの用意

hostPathのPVを使うこととし、ノード上にディレクトリーを用意する。

```shell-session
root@myicp01:/export# pwd
/export
root@myicp01:/export# ls -l
total 8
drwxr-xr-x 2 root root 4096 Jul  3 09:09 MC_jenkins02
drwxr-xr-x 2 root root 4096 Jul  3 09:09 MC_microclimate02
root@myicp01:/export#
```

Jenkins用のPVを作成する。

```yaml:mc-jenkins02-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  labels:
    mylabel: jenkins02
  name: mc-jenkins02-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 8Gi
  hostPath:
    path: /export/MC_jenkins02
    type: ""
  persistentVolumeReclaimPolicy: Retain
```

```
kubectl apply -f mc-jenkins02-pv.yaml
```

Microclimate用のPVを作成する。

```yaml:mc-microclimate02-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  labels:
    mylabel: microclimate02
  name: mc-microclimate02-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 2Gi
  hostPath:
    path: /export/MC_microclimate02
    type: ""
  persistentVolumeReclaimPolicy: Retain
```

```
kubectl apply -f mc-microclimate02-pv.yaml
```

PVが作成され、Availableとなっていることを確認する。

```
root@myicp01:~# kubectl get pv
NAME                            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM                                       STORAGECLASS               REASON    AGE
helm-repo-pv                    5Gi        RWO            Delete           Bound       kube-system/helm-repo-pvc                   helm-repo-storage                    26d
image-manager-172.30.1.224      20Gi       RWO            Retain           Bound       kube-system/image-manager-image-manager-0   image-manager-storage                26d
logging-datanode-172.30.1.224   20Gi       RWO            Retain           Bound       kube-system/data-logging-elk-data-0         logging-storage-datanode             26d
mc-jenkins02-pv                 8Gi        RWO            Retain           Available                                                                                    7s
mc-microclimate02-pv            2Gi        RWO            Retain           Available                                                                                    23s
mongodb-172.30.1.224            20Gi       RWO            Retain           Bound       kube-system/mongodbdir-icp-mongodb-0        mongodb-storage                      26d
root@myicp01:~#
```

Jenkins用のPVCを作成する。

```yaml:mc-jenkins02-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mc-jenkins02-pvc
  namespace: ns2
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  selector:
    matchLabels:
      mylabel: jenkins02
```

```
kubectl apply -f mc-jenkins02-pvc.yaml
```

Microclimate用のPVCを作成する。

```yaml:mc-microclimate02-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mc-microclimate02-pvc
  namespace: ns2
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
  selector:
    matchLabels:
      mylabel: microclimate02
```

```
kubectl apply -f mc-microclimate02-pvc.yaml
```

PVCが作成され、Boundとなっていることを確認する。

```shell-session
root@myicp01:~# kubectl get pv
NAME                            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS    CLAIM                                       STORAGECLASS               REASON    AGE
helm-repo-pv                    5Gi        RWO            Delete           Bound     kube-system/helm-repo-pvc                   helm-repo-storage                    26d
image-manager-172.30.1.224      20Gi       RWO            Retain           Bound     kube-system/image-manager-image-manager-0   image-manager-storage                26d
logging-datanode-172.30.1.224   20Gi       RWO            Retain           Bound     kube-system/data-logging-elk-data-0         logging-storage-datanode             26d
mc-jenkins02-pv                 8Gi        RWO            Retain           Bound     ns2/mc-jenkins02-pvc                                                             13m
mc-microclimate02-pv            2Gi        RWO            Retain           Bound     ns2/mc-microclimate02-pvc                                                        13m
mongodb-172.30.1.224            20Gi       RWO            Retain           Bound     kube-system/mongodbdir-icp-mongodb-0        mongodb-storage                      26d
root@myicp01:~# kubectl get pvc -n ns2
NAME                    STATUS    VOLUME                 CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mc-jenkins02-pvc        Bound     mc-jenkins02-pv        8Gi        RWO                           14s
mc-microclimate02-pvc   Bound     mc-microclimate02-pv   2Gi        RWO                           7s
root@myicp01:~#
```

## インストールの実行

以下のオプションを指定してインストールを実行する。

|オプション|設定値|説明|
|---|---|---|
|global.rbac.serviceAccountName|ns2-micro-sa|icroclimate用のService Accountを指定。|
|jenkins.rbac.serviceAccountName|ns2-devops-sa|Jenkins用のService Accountを指定。|
|hostName|microclimate.XX.XX.XX.XX.nip.io|Microclimateのホスト名を指定。ここではワイルドカードDNSを使用。|
|jenkins.Master.HostName|jenkins.XX.XX.XX.XX.nip.io|Microclimateのホスト名を指定。ここではワイルドカードDNSを使用。|
|jenkins.Pipeline.Registry.Url|mycluster.icp:8500/ns2|JenkinsがイメージをデプロイするNamespaceを指定。|
|persistence.useDynamicProvisioning|false|ストレージの動的プロビジョニングをしない。|
|persistence.existingClaimName|mc-microclimate02-pvc|事前に作成したMicroclimate用のPVCを指定|
|jenkins.Persistence.ExistingClaim|mc-jenkins02-pvc|事前に作成したJenkins用のPVCを指定|

```
helm install --tls --name microclimate02 \
  --namespace ns2 \
  --set global.rbac.serviceAccountName=ns2-micro-sa \
  --set jenkins.rbac.serviceAccountName=ns2-devops-sa \
  --set hostName=microclimate.XX.XX.XX.XX.nip.io \
  --set jenkins.Master.HostName=jenkins.XX.XX.XX.XX.nip.io \
  --set jenkins.Pipeline.Registry.Url=mycluster.icp:8500/ns2 \
  --set persistence.useDynamicProvisioning=false \
  --set persistence.existingClaimName=mc-microclimate02-pvc \
  --set jenkins.Persistence.ExistingClaim=mc-jenkins02-pvc \
  ibm-charts/ibm-microclimate
```

```shell-session
root@myicp01:~# helm install --tls --name microclimate02 \
>   --namespace ns2 \
>   --set global.rbac.serviceAccountName=ns2-micro-sa \
>   --set jenkins.rbac.serviceAccountName=ns2-devops-sa \
>   --set hostName=microclimate.XX.XX.XX.XX.nip.io \
>   --set jenkins.Master.HostName=jenkins.XX.XX.XX.XX.nip.io \
>   --set jenkins.Pipeline.Registry.Url=mycluster.icp:8500/ns2 \
>   --set persistence.useDynamicProvisioning=false \
>   --set persistence.existingClaimName=mc-microclimate02-pvc \
>   --set jenkins.Persistence.ExistingClaim=mc-jenkins02-pvc \
>   ibm-charts/ibm-microclimate
NAME:   microclimate02
LAST DEPLOYED: Tue Jul  3 09:51:11 2018
NAMESPACE: ns2
STATUS: DEPLOYED

RESOURCES:
==> v1/ConfigMap
NAME                                                   DATA  AGE
microclimate02-jenkins                                 6     1m
microclimate02-jenkins-tests                           1     1m
microclimate02-helmtest-devops                         1     1m
microclimate02-ibm-microclimate-fixup-jenkins-ingress  1     1m

==> v1/Service
NAME                                    TYPE       CLUSTER-IP  EXTERNAL-IP  PORT(S)                     AGE
microclimate02-jenkins-agent            ClusterIP  10.0.0.246  <none>       50000/TCP                   1m
microclimate02-jenkins                  ClusterIP  10.0.0.224  <none>       8080/TCP                    1m
microclimate02-ibm-microclimate-devops  ClusterIP  10.0.0.4    <none>       9191/TCP                    1m
microclimate02-ibm-microclimate         ClusterIP  10.0.0.49   <none>       4191/TCP,9090/TCP,9091/TCP  1m

==> v1beta1/Deployment
NAME                                    DESIRED  CURRENT  UP-TO-DATE  AVAILABLE  AGE
microclimate02-jenkins                  1        1        1           0          1m
microclimate02-ibm-microclimate-devops  1        1        1           0          1m
microclimate02-ibm-microclimate         1        1        1           0          1m

==> v1/Job
NAME                                         DESIRED  SUCCESSFUL  AGE
microclimate02-ibm-microclimate-oic-jenkins  1        0           1m

==> v1beta1/Ingress
NAME                             HOSTS                              ADDRESS        PORTS    AGE
microclimate02-jenkins           jenkins.XX.XX.XX.XX.nip.io       XX.XX.XX.XX  80, 443  1m
microclimate02-ibm-microclimate  microclimate.XX.XX.XX.XX.nip.io  XX.XX.XX.XX  80, 443  1m

==> v1/Pod(related)
NAME                                                     READY  STATUS    RESTARTS  AGE
microclimate02-jenkins-6968f677db-jr8pn                  0/1    Init:0/1  0         1m
microclimate02-ibm-microclimate-devops-86686c7f88-zsbt6  0/1    Running   0         1m
microclimate02-ibm-microclimate-c56f657c7-7db9t          0/1    Running   0         1m
microclimate02-ibm-microclimate-oic-jenkins-4tbfb        1/1    Running   0         1m

==> v1/Secret
NAME                             TYPE    DATA  AGE
microclimate02-jenkins           Opaque  2     1m
microclimate02-mc-tls-secret     Opaque  2     1m
microclimate02-tls-secret        Opaque  2     1m
microclimate02-ibm-microclimate  Opaque  3     1m


NOTES:
ibm-microclimate-1.3.0

1. Access the Microclimate portal at the following URL: https://microclimate.XX.XX.XX.XX.nip.io

root@myicp01:~#
```

## 稼働確認

http://microclimate.XX.XX.XX.XX.nip.io/

にアクセスする。

以前のバージョンと異なり、一度ICPコンソールにリダイレクトされ、認証がされてからMicroclimateの画面へと遷移する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/86449/c6e522aa-eab8-83f3-d756-0617d660c4f8.png)

## 以前のバージョンからの変更点

以下など変わっている。

- default以外のNamespaceへデプロイできる
- ICPインストール版のMicroclimateへのアクセス時に認証されるようになった
- Local版から、ICPへの接続でちゃんと認証されるようになった
- プロジェクトを自動ビルドするかどうか選べる

他にもいくつかあるようだ。詳細は以下のJune releaseを参照。

https://microclimate-dev2ops.github.io/news

## 参考

[IBM Cloud PrivateにMicroclimate 1.2.0をデプロイする](https://qiita.com/sotoiwa/items/ee967087f6ed3ecea7a3)