Merge "FEATURE: General-purpose RIC platform initContainer image"
[it/dep.git] / ric-infra / 00-Kubernetes / heat / scripts / k8s_vm_install.sh
1 #!/bin/bash -x
2 ################################################################################
3 #   Copyright (c) 2019 AT&T Intellectual Property.                             #
4 #   Copyright (c) 2019 Nokia.                                                  #
5 #                                                                              #
6 #   Licensed under the Apache License, Version 2.0 (the "License");            #
7 #   you may not use this file except in compliance with the License.           #
8 #   You may obtain a copy of the License at                                    #
9 #                                                                              #
10 #       http://www.apache.org/licenses/LICENSE-2.0                             #
11 #                                                                              #
12 #   Unless required by applicable law or agreed to in writing, software        #
13 #   distributed under the License is distributed on an "AS IS" BASIS,          #
14 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   #
15 #   See the License for the specific language governing permissions and        #
16 #   limitations under the License.                                             #
17 ################################################################################
18
19
20 # first parameter: number of expected running pods
21 # second parameter: namespace (all-namespaces means all namespaces)
22 # third parameter: [optional] keyword
23 wait_for_pods_running () {
24   NS="$2"
25   CMD="kubectl get pods --all-namespaces "
26   if [ "$NS" != "all-namespaces" ]; then
27     CMD="kubectl get pods -n $2 "
28   fi
29   KEYWORD="Running"
30   if [ "$#" == "3" ]; then
31     KEYWORD="${3}.*Running"
32   fi
33
34   CMD2="$CMD | grep \"$KEYWORD\" | wc -l"
35   NUMPODS=$(eval "$CMD2")
36   echo "waiting for $NUMPODS/$1 pods running in namespace [$NS] with keyword [$KEYWORD]"
37   while [  $NUMPODS -lt $1 ]; do
38     sleep 5
39     NUMPODS=$(eval "$CMD2")
40     echo "> waiting for $NUMPODS/$1 pods running in namespace [$NS] with keyword [$KEYWORD]"
41   done 
42 }
43
44
45 # first parameter: interface name
46 start_ipv6_if () {
47   # enable ipv6 interface
48   # standard Ubuntu cloud image does not have dual interface configuration or ipv6
49   IPv6IF="$1"
50   if ifconfig -a $IPv6IF; then
51     echo "" >> /etc/network/interfaces.d/50-cloud-init.cfg
52     #echo "auto ${IPv6IF}" >> /etc/network/interfaces.d/50-cloud-init.cfg
53     echo "allow-hotplug ${IPv6IF}" >> /etc/network/interfaces.d/50-cloud-init.cfg
54     echo "iface ${IPv6IF} inet6 auto" >> /etc/network/interfaces.d/50-cloud-init.cfg
55     #dhclient -r $IPv6IF
56     #systemctl restart networking
57     ifconfig ${IPv6IF} up
58   fi
59 }
60
61 echo "k8s_vm_install.sh"
62 set -x
63 export DEBIAN_FRONTEND=noninteractive
64 echo "__host_private_ip_addr__ $(hostname)" >> /etc/hosts
65 printenv
66
67 mkdir -p /opt/config
68 echo "__docker_version__" > /opt/config/docker_version.txt
69 echo "__k8s_version__" > /opt/config/k8s_version.txt
70 echo "__k8s_cni_version__" > /opt/config/k8s_cni_version.txt
71 echo "__helm_version__" > /opt/config/helm_version.txt
72 echo "__host_private_ip_addr__" > /opt/config/host_private_ip_addr.txt
73 echo "__k8s_mst_floating_ip_addr__" > /opt/config/k8s_mst_floating_ip_addr.txt
74 echo "__k8s_mst_private_ip_addr__" > /opt/config/k8s_mst_private_ip_addr.txt
75 echo "__mtu__" > /opt/config/mtu.txt
76 echo "__cinder_volume_id__" > /opt/config/cinder_volume_id.txt
77 echo "__stack_name__" > /opt/config/stack_name.txt
78
79 ISAUX='false'
80 if [[ $(cat /opt/config/stack_name.txt) == *aux* ]]; then
81   ISAUX='true'
82 fi
83
84 modprobe -- ip_vs
85 modprobe -- ip_vs_rr
86 modprobe -- ip_vs_wrr
87 modprobe -- ip_vs_sh
88 modprobe -- nf_conntrack_ipv4
89 modprobe -- nf_conntrack_ipv6
90 modprobe -- nf_conntrack_proto_sctp
91
92 start_ipv6_if ens4
93
94 # disable swap
95 SWAPFILES=$(grep swap /etc/fstab | sed '/^#/ d' |cut -f1 -d' ')
96 if [ ! -z $SWAPFILES ]; then
97   for SWAPFILE in $SWAPFILES
98   do
99     if [ ! -z $SWAPFILE ]; then
100       echo "disabling swap file $SWAPFILE"
101       if [[ $SWAPFILE == UUID* ]]; then
102         UUID=$(echo $SWAPFILE | cut -f2 -d'=')
103         swapoff -U $UUID
104       else
105         swapoff $SWAPFILE
106       fi
107       # edit /etc/fstab file, remove line with /swapfile
108       sed -i -e "/$SWAPFILE/d" /etc/fstab
109     fi
110   done
111 fi
112 # disable swap
113 #swapoff /swapfile
114 # edit /etc/fstab file, remove line with /swapfile
115 #sed -i -e '/swapfile/d' /etc/fstab
116
117
118 DOCKERV=$(cat /opt/config/docker_version.txt)
119 KUBEV=$(cat /opt/config/k8s_version.txt)
120 KUBECNIV=$(cat /opt/config/k8s_cni_version.txt)
121
122 KUBEVERSION="${KUBEV}-00"
123 CNIVERSION="${KUBECNIV}-00"
124 DOCKERVERSION="${DOCKERV}-0ubuntu1.2~16.04.1"
125 curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
126 echo 'deb http://apt.kubernetes.io/ kubernetes-xenial main' > /etc/apt/sources.list.d/kubernetes.list
127
128 # install low latency kernel, docker.io, and kubernetes
129 apt-get update
130 apt-get install -y linux-image-4.15.0-45-lowlatency curl jq netcat docker.io=${DOCKERVERSION}
131 apt-get install -y kubernetes-cni=${CNIVERSION}
132 apt-get install -y --allow-unauthenticated kubeadm=${KUBEVERSION} kubelet=${KUBEVERSION} kubectl=${KUBEVERSION}
133 apt-mark hold kubernetes-cni kubelet kubeadm kubectl
134
135
136 # test access to k8s docker registry
137 kubeadm config images pull
138
139
140 # non-master nodes have hostnames ending with -[0-9][0-9]
141 if [[ $(hostname) == *-[0-9][0-9] ]]; then
142   echo "Done for non-master node"
143   echo "Starting an NC TCP server on port 29999 to indicate we are ready"
144   nc -l -p 29999 &
145 else 
146   # below are steps for initializating master node, only run on the master node.  
147   # minion node join will be triggered from the caller of the stack creation as ssh command.
148
149
150   # create kubenetes config file
151   if [[ ${KUBEV} == 1.13.* ]]; then
152     cat <<EOF >/root/config.yaml
153 apiVersion: kubeadm.k8s.io/v1alpha3
154 kubernetesVersion: v${KUBEV}
155 kind: ClusterConfiguration
156 apiServerExtraArgs:
157   feature-gates: SCTPSupport=true
158 networking:
159   dnsDomain: cluster.local
160   podSubnet: 10.244.0.0/16
161   serviceSubnet: 10.96.0.0/12
162
163 ---
164 apiVersion: kubeproxy.config.k8s.io/v1alpha1
165 kind: KubeProxyConfiguration
166 mode: ipvs
167 EOF
168
169   elif [[ ${KUBEV} == 1.14.* ]]; then
170     cat <<EOF >/root/config.yaml
171 apiVersion: kubeadm.k8s.io/v1beta1
172 kubernetesVersion: v${KUBEV}
173 kind: ClusterConfiguration
174 apiServerExtraArgs:
175   feature-gates: SCTPSupport=true
176 networking:
177   dnsDomain: cluster.local
178   podSubnet: 10.244.0.0/16
179   serviceSubnet: 10.96.0.0/12
180
181 ---
182 apiVersion: kubeproxy.config.k8s.io/v1alpha1
183 kind: KubeProxyConfiguration
184 mode: ipvs
185 EOF
186
187   else
188     echo "Unsupported Kubernetes version requested.  Bail."
189     exit
190   fi
191
192
193   # create a RBAC file for helm (tiller)
194   cat <<EOF > /root/rbac-config.yaml
195 apiVersion: v1
196 kind: ServiceAccount
197 metadata:
198   name: tiller
199   namespace: kube-system
200 ---
201 apiVersion: rbac.authorization.k8s.io/v1
202 kind: ClusterRoleBinding
203 metadata:
204   name: tiller
205 roleRef:
206   apiGroup: rbac.authorization.k8s.io
207   kind: ClusterRole
208   name: cluster-admin
209 subjects:
210   - kind: ServiceAccount
211     name: tiller
212     namespace: kube-system
213 EOF
214
215   # start cluster (make sure CIDR is enabled with the flag)
216   kubeadm init --config /root/config.yaml
217
218
219   # install Helm
220   HELMV=$(cat /opt/config/helm_version.txt)
221   HELMVERSION=${HELMV}
222   cd /root
223   mkdir Helm
224   cd Helm
225   wget https://storage.googleapis.com/kubernetes-helm/helm-v${HELMVERSION}-linux-amd64.tar.gz
226   tar -xvf helm-v${HELMVERSION}-linux-amd64.tar.gz
227   mv linux-amd64/helm /usr/local/bin/helm
228
229   # set up kubectl credential and config
230   cd /root
231   rm -rf .kube
232   mkdir -p .kube
233   cp -i /etc/kubernetes/admin.conf /root/.kube/config
234   chown root:root /root/.kube/config
235
236   # at this point we should be able to use kubectl
237   kubectl get pods --all-namespaces
238
239   # install flannel
240   kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/bc79dd1505b0c8681ece4de4c0d86c5cd2643275/Documentation/kube-flannel.yml
241
242
243   # waiting for all 8 kube-system pods to be in running state
244   # (at this point, minions have not joined yet)
245   wait_for_pods_running 8 kube-system
246
247   # if running a single node cluster, need to enable master node to run pods
248   kubectl taint nodes --all node-role.kubernetes.io/master-
249
250   cd /root
251   # install RBAC for Helm
252   kubectl create -f rbac-config.yaml
253
254
255   rm -rf /root/.helm
256   helm init --service-account tiller
257   export HELM_HOME="/root/.helm"
258
259   # waiting for tiller pod to be in running state
260   wait_for_pods_running 1 kube-system tiller-deploy
261
262   while ! helm version; do
263     echo "Waiting for Helm to be ready"
264     sleep 15
265   done
266
267   # install ingress controller db-less kong
268   helm install stable/kong --set ingressController.enabled=true --set postgresql.enabled=false --set env.database=off
269
270
271   echo "Starting an NC TCP server on port 29999 to indicate we are ready"
272   nc -l -p 29999 &
273
274   echo "Done with master node setup"
275 fi
276
277
278 # add rancodev CI tool hostnames
279 if [[ ! -z "${__RUNRICENV_GERRIT_IP__}" && ! -z "${__RUNRICENV_GERRIT_HOST__}" ]]; then 
280   echo "${__RUNRICENV_GERRIT_IP__} ${__RUNRICENV_GERRIT_HOST__}" >> /etc/hosts
281 fi
282 if [[ ! -z "${__RUNRICENV_DOCKER_IP__}" && ! -z "${__RUNRICENV_DOCKER_HOST__}" ]]; then 
283   echo "${__RUNRICENV_DOCKER_IP__} ${__RUNRICENV_DOCKER_HOST__}" >> /etc/hosts
284 fi
285 if [[ ! -z "${__RUNRICENV_HELMREPO_IP__}" && ! -z "${__RUNRICENV_HELMREPO_HOST__}" ]]; then 
286   echo "${__RUNRICENV_HELMREPO_IP__} ${__RUNRICENV_HELMREPO_HOST__}" >> /etc/hosts
287 fi
288
289 if [ ! -z "${__RUNRICENV_HELMREPO_CERT__}" ]; then
290   cat <<EOF >/etc/ca-certificates/update.d/helm.crt
291 ${__RUNRICENV_HELMREPO_CERT__}
292 EOF
293 fi
294
295 # add cert for accessing docker registry in Azure
296 if [ ! -z "${__RUNRICENV_DOCKER_CERT__}" ]; then
297   mkdir -p /etc/docker/certs.d/${__RUNRICENV_DOCKER_HOST__}:${__RUNRICENV_DOCKER_PORT__}
298   cat <<EOF >/etc/docker/ca.crt
299 ${__RUNRICENV_DOCKER_CERT__}
300 EOF
301   cp /etc/docker/ca.crt /etc/docker/certs.d/${__RUNRICENV_DOCKER_HOST__}:${__RUNRICENV_DOCKER_PORT__}/ca.crt
302
303   service docker restart
304   systemctl enable docker.service
305   docker login -u ${__RUNRICENV_DOCKER_USER__} -p ${__RUNRICENV_DOCKER_PASS__} ${__RUNRICENV_DOCKER_HOST__}:${__RUNRICENV_DOCKER_PORT__}
306   docker pull ${__RUNRICENV_DOCKER_HOST__}:${__RUNRICENV_DOCKER_PORT__}/whoami:0.0.1
307 fi
308