|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# Copyright 2017 Istio Authors. All Rights Reserved. |
| 4 | +# |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | +# you may not use this file except in compliance with the License. |
| 7 | +# You may obtain a copy of the License at |
| 8 | +# |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | +# See the License for the specific language governing permissions and |
| 15 | +# limitations under the License. |
| 16 | +# |
| 17 | +################################################################################ |
| 18 | + |
| 19 | + |
| 20 | +# Helper functions for extending the mesh with external VMs. |
| 21 | + |
| 22 | +# Script can be sourced in other files or used from tools like ansible. |
| 23 | +# Currently the script include helpers for GKE, other providers will be added as we |
| 24 | +# test them. |
| 25 | + |
| 26 | +# Environment variables used: |
| 27 | +# |
| 28 | +# ISTIO_FILES - directory where istio artifacts are downloaded, default to current dir |
| 29 | +# ISTIO_NAMESPACE - defaults to istio-system, needs to be set for custom deployments |
| 30 | +# K8S_CLUSTER - name of the K8S cluster. |
| 31 | +# SERVICE_ACCOUNT - what account to provision on the VM. Defaults to istio.default. |
| 32 | +# SERVICE_NAMESPACE- namespace where the service account and service are running. Defaults to |
| 33 | +# the current workspace in kube config. |
| 34 | + |
| 35 | +# GCLOUD_OPTS - optional parameters for gcloud command, for example "--project P --zone Z". |
| 36 | +# If not set, defaults are used. |
| 37 | +# ISTIO_CP - command to use to copy files to the VM. |
| 38 | +# ISTIO_RUN - command to use to copy files to the VM. |
| 39 | + |
| 40 | + |
| 41 | +# Initialize internal load balancers to access K8S DNS and Istio Pilot, Mixer, CA. |
| 42 | +# Must be run once per cluster. |
| 43 | +function istioInitILB() { |
| 44 | + local NS=${ISTIO_NAMESPACE:-istio-system} |
| 45 | + |
| 46 | +cat <<EOF | kubectl apply -n $NS -f - |
| 47 | +apiVersion: v1 |
| 48 | +kind: Service |
| 49 | +metadata: |
| 50 | + name: istio-pilot-ilb |
| 51 | + annotations: |
| 52 | + cloud.google.com/load-balancer-type: "internal" |
| 53 | + labels: |
| 54 | + istio: pilot |
| 55 | +spec: |
| 56 | + type: LoadBalancer |
| 57 | + ports: |
| 58 | + - port: 8080 |
| 59 | + protocol: TCP |
| 60 | + selector: |
| 61 | + istio: pilot |
| 62 | +EOF |
| 63 | +cat <<EOF | kubectl apply -n kube-system -f - |
| 64 | +apiVersion: v1 |
| 65 | +kind: Service |
| 66 | +metadata: |
| 67 | + name: dns-ilb |
| 68 | + annotations: |
| 69 | + cloud.google.com/load-balancer-type: "internal" |
| 70 | + labels: |
| 71 | + k8s-app: kube-dns |
| 72 | +spec: |
| 73 | + type: LoadBalancer |
| 74 | + ports: |
| 75 | + - port: 53 |
| 76 | + protocol: UDP |
| 77 | + selector: |
| 78 | + k8s-app: kube-dns |
| 79 | +EOF |
| 80 | + |
| 81 | +cat <<EOF | kubectl apply -n $NS -f - |
| 82 | +apiVersion: v1 |
| 83 | +kind: Service |
| 84 | +metadata: |
| 85 | + name: mixer-ilb |
| 86 | + annotations: |
| 87 | + cloud.google.com/load-balancer-type: "internal" |
| 88 | + labels: |
| 89 | + istio: mixer |
| 90 | +spec: |
| 91 | + type: LoadBalancer |
| 92 | + ports: |
| 93 | + - port: 9091 |
| 94 | + protocol: TCP |
| 95 | + selector: |
| 96 | + istio: mixer |
| 97 | +EOF |
| 98 | + |
| 99 | +cat <<EOF | kubectl apply -n $NS -f - |
| 100 | +apiVersion: v1 |
| 101 | +kind: Service |
| 102 | +metadata: |
| 103 | + name: istio-ca-ilb |
| 104 | + annotations: |
| 105 | + cloud.google.com/load-balancer-type: "internal" |
| 106 | + labels: |
| 107 | + istio: istio-ca |
| 108 | +spec: |
| 109 | + type: LoadBalancer |
| 110 | + ports: |
| 111 | + - port: 8060 |
| 112 | + protocol: TCP |
| 113 | + selector: |
| 114 | + istio: istio-ca |
| 115 | +EOF |
| 116 | +} |
| 117 | + |
| 118 | +# Generate a kubedns file and a cluster.env |
| 119 | +# Parameters: |
| 120 | +# - name of the k8s cluster. |
| 121 | +function istioGenerateClusterConfigs() { |
| 122 | + local K8SCLUSTER=${1:-K8SCLUSTER} |
| 123 | + |
| 124 | + local NS=${ISTIO_NAMESPACE:-istio-system} |
| 125 | + |
| 126 | + # Multiple tries, it may take some time until the controllers generate the IPs |
| 127 | + for i in {1..10} |
| 128 | + do |
| 129 | + PILOT_IP=$(kubectl get -n $NS service istio-pilot-ilb -o jsonpath='{.status.loadBalancer.ingress[0].ip}') |
| 130 | + ISTIO_DNS=$(kubectl get -n kube-system service dns-ilb -o jsonpath='{.status.loadBalancer.ingress[0].ip}') |
| 131 | + MIXER_IP=$(kubectl get -n $NS service mixer-ilb -o jsonpath='{.status.loadBalancer.ingress[0].ip}') |
| 132 | + CA_IP=$(kubectl get -n $NS service istio-ca-ilb -o jsonpath='{.status.loadBalancer.ingress[0].ip}') |
| 133 | + |
| 134 | + if [ "${PILOT_IP}" == "" -o "${ISTIO_DNS}" == "" -o "${MIXER_IP}" == "" ] ; then |
| 135 | + echo Waiting for ILBs |
| 136 | + sleep 5 |
| 137 | + else |
| 138 | + break |
| 139 | + fi |
| 140 | + done |
| 141 | + |
| 142 | + if [ "${PILOT_IP}" == "" -o "${ISTIO_DNS}" == "" -o "${MIXER_IP}" == "" ] ; then |
| 143 | + echo "Failed to create ILBs" |
| 144 | + exit 1 |
| 145 | + fi |
| 146 | + |
| 147 | + #/etc/dnsmasq.d/kubedns |
| 148 | + echo "server=/svc.cluster.local/$ISTIO_DNS" > kubedns |
| 149 | + echo "address=/istio-mixer/$MIXER_IP" >> kubedns |
| 150 | + echo "address=/mixer-server/$MIXER_IP" >> kubedns |
| 151 | + echo "address=/istio-pilot/$PILOT_IP" >> kubedns |
| 152 | + echo "address=/istio-ca/$CA_IP" >> kubedns |
| 153 | + |
| 154 | + CIDR=$(gcloud container clusters describe ${K8SCLUSTER} ${GCP_OPTS:-} --format "value(servicesIpv4Cidr)") |
| 155 | + echo "ISTIO_SERVICE_CIDR=$CIDR" > cluster.env |
| 156 | +} |
| 157 | + |
| 158 | +# Get an istio service account secret, extract it to files to be provisioned on a raw VM |
| 159 | +# Params: |
| 160 | +# - service account - defaults to istio.default or SERVICE_ACCOUNT env |
| 161 | +# - service namespace - defaults to current namespace. |
| 162 | +function istio_provision_certs() { |
| 163 | + local SA=${1:-${SERVICE_ACCOUNT:-istio.default}} |
| 164 | + local NS=${2:-${SERVICE_NAMESPACE:-}} |
| 165 | + |
| 166 | + if [[ -n "$NS" ]] ; then |
| 167 | + NS="-n $NS" |
| 168 | + fi |
| 169 | + |
| 170 | + kubectl get $NS secret $SA -o jsonpath='{.data.cert-chain\.pem}' |base64 -d > cert-chain.pem |
| 171 | + kubectl get $NS secret $SA -o jsonpath='{.data.root-cert\.pem}' |base64 -d > root-cert.pem |
| 172 | + kubectl get $NS secret $SA -o jsonpath='{.data.key\.pem}' |base64 -d > key.pem |
| 173 | +} |
| 174 | + |
| 175 | + |
| 176 | +# Install required files on a VM and run the setup script. |
| 177 | +# |
| 178 | +# Must be run for each VM added to the cluster |
| 179 | +# Params: |
| 180 | +# - name of the VM - used to copy files over. |
| 181 | +# - optional service account to be provisioned (defaults to istio.default) |
| 182 | +# - optional namespace of the service account and VM services, defaults to SERVICE_NAMESPACE env |
| 183 | +# or kube config. |
| 184 | +function istioBootstrapVM() { |
| 185 | + local NAME=${1} |
| 186 | + |
| 187 | + local SA=${2:-${SERVICE_ACCOUNT:-istio.default}} |
| 188 | + local NS=${3:-${SERVICE_NAMESPACE:-}} |
| 189 | + |
| 190 | + istio_provision_certs $SA |
| 191 | + |
| 192 | + local ISTIO_FILES=${ISTIO_FILES:-.} |
| 193 | + |
| 194 | + # Copy deb, helper and config files |
| 195 | + # Reviews not copied - VMs don't support labels yet. |
| 196 | + istioCopy $NAME \ |
| 197 | + kubedns \ |
| 198 | + *.pem \ |
| 199 | + cluster.env \ |
| 200 | + $ISTIO_FILES/istio_vm_setup.sh \ |
| 201 | + $ISTIO_FILES/istio-proxy-envoy.deb \ |
| 202 | + $ISTIO_FILES/istio-agent.deb \ |
| 203 | + $ISTIO_FILES/istio-auth-node-agent.deb \ |
| 204 | + |
| 205 | + # Run the setup script. |
| 206 | + istioRun $NAME "sudo bash -c -x ./istio_vm_setup.sh" |
| 207 | +} |
| 208 | + |
| 209 | + |
| 210 | +# Helper functions for the main script |
| 211 | + |
| 212 | +# If Istio was built from source, copy the artifcats to the current directory, for use |
| 213 | +# by istioProvisionVM |
| 214 | +function istioCopyBuildFiles() { |
| 215 | + local ISTIO_IO=${ISTIO_BASE:-${GOPATH:-$HOME/go}}/src/istio.io |
| 216 | + local ISTIO_FILES=${ISTIO_FILES:-.} |
| 217 | + |
| 218 | + (cd $ISTIO_IO/proxy; bazel build tools/deb/... ) |
| 219 | + (cd $ISTIO_IO/pilot; bazel build tools/deb/... ) |
| 220 | + (cd $ISTIO_IO/auth; bazel build tools/deb/... ) |
| 221 | + |
| 222 | + cp $ISTIO_IO/proxy/bazel-bin/tools/deb/istio-proxy-envoy.deb \ |
| 223 | + $ISTIO_IO/pilot/bazel-bin/tools/deb/istio-agent.deb \ |
| 224 | + $ISTIO_IO/auth/bazel-bin/tools/deb/istio-auth-node-agent.deb \ |
| 225 | + $ISTIO_IO/istio/install/tools/istio_vm_setup.sh \ |
| 226 | + $ISTIO_FILES |
| 227 | + # For override to work |
| 228 | + chmod +w *.deb |
| 229 | +} |
| 230 | + |
| 231 | +# Copy files to the VM. |
| 232 | +# - VM name - required, destination where files will be copied |
| 233 | +# - list of files and directories to be copied |
| 234 | +function istioCopy() { |
| 235 | + # TODO: based on some env variable, use different commands for other clusters or for testing with |
| 236 | + # bare-metal machines. |
| 237 | + local NAME=$1 |
| 238 | + shift |
| 239 | + local FILES=$* |
| 240 | + |
| 241 | + ${ISTIO_CP:-gcloud compute scp --recurse ${GCP_OPTS:-}} $FILES ${NAME}: |
| 242 | +} |
| 243 | + |
| 244 | +# Run a command in a VM. |
| 245 | +# - VM name |
| 246 | +# - command to run, as one parameter. |
| 247 | +function istioRun() { |
| 248 | + local NAME=$1 |
| 249 | + local CMD=$2 |
| 250 | + |
| 251 | + ${ISTIO_RUN:-gcloud compute ssh ${GCP_OPTS:-}} $NAME --command "$CMD" |
| 252 | +} |
| 253 | + |
0 commit comments