czichy | cd6dd98 | 2022-05-23 12:05:07 +0300 | [diff] [blame] | 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" |
czichy | d44f1bc | 2023-03-13 12:24:09 +0200 | [diff] [blame] | 67 | DOCKERV="20.10.21" |
czichy | cd6dd98 | 2022-05-23 12:05:07 +0300 | [diff] [blame] | 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 |
czichy | de82854 | 2023-05-11 13:50:59 +0300 | [diff] [blame] | 173 | DOCKERVERSION="${DOCKERV}-0ubuntu1~20.04.2" # 20.10.21-0ubuntu1~20.04.2 |
czichy | cd6dd98 | 2022-05-23 12:05:07 +0300 | [diff] [blame] | 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 | |
czichy | 4e8ef19 | 2022-08-15 07:48:28 +0300 | [diff] [blame] | 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" |
czichy | cd6dd98 | 2022-05-23 12:05:07 +0300 | [diff] [blame] | 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 |