GemFire for Kubernetesで認証機能を試す

以前GemFireの認証を[こちら](https://qiita.com/ipppppei/items/528ab198da5fdb6dba60)の記事で確認した。
これをGemFire for Kubernetesで確認する。

GemFire for Kubernetesのjarファイルの取り込み方法は特殊で、以下のような感じで`kind: GemFireCluster`のManifest内のLocator, Serverそれぞれでjarを含むコンテナイメージとjarへのパスを指定する。
```yaml
  locators:
    libraries:
      - name: my-custom-security-manager
        container:
          image: my.company.com/myImage:1.0.0
          path: "/build/libs/*.jar"
          imagePullSecretRef:
            name: pull-secret-name
```

そのため、最初にjarファイルをコンテナ化する必要がある。
今回は[前回](https://qiita.com/ipppppei/items/528ab198da5fdb6dba60)作成したjarファイルをそのまま流用したいところなのだが、Kubernetes版ではgemfire.properitesの`security-peer-auth-init`の利用が必須であり、これには`AuthInitialize`のclassの指定が必要なため、以下の手順で`AuthInitialize`のclassを追加してリビルドする。
```java
cat << EOF > ./src/main/java/com/vmware/gemfire/UserPasswordAuthInit.java
package com.vmware.gemfire;

import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.security.AuthInitialize;
import org.apache.geode.security.AuthenticationFailedException;

import java.util.Properties;

public class UserPasswordAuthInit implements AuthInitialize {

  @Override
  public Properties getCredentials(Properties properties, DistributedMember distributedMember, boolean isPeer) throws AuthenticationFailedException {
    properties.setProperty("security-username", "gemfire");
    properties.setProperty("security-password", "changeme");
    return properties;
  }
}
EOF
mvn clean package
```
リビルド後、作成したjarをコンテナ化するためのDockerfileを作成する。
```dockerfile
cat << EOF > ./Dockerfile
FROM alpine:latest
COPY BasicSecurityManager-1.0-SNAPSHOT.jar .
CMD ["sleep", "365d"]
EOF
```
これでコンテナ内のroot直下にBasicSecurityManager-1.0-SNAPSHOT.jarが配置される。
ビルドしてpushする。
```sh
DOCKER_REPO=myrepo
docker build -t ${DOCKER_REPO}/basic-security-manager-jar --platform linux/x86_64 . 
docker push ${DOCKER_REPO}/basic-security-manager-jar
```

次に[こちら](https://docs.vmware.com/en/VMware-GemFire-for-Kubernetes/2.3/gf-k8s/security-authn_authz-introduction.html#provision-1)のドキュメントによると、GemFire Operatorが使う認証情報を予めSecretに作成しておく必要があり、`kind: GemFireCluster`の`spec.security.mgmtSvcCredentialsSecretName`に指定する必要があるため、予め作成する。
```sh
USERNAME=operator
PASSWORD=secret
kubectl create secret generic basic-auth-security-manager --from-literal=username=$USERNAME --from-literal=password=$PASSWORD
```
また、`security-manager`指定時に以下の制約がある。
- LocatorとServerで同じSecurityManagerを指定が必須
- `security-peer-auth-init`の指定必須

上記を踏まえて、以下のManifestを作成してapplyする。
```yaml
cat << EOF > ./gemfire-cluster-auth.yaml
apiVersion: gemfire.vmware.com/v1
kind: GemFireCluster
metadata:
  name: gemfire1
spec:
  image: registry.tanzu.vmware.com/pivotal-gemfire/vmware-gemfire:10.0.0
  security:
    mgmtSvcCredentialsSecretName: basic-auth-security-manager
    tls: {}
  locators:
    libraries:
      - name: basic-security-manager-jar
        container:
          image: ${DOCKER_REPO}/basic-security-manager-jar:latest
          path: "/*.jar"
          imagePullSecretRef:
            name: dockerhub
    overrides:
      gemFireProperties:
        - name: "security-manager"
          value: "com.vmware.gemfire.BasicSecurityManager"        
        - name: "security-peer-auth-init"
          value: "com.vmware.gemfire.UserPasswordAuthInit"
  servers:
    overrides:
      gemFireProperties:
        - name: "security-manager"
          value: "com.vmware.gemfire.BasicSecurityManager"
        - name: "security-peer-auth-init"
          value: "com.vmware.gemfire.UserPasswordAuthInit"
EOF
kubectl apply -f ./gemfire-cluster-auth.yaml
```

Podが起動すると、ログ中に指定したjarに関する記述が見つけられる。
```sh
$ kubectl logs gemfire1-locator-0
[info 2023/10/30 10:36:30.011 GMT  <main> tid=0x1] Creating automatic module for resource roots: [/gemfire/extensions/BasicSecurityManager-1.0-SNAPSHOT.jar, /gemfire/tools/Modules/gemfire-prometheus-metrics/simpleclient-0.9.0.jar, /gemfire/tools/Modules/gemfire-prometheus-metrics/simpleclient_common-0.9.0.jar, /gemfire/tools/Modules/gemfire-prometheus-metrics/gemfire-prometheus-metrics-10.0.0-build.1630.jar, /gemfire/tools/Modules/gemfire-prometheus-metrics/micrometer-registry-prometheus-1.6.3.jar, /gemfire/tools/Modules/gemfire-prometheus-metrics/gson-2.8.9.jar]
--- BasicSecurityManager-1.0-SNAPSHOT.jar
```
実際にアクセスする。GemFireのイメージを使ってgfshを叩くためのPodを起動する。
```sh
kubectl run --image registry.tanzu.vmware.com/pivotal-gemfire/vmware-gemfire:10.0.0 debug
```
Podに入り、gfshを起動する。
```sh
kubectl exec -it debug -- bash
gfsh
```
繋いでみる。前回作ったjarではユーザ名が`operator`、パスワードが`secret`でログインできた。
```sh
gfsh>connect --locator gemfire1-locator-0[10334]
Connecting to Locator at [host=gemfire1-locator-0, port=10334] ..
Connecting to Manager at [host=gemfire1-locator-0.gemfire1-locator.default.svc.cluster.local, port=1099] ..
user: operator
password: ******
Successfully connected to: [host=gemfire1-locator-0.gemfire1-locator.default.svc.cluster.local, port=1099]
```
無事認証が動いたようだ。