sigs.k8s.io/cluster-api-provider-azure@v1.14.3/scripts/kind-with-registry.sh (about)

     1  #!/usr/bin/env bash
     2  # Copyright 2020 The Kubernetes Authors.
     3  #
     4  # Licensed under the Apache License, Version 2.0 (the "License");
     5  # you may not use this file except in compliance with the License.
     6  # You may obtain a copy of the License at
     7  #
     8  #     http://www.apache.org/licenses/LICENSE-2.0
     9  #
    10  # Unless required by applicable law or agreed to in writing, software
    11  # distributed under the License is distributed on an "AS IS" BASIS,
    12  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  # See the License for the specific language governing permissions and
    14  # limitations under the License.
    15  
    16  set -o errexit
    17  set -o nounset
    18  set -o pipefail
    19  
    20  # Install kubectl and kind
    21  REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/..
    22  KUBECTL="${REPO_ROOT}/hack/tools/bin/kubectl"
    23  KIND="${REPO_ROOT}/hack/tools/bin/kind"
    24  AZWI_ENABLED=${AZWI:-}
    25  make --directory="${REPO_ROOT}" "${KUBECTL##*/}" "${KIND##*/}"
    26  
    27  # Export desired cluster name; default is "capz"
    28  KIND_CLUSTER_NAME="${KIND_CLUSTER_NAME:-capz}"
    29  export KIND_CLUSTER_NAME
    30  
    31  if [[ "$("${KIND}" get clusters)" =~ .*"${KIND_CLUSTER_NAME}".* ]]; then
    32    echo "cluster already exists, moving on"
    33    exit 0
    34  fi
    35  
    36  # 1. Create registry container unless it already exists
    37  reg_name='kind-registry'
    38  reg_port="${KIND_REGISTRY_PORT:-5000}"
    39  if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
    40    docker run \
    41      -d --restart=always -p "127.0.0.1:${reg_port}:5000" --name "${reg_name}" \
    42      registry:2
    43  fi
    44  
    45  # To use workload identity, service account signing key pairs base64 encoded should be exposed via the
    46  # env variables. The function creates the key pair files after reading it from the env variables.
    47  function checkAZWIENVPreReqsAndCreateFiles() {
    48    if [[ -z "${SERVICE_ACCOUNT_SIGNING_PUB}" ]]; then
    49      echo "'SERVICE_ACCOUNT_SIGNING_PUB' is not set."
    50      exit 1
    51    fi
    52  
    53    if [[ -z "${SERVICE_ACCOUNT_SIGNING_KEY}" ]]; then
    54      echo "'SERVICE_ACCOUNT_SIGNING_KEY' is not set."
    55      exit 1
    56    fi
    57    mkdir -p "$HOME"/azwi/creds
    58    echo "${SERVICE_ACCOUNT_SIGNING_PUB}" > "$HOME"/azwi/creds/sa.pub
    59    echo  "${SERVICE_ACCOUNT_SIGNING_KEY}" > "$HOME"/azwi/creds/sa.key
    60    SERVICE_ACCOUNT_ISSUER="${SERVICE_ACCOUNT_ISSUER:-https://oidcissuercapzci.blob.core.windows.net/oidc-capzci/}"
    61  }
    62  
    63  # This function create a kind cluster for Workload identity which requires key pairs path
    64  # to be mounted on the kind cluster and hence extra mount flags are required.
    65  function createKindForAZWI() {
    66    echo "creating azwi kind"
    67    cat <<EOF | "${KIND}" create cluster --name "${KIND_CLUSTER_NAME}" --config=-
    68    kind: Cluster
    69    apiVersion: kind.x-k8s.io/v1alpha4
    70    nodes:
    71    - role: control-plane
    72      extraMounts:
    73        - hostPath: $HOME/azwi/creds/sa.pub
    74          containerPath: /etc/kubernetes/pki/sa.pub
    75        - hostPath: $HOME/azwi/creds/sa.key
    76          containerPath: /etc/kubernetes/pki/sa.key
    77      kubeadmConfigPatches:
    78      - |
    79        kind: ClusterConfiguration
    80        apiServer:
    81          extraArgs:
    82            service-account-issuer: ${SERVICE_ACCOUNT_ISSUER}
    83            service-account-key-file: /etc/kubernetes/pki/sa.pub
    84            service-account-signing-key-file: /etc/kubernetes/pki/sa.key
    85        controllerManager:
    86          extraArgs:
    87            service-account-private-key-file: /etc/kubernetes/pki/sa.key
    88    containerdConfigPatches:
    89    - |-
    90      [plugins."io.containerd.grpc.v1.cri".registry]
    91         config_path = "/etc/containerd/certs.d"
    92  EOF
    93  }
    94  
    95  # 2. Create kind cluster with containerd registry config dir enabled
    96  # TODO: kind will eventually enable this by default and this patch will
    97  # be unnecessary.
    98  #
    99  # See:
   100  # https://github.com/kubernetes-sigs/kind/issues/2875
   101  # https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration
   102  # See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
   103  if [ "$AZWI_ENABLED" == 'true' ]
   104   then
   105     echo "azwi is enabled..."
   106     checkAZWIENVPreReqsAndCreateFiles
   107     createKindForAZWI
   108  else
   109    echo "azwi is not enabled..."
   110   cat <<EOF | ${KIND} create cluster --name "${KIND_CLUSTER_NAME}" --config=-
   111  kind: Cluster
   112  apiVersion: kind.x-k8s.io/v1alpha4
   113  containerdConfigPatches:
   114  - |-
   115    [plugins."io.containerd.grpc.v1.cri".registry]
   116      config_path = "/etc/containerd/certs.d"
   117  EOF
   118  fi
   119  
   120  # 3. Add the registry config to the nodes
   121  #
   122  # This is necessary because localhost resolves to loopback addresses that are
   123  # network-namespace local.
   124  # In other words: localhost in the container is not localhost on the host.
   125  #
   126  # We want a consistent name that works from both ends, so we tell containerd to
   127  # alias localhost:${reg_port} to the registry container when pulling images
   128  REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
   129  for node in $(${KIND} get nodes); do
   130    docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
   131    cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
   132  [host."http://${reg_name}:5000"]
   133  EOF
   134  done
   135  
   136  # 4. Connect the registry to the cluster network if not already connected
   137  # This allows kind to bootstrap the network but ensures they're on the same network
   138  if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
   139    docker network connect "kind" "${reg_name}"
   140  fi
   141  
   142  # 5. Document the local registry
   143  # https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
   144  "${KIND}" get kubeconfig -n "${KIND_CLUSTER_NAME}" > "${REPO_ROOT}/${KIND_CLUSTER_NAME}.kubeconfig"
   145  cat <<EOF | "${KUBECTL}" --kubeconfig "${REPO_ROOT}/${KIND_CLUSTER_NAME}.kubeconfig" apply -f -
   146  apiVersion: v1
   147  kind: ConfigMap
   148  metadata:
   149    name: local-registry-hosting
   150    namespace: kube-public
   151  data:
   152    localRegistryHosting.v1: |
   153      host: "localhost:${reg_port}"
   154      help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
   155  EOF
   156  
   157  # Wait 90s for the control plane node to be ready
   158  "${KUBECTL}" --kubeconfig "${REPO_ROOT}/${KIND_CLUSTER_NAME}.kubeconfig" wait node "${KIND_CLUSTER_NAME}-control-plane" --for=condition=ready --timeout=90s