Skip to content

Instantly share code, notes, and snippets.

@elcolie
Created March 21, 2019 14:14
Show Gist options
  • Save elcolie/23c14ea4322e9de18c86e3a4d6df70f8 to your computer and use it in GitHub Desktop.
Save elcolie/23c14ea4322e9de18c86e3a4d6df70f8 to your computer and use it in GitHub Desktop.
sixteen:~ hellohbot$ helm get ipman
REVISION: 1
RELEASED: Wed Mar 20 18:34:51 2019
CHART: mongodb-replicaset-3.9.2
USER-SUPPLIED VALUES:
affinity: {}
clusterDomain: cluster.local
configmap: null
image:
debug: false
pullPolicy: Always
registry: docker.io
repository: bitnami/mongodb
tag: 4.0.6
initConfigMap: {}
livenessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
metrics:
enabled: false
extraArgs: ""
image:
pullPolicy: IfNotPresent
registry: docker.io
repository: forekshub/percona-mongodb-exporter
tag: latest
livenessProbe:
enabled: false
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 5
podAnnotations:
prometheus.io/port: "9216"
prometheus.io/scrape: "true"
readinessProbe:
enabled: false
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
serviceMonitor:
additionalLabels: {}
alerting:
additionalLabels: {}
rules: {}
enabled: false
mongodbDirectoryPerDB: false
mongodbDisableSystemLog: false
mongodbEnableIPv6: true
mongodbExtraFlags: []
mongodbPassword: 7JW7vZ5gVdrEhBuR
mongodbSystemLogVerbosity: 0
mongodbUsername: hbotdb
nodeSelector: {}
persistence:
accessModes:
- ReadWriteOnce
annotations: {}
enabled: true
size: 100Gi
podAnnotations: {}
podLabels: {}
readinessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
replicaSet:
enabled: false
name: rs0
pdb:
minAvailable:
arbiter: 1
primary: 1
secondary: 1
replicas:
arbiter: 1
secondary: 1
useHostnames: true
resources: {}
securityContext:
enabled: true
fsGroup: 1001
runAsUser: 1001
service:
annotations: {}
port: 27017
type: ClusterIP
tolerations: []
updateStrategy:
type: RollingUpdate
usePassword: true
COMPUTED VALUES:
affinity: {}
auth:
enabled: false
clusterDomain: cluster.local
copyConfigImage:
pullPolicy: IfNotPresent
repository: busybox
tag: 1.29.3
extraLabels: {}
extraVars: {}
image:
debug: false
pullPolicy: Always
registry: docker.io
repository: bitnami/mongodb
tag: 4.0.6
imagePullSecrets: []
init:
resources: {}
timeout: 900
initConfigMap: {}
installImage:
pullPolicy: IfNotPresent
repository: unguiculus/mongodb-install
tag: 0.7
livenessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 30
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
metrics:
enabled: false
extraArgs: ""
image:
pullPolicy: IfNotPresent
registry: docker.io
repository: forekshub/percona-mongodb-exporter
tag: latest
livenessProbe:
enabled: false
initialDelaySeconds: 15
periodSeconds: 5
timeoutSeconds: 5
path: /metrics
podAnnotations:
prometheus.io/port: "9216"
prometheus.io/scrape: "true"
port: 9216
prometheusServiceDiscovery: true
readinessProbe:
enabled: false
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 1
resources: {}
serviceMonitor:
additionalLabels: {}
alerting:
additionalLabels: {}
rules: {}
enabled: false
socketTimeout: 3s
syncTimeout: 1m
mongodbDirectoryPerDB: false
mongodbDisableSystemLog: false
mongodbEnableIPv6: true
mongodbExtraFlags: []
mongodbPassword: 7JW7vZ5gVdrEhBuR
mongodbSystemLogVerbosity: 0
mongodbUsername: hbotdb
nodeSelector: {}
persistence:
accessModes:
- ReadWriteOnce
annotations: {}
enabled: true
size: 100Gi
persistentVolume:
accessModes:
- ReadWriteOnce
annotations: {}
enabled: true
size: 10Gi
podAnnotations: {}
podDisruptionBudget: {}
podLabels: {}
port: 27017
readinessProbe:
enabled: true
failureThreshold: 6
initialDelaySeconds: 5
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 5
replicaSet:
enabled: false
name: rs0
pdb:
minAvailable:
arbiter: 1
primary: 1
secondary: 1
replicas:
arbiter: 1
secondary: 1
useHostnames: true
replicaSetName: rs0
replicas: 3
resources: {}
securityContext:
enabled: true
fsGroup: 1001
runAsNonRoot: true
runAsUser: 1001
service:
annotations: {}
port: 27017
type: ClusterIP
serviceAnnotations: {}
terminationGracePeriodSeconds: 30
tls:
enabled: false
tolerations: []
updateStrategy:
type: RollingUpdate
usePassword: true
HOOKS:
---
# ipman-mongodb-replicaset-test
apiVersion: v1
kind: Pod
metadata:
labels:
app: mongodb-replicaset
chart: mongodb-replicaset-3.9.2
heritage: Tiller
release: ipman
name: ipman-mongodb-replicaset-test
annotations:
"helm.sh/hook": test-success
spec:
initContainers:
- name: test-framework
image: dduportal/bats:0.4.0
command:
- bash
- -c
- |
set -ex
# copy bats to tools dir
cp -R /usr/local/libexec/ /tools/bats/
volumeMounts:
- name: tools
mountPath: /tools
containers:
- name: mongo
image: "bitnami/mongodb:4.0.6"
command:
- /tools/bats/bats
- -t
- /tests/mongodb-up-test.sh
env:
- name: FULL_NAME
value: ipman-mongodb-replicaset
- name: REPLICAS
value: "3"
volumeMounts:
- name: tools
mountPath: /tools
- name: tests
mountPath: /tests
volumes:
- name: tools
emptyDir: {}
- name: tests
configMap:
name: ipman-mongodb-replicaset-tests
restartPolicy: Never
MANIFEST:
---
# Source: mongodb-replicaset/templates/mongodb-init-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app: mongodb-replicaset
chart: mongodb-replicaset-3.9.2
heritage: Tiller
release: ipman
name: ipman-mongodb-replicaset-init
data:
on-start.sh: |
#!/usr/bin/env bash
# Copyright 2018 The Kubernetes Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set -e pipefail
port=27017
replica_set="$REPLICA_SET"
script_name=${0##*/}
SECONDS=0
timeout="${TIMEOUT:-900}"
if [[ "$AUTH" == "true" ]]; then
admin_user="$ADMIN_USER"
admin_password="$ADMIN_PASSWORD"
admin_creds=(-u "$admin_user" -p "$admin_password")
if [[ "$METRICS" == "true" ]]; then
metrics_user="$METRICS_USER"
metrics_password="$METRICS_PASSWORD"
fi
auth_args=("--auth" "--keyFile=/data/configdb/key.txt")
fi
log() {
local msg="$1"
local timestamp
timestamp=$(date --iso-8601=ns)
echo "[$timestamp] [$script_name] $msg" 2>&1 | tee -a /work-dir/log.txt 1>&2
}
retry_until() {
local host="${1}"
local command="${2}"
local expected="${3}"
local creds=("${admin_creds[@]}")
# Don't need credentials for admin user creation and pings that run on localhost
if [[ "${host}" =~ ^localhost ]]; then
creds=()
fi
until [[ $(mongo admin --host "${host}" "${creds[@]}" "${ssl_args[@]}" --quiet --eval "${command}") == "${expected}" ]]; do
sleep 1
if (! ps "${pid}" &>/dev/null); then
log "mongod shutdown unexpectedly"
exit 1
fi
if [[ "${SECONDS}" -ge "${timeout}" ]]; then
log "Timed out after ${timeout}s attempting to bootstrap mongod"
exit 1
fi
log "Retrying ${command} on ${host}"
done
}
shutdown_mongo() {
local host="${1:-localhost}"
local args='force: true'
log "Shutting down MongoDB ($args)..."
if (! mongo admin --host "${host}" "${admin_creds[@]}" "${ssl_args[@]}" --eval "db.shutdownServer({$args})"); then
log "db.shutdownServer() failed, sending the terminate signal"
kill -TERM "${pid}"
fi
}
init_mongod_standalone() {
if [[ ! -f /init/initMongodStandalone.js ]]; then
log "Skipping init mongod standalone script"
return 0
elif [[ -z "$(ls -1A /data/db)" ]]; then
log "mongod standalone script currently not supported on initial install"
return 0
fi
local port="27018"
log "Starting a MongoDB instance as standalone..."
mongod --config /data/configdb/mongod.conf --dbpath=/data/db "${auth_args[@]}" --port "${port}" --bind_ip=0.0.0.0 2>&1 | tee -a /work-dir/log.txt 1>&2 &
export pid=$!
trap shutdown_mongo EXIT
log "Waiting for MongoDB to be ready..."
retry_until "localhost:${port}" "db.adminCommand('ping').ok" "1"
log "Running init js script on standalone mongod"
mongo admin --port "${port}" "${admin_creds[@]}" "${ssl_args[@]}" /init/initMongodStandalone.js
shutdown_mongo "localhost:${port}"
}
my_hostname=$(hostname)
log "Bootstrapping MongoDB replica set member: $my_hostname"
log "Reading standard input..."
while read -ra line; do
if [[ "${line}" == *"${my_hostname}"* ]]; then
service_name="$line"
fi
peers=("${peers[@]}" "$line")
done
# Generate the ca cert
ca_crt=/data/configdb/tls.crt
if [ -f "$ca_crt" ]; then
log "Generating certificate"
ca_key=/data/configdb/tls.key
pem=/work-dir/mongo.pem
ssl_args=(--ssl --sslCAFile "$ca_crt" --sslPEMKeyFile "$pem")
# Move into /work-dir
pushd /work-dir
cat >openssl.cnf <<EOL
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = $(echo -n "$my_hostname" | sed s/-[0-9]*$//)
DNS.2 = $my_hostname
DNS.3 = $service_name
DNS.4 = localhost
DNS.5 = 127.0.0.1
EOL
# Generate the certs
openssl genrsa -out mongo.key 2048
openssl req -new -key mongo.key -out mongo.csr -subj "/OU=MongoDB/CN=$my_hostname" -config openssl.cnf
openssl x509 -req -in mongo.csr \
-CA "$ca_crt" -CAkey "$ca_key" -CAcreateserial \
-out mongo.crt -days 3650 -extensions v3_req -extfile openssl.cnf
rm mongo.csr
cat mongo.crt mongo.key > $pem
rm mongo.key mongo.crt
fi
init_mongod_standalone
log "Peers: ${peers[*]}"
log "Starting a MongoDB replica"
mongod --config /data/configdb/mongod.conf --dbpath=/data/db --replSet="$replica_set" --port="${port}" "${auth_args[@]}" --bind_ip=0.0.0.0 2>&1 | tee -a /work-dir/log.txt 1>&2 &
pid=$!
trap shutdown_mongo EXIT
log "Waiting for MongoDB to be ready..."
retry_until "localhost" "db.adminCommand('ping').ok" "1"
log "Initialized."
# try to find a master
for peer in "${peers[@]}"; do
log "Checking if ${peer} is primary"
# Check rs.status() first since it could be in primary catch up mode which db.isMaster() doesn't show
if [[ $(mongo admin --host "${peer}" "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "rs.status().myState") == "1" ]]; then
retry_until "${peer}" "db.isMaster().ismaster" "true"
log "Found primary: ${peer}"
primary="${peer}"
break
fi
done
if [[ "${primary}" = "${service_name}" ]]; then
log "This replica is already PRIMARY"
elif [[ -n "${primary}" ]]; then
if [[ $(mongo admin --host "${primary}" "${admin_creds[@]}" "${ssl_args[@]}" --quiet --eval "rs.conf().members.findIndex(m => m.host == '${service_name}:${port}')") == "-1" ]]; then
log "Adding myself (${service_name}) to replica set..."
if (mongo admin --host "${primary}" "${admin_creds[@]}" "${ssl_args[@]}" --eval "rs.add('${service_name}')" | grep 'Quorum check failed'); then
log 'Quorum check failed, unable to join replicaset. Exiting prematurely.'
exit 1
fi
fi
sleep 3
log 'Waiting for replica to reach SECONDARY state...'
retry_until "${service_name}" "rs.status().myState" "2"
log '✓ Replica reached SECONDARY state.'
elif (mongo "${ssl_args[@]}" --eval "rs.status()" | grep "no replset config has been received"); then
log "Initiating a new replica set with myself ($service_name)..."
mongo "${ssl_args[@]}" --eval "rs.initiate({'_id': '$replica_set', 'members': [{'_id': 0, 'host': '$service_name'}]})"
sleep 3
log 'Waiting for replica to reach PRIMARY state...'
retry_until "localhost" "db.isMaster().ismaster" "true"
primary="${service_name}"
log '✓ Replica reached PRIMARY state.'
if [[ "${AUTH}" == "true" ]]; then
log "Creating admin user..."
mongo admin "${ssl_args[@]}" --eval "db.createUser({user: '${admin_user}', pwd: '${admin_password}', roles: [{role: 'root', db: 'admin'}]})"
fi
fi
# User creation
if [[ -n "${primary}" && "$AUTH" == "true" && "$METRICS" == "true" ]]; then
metric_user_count=$(mongo admin --host "${primary}" "${admin_creds[@]}" "${ssl_args[@]}" --eval "db.system.users.find({user: '${metrics_user}'}).count()" --quiet)
if [[ "${metric_user_count}" == "0" ]]; then
log "Creating clusterMonitor user..."
mongo admin --host "${primary}" "${admin_creds[@]}" "${ssl_args[@]}" --eval "db.createUser({user: '${metrics_user}', pwd: '${metrics_password}', roles: [{role: 'clusterMonitor', db: 'admin'}, {role: 'read', db: 'local'}]})"
fi
fi
log "MongoDB bootstrap complete"
exit 0
---
# Source: mongodb-replicaset/templates/mongodb-mongodb-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app: mongodb-replicaset
chart: mongodb-replicaset-3.9.2
heritage: Tiller
release: ipman
name: ipman-mongodb-replicaset-mongodb
data:
mongod.conf: |
null
---
# Source: mongodb-replicaset/templates/tests/mongodb-up-test-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
app: mongodb-replicaset
chart: mongodb-replicaset-3.9.2
heritage: Tiller
release: ipman
name: ipman-mongodb-replicaset-tests
data:
mongodb-up-test.sh: |
#!/usr/bin/env bash
MONGOCACRT=/ca/tls.crt
MONGOPEM=/work-dir/mongo.pem
MONGOARGS="--quiet"
if [ -f "$MONGOPEM" ]; then
MONGOARGS="$MONGOARGS --ssl --sslCAFile $MONGOCACRT --sslPEMKeyFile $MONGOPEM"
fi
if [[ "${AUTH}" == "true" ]]; then
MONGOARGS="$MONGOARGS --username $ADMIN_USER --password $ADMIN_PASSWORD --authenticationDatabase admin"
fi
pod_name() {
local full_name="${FULL_NAME?Environment variable FULL_NAME not set}"
local index="$1"
echo "$full_name-$index.$full_name"
}
replicas() {
echo "${REPLICAS?Environment variable REPLICAS not set}"
}
master_pod() {
for ((i = 0; i < $(replicas); ++i)); do
response=$(mongo $MONGOARGS "--host=$(pod_name "$i")" "--eval=rs.isMaster().ismaster")
if [[ "$response" == "true" ]]; then
pod_name "$i"
break
fi
done
}
setup() {
local ready=0
until [[ "$ready" -eq $(replicas) ]]; do
echo "Waiting for application to become ready" >&2
sleep 1
for ((i = 0; i < $(replicas); ++i)); do
response=$(mongo $MONGOARGS "--host=$(pod_name "$i")" "--eval=rs.status().ok" || true)
if [[ "$response" -eq 1 ]]; then
ready=$((ready + 1))
fi
done
done
}
@test "Testing mongodb client is executable" {
mongo -h
[ "$?" -eq 0 ]
}
@test "Connect mongodb client to mongodb pods" {
for ((i = 0; i < $(replicas); ++i)); do
response=$(mongo $MONGOARGS "--host=$(pod_name "$i")" "--eval=rs.status().ok")
if [[ ! "$response" -eq 1 ]]; then
exit 1
fi
done
}
@test "Write key to primary" {
response=$(mongo $MONGOARGS --host=$(master_pod) "--eval=db.test.insert({\"abc\": \"def\"}).nInserted")
if [[ ! "$response" -eq 1 ]]; then
exit 1
fi
}
@test "Read key from slaves" {
# wait for slaves to catch up
sleep 10
for ((i = 0; i < $(replicas); ++i)); do
response=$(mongo $MONGOARGS --host=$(pod_name "$i") "--eval=rs.slaveOk(); db.test.find({\"abc\":\"def\"})")
if [[ ! "$response" =~ .*def.* ]]; then
exit 1
fi
done
# Clean up a document after test
mongo $MONGOARGS --host=$(master_pod) "--eval=db.test.deleteMany({\"abc\": \"def\"})"
}
---
# Source: mongodb-replicaset/templates/mongodb-service-client.yaml
# A headless service for client applications to use
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
app: mongodb-replicaset
chart: mongodb-replicaset-3.9.2
heritage: Tiller
release: ipman
name: ipman-mongodb-replicaset-client
spec:
type: ClusterIP
clusterIP: None
ports:
- name: mongodb
port: 27017
selector:
app: mongodb-replicaset
release: ipman
---
# Source: mongodb-replicaset/templates/mongodb-service.yaml
# A headless service to create DNS records for discovery purposes. Use the -client service to connect applications
apiVersion: v1
kind: Service
metadata:
annotations:
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
labels:
app: mongodb-replicaset
chart: mongodb-replicaset-3.9.2
heritage: Tiller
release: ipman
name: ipman-mongodb-replicaset
spec:
type: ClusterIP
clusterIP: None
ports:
- name: mongodb
port: 27017
publishNotReadyAddresses: true
selector:
app: mongodb-replicaset
release: ipman
---
# Source: mongodb-replicaset/templates/mongodb-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app: mongodb-replicaset
chart: mongodb-replicaset-3.9.2
heritage: Tiller
release: ipman
name: ipman-mongodb-replicaset
spec:
selector:
matchLabels:
app: mongodb-replicaset
release: ipman
serviceName: ipman-mongodb-replicaset
replicas: 3
template:
metadata:
labels:
app: mongodb-replicaset
release: ipman
annotations:
checksum/config: afadb760aa46c69ddecff43c11bfcec2bedf1f9e8e4fb924f54777c8f4c6a19b
spec:
securityContext:
runAsUser: 1001
fsGroup: 1001
runAsNonRoot: true
terminationGracePeriodSeconds: 30
initContainers:
- name: copy-config
image: "busybox:1.29.3"
imagePullPolicy: "IfNotPresent"
command:
- "sh"
args:
- "-c"
- |
set -e
set -x
cp /configdb-readonly/mongod.conf /data/configdb/mongod.conf
volumeMounts:
- name: workdir
mountPath: /work-dir
- name: config
mountPath: /configdb-readonly
- name: configdir
mountPath: /data/configdb
resources:
{}
- name: install
image: "unguiculus/mongodb-install:0.7"
args:
- --work-dir=/work-dir
imagePullPolicy: "IfNotPresent"
volumeMounts:
- name: workdir
mountPath: /work-dir
resources:
{}
- name: bootstrap
image: "bitnami/mongodb:4.0.6"
command:
- /work-dir/peer-finder
args:
- -on-start=/init/on-start.sh
- "-service=ipman-mongodb-replicaset"
imagePullPolicy: "Always"
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: REPLICA_SET
value: rs0
- name: TIMEOUT
value: "900"
volumeMounts:
- name: workdir
mountPath: /work-dir
- name: init
mountPath: /init
- name: configdir
mountPath: /data/configdb
- name: datadir
mountPath: /data/db
resources:
{}
containers:
- name: mongodb-replicaset
image: "bitnami/mongodb:4.0.6"
imagePullPolicy: "Always"
ports:
- name: mongodb
containerPort: 27017
resources:
{}
command:
- mongod
args:
- --config=/data/configdb/mongod.conf
- --dbpath=/data/db
- --replSet=rs0
- --port=27017
- --bind_ip=0.0.0.0
livenessProbe:
exec:
command:
- mongo
- --eval
- "db.adminCommand('ping')"
initialDelaySeconds: 30
timeoutSeconds: 5
failureThreshold: 6
periodSeconds: 10
successThreshold: 1
readinessProbe:
exec:
command:
- mongo
- --eval
- "db.adminCommand('ping')"
initialDelaySeconds: 5
timeoutSeconds: 5
failureThreshold: 6
periodSeconds: 10
successThreshold: 1
volumeMounts:
- name: datadir
mountPath: /data/db
- name: configdir
mountPath: /data/configdb
- name: workdir
mountPath: /work-dir
volumes:
- name: config
configMap:
name: ipman-mongodb-replicaset-mongodb
- name: init
configMap:
defaultMode: 0755
name: ipman-mongodb-replicaset-init
- name: workdir
emptyDir: {}
- name: configdir
emptyDir: {}
volumeClaimTemplates:
- metadata:
name: datadir
annotations:
spec:
accessModes:
- "ReadWriteOnce"
resources:
requests:
storage: "10Gi"
sixteen:~ hellohbot$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment