Introduce LINKERD_DOCKER_REGISTRY and flexibilize CI workflows (#6782)

This allows overriding the docker images registry through the
`LINKERD_DOCKER_REGISTRY` environment variable, as the CLI's `--registry`
flag does (analogously to the `LINKERD_NAMESPACE` env var).

In the `integration_tests.yml` workflow we've been
wanting to test directly against GH's registry instead of having to
endure cr.l5d.io's problems. To achieve this we set `DOCKER_REGISTRY:
ghcr.io/linkerd` globally,
and all the docker scripts will use it
accordingly. And before triggering the integration tests, we copy that
value to `LINKERD_DOCKER_REGISTRY`. Note that the CLI and Helm manifests
will continue to point to `cr.l5d.io` by default when this is not
overridden.

`release.yml` still points to `cr.l5.io` because that's what users will experience,
so we want to test that right before releasing.

Another goal was to be able to run these workflows in forks by
overriding the global `DOCKER_REGISTRY` var pointing to the fork's own
registry.

## Nice side-effects

- This fixes the policy controller's image not being affected by the
`--registry` flag when installing through the CLI.
- The `--registry` flag (and overriding `LINKERD_DOCKER_REGISTRY` env var) have been added to `linkerd jaeger install`.
This commit is contained in:
Alejandro Pedraza 2021-09-01 13:39:05 -05:00 committed by GitHub
parent 8f15683177
commit cf7ccc394b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 182 additions and 75 deletions

View File

@ -12,6 +12,7 @@ permissions:
contents: read
env:
GH_ANNOTATION: true
DOCKER_REGISTRY: ghcr.io/linkerd
jobs:
docker_build:
runs-on: ubuntu-20.04
@ -28,9 +29,6 @@ jobs:
run: |
. bin/_tag.sh
echo "TAG=$(CI_FORCE_CLEAN=1 bin/root-tag)" >> $GITHUB_ENV
. bin/_docker.sh
echo "DOCKER_REGISTRY=cr.l5d.io/linkerd" >> $GITHUB_ENV
echo "DOCKER_BUILDKIT_CACHE=${{ runner.temp }}/.buildx-cache" >> $GITHUB_ENV
- name: Cache docker layers
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
@ -54,7 +52,7 @@ jobs:
ARCHIVES: /home/runner/archives
run: |
mkdir -p $ARCHIVES
docker save "cr.l5d.io/linkerd/${{ matrix.target }}:$TAG" > $ARCHIVES/${{ matrix.target }}.tar
docker save "$DOCKER_REGISTRY/${{ matrix.target }}:$TAG" > $ARCHIVES/${{ matrix.target }}.tar
# `with.path` values do not support environment variables yet, so an
# absolute path is used here.
#
@ -99,9 +97,6 @@ jobs:
run: |
. bin/_tag.sh
echo "TAG=$(CI_FORCE_CLEAN=1 bin/root-tag)" >> $GITHUB_ENV
. bin/_docker.sh
echo "DOCKER_REGISTRY=cr.l5d.io/linkerd" >> $GITHUB_ENV
- name: Download image archives
uses: actions/download-artifact@3be87be14a055c47b01d3bd88f8fe02320a9bb60
with:
@ -112,11 +107,13 @@ jobs:
- name: Install CLI
run: |
# Copy the CLI out of the local cli-bin container.
container_id=$(docker create "cr.l5d.io/linkerd/cli-bin:$TAG")
container_id=$(docker create "$DOCKER_REGISTRY/cli-bin:$TAG")
docker cp $container_id:/out/linkerd-linux-amd64 "$HOME/.linkerd"
# Validate the CLI version matches the current build tag.
[[ "$TAG" == "$($HOME/.linkerd version --short --client)" ]]
- name: Run integration tests
env:
LINKERD_DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }}
run: |
bin/tests --images archive --cleanup-docker --name ${{ matrix.integration_test }} "$HOME/.linkerd"

View File

@ -7,6 +7,7 @@ permissions:
contents: read
env:
GH_ANNOTATION: true
DOCKER_REGISTRY: cr.l5d.io/linkerd
jobs:
docker_build:
runs-on: ubuntu-20.04
@ -23,9 +24,6 @@ jobs:
run: |
. bin/_tag.sh
echo "TAG=$(CI_FORCE_CLEAN=1 bin/root-tag)" >> $GITHUB_ENV
. bin/_docker.sh
echo "DOCKER_REGISTRY=ghcr.io/linkerd" >> $GITHUB_ENV
echo "DOCKER_BUILDKIT_CACHE=${{ runner.temp }}/.buildx-cache" >> $GITHUB_ENV
- name: Cache docker layers
uses: actions/cache@c64c572235d810460d0d6876e9c705ad5002b353
@ -90,7 +88,7 @@ jobs:
echo "${{ secrets.DOCKER_GHCR_PAT }}" | docker login ghcr.io -u "${{ secrets.DOCKER_GHCR_USERNAME }}" --password-stdin
docker buildx build --push ./policy-controller/ \
-f ./policy-controller/${{ matrix.arch }}.dockerfile \
-t ghcr.io/linkerd/policy-controller:$TAG-${{ matrix.arch }}
-t $DOCKER_REGISTRY/policy-controller:$TAG-${{ matrix.arch }}
policy_controller_manifest:
runs-on: ubuntu-20.04
@ -105,22 +103,22 @@ jobs:
echo "TAG=$(CI_FORCE_CLEAN=1 bin/root-tag)" >> $GITHUB_ENV
- name: Create multiarch manifest
run: |
docker manifest create ghcr.io/linkerd/policy-controller:${TAG} \
ghcr.io/linkerd/policy-controller:${TAG}-amd64 \
ghcr.io/linkerd/policy-controller:${TAG}-arm64 \
ghcr.io/linkerd/policy-controller:${TAG}-arm
docker manifest create $DOCKER_REGISTRY/policy-controller:$TAG \
$DOCKER_REGISTRY/policy-controller:$TAG-amd64 \
$DOCKER_REGISTRY/policy-controller:$TAG-arm64 \
$DOCKER_REGISTRY/policy-controller:$TAG-arm
- name: Annotate multiarch manifest
run: |
docker manifest annotate ghcr.io/linkerd/policy-controller:$TAG \
ghcr.io/linkerd/policy-controller:${TAG}-amd64 --os=linux --arch=amd64
docker manifest annotate ghcr.io/linkerd/policy-controller:$TAG \
ghcr.io/linkerd/policy-controller:${TAG}-arm64 --os=linux --arch=arm64
docker manifest annotate ghcr.io/linkerd/policy-controller:$TAG \
ghcr.io/linkerd/policy-controller:${TAG}-arm --os=linux --arch=arm
docker manifest annotate $DOCKER_REGISTRY/policy-controller:$TAG \
$DOCKER_REGISTRY/policy-controller:${TAG}-amd64 --os=linux --arch=amd64
docker manifest annotate $DOCKER_REGISTRY/policy-controller:$TAG \
$DOCKER_REGISTRY/policy-controller:${TAG}-arm64 --os=linux --arch=arm64
docker manifest annotate $DOCKER_REGISTRY/policy-controller:$TAG \
$DOCKER_REGISTRY/policy-controller:${TAG}-arm --os=linux --arch=arm
- name: Push multiarch manifest
run: |
echo "${{ secrets.DOCKER_GHCR_PAT }}" | docker login ghcr.io -u "${{ secrets.DOCKER_GHCR_USERNAME }}" --password-stdin
docker manifest push ghcr.io/linkerd/policy-controller:$TAG
docker manifest push $DOCKER_REGISTRY/policy-controller:$TAG
# todo: Keep in sync with `integration_tests.yml`
windows_static_cli_tests:
@ -180,6 +178,8 @@ jobs:
echo "CMD=$CMD" >> $GITHUB_ENV
echo "TAG=$TAG" >> $GITHUB_ENV
- name: Run integration tests
env:
LINKERD_DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }}
run: |
bin/docker-pull-binaries $TAG
# Validate the CLI version matches the current build tag.
@ -220,6 +220,7 @@ jobs:
- name: Run integration tests
env:
RUN_ARM_TEST: 1
LINKERD_DOCKER_REGISTRY: ${{ env.DOCKER_REGISTRY }}
run: bin/tests --name deep --images preload --skip-cluster-create "$CMD"
- name: CNI tests
run: |

View File

@ -12,6 +12,7 @@ import (
"testing"
"github.com/linkerd/linkerd2/pkg/charts/linkerd2"
"github.com/linkerd/linkerd2/pkg/cmd"
"github.com/linkerd/linkerd2/pkg/k8s"
"github.com/linkerd/linkerd2/testutil"
)
@ -760,7 +761,7 @@ func TestOverwriteRegistry(t *testing.T) {
for i, tc := range testCases {
tc := tc // pin
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
actual := registryOverride(tc.image, tc.registry)
actual := cmd.RegistryOverride(tc.image, tc.registry)
if actual != tc.expected {
t.Fatalf("expected %q, but got %q", tc.expected, actual)
}

View File

@ -9,6 +9,8 @@ import (
"github.com/linkerd/linkerd2/pkg/charts"
cnicharts "github.com/linkerd/linkerd2/pkg/charts/cni"
"github.com/linkerd/linkerd2/pkg/charts/static"
"github.com/linkerd/linkerd2/pkg/cmd"
"github.com/linkerd/linkerd2/pkg/flags"
"github.com/linkerd/linkerd2/pkg/version"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
@ -66,8 +68,12 @@ func (options *cniPluginOptions) validate() error {
}
func (options *cniPluginOptions) pluginImage() string {
// env var overrides CLI flag
if override := os.Getenv(flags.EnvOverrideDockerRegistry); override != "" {
return cmd.RegistryOverride(options.cniPluginImage, override)
}
if options.dockerRegistry != defaultDockerRegistry {
return registryOverride(options.cniPluginImage, options.dockerRegistry)
return cmd.RegistryOverride(options.cniPluginImage, options.dockerRegistry)
}
return options.cniPluginImage
}
@ -95,7 +101,8 @@ assumes that the 'linkerd install' command will be executed with the
}
cmd.PersistentFlags().StringVarP(&options.linkerdVersion, "linkerd-version", "v", options.linkerdVersion, "Tag to be used for Linkerd images")
cmd.PersistentFlags().StringVar(&options.dockerRegistry, "registry", options.dockerRegistry, "Docker registry to pull images from")
cmd.PersistentFlags().StringVar(&options.dockerRegistry, "registry", options.dockerRegistry,
fmt.Sprintf("Docker registry to pull images from ($%s)", flags.EnvOverrideDockerRegistry))
cmd.PersistentFlags().Int64Var(&options.proxyUID, "proxy-uid", options.proxyUID, "Run the proxy under this user ID")
cmd.PersistentFlags().UintVar(&options.inboundPort, "inbound-port", options.inboundPort, "Proxy port to use for inbound traffic")
cmd.PersistentFlags().UintVar(&options.outboundPort, "outbound-port", options.outboundPort, "Proxy port to use for outbound traffic")

View File

@ -3,6 +3,7 @@ package cmd
import (
"context"
"errors"
"os"
"fmt"
"io/ioutil"
@ -12,6 +13,8 @@ import (
"github.com/linkerd/linkerd2/cli/flag"
l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
"github.com/linkerd/linkerd2/pkg/cmd"
flagspkg "github.com/linkerd/linkerd2/pkg/flags"
"github.com/linkerd/linkerd2/pkg/inject"
"github.com/linkerd/linkerd2/pkg/issuercerts"
"github.com/linkerd/linkerd2/pkg/k8s"
@ -305,15 +308,6 @@ func makeProxyFlags(defaults *l5dcharts.Values) ([]flag.Flag, *pflag.FlagSet) {
return nil
}),
flag.NewStringFlag(proxyFlags, "registry", defaultDockerRegistry, "Docker registry to pull images from",
func(values *l5dcharts.Values, value string) error {
values.ControllerImage = registryOverride(values.ControllerImage, value)
values.DebugContainer.Image.Name = registryOverride(values.DebugContainer.Image.Name, value)
values.Proxy.Image.Name = registryOverride(values.Proxy.Image.Name, value)
values.ProxyInit.Image.Name = registryOverride(values.ProxyInit.Image.Name, value)
return nil
}),
flag.NewStringFlag(proxyFlags, "image-pull-policy", defaults.ImagePullPolicy,
"Docker image pull policy", func(values *l5dcharts.Values, value string) error {
values.ImagePullPolicy = value
@ -425,6 +419,21 @@ func makeProxyFlags(defaults *l5dcharts.Values) ([]flag.Flag, *pflag.FlagSet) {
}),
}
registryFlag := flag.NewStringFlag(proxyFlags, "registry", defaultDockerRegistry,
fmt.Sprintf("Docker registry to pull images from ($%s)", flagspkg.EnvOverrideDockerRegistry),
func(values *l5dcharts.Values, value string) error {
values.ControllerImage = cmd.RegistryOverride(values.ControllerImage, value)
values.PolicyController.Image.Name = cmd.RegistryOverride(values.PolicyController.Image.Name, value)
values.DebugContainer.Image.Name = cmd.RegistryOverride(values.DebugContainer.Image.Name, value)
values.Proxy.Image.Name = cmd.RegistryOverride(values.Proxy.Image.Name, value)
values.ProxyInit.Image.Name = cmd.RegistryOverride(values.ProxyInit.Image.Name, value)
return nil
})
if reg := os.Getenv(flagspkg.EnvOverrideDockerRegistry); reg != "" {
registryFlag.Set(reg)
}
flags = append(flags, registryFlag)
proxyFlags.MarkDeprecated("proxy-memory", "use --proxy-memory-request instead")
proxyFlags.MarkDeprecated("proxy-cpu", "use --proxy-cpu-request instead")

View File

@ -11,6 +11,7 @@ import (
jaeger "github.com/linkerd/linkerd2/jaeger/cmd"
multicluster "github.com/linkerd/linkerd2/multicluster/cmd"
pkgcmd "github.com/linkerd/linkerd2/pkg/cmd"
"github.com/linkerd/linkerd2/pkg/flags"
"github.com/linkerd/linkerd2/pkg/healthcheck"
viz "github.com/linkerd/linkerd2/viz/cmd"
log "github.com/sirupsen/logrus"
@ -79,7 +80,7 @@ var RootCmd = &cobra.Command{
log.SetLevel(log.PanicLevel)
}
controlPlaneNamespaceFromEnv := os.Getenv("LINKERD_NAMESPACE")
controlPlaneNamespaceFromEnv := os.Getenv(flags.EnvOverrideNamespace)
if controlPlaneNamespace == defaultLinkerdNamespace && controlPlaneNamespaceFromEnv != "" {
controlPlaneNamespace = controlPlaneNamespaceFromEnv
}
@ -93,7 +94,9 @@ var RootCmd = &cobra.Command{
}
func init() {
RootCmd.PersistentFlags().StringVarP(&controlPlaneNamespace, "linkerd-namespace", "L", defaultLinkerdNamespace, "Namespace in which Linkerd is installed ($LINKERD_NAMESPACE)")
RootCmd.PersistentFlags().StringVarP(&controlPlaneNamespace, "linkerd-namespace", "L",
defaultLinkerdNamespace,
fmt.Sprintf("Namespace in which Linkerd is installed ($%s)", flags.EnvOverrideNamespace))
RootCmd.PersistentFlags().StringVarP(&cniNamespace, "cni-namespace", "", defaultCNINamespace, "Namespace in which the Linkerd CNI plugin is installed")
RootCmd.PersistentFlags().StringVar(&kubeconfigPath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests")
RootCmd.PersistentFlags().StringVar(&kubeContext, "context", "", "Name of the kubeconfig context to use")
@ -143,22 +146,6 @@ func deprecateCmd(cmd *cobra.Command) *cobra.Command {
return cmd
}
// registryOverride replaces the registry-portion of the provided image with the provided registry.
func registryOverride(image, newRegistry string) string {
if image == "" {
return image
}
registry := newRegistry
if registry != "" && !strings.HasSuffix(registry, slash) {
registry += slash
}
imageName := image
if strings.Contains(image, slash) {
imageName = image[strings.LastIndex(image, slash)+1:]
}
return registry + imageName
}
func flattenFlags(flags ...[]flag.Flag) []flag.Flag {
out := []flag.Flag{}
for _, f := range flags {

View File

@ -1099,7 +1099,7 @@ data:
policyController:
defaultAllowPolicy: all-unauthenticated
image:
name: cr.l5d.io/linkerd/policy-controller
name: my.custom.registry/linkerd-io/policy-controller
pullPolicy: ""
version: install-control-plane-version
logLevel: linkerd=info,warn
@ -1832,7 +1832,7 @@ spec:
env:
- name: RUST_LOG
value: "linkerd=info,warn"
image: cr.l5d.io/linkerd/policy-controller:install-control-plane-version
image: my.custom.registry/linkerd-io/policy-controller:install-control-plane-version
imagePullPolicy: IfNotPresent
livenessProbe:
httpGet:
@ -2221,7 +2221,7 @@ spec:
---
apiVersion: v1
data:
linkerd-config-overrides: Y29udHJvbGxlckltYWdlOiBteS5jdXN0b20ucmVnaXN0cnkvbGlua2VyZC1pby9jb250cm9sbGVyCmNvbnRyb2xsZXJJbWFnZVZlcnNpb246IGluc3RhbGwtY29udHJvbC1wbGFuZS12ZXJzaW9uCmRlYnVnQ29udGFpbmVyOgogIGltYWdlOgogICAgbmFtZTogbXkuY3VzdG9tLnJlZ2lzdHJ5L2xpbmtlcmQtaW8vZGVidWcKICAgIHZlcnNpb246IGluc3RhbGwtZGVidWctdmVyc2lvbgpoZWFydGJlYXRTY2hlZHVsZTogMSAyIDMgNCA1CmlkZW50aXR5OgogIGlzc3VlcjoKICAgIGNydEV4cGlyeTogIjIwMzAtMDgtMjZUMDc6MTM6NDdaIgogICAgdGxzOgogICAgICBjcnRQRU06IHwKICAgICAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgICAgICBNSUlCd0RDQ0FXZWdBd0lCQWdJUkFKUklnWjhSdE84RXdnMVhlcGY4VDQ0d0NnWUlLb1pJemowRUF3SXdLVEVuCiAgICAgICAgTUNVR0ExVUVBeE1lYVdSbGJuUnBkSGt1YkdsdWEyVnlaQzVqYkhWemRHVnlMbXh2WTJGc01CNFhEVEl3TURneQogICAgICAgIE9EQTNNVE0wTjFvWERUTXdNRGd5TmpBM01UTTBOMW93S1RFbk1DVUdBMVVFQXhNZWFXUmxiblJwZEhrdWJHbHUKICAgICAgICBhMlZ5WkM1amJIVnpkR1Z5TG14dlkyRnNNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUxL0ZwCiAgICAgICAgZmNSbkRjZWRMNkFqVWFYWVB2NERJTUJhSnVmT0k1Tld0eStYU1g3SmpYZ1p0TTcyZFF2UmFZYW51eEQzNkR0MQogICAgICAgIDIvSnh5aVNneEtXUmRvYXkrYU53TUc0d0RnWURWUjBQQVFIL0JBUURBZ0VHTUJJR0ExVWRFd0VCL3dRSU1BWUIKICAgICAgICBBZjhDQVFBd0hRWURWUjBPQkJZRUZJMVducnFNWUthSEhPbyt6cHlpaURxMnBPMEtNQ2tHQTFVZEVRUWlNQ0NDCiAgICAgICAgSG1sa1pXNTBhWFI1TG14cGJtdGxjbVF1WTJ4MWMzUmxjaTVzYjJOaGJEQUtCZ2dxaGtqT1BRUURBZ05IQURCRQogICAgICAgIEFpQXR1b0k1WHVDdHJHVlJ6U21SVGwycmEyOGFWOU15VFU3ZDVxblRBRkhLU2dJZ1JLQ3ZsdU9TZ0E1TzIxcDUKICAgICAgICA1MXRkcm1rSEVaUnIwcWxMU0pkSFlnRWZNems9CiAgICAgICAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQogICAgICBrZXlQRU06IHwKICAgICAgICAtLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KICAgICAgICBNSGNDQVFFRUlBQWU4bmZielp1OWMvT0IyKzh4Sk0wRno3TlV3VFFhenVsa0ZOczRUSTUrb0FvR0NDcUdTTTQ5CiAgICAgICAgQXdFSG9VUURRZ0FFMS9GcGZjUm5EY2VkTDZBalVhWFlQdjRESU1CYUp1Zk9JNU5XdHkrWFNYN0pqWGdadE03MgogICAgICAgIGRRdlJhWWFudXhEMzZEdDEyL0p4eWlTZ3hLV1Jkb2F5K1E9PQogICAgICAgIC0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS0KaWRlbnRpdHlUcnVzdEFuY2hvcnNQRU06IHwKICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICBNSUlCd1RDQ0FXYWdBd0lCQWdJUWVEWnA1bERhSXlnUTVVZk1LWnJGQVRBS0JnZ3Foa2pPUFFRREFqQXBNU2N3CiAgSlFZRFZRUURFeDVwWkdWdWRHbDBlUzVzYVc1clpYSmtMbU5zZFhOMFpYSXViRzlqWVd3d0hoY05NakF3T0RJNAogIE1EY3hNalEzV2hjTk16QXdPREkyTURjeE1qUTNXakFwTVNjd0pRWURWUVFERXg1cFpHVnVkR2wwZVM1c2FXNXIKICBaWEprTG1Oc2RYTjBaWEl1Ykc5allXd3dXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CQndOQ0FBUnFjNzBaCiAgbDF2Z3c3OXJqQjV1U0lUSUNVQTZHeWZ2U0ZmY3VJaXM3Qi9YRlNra3dBSFU1Uy9zMUFBUCtSMFRYN0hCV1VDNAogIHVhRzRXV3Npd0pLTm43bWdvM0F3YmpBT0JnTlZIUThCQWY4RUJBTUNBUVl3RWdZRFZSMFRBUUgvQkFnd0JnRUIKICAvd0lCQVRBZEJnTlZIUTRFRmdRVTVZdGpWVlBmZDdJN05MSHNuMkMyNkVCeUdWMHdLUVlEVlIwUkJDSXdJSUllCiAgYVdSbGJuUnBkSGt1YkdsdWEyVnlaQzVqYkhWemRHVnlMbXh2WTJGc01Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQwogIElRQ043bEJGTEREdmp4NlYwK1hranBLRVJSc0pZZjVhZE12bmxvRmw0OGlsSmdJaEFOdHhobmRjcitRSlB1QzgKICB2Z1VDMGQyLzlGTXVlSVZNYis0NldUQ09qc3FyCiAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQpwb2xpY3lDb250cm9sbGVyOgogIGltYWdlOgogICAgdmVyc2lvbjogaW5zdGFsbC1jb250cm9sLXBsYW5lLXZlcnNpb24KcG9saWN5VmFsaWRhdG9yOgogIGNhQnVuZGxlOiBwb2xpY3kgdmFsaWRhdG9yIENBIGJ1bmRsZQogIGNydFBFTTogcG9saWN5IHZhbGlkYXRvciBjcnQKICBrZXlQRU06IHBvbGljeSB2YWxpZGF0b3Iga2V5CnByb2ZpbGVWYWxpZGF0b3I6CiAgY2FCdW5kbGU6IHByb2ZpbGUgdmFsaWRhdG9yIENBIGJ1bmRsZQogIGNydFBFTTogcHJvZmlsZSB2YWxpZGF0b3IgY3J0CiAga2V5UEVNOiBwcm9maWxlIHZhbGlkYXRvciBrZXkKcHJveHk6CiAgaW1hZ2U6CiAgICBuYW1lOiBteS5jdXN0b20ucmVnaXN0cnkvbGlua2VyZC1pby9wcm94eQogICAgdmVyc2lvbjogaW5zdGFsbC1wcm94eS12ZXJzaW9uCnByb3h5SW5pdDoKICBpbWFnZToKICAgIG5hbWU6IG15LmN1c3RvbS5yZWdpc3RyeS9saW5rZXJkLWlvL3Byb3h5LWluaXQKcHJveHlJbmplY3RvcjoKICBjYUJ1bmRsZTogcHJveHkgaW5qZWN0b3IgQ0EgYnVuZGxlCiAgY3J0UEVNOiBwcm94eSBpbmplY3RvciBjcnQKICBrZXlQRU06IHByb3h5IGluamVjdG9yIGtleQo=
linkerd-config-overrides: Y29udHJvbGxlckltYWdlOiBteS5jdXN0b20ucmVnaXN0cnkvbGlua2VyZC1pby9jb250cm9sbGVyCmNvbnRyb2xsZXJJbWFnZVZlcnNpb246IGluc3RhbGwtY29udHJvbC1wbGFuZS12ZXJzaW9uCmRlYnVnQ29udGFpbmVyOgogIGltYWdlOgogICAgbmFtZTogbXkuY3VzdG9tLnJlZ2lzdHJ5L2xpbmtlcmQtaW8vZGVidWcKICAgIHZlcnNpb246IGluc3RhbGwtZGVidWctdmVyc2lvbgpoZWFydGJlYXRTY2hlZHVsZTogMSAyIDMgNCA1CmlkZW50aXR5OgogIGlzc3VlcjoKICAgIGNydEV4cGlyeTogIjIwMzAtMDgtMjZUMDc6MTM6NDdaIgogICAgdGxzOgogICAgICBjcnRQRU06IHwKICAgICAgICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICAgICAgICBNSUlCd0RDQ0FXZWdBd0lCQWdJUkFKUklnWjhSdE84RXdnMVhlcGY4VDQ0d0NnWUlLb1pJemowRUF3SXdLVEVuCiAgICAgICAgTUNVR0ExVUVBeE1lYVdSbGJuUnBkSGt1YkdsdWEyVnlaQzVqYkhWemRHVnlMbXh2WTJGc01CNFhEVEl3TURneQogICAgICAgIE9EQTNNVE0wTjFvWERUTXdNRGd5TmpBM01UTTBOMW93S1RFbk1DVUdBMVVFQXhNZWFXUmxiblJwZEhrdWJHbHUKICAgICAgICBhMlZ5WkM1amJIVnpkR1Z5TG14dlkyRnNNRmt3RXdZSEtvWkl6ajBDQVFZSUtvWkl6ajBEQVFjRFFnQUUxL0ZwCiAgICAgICAgZmNSbkRjZWRMNkFqVWFYWVB2NERJTUJhSnVmT0k1Tld0eStYU1g3SmpYZ1p0TTcyZFF2UmFZYW51eEQzNkR0MQogICAgICAgIDIvSnh5aVNneEtXUmRvYXkrYU53TUc0d0RnWURWUjBQQVFIL0JBUURBZ0VHTUJJR0ExVWRFd0VCL3dRSU1BWUIKICAgICAgICBBZjhDQVFBd0hRWURWUjBPQkJZRUZJMVducnFNWUthSEhPbyt6cHlpaURxMnBPMEtNQ2tHQTFVZEVRUWlNQ0NDCiAgICAgICAgSG1sa1pXNTBhWFI1TG14cGJtdGxjbVF1WTJ4MWMzUmxjaTVzYjJOaGJEQUtCZ2dxaGtqT1BRUURBZ05IQURCRQogICAgICAgIEFpQXR1b0k1WHVDdHJHVlJ6U21SVGwycmEyOGFWOU15VFU3ZDVxblRBRkhLU2dJZ1JLQ3ZsdU9TZ0E1TzIxcDUKICAgICAgICA1MXRkcm1rSEVaUnIwcWxMU0pkSFlnRWZNems9CiAgICAgICAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQogICAgICBrZXlQRU06IHwKICAgICAgICAtLS0tLUJFR0lOIEVDIFBSSVZBVEUgS0VZLS0tLS0KICAgICAgICBNSGNDQVFFRUlBQWU4bmZielp1OWMvT0IyKzh4Sk0wRno3TlV3VFFhenVsa0ZOczRUSTUrb0FvR0NDcUdTTTQ5CiAgICAgICAgQXdFSG9VUURRZ0FFMS9GcGZjUm5EY2VkTDZBalVhWFlQdjRESU1CYUp1Zk9JNU5XdHkrWFNYN0pqWGdadE03MgogICAgICAgIGRRdlJhWWFudXhEMzZEdDEyL0p4eWlTZ3hLV1Jkb2F5K1E9PQogICAgICAgIC0tLS0tRU5EIEVDIFBSSVZBVEUgS0VZLS0tLS0KaWRlbnRpdHlUcnVzdEFuY2hvcnNQRU06IHwKICAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KICBNSUlCd1RDQ0FXYWdBd0lCQWdJUWVEWnA1bERhSXlnUTVVZk1LWnJGQVRBS0JnZ3Foa2pPUFFRREFqQXBNU2N3CiAgSlFZRFZRUURFeDVwWkdWdWRHbDBlUzVzYVc1clpYSmtMbU5zZFhOMFpYSXViRzlqWVd3d0hoY05NakF3T0RJNAogIE1EY3hNalEzV2hjTk16QXdPREkyTURjeE1qUTNXakFwTVNjd0pRWURWUVFERXg1cFpHVnVkR2wwZVM1c2FXNXIKICBaWEprTG1Oc2RYTjBaWEl1Ykc5allXd3dXVEFUQmdjcWhrak9QUUlCQmdncWhrak9QUU1CQndOQ0FBUnFjNzBaCiAgbDF2Z3c3OXJqQjV1U0lUSUNVQTZHeWZ2U0ZmY3VJaXM3Qi9YRlNra3dBSFU1Uy9zMUFBUCtSMFRYN0hCV1VDNAogIHVhRzRXV3Npd0pLTm43bWdvM0F3YmpBT0JnTlZIUThCQWY4RUJBTUNBUVl3RWdZRFZSMFRBUUgvQkFnd0JnRUIKICAvd0lCQVRBZEJnTlZIUTRFRmdRVTVZdGpWVlBmZDdJN05MSHNuMkMyNkVCeUdWMHdLUVlEVlIwUkJDSXdJSUllCiAgYVdSbGJuUnBkSGt1YkdsdWEyVnlaQzVqYkhWemRHVnlMbXh2WTJGc01Bb0dDQ3FHU000OUJBTUNBMGtBTUVZQwogIElRQ043bEJGTEREdmp4NlYwK1hranBLRVJSc0pZZjVhZE12bmxvRmw0OGlsSmdJaEFOdHhobmRjcitRSlB1QzgKICB2Z1VDMGQyLzlGTXVlSVZNYis0NldUQ09qc3FyCiAgLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQpwb2xpY3lDb250cm9sbGVyOgogIGltYWdlOgogICAgbmFtZTogbXkuY3VzdG9tLnJlZ2lzdHJ5L2xpbmtlcmQtaW8vcG9saWN5LWNvbnRyb2xsZXIKICAgIHZlcnNpb246IGluc3RhbGwtY29udHJvbC1wbGFuZS12ZXJzaW9uCnBvbGljeVZhbGlkYXRvcjoKICBjYUJ1bmRsZTogcG9saWN5IHZhbGlkYXRvciBDQSBidW5kbGUKICBjcnRQRU06IHBvbGljeSB2YWxpZGF0b3IgY3J0CiAga2V5UEVNOiBwb2xpY3kgdmFsaWRhdG9yIGtleQpwcm9maWxlVmFsaWRhdG9yOgogIGNhQnVuZGxlOiBwcm9maWxlIHZhbGlkYXRvciBDQSBidW5kbGUKICBjcnRQRU06IHByb2ZpbGUgdmFsaWRhdG9yIGNydAogIGtleVBFTTogcHJvZmlsZSB2YWxpZGF0b3Iga2V5CnByb3h5OgogIGltYWdlOgogICAgbmFtZTogbXkuY3VzdG9tLnJlZ2lzdHJ5L2xpbmtlcmQtaW8vcHJveHkKICAgIHZlcnNpb246IGluc3RhbGwtcHJveHktdmVyc2lvbgpwcm94eUluaXQ6CiAgaW1hZ2U6CiAgICBuYW1lOiBteS5jdXN0b20ucmVnaXN0cnkvbGlua2VyZC1pby9wcm94eS1pbml0CnByb3h5SW5qZWN0b3I6CiAgY2FCdW5kbGU6IHByb3h5IGluamVjdG9yIENBIGJ1bmRsZQogIGNydFBFTTogcHJveHkgaW5qZWN0b3IgY3J0CiAga2V5UEVNOiBwcm94eSBpbmplY3RvciBrZXkK
kind: Secret
metadata:
creationTimestamp: null

View File

@ -186,6 +186,11 @@ func (flag *StringFlag) Apply(values *charts.Values) error {
return flag.apply(values, flag.Value)
}
// Set sets the given value to the underlying Flag
func (flag *StringFlag) Set(value string) error {
return flag.flagSet.Set(flag.name, value)
}
// IsSet returns true if and only if the Flag has been explicitly set with a value.
func (flag *StringFlag) IsSet() bool {
return flag.flagSet.Changed(flag.name)

View File

@ -2,6 +2,7 @@ package cmd
import (
"bytes"
"fmt"
"io"
"os"
"path"
@ -10,6 +11,7 @@ import (
"github.com/linkerd/linkerd2/jaeger/static"
"github.com/linkerd/linkerd2/pkg/charts"
partials "github.com/linkerd/linkerd2/pkg/charts/static"
"github.com/linkerd/linkerd2/pkg/cmd"
"github.com/linkerd/linkerd2/pkg/flags"
"github.com/linkerd/linkerd2/pkg/healthcheck"
api "github.com/linkerd/linkerd2/pkg/public"
@ -31,6 +33,7 @@ var (
)
func newCmdInstall() *cobra.Command {
var registry string
var skipChecks bool
var wait time.Duration
var options values.Options
@ -62,10 +65,12 @@ A full list of configurable values can be found at https://www.github.com/linker
})
}
return install(os.Stdout, options)
return install(os.Stdout, options, registry)
},
}
cmd.Flags().StringVar(&registry, "registry", "cr.l5d.io/linkerd",
fmt.Sprintf("Docker registry to pull jaeger-webhook image from ($%s)", flags.EnvOverrideDockerRegistry))
cmd.Flags().BoolVar(&skipChecks, "skip-checks", false, `Skip checks for linkerd core control-plane existence`)
cmd.Flags().DurationVar(&wait, "wait", 300*time.Second, "Wait for core control-plane components to be available")
@ -74,7 +79,7 @@ A full list of configurable values can be found at https://www.github.com/linker
return cmd
}
func install(w io.Writer, options values.Options) error {
func install(w io.Writer, options values.Options, registry string) error {
// Create values override
valuesOverrides, err := options.MergeValues(nil)
@ -84,10 +89,10 @@ func install(w io.Writer, options values.Options) error {
// TODO: Add any validation logic here
return render(w, valuesOverrides)
return render(w, valuesOverrides, registry)
}
func render(w io.Writer, valuesOverrides map[string]interface{}) error {
func render(w io.Writer, valuesOverrides map[string]interface{}, registry string) error {
files := []*loader.BufferedFile{
{Name: chartutil.ChartfileName},
@ -133,6 +138,15 @@ func render(w io.Writer, valuesOverrides map[string]interface{}) error {
return err
}
regOrig := vals["webhook"].(map[string]interface{})["image"].(map[string]interface{})["name"].(string)
if registry != "" {
vals["webhook"].(map[string]interface{})["image"].(map[string]interface{})["name"] = cmd.RegistryOverride(regOrig, registry)
}
// env var overrides CLI flag
if override := os.Getenv(flags.EnvOverrideDockerRegistry); override != "" {
vals["webhook"].(map[string]interface{})["image"].(map[string]interface{})["name"] = cmd.RegistryOverride(regOrig, override)
}
// Attach the final values into the `Values` field for rendering to work
renderedTemplates, err := engine.Render(chart, map[string]interface{}{"Values": vals})
if err != nil {

View File

@ -46,7 +46,7 @@ func TestRender(t *testing.T) {
t.Run(fmt.Sprintf("%d: %s", i, tc.goldenFileName), func(t *testing.T) {
var buf bytes.Buffer
// Merge overrides with default
if err := render(&buf, charts.MergeMaps(defaultValues, tc.values)); err != nil {
if err := render(&buf, charts.MergeMaps(defaultValues, tc.values), ""); err != nil {
t.Fatalf("Failed to render templates: %v", err)
}
testDataDiffer.DiffTestdata(t, tc.goldenFileName, buf.String())

View File

@ -327,7 +327,8 @@ A full list of configurable values can be found at https://github.com/linkerd/li
cmd.Flags().StringVar(&opts.gatewayNamespace, "gateway-namespace", defaultMulticlusterNamespace, "The namespace of the gateway service")
cmd.Flags().Uint32Var(&opts.serviceMirrorRetryLimit, "service-mirror-retry-limit", opts.serviceMirrorRetryLimit, "The number of times a failed update from the target cluster is allowed to be retried")
cmd.Flags().StringVar(&opts.logLevel, "log-level", opts.logLevel, "Log level for the Multicluster components")
cmd.Flags().StringVar(&opts.dockerRegistry, "registry", opts.dockerRegistry, "Docker registry to pull service mirror controller image from")
cmd.Flags().StringVar(&opts.dockerRegistry, "registry", opts.dockerRegistry,
fmt.Sprintf("Docker registry to pull service mirror controller image from ($%s)", flags.EnvOverrideDockerRegistry))
cmd.Flags().StringVarP(&opts.selector, "selector", "l", opts.selector, "Selector (label query) to filter which services in the target cluster to mirror")
cmd.Flags().StringVar(&opts.gatewayAddresses, "gateway-addresses", opts.gatewayAddresses, "If specified, overwrites gateway addresses when gateway service is not type LoadBalancer (comma separated list)")
cmd.Flags().Uint32Var(&opts.gatewayPort, "gateway-port", opts.gatewayPort, "If specified, overwrites gateway port when gateway service is not type LoadBalancer")
@ -379,6 +380,10 @@ func buildServiceMirrorValues(opts *linkOptions) (*multicluster.Values, error) {
return nil, err
}
if reg := os.Getenv(flags.EnvOverrideDockerRegistry); reg != "" {
opts.dockerRegistry = reg
}
defaults.TargetClusterName = opts.clusterName
defaults.Namespace = opts.namespace
defaults.ServiceMirrorRetryLimit = opts.serviceMirrorRetryLimit

View File

@ -146,3 +146,19 @@ func GetLabelSelector(labelKey string, labelValues ...string) (string, error) {
selector := labels.NewSelector().Add(*labelRequirement)
return selector.String(), nil
}
// RegistryOverride replaces the registry-portion of the provided image with the provided registry.
func RegistryOverride(image, newRegistry string) string {
if image == "" {
return image
}
registry := newRegistry
if registry != "" && !strings.HasSuffix(registry, "/") {
registry += "/"
}
imageName := image
if strings.Contains(image, "/") {
imageName = image[strings.LastIndex(image, "/")+1:]
}
return registry + imageName
}

View File

@ -12,6 +12,18 @@ import (
klog "k8s.io/klog/v2"
)
const (
// EnvOverrideNamespace is the environment variable used in the CLI to
// overidde the control-plane's namespace
EnvOverrideNamespace = "LINKERD_NAMESPACE"
// EnvOverrideDockerRegistry is the environment variable used in the
// CLI to override the docker images' registry in the control-plane
// manifests
EnvOverrideDockerRegistry = "LINKERD_DOCKER_REGISTRY"
)
// ConfigureAndParse adds flags that are common to all go processes. This
// func calls flag.Parse(), so it should be called after all other flags have
// been configured.

View File

@ -10,6 +10,7 @@ import (
"time"
"github.com/linkerd/linkerd2/controller/gen/client/clientset/versioned/scheme"
"github.com/linkerd/linkerd2/pkg/flags"
"github.com/linkerd/linkerd2/pkg/k8s"
"github.com/linkerd/linkerd2/pkg/version"
"github.com/linkerd/linkerd2/testutil"
@ -52,12 +53,16 @@ func parseDeployment(yamlString string) (*appsv1.Deployment, error) {
}
func TestInjectManualParams(t *testing.T) {
reg := "cr.l5d.io/linkerd"
if override := os.Getenv(flags.EnvOverrideDockerRegistry); reg != "" {
reg = override
}
injectionValidator := testutil.InjectValidator{
DisableIdentity: true,
Version: "proxy-version",
Image: "proxy-image",
InitImage: "init-image",
Image: reg + "/proxy-image",
InitImage: reg + "/init-image",
ImagePullPolicy: "Never",
ControlPort: 123,
SkipInboundPorts: "234,345",
@ -380,9 +385,13 @@ func TestInjectAutoPod(t *testing.T) {
truthy := true
falsy := false
zero := int64(0)
reg := "cr.l5d.io/linkerd"
if override := os.Getenv(flags.EnvOverrideDockerRegistry); override != "" {
reg = override
}
expectedInitContainer := v1.Container{
Name: k8s.InitContainerName,
Image: "cr.l5d.io/linkerd/proxy-init:" + version.ProxyInitVersion,
Image: reg + "/proxy-init:" + version.ProxyInitVersion,
Args: []string{
"--incoming-proxy-port", "4143",
"--outgoing-proxy-port", "4140",

View File

@ -13,6 +13,8 @@ import (
"text/template"
"time"
"github.com/linkerd/linkerd2/pkg/cmd"
"github.com/linkerd/linkerd2/pkg/flags"
"github.com/linkerd/linkerd2/pkg/healthcheck"
"github.com/linkerd/linkerd2/pkg/k8s"
"github.com/linkerd/linkerd2/pkg/tls"
@ -511,6 +513,24 @@ func helmOverridesEdge(root *tls.CA) ([]string, []string) {
"--set", "linkerdVersion=" + TestHelper.GetVersion(),
"--set", "namespace=" + TestHelper.GetVizNamespace(),
}
if override := os.Getenv(flags.EnvOverrideDockerRegistry); override != "" {
coreArgs = append(coreArgs,
"--set", "policyController.image.name="+cmd.RegistryOverride("cr.l5d.io/linkerd/policy-controller", override),
"--set", "proxy.image.name="+cmd.RegistryOverride("cr.l5d.io/linkerd/proxy", override),
"--set", "proxyInit.image.name="+cmd.RegistryOverride("cr.l5d.io/linkerd/proxy-init", override),
"--set", "controllerImage="+cmd.RegistryOverride("cr.l5d.io/linkerd/controller", override),
"--set", "debugContainer.image.name="+cmd.RegistryOverride("cr.l5d.io/linkerd/debug", override),
)
vizArgs = append(vizArgs,
"--set", "metricsAPI.image.registry="+override,
"--set", "tap.image.registry="+override,
"--set", "tapInjector.image.registry="+override,
"--set", "dashboard.image.registry="+override,
"--set", "grafana.image.registry="+override,
)
}
return coreArgs, vizArgs
}
@ -757,18 +777,40 @@ func TestOverridesSecret(t *testing.T) {
knownKeys := tree.Tree{
"controllerLogLevel": "debug",
"heartbeatSchedule": "1 2 3 4 5",
"identity": map[string]interface{}{
"issuer": map[string]interface{}{},
"identity": tree.Tree{
"issuer": tree.Tree{},
},
"identityTrustAnchorsPEM": extractValue(t, "identityTrustAnchorsPEM"),
"proxyInit": map[string]interface{}{
"proxyInit": tree.Tree{
"ignoreInboundPorts": skippedInboundPorts,
},
}
if reg := os.Getenv(flags.EnvOverrideDockerRegistry); reg != "" {
knownKeys["controllerImage"] = reg + "/controller"
knownKeys["debugContainer"] = tree.Tree{
"image": tree.Tree{
"name": reg + "/debug",
},
}
knownKeys["policyController"] = tree.Tree{
"image": tree.Tree{
"name": reg + "/policy-controller",
},
}
knownKeys["proxy"] = tree.Tree{
"image": tree.Tree{
"name": reg + "/proxy",
},
}
knownKeys["proxyInit"].(tree.Tree)["image"] = tree.Tree{
"name": reg + "/proxy-init",
}
}
// Check for fields that were added during upgrade
if TestHelper.UpgradeFromVersion() != "" {
knownKeys["proxyInit"].(map[string]interface{})["ignoreOutboundPorts"] = skippedOutboundPorts
knownKeys["proxyInit"].(tree.Tree)["ignoreOutboundPorts"] = skippedOutboundPorts
}
if TestHelper.GetClusterDomain() != "cluster.local" {
@ -776,13 +818,13 @@ func TestOverridesSecret(t *testing.T) {
}
if TestHelper.ExternalIssuer() {
knownKeys["identity"].(map[string]interface{})["issuer"].(map[string]interface{})["issuanceLifetime"] = "15s"
knownKeys["identity"].(map[string]interface{})["issuer"].(map[string]interface{})["scheme"] = "kubernetes.io/tls"
knownKeys["identity"].(tree.Tree)["issuer"].(tree.Tree)["issuanceLifetime"] = "15s"
knownKeys["identity"].(tree.Tree)["issuer"].(tree.Tree)["scheme"] = "kubernetes.io/tls"
} else {
if !TestHelper.Multicluster() {
knownKeys["identity"].(map[string]interface{})["issuer"].(map[string]interface{})["crtExpiry"] = extractValue(t, "identity", "issuer", "crtExpiry")
knownKeys["identity"].(tree.Tree)["issuer"].(tree.Tree)["crtExpiry"] = extractValue(t, "identity", "issuer", "crtExpiry")
}
knownKeys["identity"].(map[string]interface{})["issuer"].(map[string]interface{})["tls"] = map[string]interface{}{
knownKeys["identity"].(tree.Tree)["issuer"].(tree.Tree)["tls"] = tree.Tree{
"crtPEM": extractValue(t, "identity", "issuer", "tls", "crtPEM"),
"keyPEM": extractValue(t, "identity", "issuer", "tls", "keyPEM"),
}

View File

@ -92,11 +92,13 @@ func install(w io.Writer, options values.Options, ha bool) error {
return err
}
// if using -L to specify a non-standard CP namespace, make sure
// the linkerdNamespace Helm value is synced
// sync values overrides with Helm values
if controlPlaneNamespace != defaultLinkerdNamespace {
valuesOverrides["linkerdNamespace"] = controlPlaneNamespace
}
if reg := os.Getenv(flags.EnvOverrideDockerRegistry); reg != "" {
valuesOverrides["defaultRegistry"] = reg
}
if ha {
valuesOverrides, err = charts.OverrideFromFile(valuesOverrides, static.Templates, vizChartName, "values-ha.yaml")