Updating the G release recipe
[ric-plt/ric-dep.git] / bin / install_k8s_and_helm.sh
1 #!/bin/bash -x
2 #
3 ################################################################################
4 #   Copyright (c) 2019 AT&T Intellectual Property.                             #
5 #   Copyright (c) 2022 Nokia.                                                  #
6 #                                                                              #
7 #   Licensed under the Apache License, Version 2.0 (the "License");            #
8 #   you may not use this file except in compliance with the License.           #
9 #   You may obtain a copy of the License at                                    #
10 #                                                                              #
11 #       http://www.apache.org/licenses/LICENSE-2.0                             #
12 #                                                                              #
13 #   Unless required by applicable law or agreed to in writing, software        #
14 #   distributed under the License is distributed on an "AS IS" BASIS,          #
15 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
16 #   See the License for the specific language governing permissions and        #
17 #   limitations under the License.                                             #
18 ################################################################################
19
20
21 usage() {
22     echo "Usage: $0 [ -k <k8s version> -d <docker version> -e <helm version> -c <cni-version>" 1>&2;
23
24     echo "k:    kubernetes version" 1>&2;
25     echo "c:    kubernetes CNI  version" 1>&2;
26     echo "d:    docker version" 1>&2;
27     echo "e:    helm version" 1>&2;
28     exit 1;
29 }
30
31
32 wait_for_pods_running () {
33   NS="$2"
34   CMD="kubectl get pods --all-namespaces "
35   if [ "$NS" != "all-namespaces" ]; then
36     CMD="kubectl get pods -n $2 "
37   fi
38   KEYWORD="Running"
39   if [ "$#" == "3" ]; then
40     KEYWORD="${3}.*Running"
41   fi
42
43   CMD2="$CMD | grep \"$KEYWORD\" | wc -l"
44   NUMPODS=$(eval "$CMD2")
45   echo "waiting for $NUMPODS/$1 pods running in namespace [$NS] with keyword [$KEYWORD]"
46   while [  $NUMPODS -lt $1 ]; do
47     sleep 5
48     NUMPODS=$(eval "$CMD2")
49     echo "> waiting for $NUMPODS/$1 pods running in namespace [$NS] with keyword [$KEYWORD]"
50   done 
51 }
52
53
54 start_ipv6_if () {
55   IPv6IF="$1"
56   if ifconfig -a $IPv6IF; then
57     echo "" >> /etc/network/interfaces.d/50-cloud-init.cfg
58     echo "allow-hotplug ${IPv6IF}" >> /etc/network/interfaces.d/50-cloud-init.cfg
59     echo "iface ${IPv6IF} inet6 auto" >> /etc/network/interfaces.d/50-cloud-init.cfg
60     ifconfig ${IPv6IF} up
61   fi
62 }
63
64 KUBEV="1.16.0"
65 KUBECNIV="0.7.5"
66 HELMV="3.5.4"
67 DOCKERV="20.10.12"
68
69 echo running ${0}
70 while getopts ":k:d:e:n:c" o; do
71     case "${o}" in
72     e)  
73        HELMV=${OPTARG}
74         ;;
75     d)
76        DOCKERV=${OPTARG}
77         ;;
78     k)
79        KUBEV=${OPTARG}
80        ;;
81     c)
82        KUBECNIV=${OPTARG}
83        ;;
84     *)
85        usage
86        ;;
87     esac
88 done
89
90 if [[ ${HELMV} == 2.* ]]; then
91   echo "helm 2 ("${HELMV}")not supported anymore" 
92   exit -1
93 fi
94
95 set -x
96 export DEBIAN_FRONTEND=noninteractive
97 echo "$(hostname -I) $(hostname)" >> /etc/hosts
98 printenv
99
100 IPV6IF=""
101
102 rm -rf /opt/config
103 mkdir -p /opt/config
104 echo "" > /opt/config/docker_version.txt
105 echo "1.16.0" > /opt/config/k8s_version.txt
106 echo "0.7.5" > /opt/config/k8s_cni_version.txt
107 echo "3.5.4" > /opt/config/helm_version.txt
108 echo "$(hostname -I)" > /opt/config/host_private_ip_addr.txt
109 echo "$(curl ifconfig.co)" > /opt/config/k8s_mst_floating_ip_addr.txt
110 echo "$(hostname -I)" > /opt/config/k8s_mst_private_ip_addr.txt
111 echo "__mtu__" > /opt/config/mtu.txt
112 echo "__cinder_volume_id__" > /opt/config/cinder_volume_id.txt
113 echo "$(hostname)" > /opt/config/stack_name.txt
114
115 ISAUX='false'
116 if [[ $(cat /opt/config/stack_name.txt) == *aux* ]]; then
117   ISAUX='true'
118 fi
119
120 modprobe -- ip_vs
121 modprobe -- ip_vs_rr
122 modprobe -- ip_vs_wrr
123 modprobe -- ip_vs_sh
124 modprobe -- nf_conntrack_ipv4
125 modprobe -- nf_conntrack_ipv6
126 modprobe -- nf_conntrack_proto_sctp
127
128 if [ ! -z "$IPV6IF" ]; then
129   start_ipv6_if $IPV6IF
130 fi
131
132 SWAPFILES=$(grep swap /etc/fstab | sed '/^[ \t]*#/ d' | sed 's/[\t ]/ /g' | tr -s " " | cut -f1 -d' ')
133 if [ ! -z $SWAPFILES ]; then
134   for SWAPFILE in $SWAPFILES
135   do
136     if [ ! -z $SWAPFILE ]; then
137       echo "disabling swap file $SWAPFILE"
138       if [[ $SWAPFILE == UUID* ]]; then
139         UUID=$(echo $SWAPFILE | cut -f2 -d'=')
140         swapoff -U $UUID
141       else
142         swapoff $SWAPFILE
143       fi
144       sed -i "\%$SWAPFILE%d" /etc/fstab
145     fi
146   done
147 fi
148
149
150 echo "### Docker version  = "${DOCKERV}
151 echo "### k8s version     = "${KUBEV}
152 echo "### helm version    = "${HELMV}
153 echo "### k8s cni version = "${KUBECNIV}
154
155 KUBEVERSION="${KUBEV}-00"
156 CNIVERSION="${KUBECNIV}-00"
157 DOCKERVERSION="${DOCKERV}"
158
159 UBUNTU_RELEASE=$(lsb_release -r | sed 's/^[a-zA-Z:\t ]\+//g')
160 if [[ ${UBUNTU_RELEASE} == 16.* ]]; then
161   echo "Installing on Ubuntu $UBUNTU_RELEASE (Xenial Xerus) host"
162   if [ ! -z "${DOCKERV}" ]; then
163     DOCKERVERSION="${DOCKERV}-0ubuntu1~16.04.5"
164   fi
165 elif [[ ${UBUNTU_RELEASE} == 18.* ]]; then
166   echo "Installing on Ubuntu $UBUNTU_RELEASE (Bionic Beaver)"
167   if [ ! -z "${DOCKERV}" ]; then
168     DOCKERVERSION="${DOCKERV}-0ubuntu1~18.04.4"
169   fi
170 elif [[ ${UBUNTU_RELEASE} == 20.* ]]; then
171   echo "Installing on Ubuntu $UBUNTU_RELEASE (Focal Fossal)"
172   if [ ! -z "${DOCKERV}" ]; then
173     DOCKERVERSION="${DOCKERV}-0ubuntu2~20.04.1"  # 20.10.12-0ubuntu2~20.04.1
174   fi
175 else
176   echo "Unsupported Ubuntu release ($UBUNTU_RELEASE) detected.  Exit."
177 fi
178
179 echo "docker version to use = "${DOCKERVERSION}
180
181 curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
182 echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' > /etc/apt/sources.list.d/kubernetes.list
183
184 mkdir -p /etc/apt/apt.conf.d
185 echo "APT::Acquire::Retries \"3\";" > /etc/apt/apt.conf.d/80-retries
186
187 apt-get update
188 RES=$(apt-get install -y  curl jq netcat make ipset moreutils 2>&1)
189 if [[ $RES == */var/lib/dpkg/lock* ]]; then
190   echo "Fail to get dpkg lock.  Wait for any other package installation"
191   echo "process to finish, then rerun this script"
192   exit -1
193 fi
194
195 APTOPTS="--allow-downgrades --allow-change-held-packages --allow-unauthenticated --ignore-hold "
196
197 for PKG in kubeadm docker.io; do
198   INSTALLED_VERSION=$(dpkg --list |grep ${PKG} |tr -s " " |cut -f3 -d ' ')
199   if [ ! -z ${INSTALLED_VERSION} ]; then
200     if [ "${PKG}" == "kubeadm" ]; then
201       kubeadm reset -f
202       rm -rf ~/.kube
203       apt-get -y $APTOPTS remove kubeadm kubelet kubectl kubernetes-cni
204     else
205       apt-get -y $APTOPTS remove "${PKG}"
206     fi
207   fi
208 done
209 apt-get -y autoremove
210
211 if [ -z ${DOCKERVERSION} ]; then
212   apt-get install -y $APTOPTS docker.io
213 else
214   apt-get install -y $APTOPTS docker.io=${DOCKERVERSION}
215 fi
216 cat > /etc/docker/daemon.json <<EOF
217 {
218   "exec-opts": ["native.cgroupdriver=systemd"],
219   "log-driver": "json-file",
220   "log-opts": {
221     "max-size": "100m"
222   },
223   "storage-driver": "overlay2"
224 }
225 EOF
226 mkdir -p /etc/systemd/system/docker.service.d
227 systemctl enable docker.service
228 systemctl daemon-reload
229 systemctl restart docker
230
231 if [ -z ${CNIVERSION} ]; then
232   apt-get install -y $APTOPTS kubernetes-cni
233 else
234   apt-get install -y $APTOPTS kubernetes-cni=${CNIVERSION}
235 fi
236
237 if [ -z ${KUBEVERSION} ]; then
238   apt-get install -y $APTOPTS kubeadm kubelet kubectl
239 else
240   apt-get install -y $APTOPTS kubeadm=${KUBEVERSION} kubelet=${KUBEVERSION} kubectl=${KUBEVERSION}
241 fi
242
243 apt-mark hold docker.io kubernetes-cni kubelet kubeadm kubectl
244
245
246 kubeadm config images pull --kubernetes-version=${KUBEV}
247
248
249 NODETYPE="master"
250 if [ "$NODETYPE" == "master" ]; then
251
252   if [[ ${KUBEV} == 1.13.* ]]; then
253     cat <<EOF >/root/config.yaml
254 apiVersion: kubeadm.k8s.io/v1alpha3
255 kubernetesVersion: v${KUBEV}
256 kind: ClusterConfiguration
257 apiServerExtraArgs:
258   feature-gates: SCTPSupport=true
259 networking:
260   dnsDomain: cluster.local
261   podSubnet: 10.244.0.0/16
262   serviceSubnet: 10.96.0.0/12
263 ---
264 apiVersion: kubeproxy.config.k8s.io/v1alpha1
265 kind: KubeProxyConfiguration
266 mode: ipvs
267 EOF
268
269   elif [[ ${KUBEV} == 1.14.* ]]; then
270     cat <<EOF >/root/config.yaml
271 apiVersion: kubeadm.k8s.io/v1beta1
272 kubernetesVersion: v${KUBEV}
273 kind: ClusterConfiguration
274 apiServerExtraArgs:
275   feature-gates: SCTPSupport=true
276 networking:
277   dnsDomain: cluster.local
278   podSubnet: 10.244.0.0/16
279   serviceSubnet: 10.96.0.0/12
280 ---
281 apiVersion: kubeproxy.config.k8s.io/v1alpha1
282 kind: KubeProxyConfiguration
283 mode: ipvs
284 EOF
285   elif [[ ${KUBEV} == 1.15.* ]] || [[ ${KUBEV} == 1.16.* ]] || [[ ${KUBEV} == 1.18.* ]]; then
286     cat <<EOF >/root/config.yaml
287 apiVersion: kubeadm.k8s.io/v1beta2
288 kubernetesVersion: v${KUBEV}
289 kind: ClusterConfiguration
290 apiServer:
291   extraArgs:
292     feature-gates: SCTPSupport=true
293 networking:
294   dnsDomain: cluster.local
295   podSubnet: 10.244.0.0/16
296   serviceSubnet: 10.96.0.0/12
297 ---
298 apiVersion: kubeproxy.config.k8s.io/v1alpha1
299 kind: KubeProxyConfiguration
300 mode: ipvs
301 EOF
302   else
303     echo "Unsupported Kubernetes version requested.  Bail."
304     exit
305   fi
306
307   cat <<EOF > /root/rbac-config.yaml
308 apiVersion: v1
309 kind: ServiceAccount
310 metadata:
311   name: tiller
312   namespace: kube-system
313 ---
314 apiVersion: rbac.authorization.k8s.io/v1
315 kind: ClusterRoleBinding
316 metadata:
317   name: tiller
318 roleRef:
319   apiGroup: rbac.authorization.k8s.io
320   kind: ClusterRole
321   name: cluster-admin
322 subjects:
323   - kind: ServiceAccount
324     name: tiller
325     namespace: kube-system
326 EOF
327
328
329   kubeadm init --config /root/config.yaml
330
331   cd /root
332   rm -rf .kube
333   mkdir -p .kube
334   cp -i /etc/kubernetes/admin.conf /root/.kube/config
335   chown root:root /root/.kube/config
336   export KUBECONFIG=/root/.kube/config
337   echo "KUBECONFIG=${KUBECONFIG}" >> /etc/environment
338
339   kubectl get pods --all-namespaces
340
341   # we refer to version 0.18.1 because later versions use namespace kube-flannel instead of kube-system TODO
342   kubectl apply -f "https://raw.githubusercontent.com/flannel-io/flannel/v0.18.1/Documentation/kube-flannel.yml"
343
344   wait_for_pods_running 8 kube-system
345
346   kubectl taint nodes --all node-role.kubernetes.io/master-
347
348   HELMV=$(cat /opt/config/helm_version.txt)
349   HELMVERSION=${HELMV}
350   if [ ! -e helm-v${HELMVERSION}-linux-amd64.tar.gz ]; then
351     wget https://get.helm.sh/helm-v${HELMVERSION}-linux-amd64.tar.gz
352   fi
353   cd /root && rm -rf Helm && mkdir Helm && cd Helm
354   tar -xvf ../helm-v${HELMVERSION}-linux-amd64.tar.gz
355   mv linux-amd64/helm /usr/local/bin/helm
356
357   cd /root
358
359   rm -rf /root/.helm
360 #  if [[ ${KUBEV} == 1.16.* ]]; then
361 #    if [[ ${HELMVERSION} == 2.* ]]; then
362 #       helm init --service-account tiller --override spec.selector.matchLabels.'name'='tiller',spec.selector.matchLabels.'app'='helm' --output yaml > /tmp/helm-init.yaml
363 #       sed 's@apiVersion: extensions/v1beta1@apiVersion: apps/v1@' /tmp/helm-init.yaml > /tmp/helm-init-patched.yaml
364 #       kubectl apply -f /tmp/helm-init-patched.yaml
365 #    fi
366 #  else
367 #    if [[ ${HELMVERSION} == 2.* ]]; then
368 #       helm init --service-account tiller
369 #    fi
370 #  fi
371 #  if [[ ${HELMVERSION} == 2.* ]]; then
372 #     helm init -c
373 #     export HELM_HOME="$(pwd)/.helm"
374 #     echo "HELM_HOME=${HELM_HOME}" >> /etc/environment
375 #  fi
376
377   while ! helm version; do
378     echo "Waiting for Helm to be ready"
379     sleep 15
380   done
381
382   echo "Preparing a master node (lower ID) for using local FS for PV"
383   PV_NODE_NAME=$(kubectl get nodes |grep master | cut -f1 -d' ' | sort | head -1)
384   kubectl label --overwrite nodes $PV_NODE_NAME local-storage=enable
385   if [ "$PV_NODE_NAME" == "$(hostname)" ]; then
386     mkdir -p /opt/data/dashboard-data
387   fi
388
389   echo "Done with master node setup"
390 fi
391
392
393 if [[ ! -z "" && ! -z "" ]]; then 
394   echo " " >> /etc/hosts
395 fi
396 if [[ ! -z "" && ! -z "" ]]; then 
397   echo " " >> /etc/hosts
398 fi
399 if [[ ! -z "" && ! -z "helm.ricinfra.local" ]]; then 
400   echo " helm.ricinfra.local" >> /etc/hosts
401 fi
402
403 if [[ "1" -gt "100" ]]; then
404   cat <<EOF >/etc/ca-certificates/update.d/helm.crt
405
406 EOF
407 fi
408
409 if [[ "1" -gt "100" ]]; then
410   mkdir -p /etc/docker/certs.d/:
411   cat <<EOF >/etc/docker/ca.crt
412
413 EOF
414   cp /etc/docker/ca.crt /etc/docker/certs.d/:/ca.crt
415
416   service docker restart
417   systemctl enable docker.service
418   docker login -u  -p  :
419   docker pull :/whoami:0.0.1
420 fi