HarborをCDで用いた際の工夫

# Harborとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416540/b5aa7306-19e9-c910-2456-5eb89cb00e03.png)

Docker HubやDocker Registryのような、コンテナイメージを保存し公開する、コンテナレジストリ機能を実装したソフトウェアです。

CNCF Cloud Native Interactive Landscape
にもしっかり大きく表示されてますので、ぜひ使ってみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416540/204f5977-707d-cd94-2311-66eec85b3d97.png)


# Harborで何が困ったか

現在、`Gitlab runner`というCI/CDツールを用いて開発しているのですが、
その際にbuildしたimageのtagは、git commitのhash値を埋め込んで、harborにpushしています。

この状態で、CDを回しまくるとどうなるかというと。。。
そうです。imageがどんどんたまっていくわけです。

これはあかんな～って思っていた時に、`harbor cli`というものを発掘して、見事解決できましたので、備忘録として書きます。

# harbor cliのインストール(docker)
こちらは、最後にaliasを設定することで、harborコマンド使用時に裏でharbor cliを打つためのimageをdocker runして、コマンド送信が終わったら、コンテナが落ちる仕様になっています。

## moduleのインストール

```
# git clone https://github.com/int32bit/python-harborclient.git

# cd python-harborclient

# docker build -t harborclient .

# docker run --rm \
 -e HARBOR_USERNAME="admin" \
 -e HARBOR_PASSWORD="Harbor12345" \
 -e HARBOR_PROJECT=1 \
 -e HARBOR_URL="http://localhost" \
 harborclient harbor info
 
 +--------------------------------+---------------------+
| Property                       | Value               |
+--------------------------------+---------------------+
| admiral_endpoint               |                     |
| auth_mode                      | db_auth             |
| clair_vulnerability_status     | (omitted)           |
| disk_free                      | 4992696320          |
| disk_total                     | 18381979648         |
| external_url                   | https://localhost   |
| harbor_version                 | v1.8.1-16b59c41     |
| has_ca_root                    | True                |
| project_creation_restriction   | everyone            |
| read_only                      | False               |
| registry_storage_provider_name | filesystem          |
| registry_url                   | localhost           |
| self_registration              | True                |
| with_admiral                   | False               |
| with_chartmuseum               | True                |
| with_clair                     | False               |
| with_notary                    | False               |
+--------------------------------+---------------------+


# alias harbor='docker run \
 -e HARBOR_USERNAME="admin" \
 -e HARBOR_PASSWORD="Harbor12345" \
 -e HARBOR_PROJECT=1 \
 -e HARBOR_URL="http://localhost" \
 --rm krystism/harborclient harbor --insecure'
```




# harbor cliのインストール(python)
こちらは、harbor cliをローカルに落として実行できるようにする仕様です。
最後にaliasを設定しておくと`--insecure`オプションを打たなくて済みます。

## moduleのインストール

```
# git clone https://github.com/int32bit/python-harborclient.git

# cd python-harborclient

# pip install -r requirements.txt

# python setup.py install
```

## Harborの確認

```
# harbor --os-baseurl https://localhost --insecure --os-username admin --os-project 1 info
password: ****

+--------------------------------+---------------------+
| Property                       | Value               |
+--------------------------------+---------------------+
| admiral_endpoint               |                     |
| auth_mode                      | db_auth             |
| clair_vulnerability_status     | (omitted)           |
| disk_free                      | 4992696320          |
| disk_total                     | 18381979648         |
| external_url                   | https://localhost   |
| harbor_version                 | v1.8.1-16b59c41     |
| has_ca_root                    | True                |
| project_creation_restriction   | everyone            |
| read_only                      | False               |
| registry_storage_provider_name | filesystem          |
| registry_url                   | localhost           |
| self_registration              | True                |
| with_admiral                   | False               |
| with_chartmuseum               | True                |
| with_clair                     | False               |
| with_notary                    | False               |
+--------------------------------+---------------------+
```

## 変数のExport
ここに関しては、環境に合わせて設定をお願いします。

```
# cat >admin-harborrc <<EOF
export HARBOR_USERNAME=admin
export HARBOR_PASSWORD=Harbor12345
export HARBOR_URL=http://localhost
export HARBOR_PROJECT=1
EOF


# source admin-harborrc

# vi .bash_profile
以下を追加
source admin-harborrc
alias harbor="harbor --insecure"
```




# 基本的なコマンドの確認(少し実環境から変えてあります。)

