添加helm仓库
helm repo add kvaps https://kvaps.github.io/charts
查询下stolon
[root@master helm-stolon]# helm search repo stolon
NAME CHART VERSION APP VERSION DESCRIPTION
kvaps/stolon 1.7.0 0.16.0 Stolon - PostgreSQL cloud native High Availabil...
下载stolon的helm Chart文件
[root@master helm-stolon]# helm fetch kvaps/stolon
[root@master helm-stolon]# ls
stolon-1.7.0.tgz
# 解压下载下来的文件
[root@node1 stolon]# tar -xf stolon-1.7.0.tgz
# 进入目录
[root@node1 stolon]# cd stolon
生成自签名证书
生成key
# 该过程需要输入密码
[root@node1 cert2]# openssl genrsa -des3 -out server.key 2048
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
[root@node1 cert2]# ls
server.key
# 将生成的server.key去掉密码
[root@node1 cert2]# openssl rsa -in server.key -out server.key
Enter pass phrase for server.key:
writing RSA key
[root@node1 cert2]# ls
server.key
生成CA的crt
生成的ca.crt文件是用来签署下面的server.csr文件
[root@node1 cert2]# openssl req -new -x509 -key server.key -out ca.crt -days 3650
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN # 信息填写这个和下面的就可以
State or Province Name (full name) []:SD
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:
# 查看生成的ca.crt
[root@node1 cert2]# ls
ca.crt server.key
[root@node1 cert2]#
csr的生成方法
需要依次输入国家,地区,组织,email。最重要的是有一个common name,可以写你的名字或者域名。如果为了https申请,这个必须和域名吻合,否则会引发浏览器警报。生成的csr文件交给CA签名后形成服务端自己的证书。
[root@node1 cert2]# openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SD
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
# 这里输入域名或者IP
Common Name (eg, your name or your server's hostname) []:192.168.0.184
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# 查看生成的csr文件
[root@node1 cert2]# ls
ca.crt server.csr server.key
生成crt
CSR文件必须有CA的签名才可形成证书
[root@node1 cert2]# openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey server.key -CAcreateserial -out server.crt
Certificate request self-signature ok
subject=C = CN, ST = SD, L = Default City, O = Default Company Ltd, CN = 192.168.0.184
# 查看生成的crt
[root@node1 cert2]# ls
ca.crt ca.srl server.crt server.csr server.key
修改values.yaml文件
# clusterName:
image:
repository: sorintlab/stolon
tag: v0.16.0-pg10
pullPolicy: IfNotPresent
## Add secrets manually via kubectl on kubernetes cluster and reference here
# pullSecrets:
# - name: "myKubernetesSecret"
# used by create-cluster-job when store.backend is etcd
etcdImage:
repository: bitnami/etcd # 这里修改下镜像地址,原来的地址国内无法访问
tag: 2.3.7
pullPolicy: IfNotPresent
debug: false
# Enable the creation of a shm volume
shmVolume:
enabled: false
persistence:
enabled: true
## If defined, storageClassName: <storageClass>
## If set to "-", storageClassName: "", which disables dynamic provisioning
## If undefined (the default) or set to null, no storageClassName spec is
## set, choosing the default provisioner. (gp2 on AWS, standard on
## GKE, AWS & OpenStack)
##
storageClassName: "rook-ceph-block" # 修改下集群上部署的sc
accessModes:
- ReadWriteOnce
size: 10Gi
rbac:
create: true
serviceAccount:
create: true
# The name of the ServiceAccount to use. If not set and create is true, a name is generated using the fullname template
name:
superuserSecret:
name: ""
usernameKey: pg_su_username
passwordKey: pg_su_password
replicationSecret:
name: ""
usernameKey: pg_repl_username
passwordKey: pg_repl_password
superuserPasswordFile:
superuserUsername: "stolon" # 用户名和密码根据自己的需要进行更改
## password for the superuser (REQUIRED if superuserSecret and superuserPasswordFile are not set)
superuserPassword: "pass_123456"
replicationPasswordFile:
replicationUsername: "repluser"
## password for the replication user (REQUIRED if replicationSecret and replicationPasswordFile are not set)
replicationPassword: "repli_654321"
## backend could be one of the following: consul, etcdv2, etcdv3 or kubernetes
store:
backend: kubernetes
# endpoints: "http://stolon-consul:8500"
kubeResourceKind: configmap
pgParameters: {}
# max_connections: "1000"
ports:
stolon:
containerPort: 5432
metrics:
containerPort: 8080
serviceMonitor:
# When set to true then use a ServiceMonitor to collect metrics
enabled: false
# Custom labels to use in the ServiceMonitor to be matched with a specific Prometheus
labels: {}
# Set the namespace the ServiceMonitor should be deployed to
# namespace: default
# Set how frequently Prometheus should scrape
# interval: 30s
# Set timeout for scrape
# scrapeTimeout: 10s
job:
autoCreateCluster:
enabled: true
resources: {}
initContainers:
resources: {}
initdbScripts:
enabled: true
resources: {}
initContainers:
resources: {}
autoUpdateClusterSpec:
enabled: true
resources: {}
initContainers:
resources: {}
annotations: {}
clusterSpec: {}
# sleepInterval: 1s
# maxStandbys: 5
## Enable support ssl into postgres, you must specify the certs.
## ref: https://www.postgresql.org/docs/10/ssl-tcp.html
##
tls:
enabled: true # 开启tls
rootCa: |- # 将上面生成的证书中的ca.crt内容拷贝进该文件
-----BEGIN CERTIFICATE-----
MIIDfzCCAmegAwIBAgIUItOvNfwTwKhvnWKki9F2VlZ1ugcwDQYJKoZIhvcNAQEL
BQAwTzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNEMRUwEwYDVQQHDAxEZWZhdWx0
IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjMwOTE5MjI0
NDIzWhcNMzAxMjIxMjI0NDIzWjBPMQswCQYDVQQGEwJDTjELMAkGA1UECAwCU0Qx
FTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55
IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPragCJEn76XskpM
qBdcvlJzo6rvuWkvGnmVCcJ2W/4rP2+tAtZTpN9MK2WGkaiQ5tSdWtxseqk2eLSp
ofjkleDIDbTiYUrP+2D37qU1OO00v6AbGlFl9XMW/YkPiVRdj4n90CgIeKs7ju1d
SHTEXDA+RF4bcxZA1bXtdCRmJwZ1un0NB5/1WKowuh+GGVPVSU8UUdrnv5omd2KI
SEzJ7EMgUaV2sTb7XfIUN4Djcgjlm41WmrTqr47Zz+LpR8HHRBRXPkwqC48rk2st
oUFmsANilWkOCVBGR2UVeFaf29DHQJdrGAHe/cdmDprSXAmnzCvHwqD0Pklo0ZI1
OKokwQMCAwEAAaNTMFEwHQYDVR0OBBYEFDvkV6ctcSbW8RWJr1VrOgGkH5iEMB8G
A1UdIwQYMBaAFDvkV6ctcSbW8RWJr1VrOgGkH5iEMA8GA1UdEwEB/wQFMAMBAf8w
DQYJKoZIhvcNAQELBQADggEBAMpdwiJNDrHrAfW6M68Youtz484wy/UMiYAD4qsm
LXY1eKgyaB5N/Dqym4gZ/m/M2hGftPu4zhKm9t6wTcm2KjAIfaM4+IpiMJlDLe4G
5ZM2Ow/eJVMbT0yh8bZ/gkgCwIU3cdcUrbzmfSITVLGYp0F8Htst8ljJLzB4zoaf
TlNyQ3Fe7a69eAiLlIoMvqthdEpkVWuJ+fq1Do9C5TYNGNtxVXMK8oXVlt3ESEcB
K4x2rm5YNKooIkIyz6QKGKJoyFd/wYboByimCe64jgzuHt3Jnn+Xb6kVi5f6BCj9
gF0WYcNUO+JwT5fcwzCqklQXyGeNOokmJGRFdZcubn6FErs=
-----END CERTIFICATE-----
serverCrt: |- # 将上面生成的证书中的server.crt内容拷贝进该文件
-----BEGIN CERTIFICATE-----
MIIDPTCCAiUCFHwb1j0Bb6z/yOsftMI0ZQ413h9tMA0GCSqGSIb3DQEBCwUAME8x
CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJTRDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5
MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMB4XDTIzMDkxOTIyNDYyOVoX
DTMzMDkxNjIyNDYyOVowZzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNEMRUwEwYD
VQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQx
FjAUBgNVBAMMDTE5Mi4xNjguMC4xODQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
ggEKAoIBAQD62oAiRJ++l7JKTKgXXL5Sc6Oq77lpLxp5lQnCdlv+Kz9vrQLWU6Tf
TCtlhpGokObUnVrcbHqpNni0qaH45JXgyA204mFKz/tg9+6lNTjtNL+gGxpRZfVz
Fv2JD4lUXY+J/dAoCHirO47tXUh0xFwwPkReG3MWQNW17XQkZicGdbp9DQef9Viq
MLofhhlT1UlPFFHa57+aJndiiEhMyexDIFGldrE2+13yFDeA43II5ZuNVpq06q+O
2c/i6UfBx0QUVz5MKguPK5NrLaFBZrADYpVpDglQRkdlFXhWn9vQx0CXaxgB3v3H
Zg6a0lwJp8wrx8Kg9D5JaNGSNTiqJMEDAgMBAAEwDQYJKoZIhvcNAQELBQADggEB
AE6QkSfLlgA/KJABt1nKs98csqKbD4iP4U7BCYcRS+PWH16JZ3cB9OMMjn2LL9EN
gO8VQ8GLg+OT8TZTZl4xRfG22wP7W62exbtcRKLwSscA8J3Jk7B+BQI0tW3xZ8i9
LjFKVm7/LG/UnSX8Bf3Cs9abtyYJimcycdpSe94bQRrZI4SSbcW1beuQUF/+xbgT
uMoUyJsl63i8/NtA9JYdsWWYBbyjWBgLQ8XNcDhTYU64HUVWaolDKKBhZPesFuYR
9LkXQ/F+IQR5dDCbQrlD2ogFo3/9kWWE30qTN8PPcNtcLiIDHf+ryUdsvmeORIlx
+UMMIGA8SAX1e3BFOA5lCts=
-----END CERTIFICATE-----
serverKey: |- # 将上面生成的证书中的server.key内容拷贝进该文件
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD62oAiRJ++l7JK
TKgXXL5Sc6Oq77lpLxp5lQnCdlv+Kz9vrQLWU6TfTCtlhpGokObUnVrcbHqpNni0
qaH45JXgyA204mFKz/tg9+6lNTjtNL+gGxpRZfVzFv2JD4lUXY+J/dAoCHirO47t
XUh0xFwwPkReG3MWQNW17XQkZicGdbp9DQef9ViqMLofhhlT1UlPFFHa57+aJndi
iEhMyexDIFGldrE2+13yFDeA43II5ZuNVpq06q+O2c/i6UfBx0QUVz5MKguPK5Nr
LaFBZrADYpVpDglQRkdlFXhWn9vQx0CXaxgB3v3HZg6a0lwJp8wrx8Kg9D5JaNGS
NTiqJMEDAgMBAAECggEANLlhDhLLWoVKwWgMOmDRVcYdY8uf9jYiw+Qp2XgEDM9t
NV0xR/fros1BH8Uhb0MJaS2rj8GzJEahJyOyOfxdbhHOI7MjDNTa+n4R6CJgFSct
kYqwxOP/q1FtN3YPAK7rgO7aZdel+SN6/nPJS1WMJM2pk/gD/+zfni3K5+2ajTYd
1dj3xPgbShWJAsVLEwThVRg9gCR2t9PCLpj623QgOqSkIePy9mm7Wmgtiq3nkg0H
c3bMbcbeI5bcpAEegpcXc4bz8GWNWnFrKPzae7yfgv722vB33/tDwRz75JCnQPca
myR3I2geFjbgMornQy0reSRb304zwPhZ0bplYJ2zDQKBgQD8gaiSyxQPLn9Yls3Y
hgX1bh3T/v2tzTtF9Vb0l7cQKKMbeC51lQs4zzByhTkMQznSOx79hWQ6D5BszMqi
UXfyE5JkeaPiW9ccvLFQm9/TVu3mvC+1GCFJv7C+n7oHSoxfSQL9RaxZZpN28wNk
Flja+HhBsfDKRH1YNE7eGn9mFwKBgQD+UvzLxg+MvS4+NRvyQfVFlloM0UsreGdQ
MmCSMQlQHaHkt8uOyOOFVty+yaBWoEtsPOxkl7xIa4C6pwXMOMtbNa6ytn95lx4N
zGqmhGf/M9bS0zQVfIHPPc4fChCprv1cuaHCZxeQU/sli3IfBiemjDchCnsX7VCZ
bxGD/w179QKBgCRSNkBfS9RfONwyXQu/Q44pN8sty6m7csI+ZzKpvCBr6AJkiDJL
rSCP1QU0Gp+j7+ZIsM2A6YjcgkbUMnWkyF8e55jiUmuWEFxG3C6fLVQGFhRxj186
SFeGZlMVQLoZxBVUuERcSE1XzvB2Rk+YU1G0GgBBK0S9E1ajt5CFOTwjAoGAYwuI
vgdVePcYMkvWpWNAlSg3y7QatUQ/4ACukWCdguD3cq6NjP75dK1ebMLzOalVlkKn
wYlCX2XWjVqMrHsV32Cpt5nRTVYn8zG/+zenlMDokdSE/TUvDLnCM15lHOA0dc8p
ix9BEwlRzs5e1Gw+NuN2eNyvEaNvd0HFLYXAB50CgYEA8NbrOtd+SNw2OoKR8LOQ
2oGXat87DEpyY4QqYzjNKsPmrKBb5FTfBIGc9JoeZyocXjFSXEHupICQTQ0PArFo
FgC/sVXhnXYJybMrtBLHqZSjEUlSvZK1hedhPIWU66Z6HPLSyDwwXAIP8uXmKVAu
1BhwUVBBQ2GUhLF76Hgj5Ws=
-----END PRIVATE KEY-----
# existingSecret: name-of-existing-secret-to-postgresql
keeper:
uid_prefix: "keeper"
replicaCount: 2
annotations: {}
resources: {}
priorityClassName: ""
fsGroup: "1000" # fsGroup要设置成启动pg的用户,要不然会报权限错误
service:
type: ClusterIP
annotations: {}
ports:
keeper:
port: 5432
targetPort: 5432
protocol: TCP
nodeSelector: {}
affinity: {}
tolerations: []
volumes: []
volumeMounts: []
hooks:
failKeeper:
enabled: false
podDisruptionBudget:
# minAvailable: 1
# maxUnavailable: 1
extraEnv: []
# - name: STKEEPER_LOG_LEVEL
# value: "info"
proxy:
replicaCount: 2
annotations: {}
resources: {}
priorityClassName: ""
service:
type: ClusterIP
# loadBalancerIP: ""
annotations: {}
ports:
proxy:
port: 5432
targetPort: 5432
protocol: TCP
nodeSelector: {}
affinity: {}
tolerations: []
podDisruptionBudget:
# minAvailable: 1
# maxUnavailable: 1
extraEnv: []
# - name: STPROXY_LOG_LEVEL
# value: "info"
# - name: STPROXY_TCP_KEEPALIVE_COUNT
# value: "0"
# - name: STPROXY_TCP_KEEPALIVE_IDLE
# value: "0"
# - name: STPROXY_TCP_KEEPALIVE_INTERVAL
# value: "0"
sentinel:
replicaCount: 2
annotations: {}
resources: {}
priorityClassName: ""
nodeSelector: {}
affinity: {}
tolerations: []
podDisruptionBudget:
# minAvailable: 1
# maxUnavailable: 1
extraEnv: []
# - name: STSENTINEL_LOG_LEVEL
# value: "info"
## initdb scripts
## Specify dictionary of scripts to be run at first boot, the entry point script is create_script.sh
## i.e. you can use pgsql to run sql script on the cluster.
##
# initdbScripts:
# create_script.sh: |
# #!/bin/sh
# echo "Do something."
## nodePostStart scripts
## Specify dictionary of scripts to be run at first boot, the entry point script is postStartScript.sh
## i.e. you can create tablespace directory here.
##
# nodePostStartScript:
# postStartScript.sh: |
# #!/bin/bash
# echo "Do something."
创建名称空间
[root@node1 stolon]# kubectl create ns ssl-stolon
namespace/ssl-stolon created
部署Chart
# 在项目目录下可以用dry-run测试一下看看可不可以运行
[root@node1 stolon]# helm install stolon --dry-run . -n ssl-stolon
# 没问题的话就可以直接部署了
# 使用-f 指定变量文件
[root@node1 stolon]# helm install sslstolon kvaps/stolon -f ./values.yaml -n ssl-stolon
查看pod
[root@node1 stolon]# kubectl get pods -n ssl-stolon
NAME READY STATUS RESTARTS AGE
sslstolon-create-cluster-x7bsn 0/1 Completed 0 45s
sslstolon-keeper-0 1/1 Running 0 45s
sslstolon-keeper-1 1/1 Running 0 35s
sslstolon-proxy-8685fdb4bd-457kr 1/1 Running 0 45s
sslstolon-proxy-8685fdb4bd-8rls7 1/1 Running 0 45s
sslstolon-sentinel-6cf9cb965f-fdz8k 1/1 Running 0 45s
sslstolon-sentinel-6cf9cb965f-zd6fm 1/1 Running 0 45s
postgres连接测试
[root@node1 stolon]# kubectl get service -n ssl-stolon
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
sslstolon-keeper-headless ClusterIP None <none> 5432/TCP 2m15s
sslstolon-proxy ClusterIP 10.108.57.55 <none> 5432/TCP 2m15s
# 可以看到下面有ssl连接的提示
[root@node1 stolon]# psql -h 10.108.57.55 -U stolon -d postgres
Password for user stolon:
psql (13.11, server 10.12 (Debian 10.12-1.pgdg90+1))
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
postgres=#
遇到的问题
问题一
2023-09-20T04:05:34.381Z INFO postgresql/postgresql.go:319 starting database
2023-09-20 04:05:34.454 UTC [74] FATAL: could not load server certificate file "/certs/serverCrt.crt": Permission denied
解决办法: 需要修改下fsGroup