Merge branch 'master' into default-db-roles
This commit is contained in:
commit
e2bf0fdedf
|
|
@ -87,6 +87,12 @@ rules:
|
|||
- list
|
||||
- watch
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ configKubernetes:
|
|||
# list of labels that can be inherited from the cluster manifest
|
||||
# inherited_labels:
|
||||
# - application
|
||||
# - app
|
||||
# - environment
|
||||
|
||||
# timeout for successful migration of master pods from unschedulable node
|
||||
# master_pod_move_timeout: 20m
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ configKubernetes:
|
|||
# infrastructure_roles_secret_name: postgresql-infrastructure-roles
|
||||
|
||||
# list of labels that can be inherited from the cluster manifest
|
||||
# inherited_labels: ""
|
||||
# inherited_labels: application,environment
|
||||
|
||||
# timeout for successful migration of master pods from unschedulable node
|
||||
# master_pod_move_timeout: 20m
|
||||
|
|
|
|||
|
|
@ -14,8 +14,9 @@ PG_BIN=$PG_DIR/$PG_VERSION/bin
|
|||
DUMP_SIZE_COEFF=5
|
||||
|
||||
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
|
||||
K8S_API_URL=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT/api/v1
|
||||
K8S_API_URL=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT
|
||||
CERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
CLUSTER_NAME_LABEL=cluster-name
|
||||
|
||||
function estimate_size {
|
||||
"$PG_BIN"/psql -tqAc "${ALL_DB_SIZE_QUERY}"
|
||||
|
|
@ -48,33 +49,63 @@ function aws_upload {
|
|||
function get_pods {
|
||||
declare -r SELECTOR="$1"
|
||||
|
||||
curl "${K8S_API_URL}/namespaces/${POD_NAMESPACE}/pods?$SELECTOR" \
|
||||
curl "${K8S_API_URL}/api/v1/namespaces/${POD_NAMESPACE}/pods?$SELECTOR" \
|
||||
--cacert $CERT \
|
||||
-H "Authorization: Bearer ${TOKEN}" | jq .items[].status.podIP -r
|
||||
}
|
||||
|
||||
function get_current_pod {
|
||||
curl "${K8S_API_URL}/namespaces/${POD_NAMESPACE}/pods?fieldSelector=metadata.name%3D${HOSTNAME}" \
|
||||
curl "${K8S_API_URL}/api/v1/namespaces/${POD_NAMESPACE}/pods?fieldSelector=metadata.name%3D${HOSTNAME}" \
|
||||
--cacert $CERT \
|
||||
-H "Authorization: Bearer ${TOKEN}"
|
||||
}
|
||||
|
||||
declare -a search_strategy=(
|
||||
get_cluster_name_label
|
||||
list_all_replica_pods_current_node
|
||||
list_all_replica_pods_any_node
|
||||
get_master_pod
|
||||
)
|
||||
|
||||
function get_config_resource() {
|
||||
curl "${K8S_API_URL}/apis/apps/v1/namespaces/default/deployments/postgres-operator" \
|
||||
--cacert $CERT \
|
||||
-H "Authorization: Bearer ${TOKEN}" | jq '.spec.template.spec.containers[0].env[] | select(.name == "$1") | .value'
|
||||
}
|
||||
|
||||
function get_cluster_name_label {
|
||||
local config
|
||||
local clustername
|
||||
|
||||
config=$(get_config_resource "CONFIG_MAP_NAME")
|
||||
if [ -n "$config" ]; then
|
||||
clustername=$(curl "${K8S_API_URL}/api/v1/namespaces/default/configmaps/${config}" \
|
||||
--cacert $CERT \
|
||||
-H "Authorization: Bearer ${TOKEN}" | jq '.data.cluster_name_label')
|
||||
else
|
||||
config=$(get_config_resource "POSTGRES_OPERATOR_CONFIGURATION_OBJECT")
|
||||
if [ -n "$config" ]; then
|
||||
clustername=$(curl "${K8S_API_URL}/apis/acid.zalan.do/v1/namespaces/default/operatorconfigurations/${config}" \
|
||||
--cacert $CERT \
|
||||
-H "Authorization: Bearer ${TOKEN}" | jq '.configuration.kubernetes.cluster_name_label')
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$clustername" ]; then
|
||||
CLUSTER_NAME_LABEL=${clustername}
|
||||
fi;
|
||||
}
|
||||
|
||||
function list_all_replica_pods_current_node {
|
||||
get_pods "labelSelector=version%3D${SCOPE},spilo-role%3Dreplica&fieldSelector=spec.nodeName%3D${CURRENT_NODENAME}" | head -n 1
|
||||
get_pods "labelSelector=${CLUSTER_NAME_LABEL}%3D${SCOPE},spilo-role%3Dreplica&fieldSelector=spec.nodeName%3D${CURRENT_NODENAME}" | head -n 1
|
||||
}
|
||||
|
||||
function list_all_replica_pods_any_node {
|
||||
get_pods "labelSelector=version%3D${SCOPE},spilo-role%3Dreplica" | head -n 1
|
||||
get_pods "labelSelector=${CLUSTER_NAME_LABEL}%3D${SCOPE},spilo-role%3Dreplica" | head -n 1
|
||||
}
|
||||
|
||||
function get_master_pod {
|
||||
get_pods "labelSelector=version%3D${SCOPE},spilo-role%3Dmaster" | head -n 1
|
||||
get_pods "labelSelector=${CLUSTER_NAME_LABEL}%3D${SCOPE},spilo-role%3Dmaster" | head -n 1
|
||||
}
|
||||
|
||||
CURRENT_NODENAME=$(get_current_pod | jq .items[].spec.nodeName --raw-output)
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ parameter of the PDB is set to `1` which prevents killing masters in single-node
|
|||
clusters and/or the last remaining running instance in a multi-node cluster.
|
||||
|
||||
The PDB is only relaxed in two scenarios:
|
||||
|
||||
* If a cluster is scaled down to `0` instances (e.g. for draining nodes)
|
||||
* If the PDB is disabled in the configuration (`enable_pod_disruption_budget`)
|
||||
|
||||
|
|
@ -200,6 +201,18 @@ Postgres cluster, in order to identify its child objects. The typical use case
|
|||
is to add labels that identifies the `Pods` created by the operator, in order
|
||||
to implement fine-controlled `NetworkPolicies`.
|
||||
|
||||
**postgres-operator ConfigMap**
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: postgres-operator
|
||||
data:
|
||||
inherited_labels: application,environment
|
||||
...
|
||||
```
|
||||
|
||||
**OperatorConfiguration**
|
||||
|
||||
```yaml
|
||||
|
|
@ -375,7 +388,7 @@ manifest. Notes:
|
|||
backup via `pg_dumpall` and upload of compressed and encrypted results to an S3
|
||||
bucket; the default image ``registry.opensource.zalan.do/acid/logical-backup``
|
||||
is the same image built with the Zalando-internal CI pipeline. `pg_dumpall`
|
||||
requires a `superuser` access to a DB and runs on the replica when possible.
|
||||
requires a `superuser` access to a DB and runs on the replica when possible.
|
||||
|
||||
2. Due to the [limitation of K8s cron jobs](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#cron-job-limitations)
|
||||
it is highly advisable to set up additional monitoring for this feature; such
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ is prepended to the operator resource's names.
|
|||
|
||||
Use `--name zalando` to match with the default service account name as older
|
||||
operator versions do not support custom names for service accounts. To use
|
||||
CRD-based configuration you need to specify the [values-crd yaml file](../charts/values-crd.yaml).
|
||||
CRD-based configuration you need to specify the [values-crd yaml file](../charts/postgres-operator/values-crd.yaml).
|
||||
|
||||
```bash
|
||||
# 1) initialize helm
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ apiVersion: "acid.zalan.do/v1"
|
|||
kind: postgresql
|
||||
metadata:
|
||||
name: acid-test-cluster
|
||||
# labels:
|
||||
# environment: demo
|
||||
spec:
|
||||
dockerImage: registry.opensource.zalan.do/acid/spilo-11:1.6-p1
|
||||
initContainers:
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ data:
|
|||
enable_teams_api: "false"
|
||||
# etcd_host: ""
|
||||
# infrastructure_roles_secret_name: postgresql-infrastructure-roles
|
||||
# inherited_labels: ""
|
||||
# inherited_labels: application,environment
|
||||
# kube_iam_role: ""
|
||||
# log_s3_bucket: ""
|
||||
# logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup"
|
||||
|
|
|
|||
|
|
@ -88,6 +88,12 @@ rules:
|
|||
- list
|
||||
- watch
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/exec
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ configuration:
|
|||
# infrastructure_roles_secret_name: ""
|
||||
# inherited_labels:
|
||||
# - application
|
||||
# - app
|
||||
# - environment
|
||||
# node_readiness_label: ""
|
||||
oauth_token_secret_name: postgresql-operator
|
||||
pdb_name_format: "postgres-{cluster}-pdb"
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ func (c *Cluster) deleteStatefulSet() error {
|
|||
return fmt.Errorf("could not delete pods: %v", err)
|
||||
}
|
||||
|
||||
if err := c.deletePersistenVolumeClaims(); err != nil {
|
||||
if err := c.deletePersistentVolumeClaims(); err != nil {
|
||||
return fmt.Errorf("could not delete PersistentVolumeClaims: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ func (c *Cluster) listPersistentVolumeClaims() ([]v1.PersistentVolumeClaim, erro
|
|||
return pvcs.Items, nil
|
||||
}
|
||||
|
||||
func (c *Cluster) deletePersistenVolumeClaims() error {
|
||||
func (c *Cluster) deletePersistentVolumeClaims() error {
|
||||
c.logger.Debugln("deleting PVCs")
|
||||
pvcs, err := c.listPersistentVolumeClaims()
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ type Controller struct {
|
|||
|
||||
PodServiceAccount *v1.ServiceAccount
|
||||
PodServiceAccountRoleBinding *rbacv1beta1.RoleBinding
|
||||
namespacesWithDefinedRBAC sync.Map
|
||||
}
|
||||
|
||||
// NewController creates a new controller
|
||||
|
|
|
|||
|
|
@ -493,17 +493,16 @@ func (c *Controller) postgresqlDelete(obj interface{}) {
|
|||
}
|
||||
|
||||
/*
|
||||
Ensures the pod service account and role bindings exists in a namespace before a PG cluster is created there so that a user does not have to deploy these credentials manually.
|
||||
StatefulSets require the service account to create pods; Patroni requires relevant RBAC bindings to access endpoints.
|
||||
Ensures the pod service account and role bindings exists in a namespace
|
||||
before a PG cluster is created there so that a user does not have to deploy
|
||||
these credentials manually. StatefulSets require the service account to
|
||||
create pods; Patroni requires relevant RBAC bindings to access endpoints.
|
||||
|
||||
The operator does not sync accounts/role bindings after creation.
|
||||
*/
|
||||
func (c *Controller) submitRBACCredentials(event ClusterEvent) error {
|
||||
|
||||
namespace := event.NewSpec.GetNamespace()
|
||||
if _, ok := c.namespacesWithDefinedRBAC.Load(namespace); ok {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := c.createPodServiceAccount(namespace); err != nil {
|
||||
return fmt.Errorf("could not create pod service account %v : %v", c.opConfig.PodServiceAccountName, err)
|
||||
|
|
@ -512,7 +511,6 @@ func (c *Controller) submitRBACCredentials(event ClusterEvent) error {
|
|||
if err := c.createRoleBindings(namespace); err != nil {
|
||||
return fmt.Errorf("could not create role binding %v : %v", c.PodServiceAccountRoleBinding.Name, err)
|
||||
}
|
||||
c.namespacesWithDefinedRBAC.Store(namespace, true)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue