44e8fc60362b0366a163b05cbe9591015fb05b9b
[demo.git] / vnfs / DAaaS / training-core / charts / kubernetes-HDFS / charts / hdfs-namenode-k8s / templates / namenode-statefulset.yaml
1 # A headless service to create DNS records.
2 apiVersion: v1
3 kind: Service
4 metadata:
5   name: {{ template "hdfs-k8s.namenode.fullname" . }}
6   labels:
7     app: {{ template "hdfs-k8s.namenode.name" . }}
8     chart: {{ template "hdfs-k8s.subchart" . }}
9     release: {{ .Release.Name }}
10   annotations:
11     # TODO: Deprecated. Replace tolerate-unready-endpoints with
12     # v1.Service.PublishNotReadyAddresses.
13     service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
14 spec:
15   ports:
16   - port: 8020
17     name: fs
18   - port: 50070
19     name: http
20   clusterIP: None
21   selector:
22     app: {{ template "hdfs-k8s.namenode.name" . }}
23     release: {{ .Release.Name }}
24 ---
25 apiVersion: policy/v1beta1
26 kind: PodDisruptionBudget
27 metadata:
28   name: {{ template "hdfs-k8s.namenode.fullname" . }}
29   labels:
30     app: {{ template "hdfs-k8s.namenode.name" . }}
31     chart: {{ template "hdfs-k8s.subchart" . }}
32     release: {{ .Release.Name }}
33 spec:
34   selector:
35     matchLabels:
36       app: {{ template "hdfs-k8s.namenode.name" . }}
37       release: {{ .Release.Name }}
38   minAvailable: 1
39 ---
40 # Provides namenode helper scripts. Most of them are start scripts
41 # that meet different needs.
42 # TODO: Support upgrade of metadata in case a new Hadoop version requires it.
43 apiVersion: v1
44 kind: ConfigMap
45 metadata:
46   name: {{ template "hdfs-k8s.namenode.fullname" . }}-scripts
47   labels:
48     app: {{ template "hdfs-k8s.namenode.name" . }}
49     chart: {{ template "hdfs-k8s.subchart" . }}
50     release: {{ .Release.Name }}
51 data:
52   # A bootstrap script which will start namenode daemons after conducting
53   # optional metadata initialization steps. The metadata initialization
54   # steps will take place in case the metadata dir is empty,
55   # which will be the case only for the very first run. The specific steps
56   # will differ depending on whether the namenode is active or standby.
57   # We also assume, for the very first run, namenode-0 will be active and
58   # namenode-1 will be standby as StatefulSet will launch namenode-0 first
59   # and zookeeper will determine the sole namenode to be the active one.
60   # For active namenode, the initialization steps will format the metadata,
61   # zookeeper dir and journal node data entries.
62   # For standby namenode, the initialization steps will simply receieve
63   # the first batch of metadata updates from the journal node.
64   format-and-run.sh: |
65     #!/usr/bin/env bash
66     # Exit on error. Append "|| true" if you expect an error.
67     set -o errexit
68     # Exit on error inside any functions or subshells.
69     set -o errtrace
70     # Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR
71     set -o nounset
72     # Catch an error in command pipes. e.g. mysqldump fails (but gzip succeeds)
73     # in `mysqldump |gzip`
74     set -o pipefail
75     # Turn on traces, useful while debugging.
76     set -o xtrace
77
78     _HDFS_BIN=$HADOOP_PREFIX/bin/hdfs
79     _METADATA_DIR=/hadoop/dfs/name/current
80     if [[ "$MY_POD" = "$NAMENODE_POD_0" ]]; then
81       if [[ ! -d $_METADATA_DIR ]]; then
82           $_HDFS_BIN --config $HADOOP_CONF_DIR namenode -format  \
83               -nonInteractive hdfs-k8s ||
84               (rm -rf $_METADATA_DIR; exit 1)
85       fi
86       _ZKFC_FORMATTED=/hadoop/dfs/name/current/.hdfs-k8s-zkfc-formatted
87       if [[ ! -f $_ZKFC_FORMATTED ]]; then
88         _OUT=$($_HDFS_BIN --config $HADOOP_CONF_DIR zkfc -formatZK -nonInteractive 2>&1)
89         # zkfc masks fatal exceptions and returns exit code 0
90         (echo $_OUT | grep -q "FATAL") && exit 1
91         touch $_ZKFC_FORMATTED
92       fi
93     elif [[ "$MY_POD" = "$NAMENODE_POD_1" ]]; then
94       if [[ ! -d $_METADATA_DIR ]]; then
95         $_HDFS_BIN --config $HADOOP_CONF_DIR namenode -bootstrapStandby  \
96             -nonInteractive ||  \
97             (rm -rf $_METADATA_DIR; exit 1)
98       fi
99     fi
100     $HADOOP_PREFIX/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR start zkfc
101     $_HDFS_BIN --config $HADOOP_CONF_DIR namenode
102
103   # A start script that will just hang indefinitely. A user can then get
104   # inside the pod and debug. Or a user can conduct a custom manual operations.
105   do-nothing.sh: |
106     #!/usr/bin/env bash
107     tail -f /var/log/dmesg
108
109   # A start script that has user specified content. Can be used to conduct
110   # ad-hoc operation as specified by a user.
111   custom-run.sh: {{ .Values.customRunScript | quote }}
112 ---
113 apiVersion: apps/v1beta1
114 kind: StatefulSet
115 metadata:
116   name: {{ template "hdfs-k8s.namenode.fullname" . }}
117   labels:
118     app: {{ template "hdfs-k8s.namenode.name" . }}
119     chart: {{ template "hdfs-k8s.subchart" . }}
120     release: {{ .Release.Name }}
121 spec:
122   serviceName: {{ template "hdfs-k8s.namenode.fullname" . }}
123   replicas: 2
124   template:
125     metadata:
126       labels:
127         app: {{ template "hdfs-k8s.namenode.name" . }}
128         release: {{ .Release.Name }}
129       {{- if .Values.podAnnotations }}
130       annotations:
131 {{ toYaml .Values.podAnnotations | indent 8 }}
132       {{- end }}
133     spec:
134       {{- if .Values.hostNetworkEnabled }}
135       # Use hostNetwork so datanodes connect to namenode without going through an overlay network
136       # like weave. Otherwise, namenode fails to see physical IP address of datanodes.
137       # Disabling this will break data locality as namenode will see pod virtual IPs and fails to
138       # equate them with cluster node physical IPs associated with data nodes.
139       # We currently disable this only for CI on minikube.
140       hostNetwork: true
141       hostPID: true
142       dnsPolicy: ClusterFirstWithHostNet
143       {{- else }}
144       dnsPolicy: ClusterFirst
145       {{- end }}
146       {{- if .Values.affinity }}
147       affinity:
148 {{ toYaml .Values.affinity | indent 8 }}
149       {{- else if .Values.global.defaultAffinityEnabled }}
150       affinity:
151         podAntiAffinity:
152           requiredDuringSchedulingIgnoredDuringExecution:
153             - labelSelector:
154                 matchExpressions:
155                   - key: "app"
156                     operator: In
157                     values:
158                       - {{ template "hdfs-k8s.namenode.name" . }}
159                   - key: "release"
160                     operator: In
161                     values:
162                       - {{ .Release.Name }}
163               topologyKey: "kubernetes.io/hostname"
164       {{- end }}
165       {{- if .Values.nodeSelector }}
166       nodeSelector:
167 {{ toYaml .Values.nodeSelector | indent 8 }}
168       {{- end }}
169       {{- if .Values.tolerations }}
170       tolerations:
171 {{ toYaml .Values.tolerations | indent 8 }}
172       {{- end }}
173       containers:
174         # TODO: Support hadoop version as option.
175         - name: hdfs-namenode
176           image: uhopper/hadoop-namenode:2.7.2
177           env:
178             - name: HADOOP_CUSTOM_CONF_DIR
179               value: /etc/hadoop-custom-conf
180             - name: MULTIHOMED_NETWORK
181               value: "0"
182             # Used by the start script below.
183             - name: MY_POD
184               valueFrom:
185                 fieldRef:
186                   fieldPath: metadata.name
187             - name: NAMENODE_POD_0
188               value: {{ template "namenode-pod-0" . }}
189             - name: NAMENODE_POD_1
190               value: {{ template "namenode-pod-1" . }}
191           command: ['/bin/sh', '-c']
192           # The start script is provided by a config map.
193           args:
194             - /entrypoint.sh "/nn-scripts/{{ .Values.namenodeStartScript }}"
195           ports:
196           - containerPort: 8020
197             name: fs
198           - containerPort: 50070
199             name: http
200           volumeMounts:
201             - name: nn-scripts
202               mountPath: /nn-scripts
203               readOnly: true
204             # Mount a subpath of the volume so that the name subdir would be a
205             # brand new empty dir. This way, we won't get affected by existing
206             # files in the volume top dir.
207             - name: metadatadir
208               mountPath: /hadoop/dfs/name
209               subPath: name
210             - name: hdfs-config
211               mountPath: /etc/hadoop-custom-conf
212               readOnly: true
213             {{- if .Values.global.kerberosEnabled }}
214             - name: kerberos-config
215               mountPath: /etc/krb5.conf
216               subPath: {{ .Values.global.kerberosConfigFileName }}
217               readOnly: true
218             - name: kerberos-keytab-copy
219               mountPath: /etc/security/
220               readOnly: true
221             {{- end }}
222       {{- if .Values.global.kerberosEnabled }}
223       initContainers:
224         - name: copy-kerberos-keytab
225           image: busybox:1.27.1
226           command: ['sh', '-c']
227           args:
228             - cp /kerberos-keytabs/${MY_KERBEROS_NAME}*.keytab /kerberos-keytab-copy/hdfs.keytab
229           env:
230             - name: MY_KERBEROS_NAME
231               valueFrom:
232                 fieldRef:
233                 {{- if .Values.hostNetworkEnabled }}
234                   fieldPath: spec.nodeName
235                 {{- else }}
236                   fieldPath: metadata.name
237                 {{- end }}
238           volumeMounts:
239             - name: kerberos-keytabs
240               mountPath: /kerberos-keytabs
241             - name: kerberos-keytab-copy
242               mountPath: /kerberos-keytab-copy
243       {{- end }}
244       restartPolicy: Always
245       volumes:
246         - name: nn-scripts
247           configMap:
248             name: {{ template "hdfs-k8s.namenode.fullname" . }}-scripts
249             defaultMode: 0744
250         - name: hdfs-config
251           configMap:
252             name: {{ template "hdfs-k8s.config.fullname" . }}
253         {{- if .Values.global.kerberosEnabled }}
254         - name: kerberos-config
255           configMap:
256             name: {{ template "krb5-configmap" . }}
257         - name: kerberos-keytabs
258           secret:
259             secretName: {{ template "krb5-keytabs-secret" . }}
260         - name: kerberos-keytab-copy
261           emptyDir: {}
262         {{- end }}
263       {{- if .Values.global.podSecurityContext.enabled }}
264       securityContext:
265         runAsUser: {{ .Values.global.podSecurityContext.runAsUser }}
266         fsGroup: {{ .Values.global.podSecurityContext.fsGroup }}
267       {{- end }}
268   volumeClaimTemplates:
269     - metadata:
270         name: metadatadir
271       spec:
272         accessModes:
273           - {{ .Values.persistence.accessMode | quote }}
274         resources:
275           requests:
276             storage: {{ .Values.persistence.size | quote }}
277       {{- if .Values.persistence.storageClass }}
278         {{- if (eq "-" .Values.persistence.storageClass) }}
279         storageClassName: ""
280         {{- else }}
281         storageClassName: "{{ .Values.persistence.storageClass }}"
282         {{- end }}
283       {{- end }}
284       {{- if .Values.persistence.selector }}
285         selector:
286 {{ toYaml .Values.persistence.selector | indent 10 }}
287       {{- end }}