Embedded HarborをTKC(TKG Guest Cluster)から使えるようにする


問題提起

vSphere for k8sの目玉機能としてvCenterからEmbedded Harborをつくることができるという点です。
こんな感じでvCenterからHarborをいじれるようになります。

基本的には、これをそのまま使えばいいのですが、一つ問題があり、 TKC(Tanzu Kubernetes Guest Cluster)からは利用できないという点です。
理由がHarborのSSL証明書がTKC側で登録がされておらず、使えない状態のためです。

海外のブログで直しかたが紹介されていますが、異様に煩雑な手順となっており、気軽に試せそうにないです。

この記事では、上の改良版として

  • Step 2.をKubernetesの仕組みで自動化
  • Step 3.の手順を汎用化
  • Step 4.も改良
  • 日本語化 したものとなっています。

注意事項

この手段はサポートされた手段ではないです。
また、Privileged Podsの仕組みを使っているので、セキュリティ上よろしくない手段です。
よく理解した上、自己責任でお願いします。

手順

1. TKCのKubeconfigを生成する

まずTKCのkubeconfigをダウンロードするのですが、手順はここにあるものを使います。

最後のtkg-cluster-kubeconfig-adminKUBECONFIG関数などにエクスポートします。

export KUBECONFIG=/enter_dir/tkg-cluster-kubeconfig-admin

kubectl get nodesなどして、問題ないか確認します。

2. HarborのRoot証明書をSecretとして登録

次に、Root証明書をゲットします。

[ Cluster ] > [ Configure ] > [ Namespaces ] > [ Image Registry ]にあるのでそれをダウンロードします。

これを./root-certificate.txtなどに保管してkubernetes側に登録します。

kubectl create ns harbor-setup
kubectl create secret generic harbor-registry --from-file=./root-certificate.txt -n harbor-setup

3. TKCノードの証明書を更新するシェルスクリプト(ConfigMap)の用意

以下のシェルスクリプトを作成します。
これによってホストOSの証明書を更新するシェルスクリプトを実行します。

名前はharbor-setup.shとしてください。


#!/bin/bash
set -x

NSENTER="/usr/bin/nsenter -t 1 -m -u -n -i --"

HEAD=`cat /tmp/harbor-cert | head -2 | sed 1d`
${NSENTER} grep -q ${HEAD} /etc/pki/tls/certs/ca-bundle.crt || {

  ${NSENTER} cp /etc/pki/tls/certs/ca-bundle.crt /tmp/
  cat /tmp/harbor-cert  >> /host/ca-bundle.crt

  ${NSENTER} cp /tmp/ca-bundle.crt /etc/pki/tls/certs/ca-bundle.crt
  ${NSENTER} systemctl -a | grep -q docker.service && { 
    ${NSENTER} systemctl restart docker.service
    ${NSENTER} systemctl status docker.service
  }
  ${NSENTER} systemctl -a | grep -q containerd.service && { 
    ${NSENTER} systemctl restart containerd.service
    ${NSENTER} systemctl status containerd.service
  }
}
while true; do
 sleep 3600
done

そしてそれをConfigMapとして登録します。

kubectl create configmap harbor-setup-bash --from-file=harbor-setup.sh -n harbor-setup

4. Daemonsetを作成する。

harbor-setupネームスペースで、privileged podの作成を許可します。

kubectl create rolebinding  harbor-setup --namespace=harbor-setup --clusterrole=psp:vmware-system-privileged --group=system:serviceaccounts

以下を実行します。


kubectl create -n harbor-setup -f - <<EOF
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: harbor-setup
spec:
  selector:
    matchLabels:
      job: harbor-setup
  template:
    metadata:
      labels:
        job: harbor-setup
    spec:
      hostPID: true
      containers:
      - image: alpine
        name: harbor-setup
        command: ["sh", "/tmp/harbor-setup.sh"]
        securityContext:
          privileged: true
        volumeMounts:
        - name:  harbor-setup
          mountPath: /tmp/harbor-setup.sh
          subPath: harbor-setup.sh
          readOnly: true
        - name:  harbor-cert
          mountPath: /tmp/harbor-cert
          subPath: root-certificate.txt
          readOnly: true
        - name: host-mount
          mountPath: /host
      volumes:
      - name: harbor-setup
        configMap:
          name: harbor-setup-bash
      - name: harbor-cert
        secret:
          secretName: harbor-registry
      - name: host-mount
        hostPath:
          path: /tmp/
EOF

kubectl get ds -n harbor-setupでWorkerNode数分起動している確認します。

NAME           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
harbor-setup   3         3         3       3            3           <none>          11s

なお、このデーモンセットはprivilegedで走らせているため非常に危険なPodです。
1分以上したら 以下のコマンドでけしてあげてください

kubectl delete ds harbor-setup -n harbor-setup

手順としては以上です。

検証

HarborにあるこのイメージをTKCからダウンロードできるか試します。

1. ImagePullSecretをNamespaceごとに生成

面倒ですが、Harborの認証情報はNamespaceごとに作らないといけないです。
検証用のNamespaceを作ります。

kubectl create ns pulltest

そして、認証情報を登録します。

kubectl create -n pulltest secret docker-registry regsecret --docker-server=10.195.35.38 --docker-username=XXXXXXX --docker-password='XXXXXX'

XXXX には正しい情報をいれてください。
そして、それをdefaultサービスアカウントにパッチします。

kubectl patch sa default -n pulltest -p '"imagePullSecrets": [{"name": "regsecret" }]'

これで準備完了です。

2. 検証する

これでイメージを走らせてみます。

kubectl create deployment -n pulltest --image=10.195.35.38/common/nginx test

走っていることを確認します。

kubectl get po -n pulltest
NAME                   READY   STATUS    RESTARTS   AGE
test-ccf848d49-p42kc   1/1     Running   0          30s

ちゃんとイメージがPullされたことを確認します。

OKですね。成功です。

まとめ

TKCでHarborをつかうのも簡単にできます。