Migrating to Cloud SQL Proxy v2 🆕

こんにちは。Enabling team の山本です。

今回は Cloud SQL Proxy v2（v2）について書きます。
v2 が2月8日の [Release notes](https://cloud.google.com/release-notes) で公開されました。

> The Cloud SQL Auth proxy is a utility for ensuring secure connections to your Cloud SQL instances. The v2 release offers improvements in performance, stability, and telemetry. Among the new features, there's support for:
Metrics and tracing with Cloud Monitoring and Cloud Trace
Support for Prometheus
Service account impersonation
Separate Dialer functionality released as the Cloud SQL Go Connector
Configuration with environment variables
Fully POSIX-compliant flags
Cloud SQL Auth proxyは、Cloud SQLインスタンスへのセキュアな接続を保証するためのユーティリティです。v2リリースでは、パフォーマンス、安定性、テレメトリーが改善されています。新機能の中には、次のようなものがサポートされています。

パフォーマンスの改善と可観測性に関する記載があります。
負荷試験などを実施し、問題がなければ、リリースに向けて調整しようと思います。

## TL;DR
* 公式の Release notes で v2 への移行を推奨されています。
* Repository、Option が変更されているため、Proxy の定義自体を見直す必要があります。

## Cloud SQL Proxy v2
> We recommend all customers upgrade to v2 and have released a migration guide. For more information, see Cloud SQL Auth proxy.
すべてのお客様にv2へのアップグレードを推奨し、移行ガイドを公開しています。詳しくは、Cloud SQL Auth proxyをご覧ください。

サンプルが　[GitHub](https://github.com/GoogleCloudPlatform/cloud-sql-proxy/blob/main/migration-guide.md) で公開されています。

## 接続してみる
`postgres:13-alpine` の sidecar（proxy）で接続する。
```
new-proxy:/# psql -h localhost -p 5432 -U hoge -d hogedb
Password for user hoge: 
psql (13.10, server 14.4)
WARNING: psql major version 13, server major version 14.
         Some psql features might not work.
Type "help" for help.

hogedb=> select schemaname, tablename, tableowner from pg_tables where schemaname='information_schema';
     schemaname     |        tablename        |  tableowner   
--------------------+-------------------------+---------------
 information_schema | sql_parts               | cloudsqladmin
 information_schema | sql_implementation_info | cloudsqladmin
 information_schema | sql_features            | cloudsqladmin
 information_schema | sql_sizing              | cloudsqladmin
(4 rows)

hogedb=> 
```

## v1 と v2 の違い
- 接続文字列が変更された。`--port`（省略可能）を別で定義する。
- Private 接続の Option が `--private-ip` に変更された。
### v2
```
  - name: cloud-sql-proxy
    image: asia.gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.0.0
    imagePullPolicy: IfNotPresent
    args:
      - "--port=5432"
      - "hoge-dev:asia-northeast1:hoge-dev-93820432"
    securityContext:
      runAsNonRoot: true
    resources: {}    # 省略
```
### v1
```
  - command:
    - /cloud_sql_proxy
    - -instances=hoge-dev:asia-northeast1:hoge-dev-93820432=tcp:5432
    image: gcr.io/cloudsql-docker/gce-proxy:1.28.1
    imagePullPolicy: IfNotPresent
    name: cloud-sql-proxy
    resources: {}    # 省略
    securityContext:
      runAsNonRoot: true
```

## まとめ
v2 について検証しました。
今後、v1 の更新停止が予想されるため、順次 v2 への移行を進めていきます。

## pulling from host gcr.io failed with status code [manifests latest]: 403 Forbidden
`cloud-sql-proxy` の pull にハマりました。
原因は、Kyverno の Policy でした。
`describe` の先頭に出ている Warning を見逃していました。
Policy は、`Deployment` に対して定義されており、`Pod` での挙動を把握できていなかったことが敗因です。
```
Events:
  Type     Reason           Age                From               Message
  ----     ------           ----               ----               -------
  Warning  PolicyViolation  18m                kyverno-admission  policy restrict-image-registries/validate-registries fail: validation error: Unknown image registry. Rule validate-registries failed at path /spec/containers/0/image/
  Warning  PolicyViolation  18m                kyverno-admission  policy disallow-latest-tag/require-image-tag fail: validation error: An image tag is required. Rule require-image-tag failed at path /spec/containers/1/image/
  Warning  PolicyViolation  18m                kyverno-admission  policy disallow-latest-tag/validate-image-tag pass: validation rule 'validate-image-tag' passed.
  Normal   Scheduled        18m                default-scheduler  Successfully assigned yakult/new-proxy to gke-hoge-dev-pool-e2-custom-6-12-ea456011-2782
  Normal   Pulled           18m                kubelet            Container image "postgres:13-alpine" already present on machine
  Normal   Created          18m                kubelet            Created container new-proxy
  Normal   Started          18m                kubelet            Started container new-proxy
  Normal   Pulling          16m (x4 over 18m)  kubelet            Pulling image "gcr.io/cloud-sql-connectors/cloud-sql-proxy"
  Warning  Failed           16m (x4 over 18m)  kubelet            Failed to pull image "gcr.io/cloud-sql-connectors/cloud-sql-proxy": rpc error: code = Unknown desc = failed to pull and unpack image "gcr.io/cloud-sql-connectors/cloud-sql-proxy:latest": failed to resolve reference "gcr.io/cloud-sql-connectors/cloud-sql-proxy:latest": pulling from host gcr.io failed with status code [manifests latest]: 403 Forbidden
  Warning  Failed           16m (x4 over 18m)  kubelet            Error: ErrImagePull
  Warning  Failed           16m (x5 over 18m)  kubelet            Error: ImagePullBackOff
  Normal   BackOff          3m (x64 over 18m)  kubelet            Back-off pulling image "gcr.io/cloud-sql-connectors/cloud-sql-proxy"
```