Merge pull request #754 from weaveworks/github-actions

Migrate CI to GitHub Actions
This commit is contained in:
Stefan Prodan
2020-12-21 18:38:28 +02:00
committed by GitHub
58 changed files with 609 additions and 1648 deletions
+6 -283
View File
@@ -1,296 +1,19 @@
version: 2.1
jobs:
build-binary:
docker:
- image: circleci/golang:1.14
working_directory: ~/build
steps:
- checkout
- restore_cache:
keys:
- go-mod-v3-{{ checksum "go.sum" }}
- run:
name: Run go mod download
command: go mod download
- run:
name: Check code formatting
command: go install golang.org/x/tools/cmd/goimports && make test-fmt
- run:
name: Build Flagger
command: |
CGO_ENABLED=0 GOOS=linux go build \
-ldflags "-s -w -X github.com/weaveworks/flagger/pkg/version.REVISION=${CIRCLE_SHA1}" \
-a -installsuffix cgo -o bin/flagger ./cmd/flagger/*.go
- run:
name: Build Flagger load tester
command: |
CGO_ENABLED=0 GOOS=linux go build \
-a -installsuffix cgo -o bin/loadtester ./cmd/loadtester/*.go
- run:
name: Run unit tests
command: |
go test -race -coverprofile=coverage.txt -covermode=atomic $(go list ./pkg/...)
bash <(curl -s https://codecov.io/bash)
- run:
name: Verify code gen
command: make test-codegen
- save_cache:
key: go-mod-v3-{{ checksum "go.sum" }}
paths:
- "/go/pkg/mod/"
- persist_to_workspace:
root: bin
paths:
- flagger
- loadtester
push-container:
docker:
- image: circleci/golang:1.14
steps:
- checkout
- setup_remote_docker:
docker_layer_caching: true
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/container-push.sh
push-binary:
docker:
- image: circleci/golang:1.14
working_directory: ~/build
steps:
- checkout
- setup_remote_docker:
docker_layer_caching: true
- restore_cache:
keys:
- go-mod-v3-{{ checksum "go.sum" }}
- run: make release-notes
- run: github-release-notes -org weaveworks -repo flagger -since-latest-release -include-author > /tmp/release.txt
- run: test/goreleaser.sh
e2e-kubernetes-testing:
build:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh v1.18.2
- run: test/e2e-kubernetes.sh
- run: test/e2e-kubernetes-tests-deployment.sh
- run: test/e2e-kubernetes-cleanup.sh
- run: test/e2e-kubernetes-tests-daemonset.sh
e2e-istio-testing:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh v1.18.2
- run: test/e2e-istio.sh
- run: test/e2e-istio-dependencies.sh
- run: test/e2e-istio-tests.sh
- run: test/e2e-istio-tests-skip-analysis.sh
- run: test/e2e-kubernetes-cleanup.sh
- run: test/e2e-istio-dependencies.sh
- run: test/e2e-istio-tests-delegate.sh
e2e-gloo-testing:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh
- run: test/e2e-gloo.sh
- run: test/e2e-gloo-tests.sh
e2e-nginx-testing:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh
- run: test/e2e-nginx.sh
- run: test/e2e-nginx-tests.sh
- run: test/e2e-nginx-cleanup.sh
- run: test/e2e-nginx-custom-annotations.sh
- run: test/e2e-nginx-tests.sh
e2e-linkerd-testing:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh
- run: test/e2e-linkerd.sh
- run: test/e2e-linkerd-tests.sh
e2e-contour-testing:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh
- run: test/e2e-contour.sh
- run: test/e2e-contour-tests.sh
e2e-skipper-testing:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh
- run: test/e2e-skipper.sh
- run: test/e2e-skipper-tests.sh
- run: test/e2e-skipper-cleanup.sh
e2e-traefik-testing:
machine: true
steps:
- checkout
- attach_workspace:
at: /tmp/bin
- run: test/container-build.sh
- run: test/e2e-kind.sh
- run: test/e2e-traefik.sh
- run: test/e2e-traefik-tests.sh
- run: test/e2e-skipper-cleanup.sh
push-helm-charts:
docker:
- image: circleci/golang:1.14
steps:
- checkout
- run:
name: Install kubectl
command: sudo curl -L https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl && sudo chmod +x /usr/local/bin/kubectl
- run:
name: Install helm
command: sudo curl -L https://storage.googleapis.com/kubernetes-helm/helm-v2.14.2-linux-amd64.tar.gz | tar xz && sudo mv linux-amd64/helm /bin/helm && sudo rm -rf linux-amd64
- run:
name: Initialize helm
command: helm init --client-only --kubeconfig=$HOME/.kube/kubeconfig
- run:
name: Lint charts
command: |
helm lint ./charts/*
- run:
name: Package charts
command: |
mkdir $HOME/charts
helm package ./charts/* --destination $HOME/charts
- run:
name: Publish charts
command: |
if echo "${CIRCLE_TAG}" | grep v; then
REPOSITORY="https://weaveworksbot:${GITHUB_TOKEN}@github.com/weaveworks/flagger.git"
git config user.email weaveworksbot@users.noreply.github.com
git config user.name weaveworksbot
git remote set-url origin ${REPOSITORY}
git checkout gh-pages
mv -f $HOME/charts/*.tgz .
helm repo index . --url https://flagger.app
git add .
git commit -m "Publish Helm charts v${CIRCLE_TAG}"
git push origin gh-pages
else
echo "Not a release! Skip charts publish"
fi
- run: "echo skip"
workflows:
version: 2
build-test-push:
ignore:
jobs:
- build-binary:
- build:
filters:
branches:
ignore:
- gh-pages
- /^user-.*/
- e2e-kubernetes-testing:
requires:
- build-binary
- e2e-istio-testing:
requires:
- build-binary
- e2e-gloo-testing:
requires:
- build-binary
- e2e-nginx-testing:
requires:
- build-binary
- e2e-linkerd-testing:
requires:
- build-binary
- e2e-contour-testing:
requires:
- build-binary
- e2e-skipper-testing:
requires:
- build-binary
- e2e-traefik-testing:
requires:
- build-binary
- push-container:
requires:
- build-binary
- e2e-kubernetes-testing
- e2e-istio-testing
- e2e-gloo-testing
- e2e-nginx-testing
- e2e-linkerd-testing
- e2e-skipper-testing
- e2e-traefik-testing
filters:
branches:
only:
- master
release:
jobs:
- build-binary:
filters:
branches:
ignore: /.*/
tags:
ignore: /^chart.*/
- push-container:
requires:
- build-binary
filters:
branches:
ignore: /.*/
tags:
ignore: /^chart.*/
- push-binary:
requires:
- push-container
filters:
branches:
ignore: /.*/
tags:
ignore: /^chart.*/
- push-helm-charts:
requires:
- push-container
filters:
branches:
ignore: /.*/
tags:
ignore: /^chart.*/
- main
- github-actions
-17
View File
@@ -1,17 +0,0 @@
workflow "Publish Helm charts" {
on = "push"
resolves = ["helm-push"]
}
action "helm-lint" {
uses = "stefanprodan/gh-actions/helm@master"
args = ["lint charts/*"]
}
action "helm-push" {
needs = ["helm-lint"]
uses = "stefanprodan/gh-actions/helm-gh-pages@master"
args = ["charts/*","https://flagger.app"]
secrets = ["GITHUB_TOKEN"]
}
+47
View File
@@ -0,0 +1,47 @@
name: build
on:
pull_request:
push:
branches:
- main
- github-actions
jobs:
container:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Restore Go cache
uses: actions/cache@v1
with:
path: ~/go/pkg/mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.15.x
- name: Download modules
run: |
go mod download
go install golang.org/x/tools/cmd/goimports
- name: Run linters
run: make test-fmt test-codegen
- name: Run tests
run: go test -race -coverprofile=coverage.txt -covermode=atomic $(go list ./pkg/...)
- name: Check if working tree is dirty
run: |
if [[ $(git diff --stat) != '' ]]; then
git --no-pager diff
echo 'run make test and commit changes'
exit 1
fi
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
file: ./coverage.txt
- name: Build container image
run: docker build -t test/flagger:latest .
+35
View File
@@ -0,0 +1,35 @@
name: e2e
on:
pull_request:
push:
branches:
- main
- github-actions
jobs:
kind:
runs-on: ubuntu-latest
strategy:
matrix:
provider:
- istio
- linkerd
- contour
- nginx
- traefik
- gloo
- skipper
- kubernetes
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Kubernetes
uses: engineerd/setup-kind@v0.5.0
- name: Build container image
run: |
docker build -t test/flagger:latest .
kind load docker-image test/flagger:latest
- name: Run tests
run: |
./test/${{ matrix['provider'] }}/run.sh
+72
View File
@@ -0,0 +1,72 @@
name: release
on:
push:
tags:
- 'v*'
jobs:
build-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Prepare
id: prep
run: |
VERSION=sha-${GITHUB_SHA::8}
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF/refs\/tags\//}
fi
echo ::set-output name=BUILD_DATE::$(date -u +'%Y-%m-%dT%H:%M:%SZ')
echo ::set-output name=VERSION::${VERSION}
- name: Setup QEMU
uses: docker/setup-qemu-action@v1
with:
platforms: all
- name: Setup Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v1
with:
buildkitd-flags: "--debug"
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: fluxcdbot
password: ${{ secrets.GHCR_TOKEN }}
- name: Publish image
uses: docker/build-push-action@v2
with:
push: true
builder: ${{ steps.buildx.outputs.name }}
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64,linux/arm/v7
tags: |
ghcr.io/fluxcd/flagger:${{ steps.prep.outputs.VERSION }}
labels: |
org.opencontainers.image.title=${{ github.event.repository.name }}
org.opencontainers.image.description=${{ github.event.repository.description }}
org.opencontainers.image.url=${{ github.event.repository.html_url }}
org.opencontainers.image.source=${{ github.event.repository.html_url }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.version=${{ steps.prep.outputs.VERSION }}
org.opencontainers.image.created=${{ steps.prep.outputs.BUILD_DATE }}
- name: Check images
run: |
docker buildx imagetools inspect ghcr.io/fluxcd/flagger:${{ steps.prep.outputs.VERSION }}
- name: Publish Helm charts
uses: stefanprodan/helm-gh-pages@master
with:
token: ${{ secrets.GITHUB_TOKEN }}
charts_url: https://flagger.app
- name: Create release
uses: actions/create-release@latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: false
prerelease: false
body: |
[CHANGELOG](https://github.com/fluxcd/flagger/blob/main/CHANGELOG.md#${{ steps.prep.outputs.VERSION }})
+1
View File
@@ -20,3 +20,4 @@ artifacts/gcloud/
Makefile.dev
vendor
coverage.txt
+21 -1
View File
@@ -1,9 +1,29 @@
FROM golang:1.15-alpine as builder
ARG TARGETPLATFORM
WORKDIR /workspace
# copy modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache modules
RUN go mod download
# copy source code
COPY cmd/ cmd/
COPY pkg/ pkg/
# build
RUN CGO_ENABLED=0 go build -a -o flagger ./cmd/flagger
FROM alpine:3.12
RUN apk --no-cache add ca-certificates
USER nobody
COPY --chown=nobody:nobody /bin/flagger .
COPY --from=builder --chown=nobody:nobody /workspace/flagger .
ENTRYPOINT ["./flagger"]
+1 -1
View File
@@ -68,7 +68,7 @@ type NGrinderTask struct {
}
func (task *NGrinderTask) Hash() string {
return hash(task.canary + string(task.cloneId))
return hash(task.canary + fmt.Sprint(task.cloneId))
}
// nGrinder REST endpoints
+10 -81
View File
@@ -1,85 +1,14 @@
# Flagger end-to-end testing
The e2e testing infrastructure is powered by CircleCI and [Kubernetes Kind](https://github.com/kubernetes-sigs/kind).
The e2e testing infrastructure is powered by GitHub Actions and [Kubernetes Kind](https://github.com/kubernetes-sigs/kind).
### CircleCI e2e Istio workflow
### e2e workflow
* install latest stable kubectl [e2e-kind.sh](e2e-kind.sh)
* install Kubernetes Kind [e2e-kind.sh](e2e-kind.sh)
* create local Kubernetes cluster with kind [e2e-kind.sh](e2e-kind.sh)
* install latest stable Helm CLI [e2e-istio.sh](e2e-istio.sh)
* deploy Tiller on the local cluster [e2e-istio.sh](e2e-istio.sh)
* install Istio CRDs with Helm [e2e-istio.sh](e2e-istio.sh)
* install Istio control plane and Prometheus with Helm [e2e-istio.sh](e2e-istio.sh)
* load Flagger image onto the local cluster [e2e-istio.sh](e2e-istio.sh)
* deploy Flagger in the istio-system namespace [e2e-istio.sh](e2e-istio.sh)
* create a test namespace with Istio injection enabled [e2e-tests.sh](e2e-tests.sh)
* deploy the load tester in the test namespace [e2e-tests.sh](e2e-tests.sh)
* deploy a demo workload (podinfo) in the test namespace [e2e-tests.sh](e2e-tests.sh)
* test the canary initialization [e2e-tests.sh](e2e-tests.sh)
* test the canary analysis and promotion using weighted traffic and the load testing webhook [e2e-tests.sh](e2e-tests.sh)
* test the A/B testing analysis and promotion using cookies filters and pre/post rollout webhooks [e2e-tests.sh](e2e-tests.sh)
### CircleCI e2e Linkerd workflow
* install latest stable kubectl [e2e-kind.sh](e2e-kind.sh)
* install Kubernetes Kind [e2e-kind.sh](e2e-kind.sh)
* create local Kubernetes cluster with kind [e2e-kind.sh](e2e-kind.sh)
* install Linkerd [e2e-linkerd.sh](e2e-linkerd.sh)
* load Flagger image onto the local cluster [e2e-linkerd.sh](e2e-linkerd.sh)
* deploy Flagger in the linkerd namespace with Kustomize [e2e-linkerd.sh](e2e-linkerd.sh)
* create a test namespace with Linkerd injection enabled [e2e-linkerd-tests.sh](e2e-linkerd-tests.sh)
* deploy the load tester in the test namespace [e2e-linkerd-tests.sh](e2e-linkerd-tests.sh)
* deploy a demo workload (podinfo) in the test namespace [e2e-linkerd-tests.sh](e2e-linkerd-tests.sh)
* test the canary initialization with port discovery enabled and service target port [e2e-linkerd-tests.sh](e2e-linkerd-tests.sh)
* test the canary analysis and promotion using gRPC acceptance tests and HTTP load tests [e2e-linkerd-tests.sh](e2e-linkerd-tests.sh)
* test the canary rollback on HTTP 500 errors [e2e-linkerd-tests.sh](e2e-linkerd-tests.sh)
### CircleCI e2e NGINX ingress workflow
* install latest stable kubectl [e2e-kind.sh](e2e-kind.sh)
* install Kubernetes Kind [e2e-kind.sh](e2e-kind.sh)
* create local Kubernetes cluster with kind [e2e-kind.sh](e2e-kind.sh)
* install latest stable Helm CLI [e2e-nginx.sh](e2e-nginx.sh)
* deploy Tiller on the local cluster [e2e-nginx.sh](e2e-nginx.sh)
* install NGINX ingress with Helm [e2e-nginx.sh](e2e-nginx.sh)
* load Flagger image onto the local cluster [e2e-nginx.sh](e2e-nginx.sh)
* install Flagger and Prometheus in the ingress-nginx namespace [e2e-nginx.sh](e2e-nginx.sh)
* create a test namespace [e2e-nginx-tests.sh](e2e-nginx-tests.sh)
* deploy the load tester in the test namespace [e2e-nginx-tests.sh](e2e-nginx-tests.sh)
* deploy the demo workload (podinfo) and ingress in the test namespace [e2e-nginx-tests.sh](e2e-nginx-tests.sh)
* test the canary initialization [e2e-nginx-tests.sh](e2e-nginx-tests.sh)
* test the canary analysis and promotion using weighted traffic and the load testing webhook [e2e-nginx-tests.sh](e2e-nginx-tests.sh)
* test the A/B testing analysis and promotion using header filters and pre/post rollout webhooks [e2e-nginx-tests.sh](e2e-nginx-tests.sh)
* cleanup test environment [e2e-nginx-cleanup.sh](e2e-nginx-cleanup.sh)
* install NGINX Ingress and Flagger with custom ingress annotations prefix [e2e-nginx-custom-annotations.sh](e2e-nginx-custom-annotations.sh)
* repeat the canary and A/B testing workflow [e2e-nginx-tests.sh](e2e-nginx-tests.sh)
### CircleCI e2e Skipper ingress workflow
* install latest stable kubectl [e2e-kind.sh](e2e-kind.sh)
* install Kubernetes Kind [e2e-kind.sh](e2e-kind.sh)
* create local Kubernetes cluster with kind [e2e-kind.sh](e2e-kind.sh)
* install Skipper ingress with Kustomize [e2e-skipper.sh](e2e-skipper.sh)
* load Flagger image onto the local cluster [e2e-skipper.sh](e2e-skipper.sh)
* install Flagger and Prometheus in the flagger-system namespace [e2e-skipper.sh](e2e-skipper.sh)
* create a test namespace [e2e-skipper-tests.sh](e2e-skipper-tests.sh)
* deploy the load tester in the test namespace [e2e-skipper-tests.sh](e2e-skipper-tests.sh)
* deploy the demo workload (podinfo) and ingress in the test namespace [e2e-skipper-tests.sh](e2e-skipper-tests.sh)
* test the canary initialization [e2e-skipper-tests.sh](e2e-skipper-tests.sh)
* test the canary analysis and promotion using weighted traffic and the load testing webhook [e2e-skipper-tests.sh]e2e-skipper-tests.sh)
* cleanup test environment [e2e-skipper-cleanup.sh](e2e-skipper-cleanup.sh)
### CircleCI e2e Traefik workflow
* install latest stable kubectl [e2e-kind.sh](e2e-kind.sh)
* install Kubernetes Kind [e2e-kind.sh](e2e-kind.sh)
* create local Kubernetes cluster with kind [e2e-kind.sh](e2e-kind.sh)
* install Traeik with Helm [e2e-traefik.sh](e2e-traefik.sh)
* load Flagger image onto the local cluster [e2e-traefik.sh](e2e-traefik.sh)
* install Flagger and Prometheus in the traefik namespace [e2e-traefik.sh](e2e-traefik.sh)
* create a test namespace [e2e-traefik-tests.sh](e2e-traefik-tests.sh)
* deploy the load tester in the test namespace [e2e-traefik-tests.sh](e2e-traefik-tests.sh)
* deploy the demo workload (podinfo) and ingress in the test namespace [e2e-traefik-tests.sh](e2e-traefik-tests.sh)
* test the canary initialization [e2e-traefik-tests.sh](e2e-traefik-tests.sh)
* test the canary analysis and promotion using weighted traffic and the load testing webhook [e2e-traefik-tests.sh]e2e-traefik-tests.sh)
* create local Kubernetes cluster with KinD
* build Flagger container and load the image in KinD
* install the service mesh or ingress provider
* deploy Flagger
* create test namespace, workloads and load tester
* test the canary initialization (port discovery and metadata)
* test the canary release (progressive traffic shifting, headers routing, mirroring, analysis, promotion, rollback)
* test webhooks (conformance, load testing, pre/post rollout)
-11
View File
@@ -1,11 +0,0 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
mkdir -p ${REPO_ROOT}/bin
cp /tmp/bin/flagger ${REPO_ROOT}/bin && chmod +x ${REPO_ROOT}/bin/flagger
cp /tmp/bin/loadtester ${REPO_ROOT}/bin && chmod +x ${REPO_ROOT}/bin/loadtester
docker build -t test/flagger:latest . -f ${REPO_ROOT}/Dockerfile
-23
View File
@@ -1,23 +0,0 @@
#!/usr/bin/env bash
set -o errexit
push () {
echo $DOCKER_PASS | docker login -u=$DOCKER_USER --password-stdin
if [[ -z "$CIRCLE_TAG" ]]; then
BRANCH_COMMIT=${CIRCLE_BRANCH}-$(echo ${CIRCLE_SHA1} | head -c7);
docker tag test/flagger:latest weaveworks/flagger:${BRANCH_COMMIT};
docker push weaveworks/flagger:${BRANCH_COMMIT};
else
VER=${CIRCLE_TAG:1}
docker tag test/flagger:latest weaveworks/flagger:${VER};
docker push weaveworks/flagger:${VER};
fi
}
if [[ -z "$DOCKER_PASS" ]]; then
echo "No Docker Hub credentials, skipping image push";
else
push
fi
@@ -2,9 +2,10 @@
set -o errexit
CONTOUR_VER="v1.7.0"
REPO_ROOT=$(git rev-parse --show-toplevel)
CONTOUR_VER="v1.7.0"
mkdir -p ${REPO_ROOT}/bin
echo '>>> Installing Contour'
kubectl apply -f https://projectcontour.io/quickstart/${CONTOUR_VER}/contour.yaml
@@ -12,9 +13,6 @@ kubectl apply -f https://projectcontour.io/quickstart/${CONTOUR_VER}/contour.yam
kubectl -n projectcontour rollout status deployment/contour
kubectl -n projectcontour get all
echo '>>> Installing Flagger'
kind load docker-image test/flagger:latest
echo '>>> Installing Flagger'
helm upgrade -i flagger ${REPO_ROOT}/charts/flagger \
--namespace projectcontour \
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-canary.sh
@@ -7,16 +7,6 @@ set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
echo '>>> Installing load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
cat <<EOF | kubectl apply -f -
apiVersion: projectcontour.io/v1
kind: HTTPProxy
@@ -85,34 +75,6 @@ spec:
logCmdOutput: "true"
EOF
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo-service
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo-service
progressDeadlineSeconds: 60
service:
port: 9898
portDiscovery: true
headers:
request:
add:
x-envoy-upstream-rq-timeout-ms: "15000"
x-envoy-max-retries: "10"
x-envoy-retry-on: "gateway-error,connect-failure,refused-stream"
analysis:
interval: 15s
threshold: 15
maxWeight: 30
stepWeight: 10
EOF
echo '>>> Waiting for primary to be ready'
retries=50
count=0
@@ -132,19 +94,6 @@ kubectl -n test get httpproxy podinfo -oyaml | grep 'projectcontour.io/ingress.c
echo '✔ Canary initialization test passed'
passed=$(kubectl -n test get svc/podinfo -o jsonpath='{.spec.selector.app}' 2>&1 | { grep podinfo-primary || true; })
if [ -z "$passed" ]; then
echo -e '\u2716 podinfo selector test failed'
exit 1
fi
passed=$(kubectl -n test get svc/podinfo-service-canary -o jsonpath='{.spec.selector.app}' 2>&1 | { grep podinfo || true; })
if [ -z "$passed" ]; then
echo -e '\u2716 podinfo-service selector test failed'
exit 1
fi
echo '✔ Canary service custom metadata test passed'
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
@@ -158,11 +107,7 @@ until ${ok}; do
kubectl -n projectcontour logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n test describe deployment/podinfo
kubectl -n test describe deployment/podinfo-primary
kubectl -n test logs deployment/flagger-loadtester
kubectl -n projectcontour logs deployment/flagger
kubectl -n projectcontour get all
kubectl -n test get httpproxy podinfo -oyaml
echo "No more retries left"
exit 1
-17
View File
@@ -1,17 +0,0 @@
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: podinfo
namespace: test
labels:
app: podinfo
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: app.example.com
http:
paths:
- backend:
serviceName: podinfo
servicePort: 80
-60
View File
@@ -1,60 +0,0 @@
#
# Minimal Istio Configuration required by Flagger
#
# pilot configuration
pilot:
enabled: true
sidecar: true
resources:
requests:
cpu: 10m
memory: 128Mi
gateways:
enabled: false
istio-ingressgateway:
autoscaleMax: 1
# sidecar-injector webhook configuration
sidecarInjectorWebhook:
enabled: true
# galley configuration
galley:
enabled: false
# mixer configuration
mixer:
policy:
enabled: false
telemetry:
enabled: true
replicaCount: 1
autoscaleEnabled: false
resources:
requests:
cpu: 10m
memory: 128Mi
# addon prometheus configuration
prometheus:
enabled: true
scrapeInterval: 5s
# addon jaeger tracing configuration
tracing:
enabled: false
# Common settings.
global:
proxy:
# Resources for the sidecar.
resources:
requests:
cpu: 10m
memory: 64Mi
limits:
cpu: 1000m
memory: 256Mi
useMCP: false
-40
View File
@@ -1,40 +0,0 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
HELM_VERSION=v3.3.0
KUSTOMIZE_VERSION=3.8.1
KIND_VERSION=v0.8.1
KUBE_VERSION=v1.16.9
if [[ "$1" ]]; then
KUBE_VERSION=$1
fi
echo ">>> Installing kubectl"
curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \
chmod +x kubectl && \
sudo mv kubectl /usr/local/bin/
echo ">>> Installing kind"
curl -sSLo kind "https://github.com/kubernetes-sigs/kind/releases/download/$KIND_VERSION/kind-linux-amd64"
chmod +x kind
sudo mv kind /usr/local/bin/kind
echo ">>> Creating kind cluster"
kind create cluster --wait 5m --image kindest/node:${KUBE_VERSION}
kubectl get pods --all-namespaces
cd /tmp
echo ">>> Installing Helm"
curl -sSL https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz | tar xz && sudo mv linux-amd64/helm /usr/local/bin/ && rm -rf linux-amd64
helm repo add stable https://kubernetes-charts.storage.googleapis.com/
echo ">>> Installing Kustomize"
kustomize_url=https://github.com/kubernetes-sigs/kustomize/releases/download && \
curl -sL ${kustomize_url}/kustomize%2Fv${KUSTOMIZE_VERSION}/kustomize_v${KUSTOMIZE_VERSION}_linux_amd64.tar.gz | tar xz
chmod +x kustomize
sudo mv kustomize /usr/local/bin/kustomize
-6
View File
@@ -1,6 +0,0 @@
#!/usr/bin/env bash
set -o errexit
echo '>>> Delete test namespace'
kubectl delete namespace test --ignore-not-found=true --wait=true
-144
View File
@@ -1,144 +0,0 @@
#!/usr/bin/env bash
# This script runs e2e tests for Blue/Green initialization, analysis and promotion
# Prerequisites: Kubernetes Kind, Kustomize
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
echo '>>> Installing the load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
kubectl apply -n test -f - <<EOS
apiVersion: v1
kind: Service
metadata:
name: podinfo
spec:
ports:
- name: http
port: 9898
protocol: TCP
targetPort: http
selector:
app: podinfo
type: ClusterIP
EOS
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
provider: kubernetes
targetRef:
apiVersion: core/v1
kind: Service
name: podinfo
progressDeadlineSeconds: 60
service:
port: 9898
analysis:
interval: 15s
threshold: 10
iterations: 5
metrics:
- name: request-success-rate
threshold: 99
interval: 1m
- name: request-duration
threshold: 500
interval: 30s
webhooks:
- name: "gate"
type: confirm-rollout
url: http://flagger-loadtester.test/gate/approve
- name: acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 10s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-canary/token | grep token"
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 http://podinfo-canary.test/"
logCmdOutput: "true"
EOF
echo '>>> Waiting for primary to be ready'
kubectl -n test rollout status deploy/podinfo
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Initialized' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary initialization test passed'
echo '>>> Initializing secondary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload-v2.yaml
echo '>>> Waiting for secondary to be ready'
kubectl -n test rollout status deploy/podinfo-v2
echo '>>> Triggering canary deployment'
kubectl apply -n test -f - <<EOS
apiVersion: v1
kind: Service
metadata:
name: podinfo
spec:
ports:
- name: http
port: 9898
protocol: TCP
targetPort: http
selector:
app: podinfo-v2
type: ClusterIP
EOS
echo '>>> Waiting for canary promotion'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test describe service/podinfo-primary | grep 'podinfo-v2' && ok=true || ok=false
sleep 10
kubectl -n flagger-system logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n test describe deployment/podinfo
kubectl -n test describe deployment/podinfo-primary
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary promotion test passed'
kubectl -n flagger-system logs deployment/flagger
-218
View File
@@ -1,218 +0,0 @@
#!/usr/bin/env bash
# This script runs Linkerd e2e tests for Canary initialization, analysis and promotion
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
kubectl annotate namespace test linkerd.io/inject=enabled
echo '>>> Installing the load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1alpha1
kind: MetricTemplate
metadata:
name: latency
namespace: linkerd
spec:
provider:
type: prometheus
address: http://linkerd-prometheus.linkerd:9090
query: |
histogram_quantile(
0.99,
sum(
rate(
response_latency_ms_bucket{
namespace="{{ namespace }}",
deployment=~"{{ target }}",
direction="inbound"
}[{{ interval }}]
)
) by (le)
)
EOF
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
progressDeadlineSeconds: 60
service:
port: 80
targetPort: http
portDiscovery: true
analysis:
interval: 15s
threshold: 15
maxWeight: 50
stepWeights: [10, 20, 30, 40, 50, 60]
metrics:
- name: request-success-rate
threshold: 99
interval: 1m
- name: request-duration
threshold: 500
interval: 30s
- name: latency
templateRef:
name: latency
namespace: linkerd
threshold: 300
interval: 1m
webhooks:
- name: http-acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 30s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-canary/token | grep token"
- name: grpc-acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: bash
cmd: "grpc_health_probe -connect-timeout=1s -addr=podinfo-canary:9999"
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 http://podinfo.test/"
logCmdOutput: "true"
EOF
echo '>>> Waiting for primary to be ready'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Initialized' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n linkerd logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary initialization test passed'
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
echo '>>> Waiting for canary promotion'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test describe deployment/podinfo-primary | grep '3.1.1' && ok=true || ok=false
sleep 10
kubectl -n linkerd logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n linkerd logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '>>> Waiting for canary finalization'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Succeeded' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n linkerd logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary promotion test passed'
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
progressDeadlineSeconds: 60
service:
port: 80
targetPort: 9898
analysis:
interval: 15s
threshold: 3
maxWeight: 50
stepWeights: [10, 20, 30, 40, 50, 60]
metrics:
- name: request-success-rate
threshold: 99
interval: 1m
- name: request-duration
threshold: 500
interval: 30s
webhooks:
- name: http-acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 30s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-canary/token | grep token"
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 http://podinfo.test/status/500"
EOF
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.2
echo '>>> Waiting for canary rollback'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Failed' && ok=true || ok=false
sleep 10
kubectl -n linkerd logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n linkerd logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary rollback test passed'
-12
View File
@@ -1,12 +0,0 @@
#!/usr/bin/env bash
set -o errexit
echo '>>> Deleting NGINX Ingress'
helm delete nginx-ingress -n ingress-nginx
echo '>>> Deleting Flagger'
helm delete flagger -n ingress-nginx
echo '>>> Cleanup test namespace'
kubectl delete namespace test --ignore-not-found=true
-38
View File
@@ -1,38 +0,0 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
NGINX_HELM_VERSION=1.34.2 # ingress v0.30.0
echo '>>> Installing NGINX Ingress'
helm upgrade -i nginx-ingress stable/nginx-ingress --version=${NGINX_HELM_VERSION} \
--wait \
--namespace ingress-nginx \
--set controller.metrics.enabled=true \
--set controller.podAnnotations."prometheus\.io/scrape"=true \
--set controller.podAnnotations."prometheus\.io/port"=10254 \
--set controller.service.type=NodePort
kubectl -n ingress-nginx patch deployment/nginx-ingress-controller \
--type='json' -p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--annotations-prefix=custom.ingress.kubernetes.io"}]'
kubectl -n ingress-nginx rollout status deployment/nginx-ingress-controller
kubectl -n ingress-nginx get all
echo '>>> Loading Flagger image'
kind load docker-image test/flagger:latest
echo '>>> Installing Flagger'
helm upgrade -i flagger ${REPO_ROOT}/charts/flagger \
--namespace ingress-nginx \
--set prometheus.install=true \
--set ingressAnnotationsPrefix="custom.ingress.kubernetes.io" \
--set meshProvider=nginx \
--set crd.create=false
kubectl -n ingress-nginx set image deployment/flagger flagger=test/flagger:latest
kubectl -n ingress-nginx rollout status deployment/flagger
kubectl -n ingress-nginx rollout status deployment/flagger-prometheus
-66
View File
@@ -1,66 +0,0 @@
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
provider: skipper
progressDeadlineSeconds: 120
revertOnDeletion: true
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
ingressRef:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: podinfo-ingress
service:
# service name (defaults to targetRef.name)
name: podinfo-service
# ClusterIP port number
port: 80
# container port name or number (optional)
targetPort: http
# port name can be http or grpc (default http)
# portName: http
# add all the other container ports
# to the ClusterIP services (default false)
# portDiscovery: false
analysis:
interval: 15s
threshold: 5
maxWeight: 100
stepWeight: 10
metrics:
- name: request-success-rate
interval: 15s
# minimum req success rate (non 5xx responses)
# percentage (0-100)
thresholdRange:
min: 99
- name: request-duration
interval: 15s
# maximum req duration P99
# milliseconds
thresholdRange:
max: 500
webhooks:
- name: gate
type: confirm-rollout
url: http://flagger-loadtester.test/gate/approve
- name: acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 10s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-service-canary/token | grep token"
- name: "load test"
type: rollout
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 -host app.example.com http://skipper-ingress.kube-system"
logCmdOutput: "true"
-14
View File
@@ -1,14 +0,0 @@
#!/usr/bin/env bash
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Deleting Skipper Ingress'
kustomize build ${REPO_ROOT}/test/skipper | kubectl delete --force --wait=false -f -
echo '>>> Deleting Flagger'
kubectl delete namespace flagger-system --ignore-not-found=true --force --wait=false
echo '>>> Cleanup test namespace'
kubectl delete namespace test --ignore-not-found=true --force --wait=false
exit 0
-83
View File
@@ -1,83 +0,0 @@
#!/usr/bin/env bash
# This script runs e2e tests for Canary initialization, analysis and promotion
# Prerequisites: Kubernetes Kind and Skipper ingress controller
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test || true
echo '>>> Initialising workload'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
kubectl apply -f ${REPO_ROOT}/test/e2e-workload-ingress.yaml
echo '>>> Installing load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Create canary CRD'
kubectl apply -f ${REPO_ROOT}/test/e2e-skipper-canary.yaml
echo '>>> Waiting for primary to be ready'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Initialized' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary initialization test passed'
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
echo '>>> Waiting for canary promotion'
retries=50
count=0
ok=false
failed=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Failed' && failed=true || failed=false
if ${failed}; then
kubectl -n flagger-system logs deployment/flagger
echo "Canary failed!"
exit 1
fi
kubectl -n test describe deployment/podinfo-primary | grep '3.1.1' && ok=true || ok=false
sleep 10
kubectl -n flagger-system logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n test describe deployment/podinfo
kubectl -n test describe deployment/podinfo-primary
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '>>> Waiting for canary finalization'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Succeeded' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary promotion test passed'
-22
View File
@@ -1,22 +0,0 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Loading Flagger image'
kind load docker-image test/flagger:latest
echo '>>> Installing Skipper Ingress, Flagger and Prometheus'
# use kustomize to avoid compatibility issues:
# https://github.com/kubernetes-sigs/kustomize/issues/2390
# Skipper will throw an Prometheus warning which can be ignored:
# https://github.com/weaveworks/flagger/issues/664
kustomize build ${REPO_ROOT}/test/skipper | kubectl apply -f -
kubectl rollout status deployment/skipper-ingress -n kube-system
kubectl rollout status deployment/flagger-prometheus -n flagger-system
kubectl -n flagger-system set image deployment/flagger flagger=test/flagger:latest
kubectl -n flagger-system rollout status deployment/flagger
-17
View File
@@ -1,17 +0,0 @@
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: podinfo-ingress
namespace: test
labels:
app: podinfo
annotations:
kubernetes.io/ingress.class: skipper
spec:
rules:
- host: app.example.com
http:
paths:
- backend:
serviceName: podinfo-service
servicePort: 80
-137
View File
@@ -1,137 +0,0 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: podinfo
namespace: test
labels:
app: podinfo
spec:
minReadySeconds: 5
revisionHistoryLimit: 5
progressDeadlineSeconds: 60
strategy:
rollingUpdate:
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: podinfo
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9797"
labels:
app: podinfo
spec:
containers:
- name: podinfod
image: stefanprodan/podinfo:3.1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 9898
protocol: TCP
- name: http-metrics
containerPort: 9797
protocol: TCP
- name: grpc
containerPort: 9999
protocol: TCP
command:
- ./podinfo
- --port=9898
- --port-metrics=9797
- --grpc-port=9999
- --grpc-service-name=podinfo
- --level=info
- --random-delay=false
- --random-error=false
livenessProbe:
httpGet:
port: 9898
path: /healthz
initialDelaySeconds: 5
timeoutSeconds: 5
readinessProbe:
httpGet:
port: 9898
path: /readyz
initialDelaySeconds: 5
timeoutSeconds: 5
resources:
limits:
cpu: 1000m
memory: 128Mi
requests:
cpu: 1m
memory: 16Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: podinfo-service
namespace: test
labels:
app: podinfo
spec:
minReadySeconds: 5
revisionHistoryLimit: 5
progressDeadlineSeconds: 60
strategy:
rollingUpdate:
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: podinfo
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9797"
labels:
app: podinfo
spec:
containers:
- name: podinfod
image: stefanprodan/podinfo:3.1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 9898
protocol: TCP
- name: http-metrics
containerPort: 9797
protocol: TCP
- name: grpc
containerPort: 9999
protocol: TCP
command:
- ./podinfo
- --port=9898
- --port-metrics=9797
- --grpc-port=9999
- --grpc-service-name=podinfo
- --level=info
- --random-delay=false
- --random-error=false
livenessProbe:
httpGet:
port: 9898
path: /healthz
initialDelaySeconds: 5
timeoutSeconds: 5
readinessProbe:
httpGet:
port: 9898
path: /readyz
initialDelaySeconds: 5
timeoutSeconds: 5
resources:
limits:
cpu: 1000m
memory: 128Mi
requests:
cpu: 1m
memory: 16Mi
+4 -5
View File
@@ -5,9 +5,11 @@ set -o errexit
GLOO_VER="1.3.28"
REPO_ROOT=$(git rev-parse --show-toplevel)
mkdir -p ${REPO_ROOT}/bin
echo '>>> Installing Gloo'
helm repo add gloo https://storage.googleapis.com/solo-public-helm
kubectl create ns gloo-system
helm repo add gloo https://storage.googleapis.com/solo-public-helm
helm upgrade -i gloo gloo/gloo --version ${GLOO_VER} \
--namespace gloo-system \
--set discovery.enabled=true
@@ -16,9 +18,6 @@ kubectl -n gloo-system rollout status deployment/gloo
kubectl -n gloo-system rollout status deployment/gateway
kubectl -n gloo-system get all
echo '>>> Installing Flagger'
kind load docker-image test/flagger:latest
echo '>>> Installing Flagger'
helm upgrade -i flagger ${REPO_ROOT}/charts/flagger \
--set crd.create=false \
@@ -29,4 +28,4 @@ helm upgrade -i flagger ${REPO_ROOT}/charts/flagger \
kubectl -n gloo-system set image deployment/flagger flagger=test/flagger:latest
kubectl -n gloo-system rollout status deployment/flagger
kubectl -n gloo-system rollout status deployment/flagger-prometheus
kubectl -n gloo-system rollout status deployment/flagger-prometheus
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-canary.sh
@@ -1,22 +1,11 @@
#!/usr/bin/env bash
# This script runs e2e tests for Canary initialization, analysis and promotion
# Prerequisites: Kubernetes Kind, Helm and NGINX ingress controller
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
echo '>>> Installing load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
cat <<EOF | kubectl apply -f -
apiVersion: gateway.solo.io/v1
kind: VirtualService
@@ -65,13 +54,6 @@ spec:
- name: "gate"
type: confirm-rollout
url: http://flagger-loadtester.test/gate/approve
- name: acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 10s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-canary/token | grep token"
- name: gloo-acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
@@ -85,35 +67,6 @@ spec:
metadata:
type: cmd
cmd: "hey -z 2m -q 5 -c 2 -host app.example.com http://gateway-proxy.gloo-system"
logCmdOutput: "true"
EOF
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo-service
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo-service
progressDeadlineSeconds: 60
service:
port: 9898
portDiscovery: true
headers:
request:
add:
x-envoy-upstream-rq-timeout-ms: "15000"
x-envoy-max-retries: "10"
x-envoy-retry-on: "gateway-error,connect-failure,refused-stream"
analysis:
interval: 15s
threshold: 15
maxWeight: 30
stepWeight: 10
EOF
echo '>>> Waiting for primary to be ready'
@@ -133,19 +86,6 @@ done
echo '✔ Canary initialization test passed'
passed=$(kubectl -n test get svc/podinfo -o jsonpath='{.spec.selector.app}' 2>&1 | { grep podinfo-primary || true; })
if [ -z "$passed" ]; then
echo -e '\u2716 podinfo selector test failed'
exit 1
fi
passed=$(kubectl -n test get svc/podinfo-service-canary -o jsonpath='{.spec.selector.app}' 2>&1 | { grep podinfo || true; })
if [ -z "$passed" ]; then
echo -e '\u2716 podinfo-service selector test failed'
exit 1
fi
echo '✔ Canary service custom metadata test passed'
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
-28
View File
@@ -1,28 +0,0 @@
#!/bin/sh
set -e
TAR_FILE="/tmp/goreleaser.tar.gz"
RELEASES_URL="https://github.com/goreleaser/goreleaser/releases"
test -z "$TMPDIR" && TMPDIR="$(mktemp -d)"
last_version() {
curl -sL -o /dev/null -w %{url_effective} "$RELEASES_URL/latest" |
rev |
cut -f1 -d'/'|
rev
}
download() {
test -z "$VERSION" && VERSION="$(last_version)"
test -z "$VERSION" && {
echo "Unable to get goreleaser version." >&2
exit 1
}
rm -f "$TAR_FILE"
curl -s -L -o "$TAR_FILE" \
"$RELEASES_URL/download/$VERSION/goreleaser_$(uname -s)_$(uname -m).tar.gz"
}
download
tar -xf "$TAR_FILE" -C "$TMPDIR"
"${TMPDIR}/goreleaser" --release-notes=/tmp/release.txt
+2 -3
View File
@@ -5,6 +5,8 @@ set -o errexit
ISTIO_VER="1.8.0"
REPO_ROOT=$(git rev-parse --show-toplevel)
mkdir -p ${REPO_ROOT}/bin
echo ">>> Downloading Istio ${ISTIO_VER}"
cd ${REPO_ROOT}/bin && \
curl -L https://istio.io/downloadIstio | ISTIO_VERSION=${ISTIO_VER} sh -
@@ -19,9 +21,6 @@ kubectl -n istio-system rollout status deployment/prometheus
kubectl -n istio-system get all
echo '>>> Load Flagger image in Kind'
kind load docker-image test/flagger:latest
echo '>>> Installing Flagger'
kubectl apply -k ${REPO_ROOT}/kustomize/istio
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-canary.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-skip-analysis.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-delegation.sh
@@ -85,41 +85,12 @@ spec:
logCmdOutput: "true"
EOF
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo-service
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo-service
progressDeadlineSeconds: 60
service:
port: 9898
portDiscovery: true
headers:
request:
add:
x-envoy-upstream-rq-timeout-ms: "15000"
x-envoy-max-retries: "10"
x-envoy-retry-on: "gateway-error,connect-failure,refused-stream"
analysis:
interval: 15s
threshold: 15
maxWeight: 30
stepWeight: 10
EOF
echo '>>> Waiting for primary to be ready'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Initialized' && ok=true || ok=false
kubectl -n test get canary/podinfo-service | grep 'Initialized' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
@@ -146,11 +117,6 @@ if [ -z "$passed" ]; then
echo -e '\u2716 podinfo selector test failed'
exit 1
fi
passed=$(kubectl -n test get svc/podinfo-service-canary -o jsonpath='{.spec.selector.app}' 2>&1 | { grep podinfo || true; })
if [ -z "$passed" ]; then
echo -e '\u2716 podinfo-service selector test failed'
exit 1
fi
echo '✔ Canary service custom metadata test passed'
@@ -4,8 +4,7 @@ set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Loading Flagger image'
kind load docker-image test/flagger:latest
mkdir -p ${REPO_ROOT}/bin
echo '>>> Installing Flagger'
kubectl apply -k ${REPO_ROOT}/kustomize/kubernetes
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-deployment.sh
"$DIR"/test-daemonset.sh
@@ -7,33 +7,23 @@ set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
echo '>>> Installing the load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-daemonset.yaml
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
name: podinfo-ds
namespace: test
spec:
provider: kubernetes
targetRef:
apiVersion: apps/v1
kind: DaemonSet
name: podinfo
name: podinfo-ds
progressDeadlineSeconds: 60
service:
port: 80
targetPort: 9898
name: podinfo-svc
name: podinfo-ds
portDiscovery: true
analysis:
interval: 15s
@@ -58,13 +48,13 @@ spec:
timeout: 10s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-svc-canary/token | grep token"
cmd: "curl -sd 'test' http://podinfo-ds-canary/token | grep token"
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 http://podinfo-svc-canary.test/"
cmd: "hey -z 10m -q 10 -c 2 http://podinfo-ds-canary.test/"
logCmdOutput: "true"
EOF
@@ -73,7 +63,7 @@ retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Initialized' && ok=true || ok=false
kubectl -n test get canary/podinfo-ds | grep 'Initialized' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
@@ -86,20 +76,20 @@ done
echo '✔ Canary initialization test passed'
echo '>>> Triggering canary daemonset'
kubectl -n test set image daemonset/podinfo podinfod=stefanprodan/podinfo:3.1.1
kubectl -n test set image daemonset/podinfo-ds podinfod=stefanprodan/podinfo:3.1.1
echo '>>> Waiting for canary promotion'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test describe daemonset/podinfo-primary | grep '3.1.1' && ok=true || ok=false
kubectl -n test describe daemonset/podinfo-ds-primary | grep '3.1.1' && ok=true || ok=false
sleep 10
kubectl -n flagger-system logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n test describe daemonset/podinfo
kubectl -n test describe daemonset/podinfo-primary
kubectl -n test describe daemonset/podinfo-ds
kubectl -n test describe daemonset/podinfo-primary-ds
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
@@ -113,7 +103,7 @@ cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
name: podinfo-ds
namespace: test
spec:
revertOnDeletion: true
@@ -121,12 +111,12 @@ spec:
targetRef:
apiVersion: apps/v1
kind: DaemonSet
name: podinfo
name: podinfo-ds
progressDeadlineSeconds: 60
service:
port: 80
targetPort: 9898
name: podinfo-svc
name: podinfo-ds
portDiscovery: true
analysis:
interval: 15s
@@ -151,13 +141,13 @@ spec:
timeout: 10s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-svc-canary/token | grep token"
cmd: "curl -sd 'test' http://podinfo-ds-canary/token | grep token"
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 http://podinfo-svc-canary.test/"
cmd: "hey -z 10m -q 10 -c 2 http://podinfo-ds-canary.test/"
logCmdOutput: "true"
EOF
@@ -166,7 +156,7 @@ retries=50
count=0
ok=false
until ${ok}; do
kubectl get canary podinfo -n test -o jsonpath='{.metadata.finalizers}' | grep "finalizer.flagger.app" && ok=true || ok=false
kubectl get canary podinfo-ds -n test -o jsonpath='{.metadata.finalizers}' | grep "finalizer.flagger.app" && ok=true || ok=false
sleep 10
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
@@ -183,12 +173,12 @@ retries=50
count=0
ok=false
until ${ok}; do
kubectl get daemonset podinfo -n test -o jsonpath='{.status.numberReady}' | grep 1 && ok=true || ok=false
kubectl get daemonset podinfo-ds -n test -o jsonpath='{.status.numberReady}' | grep 1 && ok=true || ok=false
sleep 10
kubectl -n flagger-system logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n test describe canary/podinfo
kubectl -n test describe-ds canary/podinfo
echo "No more retries left"
exit 1
fi
@@ -7,16 +7,6 @@ set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
echo '>>> Installing the load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
@@ -65,7 +55,6 @@ spec:
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 http://podinfo-svc-canary.test/"
logCmdOutput: "true"
EOF
echo '>>> Waiting for primary to be ready'
@@ -5,6 +5,8 @@ set -o errexit
LINKERD_VER="stable-2.8.1"
REPO_ROOT=$(git rev-parse --show-toplevel)
mkdir -p ${REPO_ROOT}/bin
curl -SsL https://github.com/linkerd/linkerd2/releases/download/${LINKERD_VER}/linkerd2-cli-${LINKERD_VER}-linux > ${REPO_ROOT}/bin/linkerd
chmod +x ${REPO_ROOT}/bin/linkerd
@@ -15,9 +17,6 @@ ${REPO_ROOT}/bin/linkerd check
kubectl -n linkerd rollout status deployment/linkerd-controller
kubectl -n linkerd rollout status deployment/linkerd-proxy-injector
echo '>>> Load Flagger image in Kind'
kind load docker-image test/flagger:latest
echo '>>> Installing Flagger'
kubectl apply -k ${REPO_ROOT}/kustomize/linkerd
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-canary.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-steps.sh
@@ -6,17 +6,6 @@ set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
kubectl annotate namespace test linkerd.io/inject=enabled
echo '>>> Installing the load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1alpha1
kind: MetricTemplate
@@ -115,12 +104,6 @@ spec:
service:
port: 9898
portDiscovery: true
headers:
request:
add:
x-envoy-upstream-rq-timeout-ms: "15000"
x-envoy-max-retries: "10"
x-envoy-retry-on: "gateway-error,connect-failure,refused-stream"
analysis:
interval: 15s
threshold: 15
+95
View File
@@ -0,0 +1,95 @@
#!/usr/bin/env bash
# This script runs Linkerd e2e tests for Canary initialization, analysis and promotion
set -o errexit
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
progressDeadlineSeconds: 60
service:
port: 80
targetPort: http
portDiscovery: true
analysis:
interval: 15s
threshold: 15
maxWeight: 50
stepWeights: [10, 20, 30, 40, 50, 60]
metrics:
- name: request-success-rate
threshold: 99
interval: 1m
- name: request-duration
threshold: 500
interval: 30s
webhooks:
- name: load-test
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 http://podinfo.test/"
EOF
echo '>>> Waiting for primary to be ready'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Initialized' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n linkerd logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary initialization test passed'
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
echo '>>> Waiting for canary promotion'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test describe deployment/podinfo-primary | grep '3.1.1' && ok=true || ok=false
sleep 10
kubectl -n linkerd logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n linkerd logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '>>> Waiting for canary finalization'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Succeeded' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n linkerd logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary promotion test passed'
-18
View File
@@ -1,18 +0,0 @@
#!/usr/bin/env bash
# This script is intended for local workstation development convenience.
# It will run the e2e tests for Skipper and leave a working setup to play with
REPO_ROOT=$(git rev-parse --show-toplevel)
cd $REPO_ROOT
make test
make build
docker tag weaveworks/flagger:latest test/flagger:latest
make loadtester-build
(kind get clusters && kubectl delete ns/test --force) || kind create cluster --wait 5m --image kindest/node:v1.16.9
./test/e2e-skipper.sh
# port forward prometheus UI to localhost:9090
kubectl port-forward $(kubectl get pods -l=app=flagger-prometheus -o name -n flagger-system | head -n 1) 9090:9090 -n flagger-system &
./test/e2e-skipper-tests.sh
+5 -6
View File
@@ -2,12 +2,15 @@
set -o errexit
NGINX_HELM_VERSION=3.15.2 # ingress v0.41.2
REPO_ROOT=$(git rev-parse --show-toplevel)
NGINX_HELM_VERSION=1.39.1 # ingress v0.32.0
mkdir -p ${REPO_ROOT}/bin
echo '>>> Installing NGINX Ingress'
kubectl create ns ingress-nginx
helm upgrade -i nginx-ingress stable/nginx-ingress --version=${NGINX_HELM_VERSION} \
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade -i ingress-nginx ingress-nginx/ingress-nginx --version=${NGINX_HELM_VERSION} \
--wait \
--namespace ingress-nginx \
--set controller.metrics.enabled=true \
@@ -15,12 +18,8 @@ helm upgrade -i nginx-ingress stable/nginx-ingress --version=${NGINX_HELM_VERSIO
--set controller.podAnnotations."prometheus\.io/port"=10254 \
--set controller.service.type=NodePort
kubectl -n ingress-nginx rollout status deployment/nginx-ingress-controller
kubectl -n ingress-nginx get all
echo '>>> Loading Flagger image'
kind load docker-image test/flagger:latest
echo '>>> Installing Flagger'
helm upgrade -i flagger ${REPO_ROOT}/charts/flagger \
--set crd.create=false \
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-canary.sh
@@ -7,16 +7,25 @@ set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
echo '>>> Installing load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
kubectl apply -f ${REPO_ROOT}/test/e2e-ingress.yaml
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: podinfo
namespace: test
labels:
app: podinfo
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: app.example.com
http:
paths:
- backend:
serviceName: podinfo
servicePort: 80
EOF
echo '>>> Create metric templates'
cat <<EOF | kubectl apply -f -
@@ -121,35 +130,7 @@ spec:
url: http://flagger-loadtester.test/
metadata:
type: cmd
cmd: "hey -z 2m -q 10 -c 2 -host app.example.com http://nginx-ingress-controller.ingress-nginx"
EOF
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo-service
namespace: test
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo-service
progressDeadlineSeconds: 60
service:
port: 9898
portDiscovery: true
headers:
request:
add:
x-envoy-upstream-rq-timeout-ms: "15000"
x-envoy-max-retries: "10"
x-envoy-retry-on: "gateway-error,connect-failure,refused-stream"
analysis:
interval: 15s
threshold: 15
maxWeight: 30
stepWeight: 10
cmd: "hey -z 2m -q 10 -c 2 -host app.example.com http://ingress-nginx-controller.ingress-nginx"
EOF
echo '>>> Waiting for primary to be ready'
@@ -169,19 +150,6 @@ done
echo '✔ Canary initialization test passed'
passed=$(kubectl -n test get svc/podinfo -o jsonpath='{.spec.selector.app}' | { grep podinfo-primary || true; })
if [ -z "$passed" ]; then
echo -e '\u2716 podinfo selector test failed'
exit 1
fi
passed=$(kubectl -n test get svc/podinfo-service-canary -o jsonpath='{.spec.selector.app}' | { grep podinfo || true; })
if [ -z "$passed" ]; then
echo -e '\u2716 podinfo-service selector test failed'
exit 1
fi
echo '✔ Canary service custom metadata test passed'
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
@@ -276,13 +244,13 @@ spec:
timeout: 5s
metadata:
type: bash
cmd: "curl -sH 'x-user: insider' -H 'Host: app.example.com' http://nginx-ingress-controller.ingress-nginx | grep '3.1.2'"
cmd: "curl -sH 'x-user: insider' -H 'Host: app.example.com' http://ingress-nginx-controller.ingress-nginx"
- name: load-test
type: rollout
url: http://flagger-loadtester.test/
metadata:
type: cmd
cmd: "hey -z 2m -q 10 -c 2 -H 'x-user: insider' -host app.example.com http://nginx-ingress-controller.ingress-nginx"
cmd: "hey -z 2m -q 10 -c 2 -H 'x-user: insider' -host app.example.com http://ingress-nginx-controller.ingress-nginx"
EOF
echo '>>> Triggering A/B testing'
+24
View File
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
set -o errexit
KUSTOMIZE_VERSION=3.8.2
REPO_ROOT=$(git rev-parse --show-toplevel)
mkdir -p ${REPO_ROOT}/bin
echo '>>> Installing Kustomize'
cd ${REPO_ROOT}/bin && kustomize_url=https://github.com/kubernetes-sigs/kustomize/releases/download && \
curl -sL ${kustomize_url}/kustomize%2Fv${KUSTOMIZE_VERSION}/kustomize_v${KUSTOMIZE_VERSION}_linux_amd64.tar.gz | \
tar xz
echo '>>> Installing Skipper'
${REPO_ROOT}/bin/kustomize build ${REPO_ROOT}/test/skipper | kubectl apply -f -
kubectl -n kube-system rollout status deployment/skipper-ingress
echo '>>> Installing Flagger'
kubectl -n flagger-system set image deployment/flagger flagger=test/flagger:latest
kubectl -n flagger-system rollout status deployment/flagger
kubectl -n flagger-system rollout status deployment/flagger-prometheus
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-canary.sh
+120
View File
@@ -0,0 +1,120 @@
#!/usr/bin/env bash
# This script runs e2e tests for Skipper canary initialization, analysis and promotion
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating ingress'
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: podinfo-ingress
namespace: test
labels:
app: podinfo
annotations:
kubernetes.io/ingress.class: skipper
spec:
rules:
- host: app.example.com
http:
paths:
- backend:
serviceName: podinfo-service
servicePort: 80
EOF
echo '>>> Creating canary'
cat <<EOF | kubectl apply -f -
apiVersion: flagger.app/v1beta1
kind: Canary
metadata:
name: podinfo
namespace: test
spec:
provider: skipper
targetRef:
apiVersion: apps/v1
kind: Deployment
name: podinfo
ingressRef:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
name: podinfo-ingress
service:
name: podinfo-service
port: 80
targetPort: http
analysis:
interval: 15s
threshold: 5
maxWeight: 100
stepWeight: 10
metrics:
- name: request-success-rate
interval: 15s
thresholdRange:
min: 99
- name: request-duration
interval: 15s
thresholdRange:
max: 500
webhooks:
- name: acceptance-test
type: pre-rollout
url: http://flagger-loadtester.test/
timeout: 10s
metadata:
type: bash
cmd: "curl -sd 'test' http://podinfo-service-canary/token | grep token"
- name: "load test"
type: rollout
url: http://flagger-loadtester.test/
timeout: 5s
metadata:
type: cmd
cmd: "hey -z 10m -q 10 -c 2 -host app.example.com http://skipper-ingress.kube-system"
EOF
echo '>>> Waiting for primary to be ready'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test get canary/podinfo | grep 'Initialized' && ok=true || ok=false
sleep 5
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary initialization test passed'
echo '>>> Triggering canary deployment'
kubectl -n test set image deployment/podinfo podinfod=stefanprodan/podinfo:3.1.1
echo '>>> Waiting for canary promotion'
retries=50
count=0
ok=false
until ${ok}; do
kubectl -n test describe deployment/podinfo-primary | grep '3.1.1' && ok=true || ok=false
sleep 10
kubectl -n flagger-system logs deployment/flagger --tail 1
count=$(($count + 1))
if [[ ${count} -eq ${retries} ]]; then
kubectl -n test describe deployment/podinfo
kubectl -n test describe deployment/podinfo-primary
kubectl -n flagger-system logs deployment/flagger
echo "No more retries left"
exit 1
fi
done
echo '✔ Canary promotion test passed'
@@ -2,8 +2,10 @@
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
TRAEFIK_CHART_VERSION="9.11.0" # traefik 2.3.3
REPO_ROOT=$(git rev-parse --show-toplevel)
mkdir -p ${REPO_ROOT}/bin
echo '>>> Creating traefik namespace'
kubectl create ns traefik
@@ -22,9 +24,6 @@ EOF
kubectl -n traefik rollout status deployment/traefik
kubectl -n traefik get all
echo '>>> Loading Flagger image'
kind load docker-image test/flagger:latest
echo '>>> Installing Flagger'
helm upgrade -i flagger ${REPO_ROOT}/charts/flagger \
--set crd.create=false \
@@ -35,3 +34,4 @@ helm upgrade -i flagger ${REPO_ROOT}/charts/flagger \
--set image.tag=latest \
kubectl -n traefik rollout status deployment/flagger
kubectl -n traefik rollout status deployment/flagger-prometheus
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
DIR="$(cd "$(dirname "$0")" && pwd)"
"$DIR"/install.sh
"$REPO_ROOT"/test/workloads/init.sh
"$DIR"/test-canary.sh
@@ -7,16 +7,6 @@ set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Creating test namespace'
kubectl create namespace test
echo '>>> Installing load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Initialising canary'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
cat <<EOF | kubectl apply -f -
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
@@ -1,32 +1,27 @@
apiVersion: apps/v1
kind: Deployment
kind: DaemonSet
metadata:
name: podinfo-v2
name: podinfo-ds
namespace: test
labels:
app: podinfo-v2
app.kubernetes.io/name: podinfo-ds
spec:
minReadySeconds: 5
revisionHistoryLimit: 5
progressDeadlineSeconds: 60
strategy:
rollingUpdate:
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: podinfo-v2
app.kubernetes.io/name: podinfo-ds
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9797"
labels:
app: podinfo-v2
app.kubernetes.io/name: podinfo-ds
spec:
containers:
- name: podinfod
image: stefanprodan/podinfo:3.1.1
image: stefanprodan/podinfo:3.1.0
imagePullPolicy: IfNotPresent
ports:
- name: http
@@ -1,5 +1,5 @@
apiVersion: apps/v1
kind: DaemonSet
kind: Deployment
metadata:
name: podinfo
namespace: test
@@ -8,6 +8,11 @@ metadata:
spec:
minReadySeconds: 5
revisionHistoryLimit: 5
progressDeadlineSeconds: 60
strategy:
rollingUpdate:
maxUnavailable: 0
type: RollingUpdate
selector:
matchLabels:
app: podinfo
@@ -1,19 +1,23 @@
#!/usr/bin/env bash
# This script setups the scenarios for istio tests by creating a Kubernetes namespace, installing the load tester and a test workload (podinfo)
# Prerequisites: Kubernetes Kind and Istio
# This script creates the test app and load tester
set -o errexit
REPO_ROOT=$(git rev-parse --show-toplevel)
echo '>>> Delete test namespace'
kubectl delete namespace test --ignore-not-found=true --wait=true
echo '>>> Creating test namespace'
kubectl create namespace test
kubectl label namespace test istio-injection=enabled
kubectl annotate namespace test linkerd.io/inject=enabled
echo '>>> Installing the load tester'
kubectl apply -k ${REPO_ROOT}/kustomize/tester
kubectl -n test rollout status deployment/flagger-loadtester
echo '>>> Deploy podinfo'
kubectl apply -f ${REPO_ROOT}/test/e2e-workload.yaml
kubectl apply -f ${REPO_ROOT}/test/workloads/deployment.yaml
kubectl apply -f ${REPO_ROOT}/test/workloads/daemonset.yaml