diff --git a/ceph-client/Chart.yaml b/ceph-client/Chart.yaml new file mode 100644 index 000000000..225179ea7 --- /dev/null +++ b/ceph-client/Chart.yaml @@ -0,0 +1,18 @@ +# Copyright 2017 The Openstack-Helm Authors. +# +# 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. + +apiVersion: v1 +description: OpenStack-Helm Ceph Client +name: ceph-client +version: 0.1.0 diff --git a/ceph-client/requirements.yaml b/ceph-client/requirements.yaml new file mode 100644 index 000000000..53782e69b --- /dev/null +++ b/ceph-client/requirements.yaml @@ -0,0 +1,18 @@ +# Copyright 2017 The Openstack-Helm Authors. +# +# 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. + +dependencies: + - name: helm-toolkit + repository: http://localhost:8879/charts + version: 0.1.0 diff --git a/ceph-client/templates/bin/_bootstrap.sh.tpl b/ceph-client/templates/bin/_bootstrap.sh.tpl new file mode 100644 index 000000000..533c0a5a3 --- /dev/null +++ b/ceph-client/templates/bin/_bootstrap.sh.tpl @@ -0,0 +1,20 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex +{{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} diff --git a/ceph-client/templates/bin/_init-dirs.sh.tpl b/ceph-client/templates/bin/_init-dirs.sh.tpl new file mode 100644 index 000000000..dd186d4c0 --- /dev/null +++ b/ceph-client/templates/bin/_init-dirs.sh.tpl @@ -0,0 +1,46 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex +export LC_ALL=C +: "${HOSTNAME:=$(uname -n)}" +: "${MGR_NAME:=${HOSTNAME}}" +: "${MDS_NAME:=mds-${HOSTNAME}}" +: "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" +: "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" + +for keyring in ${OSD_BOOTSTRAP_KEYRING} ${MDS_BOOTSTRAP_KEYRING}; do + mkdir -p "$(dirname "$keyring")" +done + +# Let's create the ceph directories +for DIRECTORY in mds tmp mgr; do + mkdir -p "/var/lib/ceph/${DIRECTORY}" +done + +# Create socket directory +mkdir -p /run/ceph + +# Create the MDS directory +mkdir -p "/var/lib/ceph/mds/${CLUSTER}-${MDS_NAME}" + +# Create the MGR directory +mkdir -p "/var/lib/ceph/mgr/${CLUSTER}-${MGR_NAME}" + +# Adjust the owner of all those directories +chown -R ceph. /run/ceph/ /var/lib/ceph/* diff --git a/ceph-client/templates/bin/mds/_start.sh.tpl b/ceph-client/templates/bin/mds/_start.sh.tpl new file mode 100644 index 000000000..50128c76c --- /dev/null +++ b/ceph-client/templates/bin/mds/_start.sh.tpl @@ -0,0 +1,76 @@ +#!/bin/bash +set -ex +export LC_ALL=C +: "${HOSTNAME:=$(uname -n)}" +: "${CEPHFS_CREATE:=0}" +: "${CEPHFS_NAME:=cephfs}" +: "${CEPHFS_DATA_POOL:=${CEPHFS_NAME}_data}" +: "${CEPHFS_DATA_POOL_PG:=8}" +: "${CEPHFS_METADATA_POOL:=${CEPHFS_NAME}_metadata}" +: "${CEPHFS_METADATA_POOL_PG:=8}" +: "${MDS_NAME:=mds-${HOSTNAME}}" +: "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" +: "${MDS_KEYRING:=/var/lib/ceph/mds/${CLUSTER}-${MDS_NAME}/keyring}" +: "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" + +if [[ ! -e "/etc/ceph/${CLUSTER}.conf" ]]; then + echo "ERROR- /etc/ceph/${CLUSTER}.conf must exist; get it from your existing mon" + exit 1 +fi + +# Check to see if we are a new MDS +if [ ! -e "${MDS_KEYRING}" ]; then + + if [ -e "${ADMIN_KEYRING}" ]; then + KEYRING_OPT=(--name client.admin --keyring "${ADMIN_KEYRING}") + elif [ -e "${MDS_BOOTSTRAP_KEYRING}" ]; then + KEYRING_OPT=(--name client.bootstrap-mds --keyring "${MDS_BOOTSTRAP_KEYRING}") + else + echo "ERROR- Failed to bootstrap MDS: could not find admin or bootstrap-mds keyring. You can extract it from your current monitor by running 'ceph auth get client.bootstrap-mds -o ${MDS_BOOTSTRAP_KEYRING}" + exit 1 + fi + + timeout 10 ceph --cluster "${CLUSTER}" "${KEYRING_OPT[@]}" health || exit 1 + + # Generate the MDS key + ceph --cluster "${CLUSTER}" "${KEYRING_OPT[@]}" auth get-or-create "mds.${MDS_NAME}" osd 'allow rwx' mds 'allow' mon 'allow profile mds' -o "${MDS_KEYRING}" + chown ceph. "${MDS_KEYRING}" + chmod 600 "${MDS_KEYRING}" + +fi + +# NOTE (leseb): having the admin keyring is really a security issue +# If we need to bootstrap a MDS we should probably create the following on the monitors +# I understand that this handy to do this here +# but having the admin key inside every container is a concern + +# Create the Ceph filesystem, if necessary +if [ $CEPHFS_CREATE -eq 1 ]; then + + if [[ ! -e ${ADMIN_KEYRING} ]]; then + echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" + exit 1 + fi + + if [[ "$(ceph --cluster "${CLUSTER}" fs ls | grep -c name:.${CEPHFS_NAME},)" -eq 0 ]]; then + # Make sure the specified data pool exists + if ! ceph --cluster "${CLUSTER}" osd pool stats ${CEPHFS_DATA_POOL} > /dev/null 2>&1; then + ceph --cluster "${CLUSTER}" osd pool create ${CEPHFS_DATA_POOL} ${CEPHFS_DATA_POOL_PG} + fi + + # Make sure the specified metadata pool exists + if ! ceph --cluster "${CLUSTER}" osd pool stats ${CEPHFS_METADATA_POOL} > /dev/null 2>&1; then + ceph --cluster "${CLUSTER}" osd pool create ${CEPHFS_METADATA_POOL} ${CEPHFS_METADATA_POOL_PG} + fi + + ceph --cluster "${CLUSTER}" fs new ${CEPHFS_NAME} ${CEPHFS_METADATA_POOL} ${CEPHFS_DATA_POOL} + fi +fi + +# NOTE: prefixing this with exec causes it to die (commit suicide) +/usr/bin/ceph-mds \ + --cluster "${CLUSTER}" \ + --setuser "ceph" \ + --setgroup "ceph" \ + -d \ + -i "${MDS_NAME}" diff --git a/ceph-client/templates/bin/mgr/_check.sh.tpl b/ceph-client/templates/bin/mgr/_check.sh.tpl new file mode 100644 index 000000000..3520a633c --- /dev/null +++ b/ceph-client/templates/bin/mgr/_check.sh.tpl @@ -0,0 +1,42 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex +export LC_ALL=C + +COMMAND="${@:-liveness}" + +function heath_check () { + IS_MGR_AVAIL=$(ceph --cluster "${CLUSTER}" mgr dump | python -c "import json, sys; print json.load(sys.stdin)['available']") + + if [ "${IS_MGR_AVAIL}" = True ]; then + exit 0 + else + exit 1 + fi +} + +function liveness () { + heath_check +} + +function readiness () { + heath_check +} + +$COMMAND diff --git a/ceph-client/templates/bin/mgr/_start.sh.tpl b/ceph-client/templates/bin/mgr/_start.sh.tpl new file mode 100644 index 000000000..be622ac31 --- /dev/null +++ b/ceph-client/templates/bin/mgr/_start.sh.tpl @@ -0,0 +1,65 @@ +#!/bin/bash +set -ex +: "${CEPH_GET_ADMIN_KEY:=0}" +: "${MGR_NAME:=$(uname -n)}" +: "${MGR_KEYRING:=/var/lib/ceph/mgr/${CLUSTER}-${MGR_NAME}/keyring}" +: "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" + +if [[ ! -e /etc/ceph/${CLUSTER}.conf ]]; then + echo "ERROR- /etc/ceph/${CLUSTER}.conf must exist; get it from your existing mon" + exit 1 +fi + +if [ ${CEPH_GET_ADMIN_KEY} -eq 1 ]; then + if [[ ! -e ${ADMIN_KEYRING} ]]; then + echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" + exit 1 + fi +fi + +# Create a MGR keyring +rm -rf $MGR_KEYRING +if [ ! -e "$MGR_KEYRING" ]; then + # Create ceph-mgr key + timeout 10 ceph --cluster "${CLUSTER}" auth get-or-create mgr."${MGR_NAME}" mon 'allow profile mgr' osd 'allow *' mds 'allow *' -o "$MGR_KEYRING" + chown --verbose ceph. "$MGR_KEYRING" + chmod 600 "$MGR_KEYRING" +fi + +echo "SUCCESS" + +ceph --cluster "${CLUSTER}" -v + +# Env. variables matching the pattern "_" will be +# found and parsed for config-key settings by +# ceph config-key set mgr// +MODULES_TO_DISABLE=`ceph mgr dump | python -c "import json, sys; print ' '.join(json.load(sys.stdin)['modules'])"` + +for module in ${ENABLED_MODULES}; do + # This module may have been enabled in the past + # remove it from the disable list if present + MODULES_TO_DISABLE=${MODULES_TO_DISABLE/$module/} + + options=`env | grep ^${module}_ || true` + for option in ${options}; do + #strip module name + option=${option/${module}_/} + key=`echo $option | cut -d= -f1` + value=`echo $option | cut -d= -f2` + ceph --cluster "${CLUSTER}" config-key set mgr/$module/$key $value + done + ceph --cluster "${CLUSTER}" mgr module enable ${module} --force +done + +for module in $MODULES_TO_DISABLE; do + ceph --cluster "${CLUSTER}" mgr module disable ${module} +done + +echo "SUCCESS" +# start ceph-mgr +exec /usr/bin/ceph-mgr \ + --cluster "${CLUSTER}" \ + --setuser "ceph" \ + --setgroup "ceph" \ + -d \ + -i "${MGR_NAME}" diff --git a/ceph-client/templates/bin/pool/_calc.py.tpl b/ceph-client/templates/bin/pool/_calc.py.tpl new file mode 100644 index 000000000..897b0efd3 --- /dev/null +++ b/ceph-client/templates/bin/pool/_calc.py.tpl @@ -0,0 +1,46 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +{{/* +Copyright 2018 The Openstack-Helm Authors. + +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. +*/}} + +#NOTE(portdirect): this is a simple approximation of https://ceph.com/pgcalc/ + +import math +import sys + +replication = int(sys.argv[1]) +number_of_osds = int(sys.argv[2]) +percentage_data = float(sys.argv[3]) +target_pgs_per_osd = int(sys.argv[4]) + +raw_pg_num_opt = target_pgs_per_osd * number_of_osds \ + * (math.ceil(percentage_data) / 100.0) / replication + +raw_pg_num_min = number_of_osds / replication + +if raw_pg_num_min >= raw_pg_num_opt: + raw_pg_num = raw_pg_num_min +else: + raw_pg_num = raw_pg_num_opt + +max_pg_num = int(math.pow(2, math.ceil(math.log(raw_pg_num, 2)))) +min_pg_num = int(math.pow(2, math.floor(math.log(raw_pg_num, 2)))) + +if min_pg_num >= (raw_pg_num * 0.75): + print min_pg_num +else: + print max_pg_num diff --git a/ceph-client/templates/bin/pool/_init.sh.tpl b/ceph-client/templates/bin/pool/_init.sh.tpl new file mode 100644 index 000000000..5805f44cb --- /dev/null +++ b/ceph-client/templates/bin/pool/_init.sh.tpl @@ -0,0 +1,87 @@ +#!/bin/bash + +{{/* +Copyright 2018 The Openstack-Helm Authors. + +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 -ex +export LC_ALL=C + +: "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" +: "${OSD_TARGET_PGS:=100}" +: "${QUANTITY_OSDS:=15}" + +if [[ ! -e /etc/ceph/${CLUSTER}.conf ]]; then + echo "ERROR- /etc/ceph/${CLUSTER}.conf must exist; get it from your existing mon" + exit 1 +fi + +if [[ ! -e ${ADMIN_KEYRING} ]]; then + echo "ERROR- ${ADMIN_KEYRING} must exist; get it from your existing mon" + exit 1 +fi + +if ! ceph --cluster "${CLUSTER}" osd crush rule ls | grep -q "^same_host$"; then + ceph --cluster "${CLUSTER}" osd crush rule create-simple same_host default osd +fi + +function create_pool () { + POOL_APPLICATION=$1 + POOL_NAME=$2 + POOL_REPLICATION=$3 + POOL_PLACEMENT_GROUPS=$4 + POOL_CRUSH_RULE=$5 + if ! ceph --cluster "${CLUSTER}" osd pool stats "${POOL_NAME}" > /dev/null 2>&1; then + ceph --cluster "${CLUSTER}" osd pool create "${POOL_NAME}" ${POOL_PLACEMENT_GROUPS} + while [ $(ceph --cluster "${CLUSTER}" -s | grep creating -c) -gt 0 ]; do echo -n .;sleep 1; done + if [ "x${POOL_NAME}" == "xrbd" ]; then + rbd --cluster "${CLUSTER}" pool init ${POOL_NAME} + fi + ceph --cluster "${CLUSTER}" osd pool application enable "${POOL_NAME}" "${POOL_APPLICATION}" + fi + ceph --cluster "${CLUSTER}" osd pool set "${POOL_NAME}" size ${POOL_REPLICATION} + ceph --cluster "${CLUSTER}" osd pool set "${POOL_NAME}" crush_rule "${POOL_CRUSH_RULE}" + for PG_PARAM in pg_num pgp_num; do + CURRENT_PG_VALUE=$(ceph --cluster ceph osd pool get "${POOL_NAME}" "${PG_PARAM}" | awk "/^${PG_PARAM}:/ { print \$NF }") + if [ "${POOL_PLACEMENT_GROUPS}" -gt "${CURRENT_PG_VALUE}" ]; then + ceph --cluster ceph osd pool set "${POOL_NAME}" "${PG_PARAM}" "${POOL_PLACEMENT_GROUPS}" + fi + done +} + +function manage_pool () { + POOL_APPLICATION=$1 + POOL_NAME=$2 + POOL_REPLICATION=$3 + TOTAL_OSDS=$4 + TOTAL_DATA_PERCENT=$5 + TARGET_PG_PER_OSD=$6 + POOL_CRUSH_RULE=$7 + POOL_PLACEMENT_GROUPS=$(/tmp/pool-calc.py ${POOL_REPLICATION} ${TOTAL_OSDS} ${TOTAL_DATA_PERCENT} ${TARGET_PG_PER_OSD}) + create_pool "${POOL_APPLICATION}" "${POOL_NAME}" "${POOL_REPLICATION}" "${POOL_PLACEMENT_GROUPS}" "${POOL_CRUSH_RULE}" +} + +{{ $targetNumOSD := .Values.conf.pool.target.osd }} +{{ $targetPGperOSD := .Values.conf.pool.target.pg_per_osd }} +{{ $crushRuleDefault := .Values.conf.pool.default.crush_rule }} +{{- range $pool := .Values.conf.pool.spec -}} +{{- with $pool }} +manage_pool {{ .application }} {{ .name }} {{ .replication }} {{ $targetNumOSD }} {{ .percent_total_data }} {{ $targetPGperOSD }} {{ $crushRuleDefault }} +{{- end }} +{{- end }} + +{{- if .Values.conf.pool.crush.tunables }} +ceph --cluster "${CLUSTER}" osd crush tunables {{ .Values.conf.pool.crush.tunables }} +{{- end }} diff --git a/ceph-client/templates/configmap-bin.yaml b/ceph-client/templates/configmap-bin.yaml new file mode 100644 index 000000000..d4f31c0a8 --- /dev/null +++ b/ceph-client/templates/configmap-bin.yaml @@ -0,0 +1,51 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.configmap_bin .Values.deployment.ceph }} +{{- $envAll := . }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ceph-client-bin +data: +{{- if .Values.images.local_registry.active }} + image-repo-sync.sh: | +{{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} +{{- end }} + +{{- if .Values.bootstrap.enabled }} + bootstrap.sh: | +{{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{- end }} + + init-dirs.sh: | +{{ tuple "bin/_init-dirs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + + pool-init.sh: | +{{ tuple "bin/pool/_init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + pool-calc.py: | +{{ tuple "bin/pool/_calc.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + + mds-start.sh: | +{{ tuple "bin/mds/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + + mgr-start.sh: | +{{ tuple "bin/mgr/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + mgr-check.sh: | +{{ tuple "bin/mgr/_check.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + +{{- end }} diff --git a/ceph-client/templates/configmap-etc-client.yaml b/ceph-client/templates/configmap-etc-client.yaml new file mode 100644 index 000000000..7464532a3 --- /dev/null +++ b/ceph-client/templates/configmap-etc-client.yaml @@ -0,0 +1,56 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- define "ceph.configmap.etc" }} +{{- $configMapName := index . 0 }} +{{- $envAll := index . 1 }} +{{- with $envAll }} + +{{- if or (.Values.deployment.ceph) (.Values.deployment.client_secrets) }} + +{{- if empty .Values.conf.ceph.global.mon_host -}} +{{- $monHost := tuple "ceph_mon" "internal" "mon" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} +{{- $_ := $monHost | set .Values.conf.ceph.global "mon_host" -}} +{{- end -}} + +{{- if empty .Values.conf.ceph.global.mon_addr -}} +{{- $monPort := tuple "ceph_mon" "internal" "mon" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} +{{- $_ := printf ":%s" $monPort | set .Values.conf.ceph.global "mon_addr" -}} +{{- end -}} + +{{- if empty .Values.conf.ceph.osd.cluster_network -}} +{{- $_ := .Values.network.cluster | set .Values.conf.ceph.osd "cluster_network" -}} +{{- end -}} + +{{- if empty .Values.conf.ceph.osd.public_network -}} +{{- $_ := .Values.network.public | set .Values.conf.ceph.osd "public_network" -}} +{{- end -}} + +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $configMapName }} +data: + ceph.conf: | +{{ include "helm-toolkit.utils.to_ini" .Values.conf.ceph | indent 4 }} + +{{- end }} +{{- end }} +{{- end }} +{{- if .Values.manifests.configmap_etc }} +{{- list "ceph-client-etc" . | include "ceph.configmap.etc" }} +{{- end }} diff --git a/ceph-client/templates/deployment-mds.yaml b/ceph-client/templates/deployment-mds.yaml new file mode 100644 index 000000000..2118048e3 --- /dev/null +++ b/ceph-client/templates/deployment-mds.yaml @@ -0,0 +1,130 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.deployment_mds ( and .Values.deployment.ceph .Values.conf.features.mds) }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-mds"}} +{{ tuple $envAll "mds" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: ceph-mds + labels: +{{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + replicas: {{ .Values.pod.replicas.mds }} + selector: + matchLabels: +{{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} + template: + metadata: + name: ceph-mds + labels: +{{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + affinity: +{{ tuple $envAll "ceph" "mds" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ .Values.labels.mds.node_selector_key }}: {{ .Values.labels.mds.node_selector_value }} + initContainers: +{{ tuple $envAll "mds" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + - name: ceph-init-dirs +{{ tuple $envAll "ceph_mds" | include "helm-toolkit.snippets.image" | indent 10 }} + command: + - /tmp/init-dirs.sh + env: + - name: CLUSTER + value: "ceph" + volumeMounts: + - name: ceph-client-bin + mountPath: /tmp/init-dirs.sh + subPath: init-dirs.sh + readOnly: true + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + containers: + - name: ceph-mds +{{ tuple $envAll "ceph_mds" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.mds | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + command: + - /tmp/mds-start.sh + env: + - name: CLUSTER + value: "ceph" + - name: CEPHFS_CREATE + value: "1" + ports: + - containerPort: 6800 + livenessProbe: + tcpSocket: + port: 6800 + initialDelaySeconds: 60 + timeoutSeconds: 5 + readinessProbe: + tcpSocket: + port: 6800 + timeoutSeconds: 5 + volumeMounts: + - name: ceph-client-bin + mountPath: /tmp/mds-start.sh + subPath: mds-start.sh + readOnly: true + - name: ceph-client-etc + mountPath: /etc/ceph/ceph.conf + subPath: ceph.conf + readOnly: true + - name: ceph-client-admin-keyring + mountPath: /etc/ceph/ceph.client.admin.keyring + subPath: ceph.client.admin.keyring + readOnly: true + - name: ceph-bootstrap-mds-keyring + mountPath: /var/lib/ceph/bootstrap-mds/ceph.keyring + subPath: ceph.keyring + readOnly: false + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + volumes: + - name: ceph-client-etc + configMap: + name: ceph-client-etc + defaultMode: 0444 + - name: ceph-client-bin + configMap: + name: ceph-client-bin + defaultMode: 0555 + - name: pod-var-lib-ceph + emptyDir: {} + - name: pod-run + emptyDir: + medium: "Memory" + - name: ceph-client-admin-keyring + secret: + secretName: {{ .Values.secrets.keyrings.admin }} + - name: ceph-bootstrap-mds-keyring + secret: + secretName: {{ .Values.secrets.keyrings.mds }} +{{- end }} diff --git a/ceph-client/templates/deployment-mgr.yaml b/ceph-client/templates/deployment-mgr.yaml new file mode 100644 index 000000000..d81f7fda8 --- /dev/null +++ b/ceph-client/templates/deployment-mgr.yaml @@ -0,0 +1,166 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.deployment_mgr (and .Values.deployment.ceph .Values.conf.features.mgr ) }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-mgr"}} +{{ tuple $envAll "mgr" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: ceph-mgr + labels: +{{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + replicas: {{ .Values.pod.replicas.mgr }} + selector: + matchLabels: +{{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} + strategy: + type: Recreate + template: + metadata: + labels: +{{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + affinity: +{{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ .Values.labels.mgr.node_selector_key }}: {{ .Values.labels.mgr.node_selector_value }} + hostNetwork: true + dnsPolicy: {{ .Values.pod.dns_policy }} + initContainers: +{{ tuple $envAll "mgr" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + - name: ceph-init-dirs +{{ tuple $envAll "ceph_mds" | include "helm-toolkit.snippets.image" | indent 10 }} + command: + - /tmp/init-dirs.sh + env: + - name: CLUSTER + value: "ceph" + volumeMounts: + - name: ceph-client-bin + mountPath: /tmp/init-dirs.sh + subPath: init-dirs.sh + readOnly: true + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + - name: pod-etc-ceph + mountPath: /etc/ceph + containers: + - name: ceph-mgr +{{ tuple $envAll "ceph_mgr" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.mgr | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + env: + - name: CLUSTER + value: "ceph" + {{- if .Values.ceph_mgr_enabled_modules }} + - name: ENABLED_MODULES + value: |- + {{- range $value := .Values.ceph_mgr_enabled_modules }} + {{ $value }} + {{- end }} + {{- end }} + {{- if .Values.ceph_mgr_modules_config }} + {{- range $module,$params := .Values.ceph_mgr_modules_config }} + {{- range $key, $value := $params }} + - name: {{ $module }}_{{ $key }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + command: + - /mgr-start.sh + ports: + - name: mgr + containerPort: {{ tuple "ceph_mgr" "internal" "mgr" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + {{- if (has "prometheus" .Values.ceph_mgr_enabled_modules) }} + - name: metrics + containerPort: {{ tuple "ceph_mgr" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + {{ end -}} + livenessProbe: + exec: + command: + - /tmp/mgr-check.sh + - liveness + initialDelaySeconds: 30 + timeoutSeconds: 5 + readinessProbe: + exec: + command: + - /tmp/mgr-check.sh + - readiness + initialDelaySeconds: 30 + timeoutSeconds: 5 + volumeMounts: + - name: ceph-client-bin + mountPath: /mgr-start.sh + subPath: mgr-start.sh + readOnly: true + - name: ceph-client-bin + mountPath: /tmp/mgr-check.sh + subPath: mgr-check.sh + readOnly: true + - name: pod-etc-ceph + mountPath: /etc/ceph + - name: ceph-client-etc + mountPath: /etc/ceph/ceph.conf + subPath: ceph.conf + readOnly: true + - name: ceph-client-admin-keyring + mountPath: /etc/ceph/ceph.client.admin.keyring + subPath: ceph.client.admin.keyring + readOnly: true + - name: ceph-bootstrap-mgr-keyring + mountPath: /var/lib/ceph/bootstrap-mgr/ceph.keyring + subPath: ceph.keyring + readOnly: false + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + volumes: + - name: pod-etc-ceph + emptyDir: {} + - name: ceph-client-bin + configMap: + name: ceph-client-bin + defaultMode: 0555 + - name: ceph-client-etc + configMap: + name: ceph-client-etc + defaultMode: 0444 + - name: pod-var-lib-ceph + emptyDir: {} + - name: pod-run + emptyDir: + medium: "Memory" + - name: ceph-client-admin-keyring + secret: + secretName: {{ .Values.secrets.keyrings.admin }} + - name: ceph-bootstrap-mgr-keyring + secret: + secretName: {{ .Values.secrets.keyrings.mgr }} +{{- end }} diff --git a/ceph-client/templates/job-bootstrap.yaml b/ceph-client/templates/job-bootstrap.yaml new file mode 100644 index 000000000..72a935973 --- /dev/null +++ b/ceph-client/templates/job-bootstrap.yaml @@ -0,0 +1,70 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-client-bootstrap"}} +{{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: ceph-client-bootstrap +spec: + template: + metadata: + labels: +{{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + restartPolicy: OnFailure + nodeSelector: + {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} + initContainers: +{{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: ceph-client-bootstrap +{{ tuple $envAll "ceph_bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + command: + - /tmp/bootstrap.sh + volumeMounts: + - name: ceph-client-bin + mountPath: /tmp/bootstrap.sh + subPath: bootstrap.sh + readOnly: true + - name: ceph-client-etc + mountPath: /etc/ceph/ceph.conf + subPath: ceph.conf + readOnly: true + - name: ceph-client-admin-keyring + mountPath: /etc/ceph/ceph.client.admin.keyring + subPath: ceph.client.admin.keyring + readOnly: true + volumes: + - name: ceph-client-bin + configMap: + name: ceph-client-bin + defaultMode: 0555 + - name: ceph-client-etc + configMap: + name: ceph-client-etc + defaultMode: 0444 + - name: ceph-client-admin-keyring + secret: + secretName: {{ .Values.secrets.keyrings.admin }} +{{- end }} diff --git a/ceph-client/templates/job-image-repo-sync.yaml b/ceph-client/templates/job-image-repo-sync.yaml new file mode 100644 index 000000000..1814e9aef --- /dev/null +++ b/ceph-client/templates/job-image-repo-sync.yaml @@ -0,0 +1,20 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} +{{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ceph-client" -}} +{{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} +{{- end }} diff --git a/ceph-client/templates/job-rbd-pool.yaml b/ceph-client/templates/job-rbd-pool.yaml new file mode 100644 index 000000000..961321259 --- /dev/null +++ b/ceph-client/templates/job-rbd-pool.yaml @@ -0,0 +1,91 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.job_rbd_pool .Values.deployment.ceph }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-rbd-pool" }} +{{ tuple $envAll "rbd_pool" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: ceph-rbd-pool +spec: + template: + metadata: + name: ceph-rbd-pool + labels: +{{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + restartPolicy: OnFailure + affinity: +{{ tuple $envAll "ceph" "rbd-pool" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ $envAll.Values.labels.job.node_selector_key }}: {{ $envAll.Values.labels.job.node_selector_value }} + initContainers: +{{ tuple $envAll "rbd_pool" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: ceph-rbd-pool +{{ tuple $envAll "ceph_rbd_pool" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.mgr | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + env: + - name: CLUSTER + value: "ceph" + command: + - /tmp/pool-init.sh + volumeMounts: + - name: ceph-client-bin + mountPath: /tmp/pool-init.sh + subPath: pool-init.sh + readOnly: true + - name: ceph-client-bin + mountPath: /tmp/pool-calc.py + subPath: pool-calc.py + readOnly: true + - name: ceph-client-etc + mountPath: /etc/ceph/ceph.conf + subPath: ceph.conf + readOnly: true + - name: ceph-client-admin-keyring + mountPath: /etc/ceph/ceph.client.admin.keyring + subPath: ceph.client.admin.keyring + readOnly: true + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + volumes: + - name: ceph-client-etc + configMap: + name: ceph-client-etc + defaultMode: 0444 + - name: ceph-client-bin + configMap: + name: ceph-client-bin + defaultMode: 0555 + - name: pod-var-lib-ceph + emptyDir: {} + - name: pod-run + emptyDir: + medium: "Memory" + - name: ceph-client-admin-keyring + secret: + secretName: {{ .Values.secrets.keyrings.admin }} +{{- end }} diff --git a/ceph-client/templates/service-mgr.yaml b/ceph-client/templates/service-mgr.yaml new file mode 100644 index 000000000..3198e83d4 --- /dev/null +++ b/ceph-client/templates/service-mgr.yaml @@ -0,0 +1,42 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.service_mgr ( and .Values.deployment.ceph .Values.conf.features.mgr )}} +{{- $envAll := . }} +{{- $prometheus_annotations := $envAll.Values.monitoring.prometheus.ceph_mgr }} +--- +apiVersion: v1 +kind: Service +metadata: + name: ceph-mgr + annotations: +{{- if .Values.monitoring.prometheus.enabled }} +{{ tuple $prometheus_annotations | include "helm-toolkit.snippets.prometheus_service_annotations" | indent 4 }} +{{- end }} +spec: + ports: + - name: ceph-mgr + port: {{ tuple "ceph_mgr" "internal" "mgr" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + protocol: TCP + targetPort: {{ tuple "ceph_mgr" "internal" "mgr" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + {{ if (has "prometheus" .Values.ceph_mgr_enabled_modules) }} + - name: metrics + protocol: TCP + port: {{ tuple "ceph_mgr" "internal" "metrics" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + {{ end }} + selector: +{{ tuple $envAll "ceph" "mgr" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +{{- end }} diff --git a/ceph-client/values.yaml b/ceph-client/values.yaml new file mode 100644 index 000000000..218cb4879 --- /dev/null +++ b/ceph-client/values.yaml @@ -0,0 +1,374 @@ +# Copyright 2017 The Openstack-Helm Authors. +# +# 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. + +# Default values for ceph-client. +# This is a YAML-formatted file. +# Declare name/value pairs to be passed into your templates. +# name: value + +deployment: + ceph: true + +release_group: null + +images: + pull_policy: IfNotPresent + tags: + ceph_bootstrap: 'docker.io/ceph/daemon:tag-build-master-luminous-ubuntu-16.04' + ceph_config_helper: 'docker.io/port/ceph-config-helper:v1.10.3' + ceph_mds: 'docker.io/ceph/daemon:tag-build-master-luminous-ubuntu-16.04' + ceph_mgr: 'docker.io/ceph/daemon:tag-build-master-luminous-ubuntu-16.04' + ceph_rbd_pool: 'docker.io/port/ceph-config-helper:v1.10.3' + dep_check: 'quay.io/stackanetes/kubernetes-entrypoint:v0.3.1' + image_repo_sync: docker.io/docker:17.07.0 + local_registry: + active: false + exclude: + - dep_check + - image_repo_sync + +labels: + job: + node_selector_key: openstack-control-plane + node_selector_value: enabled + provisioner: + node_selector_key: openstack-control-plane + node_selector_value: enabled + mds: + node_selector_key: ceph-mds + node_selector_value: enabled + mgr: + node_selector_key: ceph-mgr + node_selector_value: enabled + +pod: + dns_policy: "ClusterFirstWithHostNet" + replicas: + mds: 2 + mgr: 2 + affinity: + anti: + type: + default: preferredDuringSchedulingIgnoredDuringExecution + topologyKey: + default: kubernetes.io/hostname + resources: + enabled: false + mds: + requests: + memory: "10Mi" + cpu: "250m" + limits: + memory: "50Mi" + cpu: "500m" + mgr: + requests: + memory: "5Mi" + cpu: "250m" + limits: + memory: "50Mi" + cpu: "500m" + jobs: + bootstrap: + limits: + memory: "1024Mi" + cpu: "2000m" + requests: + memory: "128Mi" + cpu: "500m" + image_repo_sync: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + +secrets: + keyrings: + mon: ceph-mon-keyring + mds: ceph-bootstrap-mds-keyring + osd: ceph-bootstrap-osd-keyring + rgw: ceph-bootstrap-rgw-keyring + mgr: ceph-bootstrap-mgr-keyring + admin: ceph-client-admin-keyring + +network: + public: 192.168.0.0/16 + cluster: 192.168.0.0/16 + +conf: + features: + mds: true + mgr: true + pool: + #NOTE(portdirect): this drives a simple approximation of + # https://ceph.com/pgcalc/, the `target.osd` key should be set to match the + # expected number of osds in a cluster, and the `target.pg_per_osd` should be + # set to match the desired number of placement groups on each OSD. + crush: + #NOTE(portdirect): to use RBD devices with Ubuntu 16.04's 4.4.x series + # kernel this should be set to `hammer` + tunables: null + target: + #NOTE(portdirect): arbitrarily we set the default number of expected OSD's to 5 + # to match the number of nodes in the OSH gate. + osd: 5 + pg_per_osd: 100 + default: + #NOTE(portdirect): this should be 'same_host' for a single node + # cluster to be in a healthy state + crush_rule: replicated_rule + #NOTE(portdirect): this section describes the pools that will be managed by + # the ceph pool management job, as it tunes the pgs and crush rule, based on + # the above. + spec: + # RBD pool + - name: rbd + application: rbd + replication: 3 + percent_total_data: 40 + # CephFS pools + - name: cephfs_metadata + application: cephfs + replication: 3 + percent_total_data: 5 + - name: cephfs_data + application: cephfs + replication: 3 + percent_total_data: 10 + # RadosGW pools + - name: .rgw.root + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.control + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.data.root + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.gc + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.log + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.intent-log + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.meta + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.usage + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.users.keys + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.users.email + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.users.swift + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.users.uid + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.buckets.extra + application: rgw + replication: 3 + percent_total_data: 0.1 + - name: default.rgw.buckets.index + application: rgw + replication: 3 + percent_total_data: 3 + - name: default.rgw.buckets.data + application: rgw + replication: 3 + percent_total_data: 34.8 + ceph: + global: + # auth + cephx: true + cephx_require_signatures: false + cephx_cluster_require_signatures: true + cephx_service_require_signatures: false + osd: + osd_mkfs_type: xfs + osd_mkfs_options_xfs: -f -i size=2048 + osd_max_object_name_len: 256 + ms_bind_port_min: 6800 + ms_bind_port_max: 7100 + +dependencies: + dynamic: + common: + local_image_registry: + jobs: + - ceph-client-image-repo-sync + services: + - endpoint: node + service: local_image_registry + static: + bootstrap: + jobs: null + services: + - endpoint: internal + service: ceph_mon + cephfs_client_key_generator: + jobs: null + cephfs_provisioner: + jobs: + - ceph-rbd-pool + services: + - endpoint: internal + service: ceph_mon + mds: + jobs: + - ceph-storage-keys-generator + - ceph-mds-keyring-generator + - ceph-rbd-pool + services: + - endpoint: internal + service: ceph_mon + mgr: + jobs: + - ceph-storage-keys-generator + - ceph-mgr-keyring-generator + services: + - endpoint: internal + service: ceph_mon + namespace_client_key_cleaner: + jobs: null + namespace_client_key_generator: + jobs: null + rbd_pool: + services: + - endpoint: internal + service: ceph_mon + rbd_provisioner: + jobs: + - ceph-rbd-pool + services: + - endpoint: internal + service: ceph_mon + image_repo_sync: + services: + - endpoint: internal + service: local_image_registry + +bootstrap: + enabled: false + script: | + ceph -s + function ensure_pool () { + ceph osd pool stats $1 || ceph osd pool create $1 $2 + local test_luminous=$(ceph tell osd.* version | egrep -c "12.2|luminous" | xargs echo) + if [[ ${test_luminous} -gt 0 ]]; then + ceph osd pool application enable $1 $3 + fi + } + #ensure_pool volumes 8 cinder + +# Uncomment below to enable mgr modules +# For a list of available modules: +# http://docs.ceph.com/docs/master/mgr/ +# This overrides mgr_initial_modules (default: restful, status) +# Any module not listed here will be disabled +ceph_mgr_enabled_modules: + - restful + - status + - prometheus + +# You can configure your mgr modules +# below. Each module has its own set +# of key/value. Refer to the doc +# above for more info. For example: +#ceph_mgr_modules_config: +# dashboard: +# port: 7000 +# localpool: +# failure_domain: host +# subtree: rack +# pg_num: "128" +# num_rep: "3" +# min_size: "2" + +endpoints: + cluster_domain_suffix: cluster.local + local_image_registry: + name: docker-registry + namespace: docker-registry + hosts: + default: localhost + internal: docker-registry + node: localhost + host_fqdn_override: + default: null + port: + registry: + node: 5000 + ceph_mon: + namespace: null + hosts: + default: ceph-mon + discovery: ceph-mon-discovery + host_fqdn_override: + default: null + port: + mon: + default: 6789 + ceph_mgr: + namespace: null + hosts: + default: ceph-mgr + host_fqdn_override: + default: null + port: + mgr: + default: 7000 + metrics: + default: 9283 + scheme: + default: http + +monitoring: + prometheus: + enabled: true + ceph_mgr: + scrape: true + port: 9283 + +manifests: + configmap_bin: true + configmap_etc: true + deployment_mds: true + deployment_mgr: true + job_bootstrap: false + job_cephfs_client_key: true + job_image_repo_sync: true + job_rbd_pool: true + service_mgr: true diff --git a/ceph-mon/Chart.yaml b/ceph-mon/Chart.yaml new file mode 100644 index 000000000..ba425831b --- /dev/null +++ b/ceph-mon/Chart.yaml @@ -0,0 +1,18 @@ +# Copyright 2017 The Openstack-Helm Authors. +# +# 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. + +apiVersion: v1 +description: OpenStack-Helm Ceph Mon +name: ceph-mon +version: 0.1.0 diff --git a/ceph-mon/requirements.yaml b/ceph-mon/requirements.yaml new file mode 100644 index 000000000..53782e69b --- /dev/null +++ b/ceph-mon/requirements.yaml @@ -0,0 +1,18 @@ +# Copyright 2017 The Openstack-Helm Authors. +# +# 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. + +dependencies: + - name: helm-toolkit + repository: http://localhost:8879/charts + version: 0.1.0 diff --git a/ceph-mon/templates/bin/_bootstrap.sh.tpl b/ceph-mon/templates/bin/_bootstrap.sh.tpl new file mode 100644 index 000000000..533c0a5a3 --- /dev/null +++ b/ceph-mon/templates/bin/_bootstrap.sh.tpl @@ -0,0 +1,20 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex +{{ .Values.bootstrap.script | default "echo 'Not Enabled'" }} diff --git a/ceph-mon/templates/bin/_init-dirs.sh.tpl b/ceph-mon/templates/bin/_init-dirs.sh.tpl new file mode 100644 index 000000000..5128888ba --- /dev/null +++ b/ceph-mon/templates/bin/_init-dirs.sh.tpl @@ -0,0 +1,46 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex +export LC_ALL=C +: "${HOSTNAME:=$(uname -n)}" +: "${MGR_NAME:=${HOSTNAME}}" +: "${MDS_NAME:=mds-${HOSTNAME}}" +: "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" +: "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" + +for keyring in ${OSD_BOOTSTRAP_KEYRING} ${MDS_BOOTSTRAP_KEYRING} ; do + mkdir -p "$(dirname "$keyring")" +done + +# Let's create the ceph directories +for DIRECTORY in mon osd mds radosgw tmp mgr; do + mkdir -p "/var/lib/ceph/${DIRECTORY}" +done + +# Create socket directory +mkdir -p /run/ceph + +# Create the MDS directory +mkdir -p "/var/lib/ceph/mds/${CLUSTER}-${MDS_NAME}" + +# Create the MGR directory +mkdir -p "/var/lib/ceph/mgr/${CLUSTER}-${MGR_NAME}" + +# Adjust the owner of all those directories +chown -R ceph. /run/ceph/ /var/lib/ceph/* diff --git a/ceph-mon/templates/bin/keys/_bootstrap-keyring-generator.py.tpl b/ceph-mon/templates/bin/keys/_bootstrap-keyring-generator.py.tpl new file mode 100644 index 000000000..a0a279c7b --- /dev/null +++ b/ceph-mon/templates/bin/keys/_bootstrap-keyring-generator.py.tpl @@ -0,0 +1,14 @@ +#!/bin/python +import os +import struct +import time +import base64 +key = os.urandom(16) +header = struct.pack( + ' +create_kube_key $(ceph_gen_key) ${CEPH_KEYRING_NAME} ${CEPH_KEYRING_TEMPLATE} ${KUBE_SECRET_NAME} + +{{ else }} + +echo "Not touching ${KUBE_SECRET_NAME} as this is not the initial deployment" + +{{- end -}} diff --git a/ceph-mon/templates/bin/keys/_storage-keyring-manager.sh.tpl b/ceph-mon/templates/bin/keys/_storage-keyring-manager.sh.tpl new file mode 100644 index 000000000..9521b3683 --- /dev/null +++ b/ceph-mon/templates/bin/keys/_storage-keyring-manager.sh.tpl @@ -0,0 +1,84 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex +{{ if .Release.IsInstall }} + +function ceph_gen_key () { + python ${CEPH_GEN_DIR}/keys-bootstrap-keyring-generator.py +} + +function kube_ceph_keyring_gen () { + CEPH_KEY=$1 + CEPH_KEY_TEMPLATE=$2 + sed "s|{{"{{"}} key {{"}}"}}|${CEPH_KEY}|" ${CEPH_TEMPLATES_DIR}/${CEPH_KEY_TEMPLATE} | base64 -w0 | tr -d '\n' +} + +CEPH_CLIENT_KEY=$(ceph_gen_key) + +function create_kube_key () { + CEPH_KEYRING=$1 + CEPH_KEYRING_NAME=$2 + CEPH_KEYRING_TEMPLATE=$3 + KUBE_SECRET_NAME=$4 + + if ! kubectl get --namespace ${DEPLOYMENT_NAMESPACE} secrets ${KUBE_SECRET_NAME}; then + { + cat < +create_kube_key ${CEPH_CLIENT_KEY} ${CEPH_KEYRING_NAME} ${CEPH_KEYRING_TEMPLATE} ${CEPH_KEYRING_ADMIN_NAME} + +function create_kube_storage_key () { + CEPH_KEYRING=$1 + KUBE_SECRET_NAME=$2 + + if ! kubectl get --namespace ${DEPLOYMENT_NAMESPACE} secrets ${KUBE_SECRET_NAME}; then + { + cat < +create_kube_storage_key ${CEPH_CLIENT_KEY} ${CEPH_STORAGECLASS_ADMIN_SECRET_NAME} + +{{ else }} + +echo "Not touching ${KUBE_SECRET_NAME} as this is not the initial deployment" + +{{ end }} diff --git a/ceph-mon/templates/bin/mon/_check.sh.tpl b/ceph-mon/templates/bin/mon/_check.sh.tpl new file mode 100644 index 000000000..e494540d9 --- /dev/null +++ b/ceph-mon/templates/bin/mon/_check.sh.tpl @@ -0,0 +1,63 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex +COMMAND="${@:-liveness}" +: ${K8S_HOST_NETWORK:=0} + +function heath_check () { + SOCKDIR=${CEPH_SOCKET_DIR:-/run/ceph} + SBASE=${CEPH_OSD_SOCKET_BASE:-ceph-mon} + SSUFFIX=${CEPH_SOCKET_SUFFIX:-asok} + + MON_ID=$(ps auwwx | grep ceph-mon | grep -v "$1" | grep -v grep | sed 's/.*-i\ //;s/\ .*//'|awk '{print $1}') + + if [ -z "${MON_ID}" ]; then + if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then + MON_NAME=${POD_NAME} + else + MON_NAME=${NODE_NAME} + fi + fi + + if [ -S "${SOCKDIR}/${SBASE}.${MON_NAME}.${SSUFFIX}" ]; then + MON_STATE=$(ceph -f json-pretty --connect-timeout 1 --admin-daemon "${sock}" mon_status|grep state|sed 's/.*://;s/[^a-z]//g') + echo "MON ${MON_ID} ${MON_STATE}"; + # this might be a stricter check than we actually want. what are the + # other values for the "state" field? + for S in ${MON_LIVE_STATE}; do + if [ "x${MON_STATE}x" = "x${S}x" ]; then + exit 0 + fi + done + fi + # if we made it this far, things are not running + exit 1 +} + +function liveness () { + MON_LIVE_STATE="probing electing synchronizing leader peon" + heath_check +} + +function readiness () { + MON_LIVE_STATE="leader peon" + heath_check +} + +$COMMAND diff --git a/ceph-mon/templates/bin/mon/_fluentbit-sidecar.sh.tpl b/ceph-mon/templates/bin/mon/_fluentbit-sidecar.sh.tpl new file mode 100644 index 000000000..f72e41de1 --- /dev/null +++ b/ceph-mon/templates/bin/mon/_fluentbit-sidecar.sh.tpl @@ -0,0 +1,19 @@ +#!/bin/sh +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex + +exec /fluent-bit/bin/fluent-bit -c /fluent-bit/etc/fluent-bit.conf diff --git a/ceph-mon/templates/bin/mon/_start.sh.tpl b/ceph-mon/templates/bin/mon/_start.sh.tpl new file mode 100644 index 000000000..ad2acc2c4 --- /dev/null +++ b/ceph-mon/templates/bin/mon/_start.sh.tpl @@ -0,0 +1,106 @@ +#!/bin/bash +set -ex +export LC_ALL=C +: "${K8S_HOST_NETWORK:=0}" +: "${MON_KEYRING:=/etc/ceph/${CLUSTER}.mon.keyring}" +: "${ADMIN_KEYRING:=/etc/ceph/${CLUSTER}.client.admin.keyring}" +: "${MDS_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-mds/${CLUSTER}.keyring}" +: "${OSD_BOOTSTRAP_KEYRING:=/var/lib/ceph/bootstrap-osd/${CLUSTER}.keyring}" + +if [[ -z "$CEPH_PUBLIC_NETWORK" ]]; then + echo "ERROR- CEPH_PUBLIC_NETWORK must be defined as the name of the network for the OSDs" + exit 1 +fi + +if [[ -z "$MON_IP" ]]; then + echo "ERROR- MON_IP must be defined as the IP address of the monitor" + exit 1 +fi + +if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then + MON_NAME=${POD_NAME} +else + MON_NAME=${NODE_NAME} +fi +MON_DATA_DIR="/var/lib/ceph/mon/${CLUSTER}-${MON_NAME}" +MONMAP="/etc/ceph/monmap-${CLUSTER}" + +# Make the monitor directory +su -s /bin/sh -c "mkdir -p \"${MON_DATA_DIR}\"" ceph + +function get_mon_config { + # Get fsid from ceph.conf + local fsid=$(ceph-conf --lookup fsid -c /etc/ceph/${CLUSTER}.conf) + + timeout=10 + MONMAP_ADD="" + + while [[ -z "${MONMAP_ADD// }" && "${timeout}" -gt 0 ]]; do + # Get the ceph mon pods (name and IP) from the Kubernetes API. Formatted as a set of monmap params + if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then + MONMAP_ADD=$(kubectl get pods --namespace=${NAMESPACE} ${KUBECTL_PARAM} -o template --template="{{`{{range .items}}`}}{{`{{if .status.podIP}}`}}--add {{`{{.metadata.name}}`}} {{`{{.status.podIP}}`}}:${MON_PORT} {{`{{end}}`}} {{`{{end}}`}}") + else + MONMAP_ADD=$(kubectl get pods --namespace=${NAMESPACE} ${KUBECTL_PARAM} -o template --template="{{`{{range .items}}`}}{{`{{if .status.podIP}}`}}--add {{`{{.spec.nodeName}}`}} {{`{{.status.podIP}}`}}:${MON_PORT} {{`{{end}}`}} {{`{{end}}`}}") + fi + (( timeout-- )) + sleep 1 + done + + if [[ -z "${MONMAP_ADD// }" ]]; then + exit 1 + fi + + # if monmap exists and the mon is already there, don't overwrite monmap + if [ -f "${MONMAP}" ]; then + monmaptool --print "${MONMAP}" |grep -q "${MON_IP// }"":${MON_PORT}" + if [ $? -eq 0 ]; then + echo "${MON_IP} already exists in monmap ${MONMAP}" + return + fi + fi + + # Create a monmap with the Pod Names and IP + monmaptool --create ${MONMAP_ADD} --fsid ${fsid} ${MONMAP} --clobber +} + +get_mon_config + +# If we don't have a monitor keyring, this is a new monitor +if [ ! -e "${MON_DATA_DIR}/keyring" ]; then + if [ ! -e ${MON_KEYRING}.seed ]; then + echo "ERROR- ${MON_KEYRING}.seed must exist. You can extract it from your current monitor by running 'ceph auth get mon. -o ${MON_KEYRING}' or use a KV Store" + exit 1 + else + cp -vf ${MON_KEYRING}.seed ${MON_KEYRING} + fi + + if [ ! -e ${MONMAP} ]; then + echo "ERROR- ${MONMAP} must exist. You can extract it from your current monitor by running 'ceph mon getmap -o ${MONMAP}' or use a KV Store" + exit 1 + fi + + # Testing if it's not the first monitor, if one key doesn't exist we assume none of them exist + for KEYRING in ${OSD_BOOTSTRAP_KEYRING} ${MDS_BOOTSTRAP_KEYRING} ${ADMIN_KEYRING}; do + ceph-authtool ${MON_KEYRING} --import-keyring ${KEYRING} + done + + # Prepare the monitor daemon's directory with the map and keyring + ceph-mon --setuser ceph --setgroup ceph --cluster "${CLUSTER}" --mkfs -i ${MON_NAME} --inject-monmap ${MONMAP} --keyring ${MON_KEYRING} --mon-data "${MON_DATA_DIR}" +else + echo "Trying to get the most recent monmap..." + # Ignore when we timeout, in most cases that means the cluster has no quorum or + # no mons are up and running yet + timeout 5 ceph --cluster "${CLUSTER}" mon getmap -o ${MONMAP} || true + ceph-mon --setuser ceph --setgroup ceph --cluster "${CLUSTER}" -i ${MON_NAME} --inject-monmap ${MONMAP} --keyring ${MON_KEYRING} --mon-data "${MON_DATA_DIR}" + timeout 7 ceph --cluster "${CLUSTER}" mon add "${MON_NAME}" "${MON_IP}:${MON_PORT}" || true +fi + +# start MON +exec /usr/bin/ceph-mon \ + --cluster "${CLUSTER}" \ + --setuser "ceph" \ + --setgroup "ceph" \ + -d \ + -i ${MON_NAME} \ + --mon-data "${MON_DATA_DIR}" \ + --public-addr "${MON_IP}:${MON_PORT}" diff --git a/ceph-mon/templates/bin/mon/_stop.sh.tpl b/ceph-mon/templates/bin/mon/_stop.sh.tpl new file mode 100644 index 000000000..8e4a3d59b --- /dev/null +++ b/ceph-mon/templates/bin/mon/_stop.sh.tpl @@ -0,0 +1,14 @@ +#!/bin/bash + +set -ex + +NUMBER_OF_MONS=$(ceph mon stat | awk '$3 == "mons" {print $2}') +if [ "${NUMBER_OF_MONS}" -gt "1" ]; then + if [[ ${K8S_HOST_NETWORK} -eq 0 ]]; then + ceph mon remove "${POD_NAME}" + else + ceph mon remove "${NODE_NAME}" + fi +else + echo "we are the last mon, not removing" +fi diff --git a/ceph-mon/templates/bin/moncheck/_reap-zombies.py.tpl b/ceph-mon/templates/bin/moncheck/_reap-zombies.py.tpl new file mode 100644 index 000000000..546f20c1f --- /dev/null +++ b/ceph-mon/templates/bin/moncheck/_reap-zombies.py.tpl @@ -0,0 +1,50 @@ +#!/usr/bin/python2 +import re +import os +import subprocess +import json + +MON_REGEX = r"^\d: ([0-9\.]*):\d+/\d* mon.([^ ]*)$" +# kubctl_command = 'kubectl get pods --namespace=${NAMESPACE} -l component=mon,application=ceph -o template --template="{ {{"}}"}}range .items{{"}}"}} \\"{{"}}"}}.metadata.name{{"}}"}}\\": \\"{{"}}"}}.status.podIP{{"}}"}}\\" , {{"}}"}}end{{"}}"}} }"' +if int(os.getenv('K8S_HOST_NETWORK', 0)) > 0: + kubectl_command = 'kubectl get pods --namespace=${NAMESPACE} -l component=mon,application=ceph -o template --template="{ {{"{{"}}range \$i, \$v := .items{{"}}"}} {{"{{"}} if \$i{{"}}"}} , {{"{{"}} end {{"}}"}} \\"{{"{{"}}\$v.spec.nodeName{{"}}"}}\\": \\"{{"{{"}}\$v.status.podIP{{"}}"}}\\" {{"{{"}}end{{"}}"}} }"' +else: + kubectl_command = 'kubectl get pods --namespace=${NAMESPACE} -l component=mon,application=ceph -o template --template="{ {{"{{"}}range \$i, \$v := .items{{"}}"}} {{"{{"}} if \$i{{"}}"}} , {{"{{"}} end {{"}}"}} \\"{{"{{"}}\$v.metadata.name{{"}}"}}\\": \\"{{"{{"}}\$v.status.podIP{{"}}"}}\\" {{"{{"}}end{{"}}"}} }"' + +monmap_command = "ceph --cluster=${NAMESPACE} mon getmap > /tmp/monmap && monmaptool -f /tmp/monmap --print" + + +def extract_mons_from_monmap(): + monmap = subprocess.check_output(monmap_command, shell=True) + mons = {} + for line in monmap.split("\n"): + m = re.match(MON_REGEX, line) + if m is not None: + mons[m.group(2)] = m.group(1) + return mons + +def extract_mons_from_kubeapi(): + kubemap = subprocess.check_output(kubectl_command, shell=True) + return json.loads(kubemap) + +current_mons = extract_mons_from_monmap() +expected_mons = extract_mons_from_kubeapi() + +print "current mons:", current_mons +print "expected mons:", expected_mons + +for mon in current_mons: + removed_mon = False + if not mon in expected_mons: + print "removing zombie mon ", mon + subprocess.call(["ceph", "--cluster", os.environ["NAMESPACE"], "mon", "remove", mon]) + removed_mon = True + elif current_mons[mon] != expected_mons[mon]: # check if for some reason the ip of the mon changed + print "ip change dedected for pod ", mon + subprocess.call(["kubectl", "--namespace", os.environ["NAMESPACE"], "delete", "pod", mon]) + removed_mon = True + print "deleted mon %s via the kubernetes api" % mon + + +if not removed_mon: + print "no zombie mons found ..." diff --git a/ceph-mon/templates/bin/moncheck/_start.sh.tpl b/ceph-mon/templates/bin/moncheck/_start.sh.tpl new file mode 100644 index 000000000..25d4159f7 --- /dev/null +++ b/ceph-mon/templates/bin/moncheck/_start.sh.tpl @@ -0,0 +1,14 @@ +#!/bin/bash +set -ex +export LC_ALL=C + +function watch_mon_health { + while [ true ]; do + echo "checking for zombie mons" + /tmp/moncheck-reap-zombies.py || true + echo "sleep 30 sec" + sleep 30 + done +} + +watch_mon_health diff --git a/ceph-mon/templates/configmap-bin.yaml b/ceph-mon/templates/configmap-bin.yaml new file mode 100644 index 000000000..e9945bf58 --- /dev/null +++ b/ceph-mon/templates/configmap-bin.yaml @@ -0,0 +1,61 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.configmap_bin .Values.deployment.ceph }} +{{- $envAll := . }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ceph-mon-bin +data: +{{- if .Values.images.local_registry.active }} + image-repo-sync.sh: | +{{- include "helm-toolkit.scripts.image_repo_sync" . | indent 4 }} +{{- end }} + +{{- if .Values.bootstrap.enabled }} + bootstrap.sh: | +{{ tuple "bin/_bootstrap.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{- end }} + + init-dirs.sh: | +{{ tuple "bin/_init-dirs.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + + keys-bootstrap-keyring-generator.py: | +{{ tuple "bin/keys/_bootstrap-keyring-generator.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + keys-bootstrap-keyring-manager.sh: | +{{ tuple "bin/keys/_bootstrap-keyring-manager.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + keys-storage-keyring-manager.sh: | +{{ tuple "bin/keys/_storage-keyring-manager.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + + mon-start.sh: | +{{ tuple "bin/mon/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + mon-stop.sh: | +{{ tuple "bin/mon/_stop.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + mon-check.sh: | +{{ tuple "bin/mon/_check.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + + moncheck-start.sh: | +{{ tuple "bin/moncheck/_start.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + moncheck-reap-zombies.py: | +{{ tuple "bin/moncheck/_reap-zombies.py.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + +{{ if .Values.logging.fluentd }} + fluentbit-sidecar.sh: | +{{ tuple "bin/mon/_fluentbit-sidecar.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} +{{ end }} +{{- end }} diff --git a/ceph-mon/templates/configmap-etc.yaml b/ceph-mon/templates/configmap-etc.yaml new file mode 100644 index 000000000..ac4b1e7b0 --- /dev/null +++ b/ceph-mon/templates/configmap-etc.yaml @@ -0,0 +1,73 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- define "ceph.configmap.etc" }} +{{- $configMapName := index . 0 }} +{{- $envAll := index . 1 }} +{{- with $envAll }} + +{{- if .Values.deployment.ceph }} + +{{- if empty .Values.conf.ceph.global.mon_host -}} +{{- $monHost := tuple "ceph_mon" "discovery" "mon" . | include "helm-toolkit.endpoints.host_and_port_endpoint_uri_lookup" }} +{{- $_ := $monHost | set .Values.conf.ceph.global "mon_host" -}} +{{- end -}} + +{{- if empty .Values.conf.ceph.global.mon_addr -}} +{{- $monPort := tuple "ceph_mon" "internal" "mon" . | include "helm-toolkit.endpoints.endpoint_port_lookup" }} +{{- $_ := printf ":%s" $monPort | set .Values.conf.ceph.global "mon_addr" -}} +{{- end -}} + +{{- if empty .Values.conf.ceph.global.fsid -}} +{{- $_ := uuidv4 | set .Values.conf.ceph.global "fsid" -}} +{{- end -}} + +{{- if empty .Values.conf.ceph.osd.cluster_network -}} +{{- $_ := .Values.network.cluster | set .Values.conf.ceph.osd "cluster_network" -}} +{{- end -}} + +{{- if empty .Values.conf.ceph.osd.public_network -}} +{{- $_ := .Values.network.public | set .Values.conf.ceph.osd "public_network" -}} +{{- end -}} + +{{- if not (has "fluentd_output" .Values.conf.fluentbit) -}} +{{- $fluentd_host := tuple "fluentd" "internal" $envAll | include "helm-toolkit.endpoints.hostname_namespaced_endpoint_lookup" }} +{{- $fluentd_port := tuple "fluentd" "internal" "service" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} +{{- $fluentd_output := dict "header" "output" "Name" "forward" "Match" "*" "Host" $fluentd_host "Port" $fluentd_port -}} +{{- $_ := set .Values "__fluentbit_config" ( list $fluentd_output) -}} +{{- $__fluentbit_config := append .Values.conf.fluentbit .Values.__fluentbit_config -}} +{{- $_ := set .Values.conf "fluentbit" $__fluentbit_config -}} +{{- end -}} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $configMapName }} +data: + ceph.conf: | +{{ include "helm-toolkit.utils.to_ini" .Values.conf.ceph | indent 4 }} +{{ if .Values.logging.fluentd }} + fluent-bit.conf: | +{{ include "ceph-mon.utils.to_fluentbit_conf" .Values.conf.fluentbit | indent 4 }} + parsers.conf: | +{{ include "ceph-mon.utils.to_fluentbit_conf" .Values.conf.parsers | indent 4 }} +{{ end }} +{{- end }} +{{- end }} +{{- end }} +{{- if .Values.manifests.configmap_etc }} +{{- list "ceph-mon-etc" . | include "ceph.configmap.etc" }} +{{- end }} diff --git a/ceph-mon/templates/configmap-templates.yaml b/ceph-mon/templates/configmap-templates.yaml new file mode 100644 index 000000000..43f460053 --- /dev/null +++ b/ceph-mon/templates/configmap-templates.yaml @@ -0,0 +1,35 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.configmap_templates .Values.deployment.storage_secrets }} +{{- $envAll := . }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: ceph-templates +data: + admin.keyring: | +{{ .Values.conf.templates.keyring.admin | indent 4 }} + mon.keyring: | +{{ .Values.conf.templates.keyring.mon | indent 4 }} + bootstrap.keyring.mds: | +{{ .Values.conf.templates.keyring.bootstrap.mds | indent 4 }} + bootstrap.keyring.mgr: | +{{ .Values.conf.templates.keyring.bootstrap.mgr | indent 4 }} + bootstrap.keyring.osd: | +{{ .Values.conf.templates.keyring.bootstrap.osd | indent 4 }} +{{- end }} diff --git a/ceph-mon/templates/daemonset-mon.yaml b/ceph-mon/templates/daemonset-mon.yaml new file mode 100644 index 000000000..1b388172a --- /dev/null +++ b/ceph-mon/templates/daemonset-mon.yaml @@ -0,0 +1,238 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.daemonset_mon .Values.deployment.ceph }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-mon"}} +{{ tuple $envAll "mon" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ $serviceAccountName }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ $serviceAccountName }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $serviceAccountName }} +subjects: + - kind: ServiceAccount + name: {{ $serviceAccountName }} + namespace: {{ $envAll.Release.Namespace }} +--- +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: ceph-mon + labels: +{{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + selector: + matchLabels: +{{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} + template: + metadata: + labels: +{{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + nodeSelector: + {{ .Values.labels.mon.node_selector_key }}: {{ .Values.labels.mon.node_selector_value }} + hostNetwork: true + dnsPolicy: {{ .Values.pod.dns_policy }} + initContainers: +{{ tuple $envAll "mon" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + - name: ceph-init-dirs +{{ tuple $envAll "ceph_mon" | include "helm-toolkit.snippets.image" | indent 10 }} + command: + - /tmp/init-dirs.sh + env: + - name: CLUSTER + value: "ceph" + volumeMounts: + - name: ceph-mon-bin + mountPath: /tmp/init-dirs.sh + subPath: init-dirs.sh + readOnly: true + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + containers: + - name: ceph-mon +{{ tuple $envAll "ceph_mon" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.mon | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + env: + - name: CLUSTER + value: "ceph" + - name: K8S_HOST_NETWORK + value: "1" + - name: MONMAP + value: /var/lib/ceph/mon/monmap + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: CEPH_PUBLIC_NETWORK + value: {{ .Values.network.public | quote }} + - name: KUBECTL_PARAM + value: {{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_kubectl_params" | indent 10 }} + - name: MON_PORT + value: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" | quote }} + - name: MON_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + command: + - /tmp/mon-start.sh + lifecycle: + preStop: + exec: + command: + - /tmp/mon-stop.sh + ports: + - containerPort: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + livenessProbe: + exec: + command: + - /tmp/mon-check.sh + - liveness + initialDelaySeconds: 360 + periodSeconds: 180 + readinessProbe: + exec: + command: + - /tmp/mon-check.sh + - readiness + initialDelaySeconds: 60 + periodSeconds: 60 + volumeMounts: + - name: ceph-mon-bin + mountPath: /tmp/mon-start.sh + subPath: mon-start.sh + readOnly: true + - name: ceph-mon-bin + mountPath: /tmp/mon-stop.sh + subPath: mon-stop.sh + readOnly: true + - name: ceph-mon-bin + mountPath: /tmp/mon-check.sh + subPath: mon-check.sh + readOnly: true + - name: ceph-mon-etc + mountPath: /etc/ceph/ceph.conf + subPath: ceph.conf + readOnly: true + - name: ceph-client-admin-keyring + mountPath: /etc/ceph/ceph.client.admin.keyring + subPath: ceph.client.admin.keyring + readOnly: true + - name: ceph-mon-keyring + mountPath: /etc/ceph/ceph.mon.keyring.seed + subPath: ceph.mon.keyring + readOnly: true + - name: ceph-bootstrap-osd-keyring + mountPath: /var/lib/ceph/bootstrap-osd/ceph.keyring + subPath: ceph.keyring + readOnly: true + - name: ceph-bootstrap-mds-keyring + mountPath: /var/lib/ceph/bootstrap-mds/ceph.keyring + subPath: ceph.keyring + readOnly: true + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + - name: varlog + mountPath: /var/log/ceph + {{ if .Values.logging.fluentd }} + - name: fluentbit-sidecar +{{ tuple $envAll "fluentbit" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.fluentbit | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + command: + - /tmp/fluentbit-sidecar.sh + volumeMounts: + - name: ceph-mon-bin + mountPath: /tmp/fluentbit-sidecar.sh + subPath: fluentbit-sidecar.sh + readOnly: true + - name: varlog + mountPath: /var/log/ceph + - name: ceph-mon-etc + mountPath: /fluent-bit/etc/fluent-bit.conf + subPath: fluent-bit.conf + readOnly: true + - name: ceph-mon-etc + mountPath: /fluent-bit/etc/parsers.conf + subPath: parsers.conf + readOnly: true + {{ end }} + volumes: + - name: varlog + emptyDir: {} + - name: ceph-mon-bin + configMap: + name: ceph-mon-bin + defaultMode: 0555 + - name: ceph-mon-etc + configMap: + name: ceph-mon-etc + defaultMode: 0444 + - name: pod-var-lib-ceph + hostPath: + path: {{ .Values.conf.storage.mon.directory }} + - name: pod-run + emptyDir: + medium: "Memory" + - name: ceph-client-admin-keyring + secret: + secretName: {{ .Values.secrets.keyrings.admin }} + - name: ceph-mon-keyring + secret: + secretName: {{ .Values.secrets.keyrings.mon }} + - name: ceph-bootstrap-osd-keyring + secret: + secretName: {{ .Values.secrets.keyrings.osd }} + - name: ceph-bootstrap-mds-keyring + secret: + secretName: {{ .Values.secrets.keyrings.mds }} +{{- end }} diff --git a/ceph-mon/templates/deployment-moncheck.yaml b/ceph-mon/templates/deployment-moncheck.yaml new file mode 100644 index 000000000..70f8e109a --- /dev/null +++ b/ceph-mon/templates/deployment-moncheck.yaml @@ -0,0 +1,111 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.deployment_moncheck .Values.deployment.ceph }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-mon-check"}} +{{ tuple $envAll "moncheck" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +kind: Deployment +apiVersion: apps/v1 +metadata: + name: ceph-mon-check + labels: +{{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} +spec: + replicas: {{ .Values.pod.replicas.mon_check }} + selector: + matchLabels: +{{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 6 }} + template: + metadata: + labels: +{{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + affinity: +{{ tuple $envAll "ceph" "moncheck" | include "helm-toolkit.snippets.kubernetes_pod_anti_affinity" | indent 8 }} + nodeSelector: + {{ .Values.labels.mon.node_selector_key }}: {{ .Values.labels.mon.node_selector_value }} + initContainers: +{{ tuple $envAll "moncheck" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: ceph-mon +{{ tuple $envAll "ceph_mon_check" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.moncheck | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + env: + - name: CLUSTER + value: "ceph" + - name: K8S_HOST_NETWORK + value: "1" + - name: NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + command: + - /tmp/moncheck-start.sh + ports: + - containerPort: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + volumeMounts: + - name: ceph-mon-bin + mountPath: /tmp/moncheck-start.sh + subPath: moncheck-start.sh + readOnly: true + - name: ceph-mon-bin + mountPath: /tmp/moncheck-reap-zombies.py + subPath: moncheck-reap-zombies.py + readOnly: true + - name: ceph-mon-etc + mountPath: /etc/ceph/ceph.conf + subPath: ceph.conf + readOnly: true + - name: ceph-client-admin-keyring + mountPath: /etc/ceph/ceph.client.admin.keyring + subPath: ceph.client.admin.keyring + readOnly: true + - name: ceph-mon-keyring + mountPath: /etc/ceph/ceph.mon.keyring + subPath: ceph.mon.keyring + readOnly: true + - name: pod-var-lib-ceph + mountPath: /var/lib/ceph + readOnly: false + - name: pod-run + mountPath: /run + readOnly: false + volumes: + - name: ceph-mon-etc + configMap: + name: ceph-mon-etc + defaultMode: 0444 + - name: ceph-mon-bin + configMap: + name: ceph-mon-bin + defaultMode: 0555 + - name: pod-var-lib-ceph + emptyDir: {} + - name: pod-run + emptyDir: + medium: "Memory" + - name: ceph-client-admin-keyring + secret: + secretName: {{ .Values.secrets.keyrings.admin }} + - name: ceph-mon-keyring + secret: + secretName: {{ .Values.secrets.keyrings.mon }} +{{- end }} diff --git a/ceph-mon/templates/job-bootstrap.yaml b/ceph-mon/templates/job-bootstrap.yaml new file mode 100644 index 000000000..76665038f --- /dev/null +++ b/ceph-mon/templates/job-bootstrap.yaml @@ -0,0 +1,70 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.job_bootstrap .Values.bootstrap.enabled }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-bootstrap"}} +{{ tuple $envAll "bootstrap" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: ceph-bootstrap +spec: + template: + metadata: + labels: +{{ tuple $envAll "ceph" "bootstrap" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + restartPolicy: OnFailure + nodeSelector: + {{ .Values.labels.job.node_selector_key }}: {{ .Values.labels.job.node_selector_value }} + initContainers: +{{ tuple $envAll "bootstrap" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: ceph-bootstrap +{{ tuple $envAll "ceph_bootstrap" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.jobs.bootstrap | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + command: + - /tmp/bootstrap.sh + volumeMounts: + - name: ceph-mon-bin + mountPath: /tmp/bootstrap.sh + subPath: bootstrap.sh + readOnly: true + - name: ceph-mon-etc + mountPath: /etc/ceph/ceph.conf + subPath: ceph.conf + readOnly: true + - name: ceph-client-admin-keyring + mountPath: /etc/ceph/ceph.client.admin.keyring + subPath: ceph.client.admin.keyring + readOnly: true + volumes: + - name: ceph-mon-bin + configMap: + name: ceph-mon-bin + defaultMode: 0555 + - name: ceph-mon-etc + configMap: + name: ceph-mon-etc + defaultMode: 0444 + - name: ceph-client-admin-keyring + secret: + secretName: {{ .Values.secrets.keyrings.admin }} +{{- end }} diff --git a/ceph-mon/templates/job-image-repo-sync.yaml b/ceph-mon/templates/job-image-repo-sync.yaml new file mode 100644 index 000000000..4a0b567a8 --- /dev/null +++ b/ceph-mon/templates/job-image-repo-sync.yaml @@ -0,0 +1,20 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.job_image_repo_sync .Values.images.local_registry.active }} +{{- $imageRepoSyncJob := dict "envAll" . "serviceName" "ceph-mon" -}} +{{ $imageRepoSyncJob | include "helm-toolkit.manifests.job_image_repo_sync" }} +{{- end }} diff --git a/ceph-mon/templates/job-keyring.yaml b/ceph-mon/templates/job-keyring.yaml new file mode 100644 index 000000000..30fb49e95 --- /dev/null +++ b/ceph-mon/templates/job-keyring.yaml @@ -0,0 +1,118 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.job_keyring .Values.deployment.storage_secrets }} +{{- $envAll := . }} +{{- range $key1, $cephBootstrapKey := tuple "mds" "osd" "mon" "mgr" }} +{{- $jobName := print $cephBootstrapKey "-keyring-generator" }} + +{{- $serviceAccountName := print "ceph-" $jobName }} +{{ tuple $envAll "job_keyring_generator" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ $serviceAccountName }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ $serviceAccountName }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $serviceAccountName }} +subjects: + - kind: ServiceAccount + name: {{ $serviceAccountName }} + namespace: {{ $envAll.Release.Namespace }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: ceph-{{ $jobName }} +spec: + template: + metadata: + labels: +{{ tuple $envAll "ceph" $jobName | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + restartPolicy: OnFailure + nodeSelector: + {{ $envAll.Values.labels.job.node_selector_key }}: {{ $envAll.Values.labels.job.node_selector_value }} + initContainers: +{{ tuple $envAll "job_keyring_generator" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: ceph-{{ $jobName }} +{{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.jobs.secret_provisioning | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + env: + - name: DEPLOYMENT_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CEPH_GEN_DIR + value: /tmp + - name: CEPH_TEMPLATES_DIR + value: /tmp/templates + {{- if eq $cephBootstrapKey "mon"}} + - name: CEPH_KEYRING_NAME + value: ceph.mon.keyring + - name: CEPH_KEYRING_TEMPLATE + value: mon.keyring + {{- else }} + - name: CEPH_KEYRING_NAME + value: ceph.keyring + - name: CEPH_KEYRING_TEMPLATE + value: bootstrap.keyring.{{ $cephBootstrapKey }} + {{- end }} + - name: KUBE_SECRET_NAME + value: {{ index $envAll.Values.secrets.keyrings $cephBootstrapKey }} + command: + - /tmp/keys-bootstrap-keyring-manager.sh + volumeMounts: + - name: ceph-mon-bin + mountPath: /tmp/keys-bootstrap-keyring-manager.sh + subPath: keys-bootstrap-keyring-manager.sh + readOnly: true + - name: ceph-mon-bin + mountPath: /tmp/keys-bootstrap-keyring-generator.py + subPath: keys-bootstrap-keyring-generator.py + readOnly: true + - name: ceph-templates + mountPath: /tmp/templates + readOnly: true + volumes: + - name: ceph-mon-bin + configMap: + name: ceph-mon-bin + defaultMode: 0555 + - name: ceph-templates + configMap: + name: ceph-templates + defaultMode: 0444 +{{- end }} +{{- end }} diff --git a/ceph-mon/templates/job-storage-admin-keys.yaml b/ceph-mon/templates/job-storage-admin-keys.yaml new file mode 100644 index 000000000..9f6f1e280 --- /dev/null +++ b/ceph-mon/templates/job-storage-admin-keys.yaml @@ -0,0 +1,110 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.job_storage_admin_keys .Values.deployment.storage_secrets }} +{{- $envAll := . }} + +{{- $serviceAccountName := "ceph-storage-keys-generator" }} +{{ tuple $envAll "storage_keys_generator" $serviceAccountName | include "helm-toolkit.snippets.kubernetes_pod_rbac_serviceaccount" }} +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: Role +metadata: + name: {{ $serviceAccountName }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create + - patch +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: RoleBinding +metadata: + name: {{ $serviceAccountName }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $serviceAccountName }} +subjects: + - kind: ServiceAccount + name: {{ $serviceAccountName }} + namespace: {{ $envAll.Release.Namespace }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: ceph-storage-keys-generator +spec: + template: + metadata: + labels: +{{ tuple $envAll "ceph" "storage-keys-generator" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 8 }} + spec: + serviceAccountName: {{ $serviceAccountName }} + restartPolicy: OnFailure + nodeSelector: + {{ $envAll.Values.labels.job.node_selector_key }}: {{ $envAll.Values.labels.job.node_selector_value }} + initContainers: +{{ tuple $envAll "storage_keys_generator" list | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + containers: + - name: ceph-storage-keys-generator +{{ tuple $envAll "ceph_config_helper" | include "helm-toolkit.snippets.image" | indent 10 }} +{{ tuple $envAll $envAll.Values.pod.resources.jobs.secret_provisioning | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + env: + - name: DEPLOYMENT_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CEPH_GEN_DIR + value: /tmp + - name: CEPH_TEMPLATES_DIR + value: /tmp/templates + - name: CEPH_KEYRING_NAME + value: ceph.client.admin.keyring + - name: CEPH_KEYRING_TEMPLATE + value: admin.keyring + - name: CEPH_KEYRING_ADMIN_NAME + value: {{ .Values.secrets.keyrings.admin }} + - name: CEPH_STORAGECLASS_ADMIN_SECRET_NAME + value: {{ .Values.storageclass.rbd.admin_secret_name }} + command: + - /tmp/keys-storage-keyring-manager.sh + volumeMounts: + - name: ceph-mon-bin + mountPath: /tmp/keys-storage-keyring-manager.sh + subPath: keys-storage-keyring-manager.sh + readOnly: true + - name: ceph-mon-bin + mountPath: /tmp/keys-bootstrap-keyring-generator.py + subPath: keys-bootstrap-keyring-generator.py + readOnly: true + - name: ceph-templates + mountPath: /tmp/templates + readOnly: true + volumes: + - name: ceph-mon-bin + configMap: + name: ceph-mon-bin + defaultMode: 0555 + - name: ceph-templates + configMap: + name: ceph-templates + defaultMode: 0444 +{{- end }} diff --git a/ceph-mon/templates/service-mon-discovery.yaml b/ceph-mon/templates/service-mon-discovery.yaml new file mode 100644 index 000000000..ffe2eacd0 --- /dev/null +++ b/ceph-mon/templates/service-mon-discovery.yaml @@ -0,0 +1,40 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.service_mon_discovery .Values.deployment.ceph }} +{{- $envAll := . }} +--- +kind: Service +apiVersion: v1 +metadata: + name: {{ tuple "ceph_mon" "discovery" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} + annotations: + # In kubernetes 1.6 and beyond, it seems there was a change in behavior + # requiring us to tolerate unready endpoints to form a quorum. I can only + # guess at some small timing change causing statefulset+2 to not see the + # now ready statefulset+1, and because we do not tolerate unready endpoints + # a newly provisioned ceph-mon will most certainly never see itself in the + # peer list. This change allows us to form a quorum reliably everytime + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +spec: + ports: + - port: {{ tuple "ceph_mon" "discovery" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + protocol: TCP + targetPort: {{ tuple "ceph_mon" "discovery" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + selector: +{{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} + clusterIP: None +{{- end }} diff --git a/ceph-mon/templates/service-mon.yaml b/ceph-mon/templates/service-mon.yaml new file mode 100644 index 000000000..c69aa82c1 --- /dev/null +++ b/ceph-mon/templates/service-mon.yaml @@ -0,0 +1,32 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +{{- if and .Values.manifests.service_mon .Values.deployment.ceph }} +{{- $envAll := . }} +--- +kind: Service +apiVersion: v1 +metadata: + name: {{ tuple "ceph_mon" "internal" . | include "helm-toolkit.endpoints.hostname_short_endpoint_lookup" }} +spec: + ports: + - port: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + protocol: TCP + targetPort: {{ tuple "ceph_mon" "internal" "mon" $envAll | include "helm-toolkit.endpoints.endpoint_port_lookup" }} + selector: +{{ tuple $envAll "ceph" "mon" | include "helm-toolkit.snippets.kubernetes_metadata_labels" | indent 4 }} + clusterIP: None +{{- end }} diff --git a/ceph-mon/templates/utils/_to_fluentbit_conf.tpl b/ceph-mon/templates/utils/_to_fluentbit_conf.tpl new file mode 100644 index 000000000..773120488 --- /dev/null +++ b/ceph-mon/templates/utils/_to_fluentbit_conf.tpl @@ -0,0 +1,38 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +# This function generates fluentbit configuration files with entries in the +# ceph-mon values.yaml. It results in a configuration section with the +# following format (for as many key/value pairs defined in values for a section): +# [HEADER] +# key value +# key value +# key value +# The configuration schema can be found here: +# http://fluentbit.io/documentation/0.12/configuration/schema.html + +{{- define "ceph-mon.utils.to_fluentbit_conf" -}} +{{- range $values := . -}} +{{- range $section := . -}} +{{- $header := pick . "header" -}} +{{- $config := omit . "header" }} +[{{$header.header | upper }}] +{{range $key, $value := $config -}} +{{ $key | indent 4 }} {{ $value }} +{{end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/ceph-mon/values.yaml b/ceph-mon/values.yaml new file mode 100644 index 000000000..757881864 --- /dev/null +++ b/ceph-mon/values.yaml @@ -0,0 +1,321 @@ +# Copyright 2017 The Openstack-Helm Authors. +# +# 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. + +# Default values for ceph-mon. +# This is a YAML-formatted file. +# Declare name/value pairs to be passed into your templates. +# name: value + +deployment: + ceph: true + storage_secrets: true + +images: + pull_policy: IfNotPresent + tags: + ceph_bootstrap: 'docker.io/ceph/daemon:tag-build-master-luminous-ubuntu-16.04' + ceph_config_helper: 'docker.io/port/ceph-config-helper:v1.10.3' + ceph_mon: 'docker.io/ceph/daemon:tag-build-master-luminous-ubuntu-16.04' + ceph_mon_check: 'docker.io/port/ceph-config-helper:v1.10.3' + fluentbit: docker.io/fluent/fluent-bit:0.12.14 + dep_check: 'quay.io/stackanetes/kubernetes-entrypoint:v0.3.1' + image_repo_sync: docker.io/docker:17.07.0 + local_registry: + active: false + exclude: + - dep_check + - image_repo_sync + +labels: + job: + node_selector_key: openstack-control-plane + node_selector_value: enabled + mon: + node_selector_key: ceph-mon + node_selector_value: enabled + +pod: + dns_policy: "ClusterFirstWithHostNet" + replicas: + mon_check: 1 + affinity: + anti: + type: + default: preferredDuringSchedulingIgnoredDuringExecution + topologyKey: + default: kubernetes.io/hostname + resources: + enabled: false + mon: + requests: + memory: "50Mi" + cpu: "250m" + limits: + memory: "100Mi" + cpu: "500m" + mon_check: + requests: + memory: "5Mi" + cpu: "250m" + limits: + memory: "50Mi" + cpu: "500m" + fluentbit: + requests: + memory: "5Mi" + cpu: "250m" + limits: + memory: "50Mi" + cpu: "500m" + jobs: + bootstrap: + limits: + memory: "1024Mi" + cpu: "2000m" + requests: + memory: "128Mi" + cpu: "500m" + secret_provisioning: + limits: + memory: "1024Mi" + cpu: "2000m" + requests: + memory: "128Mi" + cpu: "500m" + image_repo_sync: + requests: + memory: "128Mi" + cpu: "100m" + limits: + memory: "1024Mi" + cpu: "2000m" + +secrets: + keyrings: + mon: ceph-mon-keyring + mds: ceph-bootstrap-mds-keyring + osd: ceph-bootstrap-osd-keyring + mgr: ceph-bootstrap-mgr-keyring + admin: ceph-client-admin-keyring + +network: + public: 192.168.0.0/16 + cluster: 192.168.0.0/16 + +conf: + templates: + keyring: + admin: | + [client.admin] + key = {{ key }} + auid = 0 + caps mds = "allow" + caps mon = "allow *" + caps osd = "allow *" + caps mgr = "allow *" + mon: | + [mon.] + key = {{ key }} + caps mon = "allow *" + bootstrap: + mds: | + [client.bootstrap-mds] + key = {{ key }} + caps mon = "allow profile bootstrap-mds" + mgr: | + [client.bootstrap-mgr] + key = {{ key }} + caps mgr = "allow profile bootstrap-mgr" + osd: | + [client.bootstrap-osd] + key = {{ key }} + caps mon = "allow profile bootstrap-osd" + ceph: + global: + # auth + cephx: true + cephx_require_signatures: false + cephx_cluster_require_signatures: true + cephx_service_require_signatures: false + osd: + osd_mkfs_type: xfs + osd_mkfs_options_xfs: -f -i size=2048 + osd_max_object_name_len: 256 + ms_bind_port_min: 6800 + ms_bind_port_max: 7100 + storage: + mon: + directory: /var/lib/openstack-helm/ceph/mon + fluentbit: + - service: + header: service + Flush: 30 + Daemon: Off + Log_Level: info + Parsers_File: parsers.conf + - ceph_tail: + # NOTE(srwilkers): Despite being exposed, these values should not be + # modified, as the ceph-mon logs are always placed here + header: input + Name: tail + Tag: ceph-mon.* + Path: /var/log/ceph/*.log + Parser: syslog + DB: /var/log/ceph/ceph.db + DB.Sync: Normal + Buffer_Chunk_Size: 1M + Buffer_Max_Size: 1M + Mem_Buf_Limit: 5MB + Refresh_Interval: 10s + parsers: + - syslog: + header: parser + Name: syslog + Format: regex + Regex: '^(?