From: Borislav Glozman Date: Thu, 6 Feb 2020 08:46:04 +0000 (+0000) Subject: Merge "[COMMON] Create templates for services and PV" X-Git-Tag: 6.0.0~408 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=39180c61bcbd8785c84a1f9fd8ff30a6dc594e5d;hp=0ccdd6c9f20793ae46d0b39650d314e01ddec908;p=oom.git Merge "[COMMON] Create templates for services and PV" --- diff --git a/docs/oom_developer_guide.rst b/docs/oom_developer_guide.rst index a2ccc1ba60..c3fb603d04 100644 --- a/docs/oom_developer_guide.rst +++ b/docs/oom_developer_guide.rst @@ -79,159 +79,123 @@ have been created following the guidelines provided. The top level of the ONAP charts is shown below: -.. graphviz:: +.. code-block:: bash + + common + ├── cassandra + │   ├── Chart.yaml + │   ├── requirements.yaml + │   ├── resources + │   │   ├── config + │   │   │   └── docker-entrypoint.sh + │   │   ├── exec.py + │   │   └── restore.sh + │   ├── templates + │   │   ├── backup + │   │   │   ├── configmap.yaml + │   │   │   ├── cronjob.yaml + │   │   │   ├── pv.yaml + │   │   │   └── pvc.yaml + │   │   ├── configmap.yaml + │   │   ├── pv.yaml + │   │   ├── service.yaml + │   │   └── statefulset.yaml + │   └── values.yaml + ├── common + │   ├── Chart.yaml + │   ├── templates + │   │   ├── _createPassword.tpl + │   │   ├── _ingress.tpl + │   │   ├── _labels.tpl + │   │   ├── _mariadb.tpl + │   │   ├── _name.tpl + │   │   ├── _namespace.tpl + │   │   ├── _repository.tpl + │   │   ├── _resources.tpl + │   │   ├── _secret.yaml + │   │   ├── _service.tpl + │   │   ├── _storage.tpl + │   │   └── _tplValue.tpl + │   └── values.yaml + ├── ... + └── postgres-legacy +    ├── Chart.yaml +   ├── requirements.yaml + ├── charts + └── configs - digraph onap_top_chart { - rankdir="LR"; - { - node [shape=folder] - oValues [label="values.yaml"] - oChart [label="Chart.yaml"] - dev [label="dev.yaml"] - prod [label="prod.yaml"] - crb [label="clusterrolebindings.yaml"] - secrets [label="secrets.yaml"] - } - { - node [style=dashed] - vCom [label="component"] - } +The common section of charts consists of a set of templates that assist with +parameter substitution (`_name.tpl`, `_namespace.tpl` and others) and a set of charts +for components used throughout ONAP. When the common components are used by other charts they +are instantiated each time or we can deploy a shared instances for several components. - onap -> oValues - onap -> oChart - onap -> templates - onap -> resources - oValues -> vCom - resources -> environments - environments -> dev - environments -> prod - templates -> crb - templates -> secrets - } +All of the ONAP components have charts that follow the pattern shown below: -Within the `values.yaml` file at the `onap` level, one will find a set of -boolean values that control which of the ONAP components get deployed as shown -below: +.. code-block:: bash + + name-of-my-component + ├── Chart.yaml + ├── requirements.yaml + ├── component + │   └── subcomponent-folder + ├── charts + │   └── subchart-folder + ├── resources + │   ├── folder1 + │   │   ├── file1 + │   │   └── file2 + │   └── folder1 + │   ├── file3 + │   └── folder3 + │      └── file4 + ├── templates + │   ├── NOTES.txt + │   ├── configmap.yaml + │   ├── deployment.yaml + │   ├── ingress.yaml + │   ├── job.yaml + │   ├── secrets.yaml + │   └── service.yaml + └── values.yaml + +Note that the component charts / components may include a hierarchy of sub +components and in themselves can be quite complex. + +You can use either `charts` or `components` folder for your subcomponents. +`charts` folder means that the subcomponent will always been deployed. + +`components` folders means we can choose if we want to deploy the sub component. + +This choice is done in root `values.yaml`: .. code-block:: yaml - aaf: # Application Authorization Framework - enabled: false - <...> - so: # Service Orchestrator - enabled: true - -By setting these flags a custom deployment can be created and used during -deployment by using the `-f` Helm option as follows:: - - > helm install local/onap -name development -f dev.yaml - -Note that there are one or more example deployment files in the -`onap/resources/environments/` directory. It is best practice to create a -unique deployment file for each environment used to ensure consistent -behaviour. - -To aid in the long term supportability of ONAP, a set of common charts have -been created (and will be expanded in subsequent releases of ONAP) that can be -used by any of the ONAP components by including the common component in its -`requirements.yaml` file. The common components are arranged as follows: - -.. graphviz:: - - digraph onap_common_chart { - rankdir="LR"; - { - node [shape=folder] - mValues [label="values.yaml"] - ccValues [label="values.yaml"] - comValues [label="values.yaml"] - comChart [label="Chart.yaml"] - ccChart [label="Chart.yaml"] - mChart [label="Chart.yaml"] - - mReq [label="requirements.yaml"] - mService [label="service.yaml"] - mMap [label="configmap.yaml"] - ccName [label="_name.tpl"] - ccNS [label="_namespace.tpl"] - } - { - cCom [label="common"] - mTemp [label="templates"] - ccTemp [label="templates"] - } - { - more [label="...",style=dashed] - } - - common -> comValues - common -> comChart - common -> cCom - common -> mysql - common -> more - - cCom -> ccChart - cCom -> ccValues - cCom -> ccTemp - ccTemp -> ccName - ccTemp -> ccNS - - mysql -> mValues - mysql -> mChart - mysql -> mReq - mysql -> mTemp - mTemp -> mService - mTemp -> mMap - } + --- + global: + key: value -The common section of charts consists of a set of templates that assist with -parameter substitution (`_name.tpl` and `_namespace.tpl`) and a set of charts -for components used throughout ONAP. Initially `mysql` is in the common area -but this will expand to include other databases like `mariadb-galera`, -`postgres`, and `cassandra`. Other candidates for common components include -`redis` and`kafka`. When the common components are used by other charts they -are instantiated each time. In subsequent ONAP releases some of the common -components could be a setup as services that are used by multiple ONAP -components thus minimizing the deployment and operational costs. - -All of the ONAP components have charts that follow the pattern shown below: - -.. graphviz:: - - digraph onap_component_chart { - rankdir="LR"; - { - node [shape=folder] - cValues [label="values.yaml"] - cChart [label="Chart.yaml"] - cService [label="service.yaml"] - cMap [label="configmap.yaml"] - cFiles [label="config file(s)"] - } - { - cCharts [label="charts"] - cTemp [label="templates"] - cRes [label="resources"] + component1: + enabled: true + component2: + enabled: true - } - { - sCom [label="component",style=dashed] - } +Then in `requirements.yaml`, you'll use these values: - component -> cValues - component -> cChart - component -> cCharts - component -> cTemp - component -> cRes - cTemp -> cService - cTemp -> cMap - cRes -> config - config -> cFiles - cCharts -> sCom - } +.. code-block:: yaml -Note that the component charts may include a hierarchy of components and in -themselves can be quite complex. + --- + dependencies: + - name: common + version: ~x.y-0 + repository: '@local' + - name: component1 + version: ~x.y-0 + repository: 'file://components/component1' + condition: component1.enabled + - name: component2 + version: ~x.y-0 + repository: 'file://components/component2' + condition: component2.enabled Configuration of the components varies somewhat from component to component but generally follows the pattern of one or more `configmap.yaml` files which can @@ -260,126 +224,134 @@ configuration as well as ONAP components configuration. One of the artifacts that OOM/Kubernetes uses to deploy ONAP components is the deployment specification, yet another yaml file. Within these deployment specs -are a number of parameters as shown in the following mariadb example: +are a number of parameters as shown in the following example: .. code-block:: yaml - apiVersion: extensions/v1beta1 - kind: Deployment + apiVersion: apps/v1 + kind: StatefulSet metadata: - name: mariadb + labels: + app.kubernetes.io/name: zookeeper + helm.sh/chart: zookeeper + app.kubernetes.io/component: server + app.kubernetes.io/managed-by: Tiller + app.kubernetes.io/instance: onap-oof + name: onap-oof-zookeeper + namespace: onap spec: - <...> + <...> + replicas: 3 + selector: + matchLabels: + app.kubernetes.io/name: zookeeper + app.kubernetes.io/component: server + app.kubernetes.io/instance: onap-oof + serviceName: onap-oof-zookeeper-headless template: - <...> + metadata: + labels: + app.kubernetes.io/name: zookeeper + helm.sh/chart: zookeeper + app.kubernetes.io/component: server + app.kubernetes.io/managed-by: Tiller + app.kubernetes.io/instance: onap-oof spec: - hostname: mariadb + <...> + affinity: containers: - - args: - image: nexus3.onap.org:10001/mariadb:10.1.11 - name: "mariadb" - env: - - name: MYSQL_ROOT_PASSWORD - value: password - - name: MARIADB_MAJOR - value: "10.1" + - name: zookeeper + <...> + image: gcr.io/google_samples/k8szk:v3 + imagePullPolicy: Always <...> - imagePullSecrets: - - name: onap-docker-registry-key - -Note that within the deployment specification, one of the container arguments -is the key/value pair image: nexus3.onap.org:10001/mariadb:10.1.11 which -specifies the version of the mariadb software to deploy. Although the -deployment specifications greatly simplify deployment, maintenance of the -deployment specifications themselves become problematic as software versions + ports: + - containerPort: 2181 + name: client + protocol: TCP + - containerPort: 3888 + name: election + protocol: TCP + - containerPort: 2888 + name: server + protocol: TCP + <...> + +Note that within the statefulset specification, one of the container arguments +is the key/value pair image: gcr.io/google_samples/k8szk:v3 which +specifies the version of the zookeeper software to deploy. Although the +statefulset specifications greatly simplify statefulset, maintenance of the +statefulset specifications themselves become problematic as software versions change over time or as different versions are required for different -deployments. For example, if the R&D team needs to deploy a newer version of +statefulsets. For example, if the R&D team needs to deploy a newer version of mariadb than what is currently used in the production environment, they would -need to clone the deployment specification and change this value. Fortunately, +need to clone the statefulset specification and change this value. Fortunately, this problem has been solved with the templating capabilities of Helm. -The following example shows how the deployment specifications are modified to +The following example shows how the statefulset specifications are modified to incorporate Helm templates such that key/value pairs can be defined outside of -the deployment specifications and passed during instantiation of the component. +the statefulset specifications and passed during instantiation of the component. .. code-block:: yaml - apiVersion: extensions/v1beta1 - kind: Deployment + apiVersion: apps/v1 + kind: StatefulSet metadata: - name: mariadb - namespace: "{{ .Values.nsPrefix }}-mso" + name: {{ include "common.fullname" . }} + namespace: {{ include "common.namespace" . }} + labels: {{- include "common.labels" . | nindent 4 }} spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: {{- include "common.matchLabels" . | nindent 6 }} + # serviceName is only needed for StatefulSet + # put the postfix part only if you have add a postfix on the service name + serviceName: {{ include "common.servicename" . }}-{{ .Values.service.postfix }} <...> template: - <...> + metadata: + labels: {{- include "common.labels" . | nindent 8 }} + annotations: {{- include "common.tplValue" (dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + name: {{ include "common.name" . }} spec: - hostname: mariadb - containers: - - args: - image: {{ .Values.image.mariadb }} - imagePullPolicy: {{ .Values.pullPolicy }} - name: "mariadb" - env: - - name: MYSQL_ROOT_PASSWORD - value: password - - name: MARIADB_MAJOR - value: "10.1" <...> - imagePullSecrets: - - name: "{{ .Values.nsPrefix }}-docker-registry-key"apiVersion: extensions/v1beta1 - kind: Deployment - metadata: - name: mariadb - namespace: "{{ .Values.nsPrefix }}-mso" - spec: - <...> - template: - <...> - spec: - hostname: mariadb containers: - - args: - image: {{ .Values.image.mariadb }} - imagePullPolicy: {{ .Values.pullPolicy }} - name: "mariadb" - env: - - name: MYSQL_ROOT_PASSWORD - value: password - - name: MARIADB_MAJOR - value: "10.1" - <...> - imagePullSecrets: - - name: "{{ .Values.nsPrefix }}-docker-registry-key" - -This version of the deployment specification has gone through the process of -templating values that are likely to change between deployments. Note that the -image is now specified as: image: {{ .Values.image.mariadb }} instead of a -string used previously. During the deployment phase, Helm (actually the Helm + - name: {{ include "common.name" . }} + image: {{ .Values.image }} + imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} + ports: + {{- range $index, $port := .Values.service.ports }} + - containerPort: {{ $port.port }} + name: {{ $port.name }} + {{- end }} + {{- range $index, $port := .Values.service.headlessPorts }} + - containerPort: {{ $port.port }} + name: {{ $port.name }} + {{- end }} + <...> + +This version of the statefulset specification has gone through the process of +templating values that are likely to change between statefulsets. Note that the +image is now specified as: image: {{ .Values.image }} instead of a +string used previously. During the statefulset phase, Helm (actually the Helm sub-component Tiller) substitutes the {{ .. }} entries with a variable defined in a values.yaml file. The content of this file is as follows: .. code-block:: yaml - nsPrefix: onap - pullPolicy: IfNotPresent - image: - readiness: oomk8s/readiness-check:2.0.0 - mso: nexus3.onap.org:10001/openecomp/mso:1.0-STAGING-latest - mariadb: nexus3.onap.org:10001/mariadb:10.1.11 + <...> + image: gcr.io/google_samples/k8szk:v3 + replicaCount: 3 + <...> + -Within the values.yaml file there is an image section with the key/value pair -mariadb: nexus3.onap.org:10001/mariadb:10.1.11 which is the same value used in +Within the values.yaml file there is an image key with the value +`gcr.io/google_samples/k8szk:v3` which is the same value used in the non-templated version. Once all of the substitutions are complete, the -resulting deployment specification ready to be used by Kubernetes. - -Also note that in this example, the namespace key/value pair is specified in -the values.yaml file. This key/value pair will be global across the entire -ONAP deployment and is therefore a prime example of where configuration -hierarchy can be very useful. +resulting statefulset specification ready to be used by Kubernetes. -When creating a deployment template consider the use of default values if -appropriate. Helm templating has built in support for DEFAULT values, here is +When creating a template consider the use of default values if appropriate. +Helm templating has built in support for DEFAULT values, here is an example: .. code-block:: yaml @@ -394,6 +366,227 @@ Helm template language is a superset of the Go template language). These functions include simple string operations like upper and more complex flow control operations like if/else. +OOM is mainly helm templating. In order to have consistent deployment of the +different components of ONAP, some rules must be followed. + +Templates are provided in order to create Kubernetes resources (Secrets, +Ingress, Services, ...) or part of Kubernetes resources (names, labels, +resources requests and limits, ...). + +Service template +---------------- + +In order to create a Service for a component, you have to create a file (with +`service` in the name. +For normal service, just put the following line: + +.. code-block:: yaml + + {{ include "common.service" . }} + +For headless service, the line to put is the following: + +.. code-block:: yaml + + {{ include "common.headlessService" . }} + +The configuration of the service is done in component `values.yaml`: + +.. code-block:: yaml + + service: + name: NAME-OF-THE-SERVICE + postfix: MY-POSTFIX + type: NodePort + annotations: + someAnnotationsKey: value + ports: + - name: tcp-MyPort + port: 5432 + nodePort: 88 + - name: http-api + port: 8080 + nodePort: 89 + - name: https-api + port: 9443 + nodePort: 90 + +`annotations` and `postfix` keys are optional. +if `service.type` is `NodePort`, then you have to give `nodePort` value for your +service ports (which is the end of the computed nodePort, see example). + +It would render the following Service Resource (for a component named +`name-of-my-component`, with version `x.y.z`, helm deployment name +`my-deployment` and `global.nodePortPrefix` `302`): + +.. code-block:: yaml + + apiVersion: v1 + kind: Service + metadata: + annotations: + someAnnotationsKey: value + name: NAME-OF-THE-SERVICE-MY-POSTFIX + labels: + app.kubernetes.io/name: name-of-my-component + helm.sh/chart: name-of-my-component-x.y.z + app.kubernetes.io/instance: my-deployment-name-of-my-component + app.kubernetes.io/managed-by: Tiller + spec: + ports: + - port: 5432 + targetPort: tcp-MyPort + nodePort: 30288 + - port: 8080 + targetPort: http-api + nodePort: 30289 + - port: 9443 + targetPort: https-api + nodePort: 30290 + selector: + app.kubernetes.io/name: name-of-my-component + app.kubernetes.io/instance: my-deployment-name-of-my-component + type: NodePort + +In the deployment or statefulSet file, you needs to set the good labels in order +for the service to match the pods. + +here's an example to be sure it matchs (for a statefulSet): + +.. code-block:: yaml + + apiVersion: apps/v1 + kind: StatefulSet + metadata: + name: {{ include "common.fullname" . }} + namespace: {{ include "common.namespace" . }} + labels: {{- include "common.labels" . | nindent 4 }} + spec: + selector: + matchLabels: {{- include "common.matchLabels" . | nindent 6 }} + # serviceName is only needed for StatefulSet + # put the postfix part only if you have add a postfix on the service name + serviceName: {{ include "common.servicename" . }}-{{ .Values.service.postfix }} + <...> + template: + metadata: + labels: {{- include "common.labels" . | nindent 8 }} + annotations: {{- include "common.tplValue" (dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + name: {{ include "common.name" . }} + spec: + <...> + containers: + - name: {{ include "common.name" . }} + ports: + {{- range $index, $port := .Values.service.ports }} + - containerPort: {{ $port.port }} + name: {{ $port.name }} + {{- end }} + {{- range $index, $port := .Values.service.headlessPorts }} + - containerPort: {{ $port.port }} + name: {{ $port.name }} + {{- end }} + <...> + +The configuration of the service is done in component `values.yaml`: + +.. code-block:: yaml + + service: + name: NAME-OF-THE-SERVICE + headless: + postfix: NONE + annotations: + anotherAnnotationsKey : value + publishNotReadyAddresses: true + headlessPorts: + - name: tcp-MyPort + port: 5432 + - name: http-api + port: 8080 + - name: https-api + port: 9443 + +`headless.annotations`, `headless.postfix` and +`headless.publishNotReadyAddresses` keys are optional. + +If `headless.postfix` is not set, then we'll add `-headless` at the end of the +service name. + +If it set to `NONE`, there will be not postfix. + +And if set to something, it will add `-something` at the end of the service +name. + +It would render the following Service Resource (for a component named +`name-of-my-component`, with version `x.y.z`, helm deployment name +`my-deployment` and `global.nodePortPrefix` `302`): + +.. code-block:: yaml + + apiVersion: v1 + kind: Service + metadata: + annotations: + anotherAnnotationsKey: value + name: NAME-OF-THE-SERVICE + labels: + app.kubernetes.io/name: name-of-my-component + helm.sh/chart: name-of-my-component-x.y.z + app.kubernetes.io/instance: my-deployment-name-of-my-component + app.kubernetes.io/managed-by: Tiller + spec: + clusterIP: None + ports: + - port: 5432 + targetPort: tcp-MyPort + nodePort: 30288 + - port: 8080 + targetPort: http-api + nodePort: 30289 + - port: 9443 + targetPort: https-api + nodePort: 30290 + publishNotReadyAddresses: true + selector: + app.kubernetes.io/name: name-of-my-component + app.kubernetes.io/instance: my-deployment-name-of-my-component + type: ClusterIP + +Previous example of StatefulSet would also match (except for the `postfix` part +obviously). + +Creating Deployment or StatefulSet +---------------------------------- + +Deployment and StatefulSet should use the `apps/v1` (which has appeared in +v1.9). +As seen on the service part, the following parts are mandatory: + +.. code-block:: yaml + + apiVersion: apps/v1 + kind: StatefulSet + metadata: + name: {{ include "common.fullname" . }} + namespace: {{ include "common.namespace" . }} + labels: {{- include "common.labels" . | nindent 4 }} + spec: + selector: + matchLabels: {{- include "common.matchLabels" . | nindent 6 }} + # serviceName is only needed for StatefulSet + # put the postfix part only if you have add a postfix on the service name + serviceName: {{ include "common.servicename" . }}-{{ .Values.service.postfix }} + <...> + template: + metadata: + labels: {{- include "common.labels" . | nindent 8 }} + annotations: {{- include "common.tplValue" (dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + name: {{ include "common.name" . }} + spec: + <...> + containers: + - name: {{ include "common.name" . }} ONAP Application Configuration ------------------------------ @@ -423,18 +616,16 @@ SO deployment specification excerpt: .. code-block:: yaml - apiVersion: extensions/v1beta1 + apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "common.name" . }} + name: {{ include "common.fullname" . }} namespace: {{ include "common.namespace" . }} - labels: - app: {{ include "common.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} + labels: {{- include "common.labels" . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} + selector: + matchLabels: {{- include "common.matchLabels" . | nindent 6 }} template: metadata: labels: diff --git a/kubernetes/common/cassandra/templates/backup/cronjob.yaml b/kubernetes/common/cassandra/templates/backup/cronjob.yaml index 2edc8071f9..e4f2aabfa0 100644 --- a/kubernetes/common/cassandra/templates/backup/cronjob.yaml +++ b/kubernetes/common/cassandra/templates/backup/cronjob.yaml @@ -19,11 +19,7 @@ kind: CronJob metadata: name: {{ include "common.fullname" . }}-backup namespace: {{ include "common.namespace" . }} - labels: - app: {{ include "common.fullname" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - release: {{ include "common.release" . }} - heritage: {{ .Release.Service }} + labels: {{- include "common.labels" . | nindent 4 }} spec: schedule: {{ .Values.backup.cron | quote }} concurrencyPolicy: Forbid @@ -31,6 +27,10 @@ spec: jobTemplate: spec: template: + metadata: + labels: {{- include "common.labels" . | nindent 12 }} + annotations: {{- include "common.tplValue" (dict "value" .Values.podAnnotations "context" .) | nindent 12 }} + name: {{ include "common.name" . }} spec: restartPolicy: Never initContainers: diff --git a/kubernetes/common/cassandra/templates/pv.yaml b/kubernetes/common/cassandra/templates/pv.yaml index fd0a758e63..76a224ab5f 100644 --- a/kubernetes/common/cassandra/templates/pv.yaml +++ b/kubernetes/common/cassandra/templates/pv.yaml @@ -12,35 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -{{- $global := . }} -{{- if and $global.Values.persistence.enabled (not $global.Values.persistence.existingClaim) }} -{{- if eq "True" (include "common.needPV" .) -}} -{{- range $i := until (int $global.Values.replicaCount)}} ---- -apiVersion: v1 -kind: PersistentVolume -metadata: - name: {{ include "common.release" $global }}-{{ $global.Values.service.name }}-{{ $i }} - namespace: {{ $global.Release.Namespace }} - labels: - type: {{ $global.Values.persistence.storageType }} - app: {{ $global.Values.service.name }} - chart: {{ $global.Chart.Name }}-{{ $global.Chart.Version | replace "+" "_" }} - release: {{ include "common.release" $global }} - heritage: {{ $global.Release.Service }} -spec: - capacity: - storage: {{ $global.Values.persistence.size }} - accessModes: - {{- if $global.Values.backup.enabled }} - - ReadWriteMany - {{- else }} - - ReadWriteOnce - {{- end }} - persistentVolumeReclaimPolicy: {{ $global.Values.persistence.volumeReclaimPolicy }} - storageClassName: "{{ include "common.fullname" $global }}-data" - hostPath: - path: {{ $global.Values.persistence.mountPath }}/{{ include "common.release" $global }}/{{ $global.Values.persistence.mountSubPath }}-{{ $i }} -{{- end -}} -{{- end -}} -{{- end -}} +{{ include "common.replicaPV" . }} diff --git a/kubernetes/common/cassandra/templates/service.yaml b/kubernetes/common/cassandra/templates/service.yaml index 6cbddbea40..0b91076f82 100644 --- a/kubernetes/common/cassandra/templates/service.yaml +++ b/kubernetes/common/cassandra/templates/service.yaml @@ -12,38 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -apiVersion: v1 -kind: Service -metadata: - name: {{ include "common.servicename" . }} - namespace: {{ include "common.namespace" . }} - labels: - app: {{ include "common.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - release: {{ include "common.release" . }} - heritage: {{ .Release.Service }} - annotations: - service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" -spec: - type: {{ .Values.service.type }} - publishNotReadyAddresses: true - ports: - {{if eq .Values.service.type "NodePort" -}} - {{- $global := . }} - {{- range $index, $ports := .Values.service.ports }} - - port: {{ $ports.port }} - targetPort: {{ $ports.port }} - nodePort: {{ $global.Values.global.nodePortPrefix | default $global.Values.nodePortPrefix }}{{ $ports.nodePort }} - name: {{ $ports.name }} - {{- end }} -{{- else -}} - {{- range $index, $ports := .Values.service.ports }} - - port: {{ $ports.port }} - targetPort: {{ $ports.port }} - name: {{ $ports.name }} - {{- end }} -{{- end}} - selector: - app: {{ include "common.name" . }} - release: {{ include "common.release" . }} - clusterIP: None +{{ include "common.headlessService" . }} diff --git a/kubernetes/common/cassandra/templates/statefulset.yaml b/kubernetes/common/cassandra/templates/statefulset.yaml index b737a8f960..16aa27f68a 100644 --- a/kubernetes/common/cassandra/templates/statefulset.yaml +++ b/kubernetes/common/cassandra/templates/statefulset.yaml @@ -12,42 +12,25 @@ # See the License for the specific language governing permissions and # limitations under the License. -apiVersion: apps/v1beta1 +apiVersion: apps/v1 kind: StatefulSet -metadata: - name: {{ include "common.fullname" . }} - namespace: {{ include "common.namespace" . }} - labels: - app: {{ include "common.name" . }} - chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} - release: {{ include "common.release" . }} - heritage: {{ .Release.Service }} +metadata: {{- include "common.resourceMetadata" . | nindent 2 }} spec: - selector: - matchLabels: - app: {{ include "common.name" . }} - release: {{ include "common.release" . }} + selector: {{- include "common.selectors" . | nindent 4 }} serviceName: {{ include "common.servicename" . }} replicas: {{ .Values.replicaCount }} podManagementPolicy: {{ .Values.podManagementPolicy }} updateStrategy: type: {{ .Values.updateStrategy.type }} template: - metadata: - labels: - app: {{ include "common.name" . }} - release: {{ include "common.release" . }} - name: {{ include "common.name" . }} + metadata: {{- include "common.templateMetadata" . | nindent 6 }} spec: hostNetwork: {{ .Values.hostNetwork }} containers: - name: {{ include "common.name" . }} image: {{ .Values.image }} imagePullPolicy: {{ .Values.global.pullPolicy | default .Values.pullPolicy }} - ports: - {{- range $index, $ports := .Values.service.ports }} - - containerPort: {{ $ports.port }} - {{- end }} + ports: {{ include "common.containerPorts" . | nindent 8 }} volumeMounts: - name: {{ include "common.fullname" . }}-data mountPath: /var/lib/cassandra diff --git a/kubernetes/common/cassandra/values.yaml b/kubernetes/common/cassandra/values.yaml index c3af7e59b2..dfa0a3e250 100644 --- a/kubernetes/common/cassandra/values.yaml +++ b/kubernetes/common/cassandra/values.yaml @@ -75,22 +75,27 @@ readiness: failureThreshold: 3 service: - type: ClusterIP name: cassandra - ports: - - name: intra + headless: + suffix: "" + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + publishNotReadyAddresses: true + headlessPorts: + - name: tcp-intra port: 7000 - name: tls port: 7001 - - name: jmx + - name: tcp-jmx port: 7199 - - name: cql + - name: tcp-cql port: 9042 - - name: thrift + - name: tcp-thrift port: 9160 - - name: agent + - name: tcp-agent port: 61621 +podAnnotations: {} podManagementPolicy: OrderedReady updateStrategy: type: RollingUpdate @@ -116,7 +121,7 @@ persistence: ## ## storageClass: "-" ## Not set as it depends of the backup enabledment or not. - #accessMode: ReadWriteOnce + accessMode: ReadWriteOnce size: 2Gi mountPath: /dockerdata-nfs mountSubPath: cassandra diff --git a/kubernetes/common/common/templates/_labels.tpl b/kubernetes/common/common/templates/_labels.tpl new file mode 100644 index 0000000000..95d51e17b7 --- /dev/null +++ b/kubernetes/common/common/templates/_labels.tpl @@ -0,0 +1,62 @@ +{{/* +# Copyright © 2019 Orange +# +# 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. +*/}} + + + +{{/* +Common labels +*/}} +{{- define "common.labels" -}} +app.kubernetes.io/name: {{ include "common.name" . }} +helm.sh/chart: {{ include "common.chart" . }} +app.kubernetes.io/instance: {{ include "common.release" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector +*/}} +{{- define "common.matchLabels" -}} +app.kubernetes.io/name: {{ include "common.name" . }} +app.kubernetes.io/instance: {{ include "common.release" . }} +{{- end -}} + +{{/* + Generate "top" metadata for Deployment / StatefulSet / ... +*/}} +{{- define "common.resourceMetadata" -}} +name: {{ include "common.fullname" . }} +namespace: {{ include "common.namespace" . }} +labels: {{- include "common.labels" . | nindent 2 }} +{{- end -}} + +{{/* + Generate selectors for Deployment / StatefulSet / ... +*/}} +{{- define "common.selectors" -}} +matchLabels: {{- include "common.matchLabels" . | nindent 2 }} +{{- end -}} + +{{/* + Generate "template" metadata for Deployment / StatefulSet / ... +*/}} +{{- define "common.templateMetadata" -}} +{{- if .Values.podAnnotations }} +annotations: {{- include "common.tplValue" (dict "value" .Values.podAnnotations "context" $) | nindent 2 }} +{{- end }} +labels: {{- include "common.labels" . | nindent 2 }} +name: {{ include "common.name" . }} +{{- end -}} diff --git a/kubernetes/common/common/templates/_name.tpl b/kubernetes/common/common/templates/_name.tpl index 7719cdbb9f..943078ff2f 100644 --- a/kubernetes/common/common/templates/_name.tpl +++ b/kubernetes/common/common/templates/_name.tpl @@ -49,3 +49,7 @@ {{- define "common.release" -}} {{- first (regexSplit "-" .Release.Name -1) }} {{- end -}} + +{{- define "common.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/kubernetes/common/common/templates/_pod.tpl b/kubernetes/common/common/templates/_pod.tpl new file mode 100644 index 0000000000..9329572a92 --- /dev/null +++ b/kubernetes/common/common/templates/_pod.tpl @@ -0,0 +1,38 @@ +{{/* +# Copyright © 2019 Orange +# +# 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. +*/}} + +{{/* + Generate the container port list. + Will use first ".Values.service.ports" list. + Will append ports from ".Values.service.headlessPorts" only if port number is + not already in port list. +*/}} +{{- define "common.containerPorts" -}} +{{- $ports := default (list) .Values.service.ports }} +{{- $portsNumber := list }} +{{- range $index, $port := $ports }} +{{- $portsNumber = append $portsNumber $port.port }} +{{- end }} +{{- range $index, $port := .Values.service.headlessPorts }} +{{- if not (has $port.port $portsNumber) }} +{{- $ports = append $ports $port }} +{{- end }} +{{- end }} +{{- range $index, $port := $ports }} +- containerPort: {{ $port.port }} + name: {{ $port.name }} +{{- end }} +{{- end -}} diff --git a/kubernetes/common/common/templates/_service.tpl b/kubernetes/common/common/templates/_service.tpl index 77b77d059a..075f7965b9 100644 --- a/kubernetes/common/common/templates/_service.tpl +++ b/kubernetes/common/common/templates/_service.tpl @@ -20,7 +20,7 @@ The default will be the chart name (or .Values.nameOverride if set). And the use of .Values.service.name overrides all. - - .Values.service.name : override default service (ie. chart) name + - .Values.service.name: override default service (ie. chart) name */}} {{/* Expand the service name for a chart. @@ -28,4 +28,107 @@ {{- define "common.servicename" -}} {{- $name := default .Chart.Name .Values.nameOverride -}} {{- default $name .Values.service.name | trunc 63 | trimSuffix "-" -}} -{{- end -}} \ No newline at end of file +{{- end -}} + +{{/* Define the metadata of Service + The function takes from one to three arguments (inside a dictionary): + - .dot : environment (.) + - .suffix : a string which will be added at the end of the name (with a '-'). + - .annotations: the annotations to add + Usage example: + {{ include "common.serviceMetadata" ( dict "suffix" "myService" "dot" .) }} + {{ include "common.serviceMetadata" ( dict "annotations" .Values.service.annotation "dot" .) }} +*/}} +{{- define "common.serviceMetadata" -}} + {{- $dot := default . .dot -}} + {{- $suffix := default "" .suffix -}} + {{- $annotations := default "" .annotations -}} +{{- if $annotations -}} +annotations: {{- include "common.tplValue" (dict "value" $annotations "context" $dot) | nindent 2 }} +{{- end }} +name: {{ include "common.servicename" $dot }}{{ if $suffix }}{{ print "-" $suffix }}{{ end }} +namespace: {{ include "common.namespace" $dot }} +labels: {{- include "common.labels" $dot | nindent 2 -}} +{{- end -}} + +{{/* Define the ports of Service + The function takes three arguments (inside a dictionary): + - .dot : environment (.) + - .ports : an array of ports + - .portType: the type of the service +*/}} +{{- define "common.servicePorts" -}} +{{- $portType := .portType -}} +{{- $dot := .dot -}} +{{- range $index, $port := .ports }} +- port: {{ $port.port }} + targetPort: {{ $port.name }} + {{- if (eq $portType "NodePort") }} + nodePort: {{ $dot.Values.global.nodePortPrefix | default $dot.Values.nodePortPrefix }}{{ $port.nodePort }} + {{- end }} + name: {{ $port.name }} +{{- end -}} +{{- end -}} + +{{/* Create generic service template + The function takes several arguments (inside a dictionary): + - .dot : environment (.) + - .ports : an array of ports + - .portType: the type of the service + - .suffix : a string which will be added at the end of the name (with a '-') + - .annotations: the annotations to add + - .publishNotReadyAddresses: if we publish not ready address + - .headless: if the service is headless +*/}} +{{- define "common.genericService" -}} +{{- $dot := default . .dot -}} +{{- $suffix := default "" .suffix -}} +{{- $annotations := default "" .annotations -}} +{{- $publishNotReadyAddresses := default false .publishNotReadyAddresses -}} +{{- $portType := .portType -}} +{{- $ports := .ports -}} +{{- $headless := default false .headless -}} +apiVersion: v1 +kind: Service +metadata: {{ include "common.serviceMetadata" (dict "suffix" $suffix "annotations" $annotations "dot" $dot ) | nindent 2 }} +spec: + {{- if $headless }} + clusterIP: None + {{- end }} + ports: {{- include "common.servicePorts" (dict "portType" $portType "ports" $ports "dot" $dot) | nindent 4 }} + {{- if $publishNotReadyAddresses }} + publishNotReadyAddresses: true + {{- end }} + type: {{ $portType }} + selector: {{- include "common.matchLabels" $dot | nindent 4 }} +{{- end -}} + +{{/* Create service template */}} +{{- define "common.service" -}} +{{- $suffix := default "" .Values.service.suffix -}} +{{- $annotations := default "" .Values.service.annotations -}} +{{- $publishNotReadyAddresses := default false .Values.service.publishNotReadyAddresses -}} +{{- $portType := .Values.service.type -}} +{{- $ports := .Values.service.ports -}} +{{ include "common.genericService" (dict "suffix" $suffix "annotations" $annotations "dot" . "publishNotReadyAddresses" $publishNotReadyAddresses "ports" $ports "portType" $portType) }} +{{- end -}} + +{{/* Create headless service template */}} +{{- define "common.headlessService" -}} +{{- $suffix := include "common._makeHeadlessSuffix" . -}} +{{- $annotations := default "" .Values.service.headless.annotations -}} +{{- $publishNotReadyAddresses := default false .Values.service.headless.publishNotReadyAddresses -}} +{{- $ports := .Values.service.headlessPorts -}} +{{ include "common.genericService" (dict "suffix" $suffix "annotations" $annotations "dot" . "publishNotReadyAddresses" $publishNotReadyAddresses "ports" $ports "portType" "ClusterIP" "headless" true ) }} +{{- end -}} + +{{/* + Generate the right suffix for headless service +*/}} +{{- define "common._makeHeadlessSuffix" -}} +{{- if hasKey .Values.service.headless "suffix" }} +{{- .Values.service.headless.suffix }} +{{- else }} +{{- print "headless" }} +{{- end }} +{{- end -}} diff --git a/kubernetes/common/common/templates/_storageClass.tpl b/kubernetes/common/common/templates/_storage.tpl similarity index 63% rename from kubernetes/common/common/templates/_storageClass.tpl rename to kubernetes/common/common/templates/_storage.tpl index 8fd1f9772b..ae9335909d 100644 --- a/kubernetes/common/common/templates/_storageClass.tpl +++ b/kubernetes/common/common/templates/_storage.tpl @@ -49,9 +49,36 @@ Calculate if we need a PV. If a storageClass is provided, then we don't need. */}} {{- define "common.needPV" -}} -{{- if or (or .Values.persistence.storageClassOverride .Values.persistence.storageClass) .Values.global.persistence.storageClass -}} - False -{{- else -}} +{{- if not (or (or .Values.persistence.storageClassOverride .Values.persistence.storageClass) .Values.global.persistence.storageClass) -}} True {{- end -}} {{- end -}} + +{{/* + Generate N PV for a statefulset +*/}} +{{- define "common.replicaPV" -}} +{{- $global := . }} +{{- if and $global.Values.persistence.enabled (not $global.Values.persistence.existingClaim) }} +{{- if (include "common.needPV" .) -}} +{{- range $i := until (int $global.Values.replicaCount)}} +--- +kind: PersistentVolume +apiVersion: v1 +metadata: + name: {{ include "common.fullname" $global }}-data-{{$i}} + namespace: {{ include "common.namespace" $global }} + labels: {{- include "common.labels" $global | nindent 4 }} +spec: + capacity: + storage: {{ $global.Values.persistence.size}} + accessModes: + - {{ $global.Values.persistence.accessMode }} + persistentVolumeReclaimPolicy: {{ $global.Values.persistence.volumeReclaimPolicy }} + storageClassName: "{{ include "common.fullname" $global }}-data" + hostPath: + path: {{ $global.Values.global.persistence.mountPath | default $global.Values.persistence.mountPath }}/{{ include "common.release" $global }}/{{ $global.Values.persistence.mountSubPath }}-{{$i}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/kubernetes/common/common/templates/_tplValue.tpl b/kubernetes/common/common/templates/_tplValue.tpl new file mode 100644 index 0000000000..b74ecbda19 --- /dev/null +++ b/kubernetes/common/common/templates/_tplValue.tpl @@ -0,0 +1,28 @@ +{{/* +# Copyright © 2019 Orange +# +# 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. +*/}} + +{{/* +Renders a value that contains template. +Usage: +{{ include "common.tplValue" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "common.tplValue" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} diff --git a/kubernetes/onap/values.yaml b/kubernetes/onap/values.yaml index 5344a423f3..2395495df3 100755 --- a/kubernetes/onap/values.yaml +++ b/kubernetes/onap/values.yaml @@ -173,4 +173,4 @@ vid: vnfsdk: enabled: false modeling: - enabled: false \ No newline at end of file + enabled: false diff --git a/kubernetes/sdc/values.yaml b/kubernetes/sdc/values.yaml index a7006bc56c..6abf911a89 100644 --- a/kubernetes/sdc/values.yaml +++ b/kubernetes/sdc/values.yaml @@ -29,7 +29,7 @@ global: ubuntuInitRepository: oomk8s ubuntuInitImage: ubuntu-init:1.0.0 cassandra: - #This flag allows SDC to instantiate its own cluster, serviceName + #This flag allows SDC to instantiate its own cluster, serviceName #should be sdc-cs if this flag is enabled localCluster: false #The cassandra service name to connect to (default: shared cassandra service)