はじめに
これまでDockerHubの有料プランを利用してきましたが、さすがに開発用のイメージまで置く余裕はないので、Harborをデプロイして試すことにしました。今回はHelmを利用しています。
この記事を投稿したタイミングでは、DockerHubはPrivateコンテナの数に応じた料金体系でした。現在は最低限の有料プランでコンテナ数の制限はなくなっていますので、再びDockerHubをメインで利用しています。しかしDockerHubの事故によって外部に流出した場合に問題となる可能性のあるデータを含むコンテナについては、インターネットを中継しないようイントラネットのHarborを利用しています。
環境
- Harbor-Helmを利用してk8s環境にデプロイ
- ユーザー認証はLDAPを利用
- HarborへのアクセスにはLoadBalancerを利用
- Rook/Cephを利用しているためBlock Storageの利用にStorageClassの指定が必要
- Private LAN内部では、利用している192.168.x.xのIPについて、DNSのホスト名⇔IPの解決が可能 (dnsmasqを利用)
今回はIntranetからアクセスできるよう境界NWに設置したReverse-Proxyサーバー(nginx)を経由してHarborにアクセスし、Harbor自身はIntranetから直接アクセスできないようにしています。
ユースケース1 - NginxをFrontend Reverse-Proxy Serverとして利用する
nginxをLANとの境界に設置して、IntranetとHarborが動作するk8sクラスターを設置するLANを分離しています。
この場合はdocker login/push を実行する時に通信に、正規のTLS証明書が利用できます。利用者側での特別な設定は必要ありません。もし自己証明TLS鍵を利用するのであれば、後述するPrivate Network内で利用する方法と同様に利用者側でCAの証明書情報を管理する必要があります。
内部の第三者が接続できるため、adminパスワードの管理には特に注意が必要です。
ユースケース2 - Private Netowrk内から利用する
この場合はDockerからコンテナを登録する場合と、k8sからコンテナイメージをpullする場合に考慮が必要です。
通常はdockerコマンドからHarborに接続するためのTLS証明書について、独自CAが発行する自己認証鍵になるはずです。このような構成では、独自のCAの証明書をdockerやk8sクラスターに登録する必要があります。TLS鍵の準備には次の2つの方法があります。
- TLS鍵をharborに自動生成させる。生成されたCAの証明書をdockerやクライアントPC(openssl-client)などに登録する
- Private LAN内部で利用するDomain用にeasy-rsa3を利用してCAを構築し、Harbor用のサーバー証明書を作成し利用する。(1)と同様にeasy-rsa3が生成したCA局の証明書を利用側に登録する
自己証明鍵を利用する場合には、docker login や docker push でエラーになります。利用するシステムの /etc/docker/certs.d//ca.crt にCAの証明書を配置する必要がある点に注意してください。
Kubernetesがdockerを利用していれば、同様にk8sクラスターでもCA証明書を配置する必要があります。
導入までの流れ
以下では手元にユースケース1やユースケース2-2を想定して、手元にTLS証明書のセット(ca.crt, {tls.crt, tls.key})があることを前提に説明を進めます。
kubectlコマンドが実行できる場所でgit clone
$ git clone https://github.com/goharbor/harbor-helm.git
$ cd harbor-helm
## git tag で最新版を確認し、checkoutします。
$ git checkout refs/tags/v1.3.0 -b my_v1.3.0
繰り返し作業をいろいろするので、作業用にMakefileを準備しておきます。
$ cd .. ## from harbor-helm
$ cat > Makefile
NAMESPACE = harbor
HELM_RELEASE = my-harbor
.PHONY: init install delete delete-ns check create-tls-secret
init:
sudo kubectl create ns $(NAMESPACE)
install:
(cd harbor-helm; sudo helm install --name $(HELM_RELEASE) --namespace $(NAMESPACE) .)
delete:
(cd harbor-helm; sudo helm delete --purge $(HELM_RELEASE))
delete-ns:
sudo kubectl delete ns $(NAMESPACE)
check:
sudo helm -n $(NAMESPACE) list
create-tls-secret:
sudo kubectl -n $(NAMESPACE) create secret generic nginx-tls-keys --from-file pki/ca.crt --from-file pki/tls.crt --from-file pki/tls.key
この部分をCopy&Pasteするとインデントはスペース8個になってしまいますが、タブ文字である点に注意してください。
TLS鍵の配置
values.yamlのsecretName:を空にしたままにすると、TLS鍵が自動的に生成され、secret/helm_release-namespace-nginxに設定されます。今回はca.crt, tls.crt, tls.keyファイルをpki/ディレクトリに準備し、secret/nginx-tls-keysに格納します。
$ make init
$ mkdir pki
$ cp .../ca.crt .../harbor.example.com.crt .../harbor.example.com.key pki/
$ openssl rsa -in pki/harbor.example.com.key -out pki/harbor.example.com.nopass.key
$ ln -s harbor.example.com.crt pki/tls.crt
$ ln -s harbor.example.com.nopass.key pki/tls.key
$ make create-tls-secret
values.yamlの編集
git cloneしているので、git diff
の結果を添付します。これはProxy(proxy.example.com)を経由せずに、直接Private LAN内部でアクセスする場合のものです。
Proxy Serverを経由する場合には、externalURL:に外部に公開するProxy ServerのURLを指定します。commonNameにはPrivate LAN内部でDNS名前解決できるホスト名を指定しています。
diff --git a/values.yaml b/values.yaml
index 474ffdb..74f9fa5 100644
--- a/values.yaml
+++ b/values.yaml
@@ -2,7 +2,7 @@ expose:
# Set the way how to expose the service. Set the type as "ingress",
# "clusterIP", "nodePort" or "loadBalancer" and fill the information
# in the corresponding section
- type: ingress
+ type: loadBalancer
tls:
# Enable the tls or not. Note: if the type is "ingress" and the tls
# is disabled, the port must be included in the command when pull/push
@@ -16,14 +16,14 @@ expose:
# "ca.crt" - the certificate of CA (optional), this enables the download
# link on portal to download the certificate of CA
# These files will be generated automatically if the "secretName" is not set
- secretName: ""
+ secretName: "nginx-tls-keys"
# By default, the Notary service will use the same cert and key as
# described above. Fill the name of secret if you want to use a
# separated one. Only needed when the type is "ingress".
notarySecretName: ""
# The common name used to generate the certificate, it's necessary
# when the type isn't "ingress" and "secretName" is null
- commonName: ""
+ commonName: "harbor.example.com"
ingress:
hosts:
core: core.harbor.domain
@@ -73,7 +73,7 @@ expose:
# The name of LoadBalancer service
name: harbor
# Set the IP if the LoadBalancer supports assigning IP
- IP: ""
+ IP: "192.168.1.43"
ports:
# The service port Harbor listens on when serving with HTTP
httpPort: 80
@@ -98,7 +98,7 @@ expose:
# the IP address of k8s node
#
# If Harbor is deployed behind the proxy, set it as the URL of proxy
-externalURL: https://core.harbor.domain
+externalURL: https://harbor.example.com
# The persistence is enabled by default and a default StorageClass
# is needed in the k8s cluster to provision volumes dynamicly.
@@ -120,19 +120,19 @@ persistence:
# Specify the "storageClass" used to provision the volume. Or the default
# StorageClass will be used(the default).
# Set it to "-" to disable dynamic provisioning
- storageClass: ""
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
- size: 5Gi
+ size: 20Gi
chartmuseum:
existingClaim: ""
- storageClass: ""
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 5Gi
jobservice:
existingClaim: ""
- storageClass: ""
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 1Gi
@@ -140,7 +140,7 @@ persistence:
# be ignored
database:
existingClaim: ""
- storageClass: ""
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 1Gi
@@ -148,7 +148,7 @@ persistence:
# be ignored
redis:
existingClaim: ""
- storageClass: ""
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
size: 1Gi
Harborのデプロイなどの一連の作業
Makefileを配置したディレクトリは次のようになっています。
$ ls -l
total 32
-rw-rw-r-- 1 yasu yasu 219 Jan 9 12:33 Makefile
drwxrwxr-x 8 yasu yasu 4096 Jan 9 14:10 harbor-helm
namespaceは既に存在する(make initした)ものとして、helm installを実行します。
$ make install
$ make check
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
my-harbor 1 Thu Jan 9 21:37:55 2020 DEPLOYED harbor-1.3.0 1.10.0 harbor
もしharborを削除したい場合には、make delete, make delete-nsを実行します。delete-nsを実行しない場合には、PVCはnamespace内に残ります。
$ make delete
$ make check
## my-harborが削除されていれば、delete-nsを実行
$ make delete-ns
正常に稼動すればWeb UIなどでログインすることができるようになります。Namespaceのsecretにca.crt,tls.crt,tls.keyを登録済みであれば不要ですが、secretName:を空("")にしてhelmが自動生成する証明書を利用する場合には、ca.crtファイルを抽出して、docker push, kubectl を実行するホスト上に登録する必要があります。
アップグレード
v1.8.3からv1.9.6にアップグレードした時の作業手順をメモしておきます。
$ sudo helm list --namespace harbor
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-harbor harbor 6 2022-08-30 03:49:02.246171523 +0000 UTC deployed harbor-1.8.3 2.4.3
続いて、git を使って新しい tag を checkout していきます。
$ cd harbor-helm
## 未保存の作業内容を全てコミットする
$ git add .
$ git commit -m 'save all performed work.'
## masterブランチに移動し、最新にする
$ git checkout
$ git pull
## タグ名を確認し、n+1版の最新版をダウンロードする
$ git tag
$ git checkout refs/tags/v1.9.6 -b my_v1.9.6
## 前バージョンのvalues.yamlとの差分を確認し、追記する
$ git diff my_v1.8.3 values.yaml
## existingClaim: に追記するPVCの名前を確認し、existingClaim: を更新する
$ sudo kubectl -n harbor get pvc
values.yamlの内容を正しく記述しないとエラーになってしまうため気をつけること。
差分を再度確認し、問題がなければアップグレードします。
$ git diff my_v1.8.3
$ sudo helm -n harbor upgrade my-harbor --force --set fullnameOverride=my-harbor-harbor .
再度状況を確認します。実際にはvalues.yamlの編集ミスがあったので、再度 helm upgrade を実行しているので、REVISIONが 6 から 8 に更新されています。
$ sudo helm list --namespace harbor
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
my-harbor harbor 8 2023-03-05 12:02:33.732748916 +0000 UTC deployed harbor-1.9.6 2.5.6
結果として無事にアップグレードが完了しました。
values.yaml
参考までに実際に編集した v1.9.6 の values.yaml は次のような変更を実施しています。
(※パスワードなどは無関係な文字列に置換しています)
diff --git a/values.yaml b/values.yaml
index b7c2e20..00076dd 100644
--- a/values.yaml
+++ b/values.yaml
@@ -1,7 +1,7 @@
expose:
# Set how to expose the service. Set the type as "ingress", "clusterIP", "nodePort" or "loadBalancer"
# and fill the information in the corresponding section
- type: ingress
+ type: loadBalancer
tls:
# Enable TLS or not.
# Delete the "ssl-redirect" annotations in "expose.ingress.annotations" when TLS is disabled and "expose.
type" is "ingress"
@@ -20,7 +20,7 @@ expose:
auto:
# The common name used to generate the certificate, it's necessary
# when the type isn't "ingress"
- commonName: ""
+ commonName: "harbor.example.com"
secret:
# The name of secret which contains keys named:
# "tls.crt" - the certificate
@@ -97,7 +97,7 @@ expose:
# The name of LoadBalancer service
name: harbor
# Set the IP if the LoadBalancer supports assigning IP
- IP: ""
+ IP: "192.168.1.43"
ports:
# The service port Harbor listens on when serving HTTP
httpPort: 80
@@ -122,7 +122,7 @@ expose:
# the IP address of k8s node
#
# If Harbor is deployed behind the proxy, set it as the URL of proxy
-externalURL: https://core.harbor.domain
+externalURL: https://harbor.example.com
# The internal TLS used for harbor components secure communicating. In order to enable https
# in each components tls cert files need to provided in advance.
@@ -188,7 +188,7 @@ internalTLS:
ipFamily:
# ipv6Enabled set to true if ipv6 is enabled in cluster, currently it affected the nginx related component
ipv6:
- enabled: true
+ enabled: false
# ipv4Enabled set to true if ipv4 is enabled in cluster, currently it affected the nginx related component
ipv4:
enabled: true
@@ -211,53 +211,53 @@ persistence:
registry:
# Use the existing PVC which must be created manually before bound,
# and specify the "subPath" if the PVC is shared with other components
- existingClaim: ""
+ existingClaim: "my-harbor-registry"
# Specify the "storageClass" used to provision the volume. Or the default
# StorageClass will be used (the default).
# Set it to "-" to disable dynamic provisioning
- storageClass: ""
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
- size: 5Gi
+ size: 50Gi
annotations: {}
chartmuseum:
- existingClaim: ""
- storageClass: ""
+ existingClaim: "my-harbor-chartmuseum"
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
- size: 5Gi
+ size: 50Gi
annotations: {}
jobservice:
- existingClaim: ""
- storageClass: ""
+ existingClaim: "my-harbor-jobservice"
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
- size: 1Gi
+ size: 10Gi
annotations: {}
# If external database is used, the following settings for database will
# be ignored
database:
- existingClaim: ""
- storageClass: ""
+ existingClaim: "database-data-my-harbor-database-0"
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
- size: 1Gi
+ size: 10Gi
annotations: {}
# If external Redis is used, the following settings for Redis will
# be ignored
redis:
- existingClaim: ""
- storageClass: ""
+ existingClaim: "data-my-harbor-redis-0"
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
- size: 1Gi
+ size: 10Gi
annotations: {}
trivy:
- existingClaim: ""
- storageClass: ""
+ existingClaim: "data-my-harbor-trivy-0"
+ storageClass: "rook-ceph-block"
subPath: ""
accessMode: ReadWriteOnce
- size: 5Gi
+ size: 50Gi
annotations: {}
# Define which storage backend is used for registry and chartmuseum to store
# images and charts. Refer to
@@ -361,7 +361,7 @@ updateStrategy:
logLevel: info
# The initial password of Harbor admin. Change it from portal after launching Harbor
-harborAdminPassword: "Harbor12345"
+harborAdminPassword: "ff0dfac092171002"
# The name of the secret which contains key named "ca.crt". Setting this enables the
# download link on portal to download the CA certificate when the certificate isn't
@@ -369,7 +369,7 @@
harborAdminPassword: "Harbor12345"
caSecretName: ""
# The secret key used for encryption. Must be a string of 16 chars.
-secretKey: "not-a-secure-key"
+secretKey: "3713e2acf3d71ca3"
# The proxy settings for updating trivy vulnerabilities from the Internet and replicating
# artifacts from/to the registries that cannot be reached directly
@@ -565,10 +565,10 @@ registry:
# If true, the registry returns relative URLs in Location headers. The client is responsible for resolving
the correct URL.
relativeurls: false
credentials:
- username: "harbor_registry_user"
- password: "harbor_registry_password"
+ username: "474a32523383f006"
+ password: "ae630f3a5cba1461"
# Login and password in htpasswd string format. Excludes `registry.credentials.username` and `registry.c
redentials.password`. May come in handy when integrating with tools like argocd or flux. This allows the same
line to be generated each time the template is rendered, instead of the `htpasswd` function from helm, which g
enerates different lines each time because of the salt.
- # htpasswdString: $apr1$XLefHzeG$Xl4.s00sMSCCcMyJljSZb0 # example string
+ htpasswdString: "d17f469f791b3d13:$apr1$XLefHzeG$Xl4.s00sMSCCcMyJljSZb0"
middleware:
enabled: false
type: cloudFront
@@ -750,7 +750,7 @@ database:
repository: goharbor/harbor-db
tag: v2.5.6
# The initial superuser password for internal database
- password: "changeit"
+ password: "3cefaedde881b07c"
# The size limit for Shared memory, pgSQL use it for shared_buffer
# More details see:
# https://github.com/goharbor/harbor/issues/15034
TLS接続時の検証エラーの回避
docker・kubectlコマンドから直接、Harborに接続する場合には、https://docs.docker.com/registry/insecure/ に記述があるように、自己署名CAをそのコマンドを実行するマシンの /etc/docker/certs.d/hostname/ca.crt に配置する方法がお勧めです。
WebブラウザからHarborのWeb UIにアクセスする場合には、そのシステム(Ubuntuであればca-certificatesの管理下)に自己署名CAを登録する方法がお勧めです。
自分が管理していない自己署名CAをシステムに登録する方法はお勧めしませんが、TLS鍵の検証を無視する設定は安直ですができるだけ避けるべきだと思います。自分の管理下にある自己署名CAを登録する方が、対象を限定できるので、お勧めです。
実際に鍵を配布する方法には、ansibleを利用して、全マシンに配布しています。
自己署名CAの抽出
kubectlが実行できるマシンでsecretに登録されているca.tlsの内容を取得します。1行で実行すると次のようになりますが、単純に$ kubectl get secret my-harbor-harbor-nginx -o yaml
の出力からca.crt部分をコピーして、base64 -dの入力に与える方法もあります。
$ kubectl get secret my-harbor-harbor-nginx -o jsonpath='{.data.ca\.crt}' | base64 -d
-----BEGIN CERTIFICATE-----
.....
-----END CERTIFICATE-----
ここで画面に出力された内容を、ca.crtとして保存し、docker pushを実行するホスト、kubernetesの各ノードに登録(/etc/docker/certs.d/harbor.example.com/ca.crtへの配置)をします。
Harborの稼動確認
ca.crtの内容がシステムに登録された後は、Web UIからログインします。
$ firefox https://harbor.example.com/
自己署名CAを利用している場合には警告がでますが、Acceptして次に進みます。
- ID: admin
- Password: Harbor12345
パスワードはログインした後の左上にあるAdminユーザーのメニューから、必ず変更するようにしましょう。LDAPを利用したいので、Configurationに進んで情報を登録しますが、今回は省略します。
Projects "library" へのユーザーの登録
LDAPとの接続ができるようになったところで、自分のIDをProjects"libarary"のMembersタブに進み、"+ USER"ボタンからMasterとして登録しています。
libraryプロジェクトに一般ユーザーを登録したところで、イメージを登録します。
Dockerでのイメージの作成と登録
ネーミングルールは、ホスト名/プロジェクト名/image[:TAG] となっているので、docker buildする場合には適切なtagをつけるか、手元でのテストでも利用すると思うので、次のような方法で、既存のイメージにHarbor登録用の名称を設定するという事になると思います。
$ docker login harbor.example.com
Username: user01
Password:
$ docker pull nginx:latest
$ docker tag nginx:latest harbor.example.com/library/mynginx:1.0
$ docker push harbor.example.com/library/mynginx:1.0
The push refers to repository [harbor.example.com/library/mynginx]
918efb8f161b: Pushed
27dd43ea46a8: Pushed
9f3bfcc4a1a8: Pushed
2dc9f76fb25b: Pushed
1.0: digest: sha256:2695d3e10e69cc500a16eae6d6629c803c43ab075fa5ce60813a0fc49c47e859 size: 1152
独自にProjectを登録している場合には、"library"の部分を適宜変更します。
最後にWeb UIから自分のIDでログインし、イメージが登録されていることを確認しておきます。
Kubernetesでのデプロイメントのテスト
次の2つのYAMLファイルを準備します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
imagePullSecrets:
- name: selfreg
containers:
- name: nginx
image: harbor.example.com/library/mynginx:1.0
ports:
- containerPort: 80
apiVersion: v1
kind: Service
metadata:
name: nginx
namespace: default
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
deploymentの中で参照(.spec.template.spec.imagePullSecrets.name)している、selfregを作成します。
$ read -s regpasswd
## 入力しているパスワードは非表示な点に注意
$ kubectl -n default create secret docker-registry selfreg --docker-username=user01 --docker-email=user01@example.com --docker-password="${regpasswd}"
これで作成した2つのYAMLファイルを登録します。
$ kubectl -n default apply -f deploy-mynginx.yaml
$ kubectl -n default apply -f svc-mynginx.yaml
## 状況の確認
$ kubectl -n default get all
NAME READY STATUS RESTARTS AGE
pod/nginx-deployment-55d5f94b5-nbw4v 1/1 Running 0 43m
pod/nginx-deployment-55d5f94b5-wkwb4 1/1 Running 0 43m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.233.0.1 <none> 443/TCP 75d
service/nginx LoadBalancer 10.233.7.30 192.168.1.24 80:30243/TCP 59m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/nginx-deployment 2/2 2 2 59m
NAME DESIRED CURRENT READY AGE
replicaset.apps/nginx-deployment-55d5f94b5 2 2 2 43m
正常にCAファイルが登録されていない場合には、次のようにエラーになります。
LDAP設定時に注意する点
HarborのLDAP設定は複雑なことができないようになっていて柔軟性には欠けますが、反面、設定自体に困る事はあまりないと思います。
ただ、LDAPサーバーのURLを指定する部分では、次のように設定するとエラーになります。
ldaps://ldap.example.com:636
末尾の :636 の部分は間違いではないはずですが、エラーとなるため ldaps://ldap.example.com
のように指定する必要がありました。
Kubernetesにca.crtが登録されていない場合のエラー
ファイルが正常に配置されていれば再起動は不要ですが、内容が正しくない場合には、次ようなエラーとなります。
$ kubectl -n default describe pod -l app=nginx
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 51s default-scheduler Successfully assigned default/nginx-deployment-55d5f94b5-km9ms to ibox01a2
Normal BackOff 18s (x2 over 43s) kubelet, ibox01a2 Back-off pulling image "harbor.example.com/library/mynginx:1.0"
Warning Failed 18s (x2 over 43s) kubelet, ibox01a2 Error: ImagePullBackOff
Normal Pulling 4s (x3 over 49s) kubelet, ibox01a2 Pulling image "harbor.example.com/library/mynginx:1.0"
Warning Failed 4s (x3 over 44s) kubelet, ibox01a2 Failed to pull image "harbor.example.com/library/mynginx:1.0": rpc error: code = Unknown desc = Error response from daemon: Get https://harbor.example.com/v2/: x509: certificate signed by unknown authority
Warning Failed 4s (x3 over 44s) kubelet, ibox01a2 Error: ErrImagePull
およそ、ここまでで一般的なユースケースは満たせるのかなと思います。
デプロイ後に遭遇した問題
ある日、気がつくとcoreプロセスが正常に起動しない状態になっていました。
postgresqlが稼動しているdatabaseに接続できない事が理由と分かったので、ログを確認すると次のようなメッセージが表示されていました。
$ kubectl -n harbor logs statefulset.apps/my-harbor-harbor-database
FATAL: data directory "/var/lib/postgresql/data" has group or world access
DETAIL: Permissions should be u=rwx (0700).
今回はこれを修復する方法として、initContainersを利用します。
$ kubectl -n harbor edit statefulset.apps/my-harbor-harbor-database
initContainers:
- args:
- -c
- "chown -R postgres:postgres /var/lib/postgresql/data ; chmod 0700 /var/lib/postgresql/data"
command:
- /bin/sh
これで問題なく起動時にマウントした/var/lib/postgresql/dataのパーミッションを変更し、起動するようになりました。
以上