## コマンド確認
```
# harbor -h
usage: harbor [--debug] [--timings] [--version] [--os-username <username>]
              [--os-password <password>] [--os-project <project>]
              [--timeout <timeout>] [--os-baseurl <baseurl>] [--insecure]
              [--os-cacert <ca-certificate>] [--os-api-version <api-version>]
              <subcommand> ...

Command-line interface to the Harbor API.

Positional arguments:
  <subcommand>
    change-password             Change the password on a user that already
                                exists.
    get-cert                    Get default root cert under OVA deployment.
    get-conf                    Get system configurations.
    info                        Get general system info.
    job-list                    List filters jobs according to the policy and
                                repository.
    job-log                     Get job logs.
    list                        Get repositories accompany with relevant
                                project and repo name.
    logs                        Get recent logs of the projects which the user
                                is a member of.
    member-list                 List a project's relevant role members.
    policy-list                 List filters policies by name and project_id.
    project-create              Create a new project.
    project-delete              Delete project by Id or name.
    project-list                List projects.
    project-show                Show specific project detail infomation.
    repository-delete           Delete repository
    revoke-admin                Update a registered user to be a non-admin of
                                Harbor.
    search                      Search for projects and repositories.
    set-admin                   Update a registered user to change to be an
                                administrator of Harbor.
    show                        Show specific repository detail infomation.
    tags-delete                 delete tag of a relevant repository.
    tags-delete-reg             delete all tags that matches the expression of
                                a relevant repository.
    tags-list                   Get tags of a relevant repository.
    target-list                 List filters targets.
    target-ping                 Ping validates target.
    top                         Get public repositories which are accessed
                                most.
    usage                       Get projects number and repositories number
                                relevant to the user.
    user-create                 Creates a new user account.
    user-delete                 Mark a registered user as be removed.
    user-list                   Get registered users of Harbor.
    user-show                   Get a user's profile.
    user-update                 Update a registered user to change his
                                profile.
    version                     Get harbor version.
    whoami                      Get current user info.
    bash-completion             Print bash completion Prints all of the
                                commands and options to stdout so that the
                                harbor.bash_completion script doesn't have to
                                hard code them.
    help                        Display help about this program or one of its
                                subcommands.

Optional arguments:
  --debug                       Print debugging output.
  --timings                     Print call timing info.
  --version                     show program's version number and exit
  --os-username <username>      Username
  --os-password <password>      User's password
  --os-project <project>        Project Id
  --timeout <timeout>           Set request timeout (in seconds).
  --os-baseurl <baseurl>        API base url
  --insecure                    Explicitly allow client to perform "insecure"
                                TLS (https) requests. The server's certificate
                                will not be verified against any certificate
                                authorities. This option should be used with
                                caution.
  --os-cacert <ca-certificate>  Specify a CA bundle file to use in verifying a
                                TLS (https) server certificate. Defaults to
                                env[OS_CACERT].
  --os-api-version <api-version>
                                Accepts X, X.Y (where X is major and Y is
                                minor part) or "X.latest", defaults to
                                env[HARBOR_API_VERSION].

See "harbor help COMMAND" for help on a specific command.
```


## リポジトリの確認

```
# harbor top
+-------------------------------+------------+------------+
|              name             | pull_count | star_count |
+-------------------------------+------------+------------+
|      test-project/test        |     17     |     0      |
|     sample-project/sample     |     31     |     0      |
+-------------------------------+------------+------------+
```


## Projectの確認

```
# harbor project-list
+------------+-------------------+----------+----------------------+------------+-----------------------------+--------+
| project_id |        name       | owner_id | current_user_role_id | repo_count |        creation_time        | public |
+------------+-------------------+----------+----------------------+------------+-----------------------------+--------+
|     1      |      library      |    1     |          1           |     0      | 2019-07-30T07:11:28.228409Z |   -    |
|     3      |   sample-project  |    1     |          1           |     1      |     2019-07-31T06:41:08Z    |   -    |
|     5      |    test-project   |    1     |          1           |     1      |     2019-08-21T15:18:17Z    |   -    |
+------------+-------------------+----------+----------------------+------------+-----------------------------+--------+

# harbor project-show test-project
+----------------------+----------------------+
| Property             | Value                |
+----------------------+----------------------+
| chart_count          | 0                    |
| creation_time        | 2019-08-21T15:18:17Z |
| current_user_role_id | 1                    |
| deleted              | False                |
| metadata             | {"public": "true"}   |
| name                 |    test-project      |
| owner_id             | 1                    |
| owner_name           |                      |
| project_id           | 5                    |
| repo_count           | 1                    |
| togglable            | True                 |
| update_time          | 2019-08-21T15:18:17Z |
+----------------------+----------------------+

```


## project の検索(公式より引用)

```
# harbor search int32bit 
Find 1 Projects:
+------------+----------+--------+------------+----------------------+
| project_id |   name   | public | repo_count |    creation_time     |
+------------+----------+--------+------------+----------------------+
|     2      | int32bit |   1    |     3      | 2017-11-01T06:56:07Z |
+------------+----------+--------+------------+----------------------+

Find 3 Repositories:
+----------------------+--------------+------------+----------------+
|   repository_name    | project_name | project_id | project_public |
+----------------------+--------------+------------+----------------+
|   int32bit/busybox   |   int32bit   |     2      |       1        |
|   int32bit/golang    |   int32bit   |     2      |       1        |
| int32bit/hello-world |   int32bit   |     2      |       1        |
+----------------------+--------------+------------+----------------+
```


