社内Proxy環境下の K8s で docker private registry を構築する

## 前提

* K8s クラスタ : k8s-node   ※control-planeにラウンドロビンとなるようロードバランサを設定しておく
* インターネットアクセスにはProxy経由である必要がある
* コンテナ保存先を実行ノードに依存しないよう PersistenceVolume を使用して共有ディレクトリ上に作成

## docker-registry を k8s にデプロイ

docker-registry用のnamespace作成。

```sh
$ kubectl create namespace docker-registry
```

マニフェストを作成。

`docker-registry.yaml`:

```yaml
### イメージ格納用の Persistent Volume 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: docker-registry-pvc
  namespace: docker-registry
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1000Gi
---
### Deployment 設定
apiVersion: apps/v1
kind: Deployment
metadata:
  name: docker-registry
  namespace: docker-registry
  labels:
    app: docker-registry
spec:
  replicas: 1
  selector:
    matchLabels:
      app: docker-registry
  template:
    metadata:
      labels:
        app: docker-registry
    spec:
      containers:
      - name: docker-registry
        image: registry:2  #3.0.0-rc.1 がlatestだがバージョンがstableになっていないため2.xを使う
        ports:
        - containerPort: 5000
        volumeMounts:
        - name: registry-data
          mountPath: /var/lib/registry
      volumes:
      - name: registry-data
        persistentVolumeClaim:
          claimName: docker-registry-pvc
---
### 公開用サービス設定
apiVersion: v1
kind: Service
metadata:
  name: docker-registry
  namespace: docker-registry
spec:
  selector:
    app: docker-registry

  type: NodePort
  ports:
  - port: 5000
    targetPort: 5000
    nodePort: 30500
---
```

適用してデプロイ。

```sh
$ kubectl apply -f docker-registry.yaml
persistentvolumeclaim/docker-registry-pvc created
deployment.apps/docker-registry created
service/docker-registry created

$ kubectl get pvc,deploy,svc,pods -n docker-registry
NAME                                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
persistentvolumeclaim/docker-registry-pvc   Bound    pvc-****************
1000Gi     RWO            local-path     <unset>                 60s

NAME                              READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/docker-registry   1/1     1            1           60s

NAME                      TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/docker-registry   NodePort   10.107.163.50   <none>        5000:30500/TCP   60s

NAME                                   READY   STATUS    RESTARTS   AGE
pod/docker-registry-***********   1/1     Running   0          60s
```

## TLS除外設定

クライアント側、つまり docker pull/push を実行するノードにおいて、Private docker-registry を insecure-registry に追加が必要。

### for docker

`/etc/docker/daemon.json`:
```json
{
    "insecure-registries" : ["k8s-node:30500"]
}
```

### for podman

[コンテナーレジストリーの設定](https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/con_configuring-container-registries_working-with-container-registries#con_configuring-container-registries_working-with-container-registries) に従って設定。

上記ドキュメントでは `/etc/containers/registries.conf` に対して設定するとあるが、
`/etc/containers/registries.conf.d/` 以下に適当なconfファイルを作るほうがよい。

`/etc/containers/registries.conf.d/500-insecure-registries.conf`:
```
[[registry]]
location = "k8s-node:30500"
insecure = true
```



## Proxy対象から除外

NO_PROXYにK8sクラスタを追加してProxy対象から外す。

```sh
$ sudo systemctl edit docker

Environment="NO_PROXY=localhost,127.0.0.1,k8s-node"
```

dockerを再起動して反映。

```sh
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
```


## アクセス確認

ユーザ側でも k8s-node に Proxy 経由しないよう Proxy 除外しておく。

```sh
$ export no_proxy=$no_proxy,k8s-node

$ curl -v k8s-node:30500
* Rebuilt URL to: k8s-node:30500/
* Uses proxy env variable no_proxy == 'localhost,127.0.0.1,k8s-node'
*   Trying 192.168.100.41...
* TCP_NODELAY set
* Connected to k8s-node (192.168.100.41) port 30500 (#0)
> GET / HTTP/1.1
> Host: k8s-node:30500
> User-Agent: curl/7.61.1
> Accept: */*
```

これで push,pull とかできるようになれば OK

```sh
$ docker push k8s-node:30500/hello-world:latest
The push refers to repository [k8s-node:30500/hello-world]
XXXXXXXXXXXX: Pushed
latest: digest: sha256:******************************* size: 524
```


## 参考

* [pvcの割り当て方法など](https://kb.leaseweb.com/kb/kubernetes/kubernetes-deploying-a-docker-registry-on-kubernetes/)
* [マニフェスト例](https://qiita.com/tkarube/items/d3c008cc0dc9d139f819)
* [insecure registry設定](https://qiita.com/kanegoon/items/e250c0a328673b0fca82#insecure-registry-%E3%81%AE%E8%A8%AD%E5%AE%9A)
* [コンテナーレジストリーの使用](https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/working-with-container-registries_building-running-and-managing-containers)