## ユーザの確認

```
# harbor user-list
+---------+----------+----------+------------------------+--------------+------------+
| user_id | username | is_admin |          email         |   realname   |  comment   |
+---------+----------+----------+------------------------+--------------+------------+
|    1    |  admin   |   True   |    admin@example.com   | system admin | admin user |
|    3    |  test    |   True   |    test@test.com       |     test     |     -      |
+---------+----------+----------+------------------------+--------------+------------+
```


## ログ確認

```
# harbor logs
+--------+-----------------------------+-----------+------------+-----------+------------------------------------------------------------------------+
| log_id |           op_time           |  username | project_id | operation |                               repository                               |
+--------+-----------------------------+-----------+------------+-----------+------------------------------------------------------------------------+
|   1    | 2019-07-30T07:13:47.223808Z |   admin   |     2      |   create  |                            errandsmoketest/                            |
|   2    | 2019-07-30T07:13:47.900413Z |   admin   |     2      |    push   |                     errandsmoketest/busybox:latest                     |
|   3    | 2019-07-30T07:13:48.303925Z |   admin   |     2      |    pull   |                     errandsmoketest/busybox:latest                     |
|   4    |  2019-07-30T07:13:48.4572Z  |   admin   |     2      |   delete  |                     errandsmoketest/busybox:latest                     |
|   5    | 2019-07-30T07:13:48.520026Z |   admin   |     2      |   delete  |                            errandsmoketest/                            |
|   6    | 2019-07-31T06:41:08.682933Z |   admin   |     3      |   create  |                            sample-project/                             |
|   7    | 2019-07-31T10:30:27.420127Z |   admin   |     4      |   create  |                            errandsmoketest/                            |
|   8    | 2019-07-31T10:30:28.005056Z |   admin   |     4      |    push   |                     errandsmoketest/busybox:latest                     |
|   9    | 2019-07-31T10:30:28.383412Z |   admin   |     4      |    pull   |                     errandsmoketest/busybox:latest                     |
|   10   |  2019-07-31T10:30:28.52028Z |   admin   |     4      |   delete  |                     errandsmoketest/busybox:latest                     |
( 以降省略 )
```

## HarborをGitlab runnerで使う

ここまで確認出来たら、あとはCD上で使うのみですね。
(使うと言っても、harbor上の不要なimageを消すだけですが。。。)

gitlab runnerを用いる際は、以下の２パターンは最小で分岐することになります。

1. gitlab runner上でまずdocker hostに対してdockerコマンドを叩ける様にするか
2. gitlab runner上でpythonを使ってインストールしておく

インストール時のパターンによって、ymlに書くコマンドが変わります。

### 始める前に
私は、アプリケーションに必要なmoduleやソフトウェアをインストールし終わったものをimageにしていて、それをdocker buildに用いる初期imageとしています。

そういったものがある場合は、docker buildをし終わったものをpushする受け口のrepositoryとは別repositoryにするかそもそもprojectを変えておいてください。
(見栄え的にも前者がオススメ)

理由としては、harbor内のリソースを消去する際、imageではなくrepositoryが消去対象の最小単位だからです。

例としては


| project | repository | image |
|:--------|:----------|:-----|
| test | test1 | build後のimage |
| |foundation|初期image|


### 1. docker

#### admin-harborrc fileの編集
以下の作業は、gitlab-runnerの`home`ディレクトリにおいて実施します。

前半で作成した`admin-harborrc`から`HARBOR_PROJECT`をなくします。

理由としては、removeとかの処理は、ここで指定したprojectに対して働くからです。

```
export HARBOR_USERNAME=admin
export HARBOR_PASSWORD=<password>
export HARBOR_URL=http://localhost
```

上記だけにしておきます。

そのあと、`bash_profile`には以下追記します。

```
source /home/gitlab-runner/admin-harborrc
alias harbor="harbor --insecure"
```

#### .gitlab-ci.ymlの編集

以下のコマンドを、任意の箇所に追加します。
自分の場合では、 `stage: build > before_script:`に記述しています。

```
sudo docker run --rm -e HARBOR_USERNAME=admin -e HARBOR_PASSWORD=<password> -e HARBOR_PROJECT=<project No> -e HARBOR_URL="https://localhost" krystism/harborclient harbor --insecure repository-delete <project名/repository名>
```

### 2. Python

#### .gitlab-ci.ymlの編集
dockerにおける`admin-harborrc の編集` までは一緒です。

その後、同様に以下のコマンドを、任意の箇所に追加します。

```
harbor --os-project <project No> repository-delete <project名/repository名>
```

### response
以下が、responseで返ってきたら、成功です。

```
Repository <project名/repository名> deleted
```

# 終わりに
ぜひ、private-repositoryの仕様を考えた際に、一度使ってみていただけたら、うれしいです。