diff --git a/.ci/tag-version b/.ci/tag-version index 0545f29..eb29aac 100755 --- a/.ci/tag-version +++ b/.ci/tag-version @@ -2,7 +2,7 @@ TAG=${1} VALID_TAG=false -MASTER_ONLY=true +MAIN_ONLY=true if [ "x${TAG}" == "x" ]; then echo "You must specify a tag" @@ -23,16 +23,16 @@ fi if echo "${TAG}" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+-rc\.[0-9]+$"; then VALID_TAG=true - MASTER_ONLY=false + MAIN_ONLY=false fi if echo "${TAG}" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+-rc[0-9]+$"; then VALID_TAG=true - MASTER_ONLY=false + MAIN_ONLY=false fi -if [ "${BRANCH}" != "master" ] && [ "${MASTER_ONLY}" == "true" ]; then - echo "You must only be on the master branch" +if [ "${BRANCH}" != "main" ] && [ "${MAIN_ONLY}" == "true" ]; then + echo "You must only be on the main branch" exit 12 fi @@ -46,10 +46,10 @@ MSG="version: ${TAG}" echo "$TAG" > VERSION -if [ -f chart/Chart.yaml ]; then - sed -i.bak "s/appVersion: .*/appVersion: ${TAG}/g" chart/Chart.yaml - sed -i.bak "s/tag: .*/tag: ${VTAG}/g" chart/values.yaml - rm chart/*.bak +if [ -f charts/atlas/Chart.yaml ]; then + sed -i.bak "s/appVersion: .*/appVersion: ${TAG}/g" charts/atlas/Chart.yaml + sed -i.bak "s/tag: .*/tag: ${VTAG}/g" charts/atlas/values.yaml + rm charts/atlas/*.bak fi if [ -f pkg/common/version.go ]; then diff --git a/.github/renovate.json b/.github/renovate.json index 8459fe2..c68705c 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -14,12 +14,37 @@ ] }, { - "matchDatasources": [ - "go" - ], + "groupName": "atlas-envoy", + "groupSlug": "atlas-envoy", "matchPackagePatterns": [ - "^github.com/aws/aws-sdk-go-v2/.*" + "envoy" + ], + "matchDatasources": [ + "helm" ] } + ], + "regexManagers": [ + { + "fileMatch": [ + "charts/.+.yaml$" + ], + "matchStrings": [ + "appVersion:\\s(?.*)\\s?", + "image:\\srepository:\\s(?.*)\\stag:\\s(?.*)\\s?" + ], + "datasourceTemplate": "github-releases" + }, + { + "fileMatch": [ + ".*.tmpl$" + ], + "matchStrings": [ + "chart:\\shttps://charts.goatlas.io/envoy-(?.*).tgz\\s?", + "spec:\\s+chart:\\s(?.*)\\s+version:\\s(?.*)\\s+?" + ], + "datasourceTemplate": "helm", + "registryUrlTemplate": "https://charts.goatlas.io" + } ] } \ No newline at end of file diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index 9677d79..0000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,103 +0,0 @@ -name: docker - -on: - workflow_dispatch: - push: - branches: - - master - tags: - - "v*.*.*" - pull_request: - branches: - - master - -jobs: - version: - runs-on: ubuntu-latest - if: startsWith(github.head_ref, 'renovate') == false - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Detect Version for Docker - id: docker-version - run: echo ::set-output name=version::$(SEP="-" .ci/version) - - name: Detect Version - id: version - run: echo ::set-output name=version::$(.ci/version) - outputs: - docker-version: ${{ steps.docker-version.outputs.version }} - version: ${{ steps.version.outputs.version }} - - image: - runs-on: ubuntu-latest - needs: [version] - steps: - - name: Get current date - id: date - run: echo "::set-output name=date::$(date +'%s')" - - name: Checkout - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - name: Get branch names - id: branch-name - uses: tj-actions/branch-names@v4.9 - - name: Setup Docker Metadata - id: docker_metadata - uses: crazy-max/ghaction-docker-meta@v3 - with: - images: | - ghcr.io/ekristen/atlas - tags: | - type=sha,prefix=${{ steps.branch-name.outputs.current_branch }}- - type=sha,prefix=${{ steps.branch-name.outputs.current_branch }}-,suffix=-${{ steps.date.outputs.date }} - type=ref,event=tag - type=ref,event=pr - type=raw,value=v${{ needs.version.outputs.docker-version }} - type=raw,value=${{ steps.branch-name.outputs.current_branch }} - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v1 - - name: Login to GitHub Container Registry - uses: docker/login-action@v1 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build to Registry - uses: docker/build-push-action@v2 - with: - context: . - tags: ${{ steps.docker_metadata.outputs.tags }} - labels: ${{ steps.docker_metadata.outputs.labels }} - build-args: | - BRANCH=${{ steps.branch-name.outputs.current_branch }} - cache-from: | - type=registry,ref=ghcr.io/ekristen/atlas:master - type=registry,ref=ghcr.io/ekristen/atlas:${{ steps.branch-name.outputs.current_branch }} - cache-to: type=inline - outputs: type=registry - - name: Build to Docker - uses: docker/build-push-action@v2 - with: - context: . - tags: ${{ steps.docker_metadata.outputs.tags }} - labels: ${{ steps.docker_metadata.outputs.labels }} - build-args: | - BRANCH=${{ steps.branch-name.outputs.current_branch }} - cache-from: | - type=registry,ref=ghcr.io/ekristen/atlas:master - type=registry,ref=ghcr.io/ekristen/atlas:${{ steps.branch-name.outputs.current_branch }} - cache-to: type=inline - outputs: type=docker - - name: Run Trivy vulnerability scanner in docker mode - uses: aquasecurity/trivy-action@master - if: ${{ github.event_name == 'pull_request' }} - with: - image-ref: ghcr.io/ekristen/atlas:${{ steps.docker_metadata.outputs.version }} - format: "table" - exit-code: "1" - ignore-unfixed: true - vuln-type: "os,library" - severity: "CRITICAL,HIGH" diff --git a/.github/workflows/release-charts.yml b/.github/workflows/release-charts.yml new file mode 100644 index 0000000..b19bb37 --- /dev/null +++ b/.github/workflows/release-charts.yml @@ -0,0 +1,23 @@ +name: release-charts + +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + charts: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Publish Helm charts + uses: stefanprodan/helm-gh-pages@master + with: + token: ${{ secrets.BOT_GITHUB_TOKEN }} + charts_dir: charts + charts_url: https://charts.goatlas.io + owner: goatlas-io + repository: charts + branch: gh-pages + linting: off diff --git a/.github/workflows/release-docs.yml b/.github/workflows/release-docs.yml new file mode 100644 index 0000000..5e4b79d --- /dev/null +++ b/.github/workflows/release-docs.yml @@ -0,0 +1,29 @@ +name: release-docs + +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - uses: actions/setup-python@v2 + with: + python-version: 3.x + - run: pip install mkdocs-material + - run: pip install mkdocs-material mkdocs-awesome-pages-plugin mkdocs-minify-plugin mkdocs-redirects + - run: mkdocs build + - name: Deploy to GitHub Pages + if: success() + uses: crazy-max/ghaction-github-pages@v2 + with: + repo: goatlas-io/docs + target_branch: gh-pages + build_dir: public + env: + GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }} diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml deleted file mode 100644 index ecba06c..0000000 --- a/.github/workflows/release-drafter.yml +++ /dev/null @@ -1,16 +0,0 @@ -name: Release Drafter - -on: - push: - branches: - - master - pull_request: - types: [opened, reopened, synchronize] - -jobs: - update_release_draft: - runs-on: ubuntu-latest - steps: - - uses: release-drafter/release-drafter@v5 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..d47cdf2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,92 @@ +name: release + +on: + workflow_dispatch: + push: + branches: + - main + tags: + - "v*" + pull_request: + branches: + - main + +jobs: + version: + runs-on: ubuntu-latest + if: startsWith(github.head_ref, 'renovate') == false + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Detect Version for Docker + id: docker-version + run: echo ::set-output name=VERSION::$(SEP="-" .ci/version) + - name: Detect Version + id: version + run: echo ::set-output name=VERSION::$(.ci/version) + outputs: + docker-version: ${{ steps.docker-version.outputs.VERSION }} + version: ${{ steps.version.outputs.VERSION }} + + goreleaser: + runs-on: ubuntu-latest + needs: + - version + env: + SUMMARY: ${{ needs.version.outputs.docker-version }} + VERSION: ${{ needs.version.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.16 + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract branch name + shell: bash + run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" + id: extract_branch + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v2 + if: startsWith(github.ref , 'refs/tags/v') == true + with: + distribution: goreleaser + version: latest + args: release --rm-dist + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: ${{ steps.extract_branch.outputs.branch }} + - name: Run GoReleaser in Snapshot Mode + uses: goreleaser/goreleaser-action@v2 + if: startsWith(github.ref , 'refs/tags/v') == false + with: + distribution: goreleaser + version: latest + args: release --rm-dist --snapshot + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BRANCH: ${{ steps.extract_branch.outputs.branch }} + GORELEASER_CURRENT_TAG: ${{ needs.version.outputs.docker-version }} + - name: Push Snapshot Docker Image + if: startsWith(github.ref , 'refs/tags/v') == false + run: | + docker push $(docker images -a | grep goatlas | awk '{ print $1 ":" $2 }') + - name: Artifact Upload + uses: actions/upload-artifact@v2 + if: startsWith(github.ref , 'refs/tags/v') == false + with: + name: release + path: | + release/*.tar.gz + release/config.yaml + release/checksums.txt diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 261b77f..30abd87 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,10 +4,10 @@ on: workflow_dispatch: pull_request: branches: - - master + - main push: branches: - - master + - main jobs: tests: diff --git a/.gitignore b/.gitignore index 04d0932..a4cbf87 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,11 @@ vendor hack/deployment/**/*.json hack/deployment/**/*.yaml +examples/demo*/**/*.json +examples/demo*/**/*.yaml +charts/**/*.tgz +release +archive # Files .envrc @@ -10,5 +15,5 @@ test-*.yaml chart/charts/*.tgz droplet.json envoy-values.yaml -archive helm-values.yaml +*.bak \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..72b2019 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,62 @@ +dist: release +env: + - PACKAGE_NAME=github.com/goatlas-io/atlas + - SUMMARY={{ .Env.SUMMARY }} + - VERSION={{ .Env.VERSION }} + - BRANCH={{ .Env.BRANCH }} +before: + hooks: + - go mod vendor + - go mod tidy +release: + github: + owner: goatlas-io + name: atlas +builds: + - id: linux + goos: + - linux + goarch: + - amd64 + ignore: + - goarch: 386 + ldflags: + - -X {{.Env.PACKAGE_NAME}}/pkg/common.SUMMARY={{.Env.SUMMARY}} -X {{.Env.PACKAGE_NAME}}/pkg/common.BRANCH={{.Env.BRANCH}} -X {{.Env.PACKAGE_NAME}}/pkg/common.VERSION={{.Env.VERSION}} + - id: darwin + goos: + - darwin + goarch: + - amd64 + ignore: + - goarch: 386 + ldflags: + - -X {{.Env.PACKAGE_NAME}}/pkg/common.SUMMARY={{.Env.SUMMARY}} -X {{.Env.PACKAGE_NAME}}/pkg/common.BRANCH={{.Env.BRANCH}} -X {{.Env.PACKAGE_NAME}}/pkg/common.VERSION={{.Env.VERSION}} +archives: + - replacements: + 386: i386 + amd64: x86_64 +dockers: + - use: buildx + goos: linux + goarch: amd64 + dockerfile: Dockerfile.gorelease + image_templates: + - ghcr.io/goatlas-io/atlas:{{- if .IsSnapshot -}}{{ .Version }}{{- else -}}{{ .Tag }}{{- end -}} + build_flag_templates: + - "--pull" + - "--label=org.opencontainers.image.created={{.Date}}" + - "--label=org.opencontainers.image.title={{.ProjectName}}" + - "--label=org.opencontainers.image.revision={{.FullCommit}}" + - "--label=org.opencontainers.image.version={{.Version}}" + - "--label=org.opencontainers.image.source=https://github.com/goatlas-io/atlas" + - "--platform=linux/amd64" +checksum: + name_template: "checksums.txt" +snapshot: + name_template: "{{ .Env.BRANCH }}-{{ .ShortCommit }}-{{ .Timestamp }}" +changelog: + sort: asc + filters: + exclude: + - "^docs:" + - "^test:" diff --git a/Dockerfile b/Dockerfile index 743caaa..168104e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ RUN curl --fail -sLo /tini https://github.com/krallin/tini/releases/download/${T FROM debian:stretch-slim ENTRYPOINT ["/usr/bin/tini", "--", "/usr/bin/atlas"] -RUN apt-get update && apt-get install -y ca-certificates liblz4-1 && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* RUN useradd -r -u 999 -d /home/atlas atlas COPY --from=binaries /tini /usr/bin/tini diff --git a/Dockerfile.gorelease b/Dockerfile.gorelease new file mode 100644 index 0000000..bf67a19 --- /dev/null +++ b/Dockerfile.gorelease @@ -0,0 +1,5 @@ + +FROM debian +ENTRYPOINT ["/usr/local/bin/atlas"] +RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* +COPY atlas /usr/local/bin/atlas diff --git a/Makefile b/Makefile index 4fcc325..f305224 100644 --- a/Makefile +++ b/Makefile @@ -1,25 +1,25 @@ BRANCH := $(shell bash .ci/branch) -SUMMARY := $(shell bash .ci/version) +SUMMARY := $(shell SEP="-" bash .ci/version) VERSION := $(shell cat VERSION) NAME := $(shell basename `pwd`) MODULE := $(shell head -n1 go.mod | cut -f2 -d' ') -.PHONY: docs-build docs-serve +.PHONY: docs-build docs-serve build release snapshot vendor: go mod vendor -build: - go build -ldflags "-X $(MODULE)/pkg/common.SUMMARY=$(SUMMARY) -X $(MODULE)/pkg/common.BRANCH=$(BRANCH) -X $(MODULE)/pkg/common.VERSION=$(VERSION)" -o $(NAME) - -release: vendor - go build -mod=vendor -ldflags "-X $(MODULE)/pkg/common.SUMMARY=$(SUMMARY) -X $(MODULE)/pkg/common.BRANCH=$(BRANCH) -X $(MODULE)/pkg/common.VERSION=$(VERSION)" -o $(NAME) . - -run-%: - go run -mod=vendor -ldflags "-X $(MODULE)/pkg/common.SUMMARY=$(SUMMARY) -X $(MODULE)/pkg/common.BRANCH=$(BRANCH) -X $(MODULE)/pkg/common.VERSION=$(VERSION)" main.go $* - docs-build: docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material build docs-serve: - docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material + docke/r run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material + +build: + SUMMARY=$(SUMMARY) VERSION=$(VERSION) BRANCH=$(BRANCH) goreleaser build + +release: + SUMMARY=$(SUMMARY) VERSION=$(VERSION) BRANCH=$(BRANCH) goreleaser release --skip-publish --rm-dist --skip-validate + +snapshot: + GORELEASER_CURRENT_TAG=$(SUMMARY) SUMMARY=$(SUMMARY) VERSION=$(VERSION) BRANCH=$(BRANCH) goreleaser release --snapshot --skip-publish --rm-dist \ No newline at end of file diff --git a/VERSION b/VERSION index 6c6aa7c..9e11b32 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.0 \ No newline at end of file +0.3.1 diff --git a/chart/Chart.lock b/chart/Chart.lock deleted file mode 100644 index c3446ee..0000000 --- a/chart/Chart.lock +++ /dev/null @@ -1,6 +0,0 @@ -dependencies: -- name: envoy - repository: https://charts.helm.sh/stable/ - version: 1.9.4 -digest: sha256:6308d164e7da4f068dfe73583eb5c99def7e2dc505d1e9e12d55e42aeaeb1bc0 -generated: "2021-09-06T12:01:14.803655-06:00" diff --git a/chart/Chart.yaml b/chart/Chart.yaml deleted file mode 100644 index 2bbab83..0000000 --- a/chart/Chart.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: v2 -name: atlas -version: 1.0.0 -appVersion: 1.0.0 -description: Atlas, forced by Zeus to support the heavens and the skies on his shoulders. -dependencies: -- name: envoy - version: 1.9.4 - repository: https://charts.helm.sh/stable/ \ No newline at end of file diff --git a/charts/atlas/Chart.lock b/charts/atlas/Chart.lock new file mode 100644 index 0000000..c755e83 --- /dev/null +++ b/charts/atlas/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: envoy + repository: https://charts.goatlas.io + version: 1.2.1 +digest: sha256:7e0364788c934c016a1884099f6a8c84d111bf70b49be4dd8a877fcbcc42a25d +generated: "2021-10-16T16:01:12.337906289Z" diff --git a/charts/atlas/Chart.yaml b/charts/atlas/Chart.yaml new file mode 100644 index 0000000..dd92cac --- /dev/null +++ b/charts/atlas/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +name: atlas +version: 1.0.0 +appVersion: 0.3.1 +description: Atlas delivers automated secure communications between Prometheus and Thanos Sidecars. +dependencies: +- name: envoy + version: 1.2.1 + repository: https://charts.goatlas.io \ No newline at end of file diff --git a/chart/templates/_helpers.yaml b/charts/atlas/templates/_helpers.yaml similarity index 100% rename from chart/templates/_helpers.yaml rename to charts/atlas/templates/_helpers.yaml diff --git a/chart/templates/cm-coredns.yaml b/charts/atlas/templates/cm-coredns.yaml similarity index 100% rename from chart/templates/cm-coredns.yaml rename to charts/atlas/templates/cm-coredns.yaml diff --git a/chart/templates/deployment-controller.yaml b/charts/atlas/templates/deployment-controller.yaml similarity index 96% rename from chart/templates/deployment-controller.yaml rename to charts/atlas/templates/deployment-controller.yaml index 9a7857b..abbd545 100644 --- a/chart/templates/deployment-controller.yaml +++ b/charts/atlas/templates/deployment-controller.yaml @@ -77,6 +77,8 @@ spec: value: {{ .Values.envoyads.host }} - name: ATLAS_ENVOY_ADDRESS value: {{ .Values.controller.envoy.host }} + - name: ATLAS_ALERTMANAGER_SELECTOR + value: {{ .Values.atlas.alertmanagerSelector }} {{- if .Values.resources }} resources: {{ toYaml .Values.resources | indent 10 }} diff --git a/chart/templates/deployment-coredns.yaml b/charts/atlas/templates/deployment-coredns.yaml similarity index 100% rename from chart/templates/deployment-coredns.yaml rename to charts/atlas/templates/deployment-coredns.yaml diff --git a/chart/templates/deployment-envoy-ads.yaml b/charts/atlas/templates/deployment-envoy-ads.yaml similarity index 95% rename from chart/templates/deployment-envoy-ads.yaml rename to charts/atlas/templates/deployment-envoy-ads.yaml index 8b5e2e5..5db7ca2 100644 --- a/chart/templates/deployment-envoy-ads.yaml +++ b/charts/atlas/templates/deployment-envoy-ads.yaml @@ -74,6 +74,8 @@ spec: env: - name: ATLAS_ENVOY_ADDRESS value: {{ .Values.controller.envoy.host }} + - name: ATLAS_ALERTMANAGER_SELECTOR + value: {{ .Values.atlas.alertmanagerSelector }} {{- if .Values.envoyads.resources }} resources: {{ toYaml .Values.envoyads.resources | indent 10 }} diff --git a/chart/templates/ingress-envoy-ads.yaml b/charts/atlas/templates/ingress-envoy-ads.yaml similarity index 100% rename from chart/templates/ingress-envoy-ads.yaml rename to charts/atlas/templates/ingress-envoy-ads.yaml diff --git a/chart/templates/rbac-bindings.yaml b/charts/atlas/templates/rbac-bindings.yaml similarity index 100% rename from chart/templates/rbac-bindings.yaml rename to charts/atlas/templates/rbac-bindings.yaml diff --git a/chart/templates/rbac-roles.yaml b/charts/atlas/templates/rbac-roles.yaml similarity index 100% rename from chart/templates/rbac-roles.yaml rename to charts/atlas/templates/rbac-roles.yaml diff --git a/chart/templates/rbac-sa.yaml b/charts/atlas/templates/rbac-sa.yaml similarity index 100% rename from chart/templates/rbac-sa.yaml rename to charts/atlas/templates/rbac-sa.yaml diff --git a/chart/templates/service-coredns.yaml b/charts/atlas/templates/service-coredns.yaml similarity index 100% rename from chart/templates/service-coredns.yaml rename to charts/atlas/templates/service-coredns.yaml diff --git a/chart/templates/service-envoy-ads.yaml b/charts/atlas/templates/service-envoy-ads.yaml similarity index 100% rename from chart/templates/service-envoy-ads.yaml rename to charts/atlas/templates/service-envoy-ads.yaml diff --git a/chart/values.yaml b/charts/atlas/values.yaml similarity index 90% rename from chart/values.yaml rename to charts/atlas/values.yaml index ea77e8a..a7c733b 100644 --- a/chart/values.yaml +++ b/charts/atlas/values.yaml @@ -1,6 +1,6 @@ image: - repository: ghcr.io/ekristen/atlas - tag: v1.0.0 + repository: ghcr.io/goatlas-io/atlas + tag: v0.3.1 pullPolicy: IfNotPresent pullSecret: "" @@ -12,6 +12,11 @@ rbac: metrics: enabled: true +# This is a label selector for the service that represents the +# alertmanager on the observability cluster. +atlas: + alertmanagerSelector: "app=kube-prometheus-stack-alertmanager" + controller: ports: grpc: 6305 @@ -29,10 +34,6 @@ coredns: envoyads: enabled: true - # This is a label selector for the service that represents the - # alertmanager on the observability cluster. - alertmanager: - selector: "app=kube-prometheus-stack-alertmanager" ingress: enabled: true host: envoyads.atlas.local @@ -53,10 +54,6 @@ envoy: - info - -c - /config/envoy.yaml - image: - repository: envoyproxy/envoy - tag: v1.18.3 - pullPolicy: IfNotPresent service: enabled: true ports: diff --git a/charts/envoy/Chart.yaml b/charts/envoy/Chart.yaml new file mode 100755 index 0000000..9b1ce14 --- /dev/null +++ b/charts/envoy/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +appVersion: 1.18.3 +description: Envoy is an open source edge and service proxy, designed for cloud-native applications. +home: https://goatlas.io/ +keywords: +- envoy +- proxy +- atlas +name: envoy +sources: +- https://github.com/goatlas-io/atlas +version: 1.2.1 diff --git a/charts/envoy/README.md b/charts/envoy/README.md new file mode 100644 index 0000000..4c7ed53 --- /dev/null +++ b/charts/envoy/README.md @@ -0,0 +1,8 @@ +# Envoy Chart for Atlas + +This chart was originally forked from the stable/envoy chart, but has been slightly modified to add some specific Atlas related configurations that compliment the Envoy deployment. + +## Modifications + +- Atlas Additional Alertmanager Configuration -- based on the number of alertmanagers deployed in the observability cluster, this is automatically configured. +- Atlas Alertmanager Services -- based on the number of alertmanagers deployed in the observability cluster, this is automatically configured. diff --git a/charts/envoy/templates/NOTES.txt b/charts/envoy/templates/NOTES.txt new file mode 100755 index 0000000..e69de29 diff --git a/charts/envoy/templates/_helpers.tpl b/charts/envoy/templates/_helpers.tpl new file mode 100755 index 0000000..d141d3a --- /dev/null +++ b/charts/envoy/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "envoy.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "envoy.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "envoy.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/envoy/templates/atlas-am.yaml b/charts/envoy/templates/atlas-am.yaml new file mode 100644 index 0000000..a6e9ba8 --- /dev/null +++ b/charts/envoy/templates/atlas-am.yaml @@ -0,0 +1,32 @@ +{{- range $i, $e := until (int .Values.atlas.alertmanagerCount) }} +--- +apiVersion: v1 +kind: Service +metadata: + name: alertmanager{{ $i }} +spec: + ports: + - name: http + port: 11903 + protocol: TCP + targetPort: 11903 + selector: + app: envoy + release: {{ $.Release.Name }} + type: ClusterIP + clusterIP: None +{{- end }} +{{- if gt (int .Values.atlas.alertmanagerCount) 0 }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: atlas-alertmanager-configs +stringData: + config.yaml: | + - static_configs: + - targets: +{{- range $i, $e := until (int .Values.atlas.alertmanagerCount) }} + - alertmanager{{ $i }}.{{ $.Release.Namespace }}.svc.cluster.local:11903 +{{- end }} +{{- end }} diff --git a/charts/envoy/templates/configmap.yaml b/charts/envoy/templates/configmap.yaml new file mode 100755 index 0000000..f55a4ed --- /dev/null +++ b/charts/envoy/templates/configmap.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "envoy.fullname" . }} + labels: + app: {{ template "envoy.name" . }} + chart: {{ template "envoy.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: +{{- range $key, $value := .Values.files }} + {{ $key }}: |- +{{ $value | default "" | indent 4 }} +{{- end -}} +{{- range $key, $value := .Values.templates }} + {{ $key }}: |- +{{ $valueWithDefault := default "" $value -}} +{{ tpl $valueWithDefault $ | indent 4 }} +{{- end -}} diff --git a/charts/envoy/templates/deployment.yaml b/charts/envoy/templates/deployment.yaml new file mode 100755 index 0000000..b1f92b7 --- /dev/null +++ b/charts/envoy/templates/deployment.yaml @@ -0,0 +1,122 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "envoy.fullname" . }} + labels: + app: {{ template "envoy.name" . }} + chart: {{ template "envoy.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ template "envoy.name" . }} + release: {{ .Release.Name }} + strategy: + {{ .Values.strategy | nindent 4 }} + template: + metadata: + labels: + app: {{ template "envoy.name" . }} + release: {{ .Release.Name }} + component: controller + {{- if .Values.podLabels }} + ## Custom pod labels + {{- range $key, $value := .Values.podLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + annotations: + checksum/config: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- if .Values.podAnnotations }} + ## Custom pod annotations + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + spec: + securityContext: + {{ toYaml .Values.securityContext | nindent 8 }} + {{- if .Values.priorityClassName }} + priorityClassName: "{{ .Values.priorityClassName }}" + {{- end }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- if .Values.initContainersTemplate }} + initContainers: + {{ tpl .Values.initContainersTemplate $ | nindent 8 }} + {{- end }} + containers: + + - name: envoy + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + {{ toYaml .Values.command | nindent 12 }} + args: + {{- if $.Values.argsTemplate }} + {{ tpl $.Values.argsTemplate $ | nindent 12}} + {{- else }} + {{ toYaml .Values.args | nindent 12 }} + {{- end }} + ports: + {{- with .Values.ports }} + {{- range $key, $port := . }} + - name: {{ $key }} + {{ toYaml $port | nindent 14 }} + {{- end }} + {{- end }} + + livenessProbe: + {{ toYaml .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{ toYaml .Values.readinessProbe | nindent 12 }} + env: + {{- range $key, $value := .Values.env }} + - name: {{ $key | upper | replace "." "_" }} + value: {{ $value | quote }} + {{- end }} + resources: + {{ toYaml .Values.resources | nindent 12 }} + volumeMounts: + - name: config + mountPath: /config + {{- if .Values.volumeMounts }} + {{ toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- range $key, $value := .Values.secretMounts }} + - name: {{ $key }} + mountPath: {{ $value.mountPath }} + {{- end }} + lifecycle: + {{ toYaml .Values.lifecycle | nindent 12 }} + + {{- if .Values.sidecarContainersTemplate }} + {{ tpl .Values.sidecarContainersTemplate $ | nindent 8 }} + {{- end }} + + {{- with .Values.nodeSelector }} + nodeSelector: + {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "envoy.fullname" . }} + {{- if .Values.volumes }} + {{ toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- range $key, $value := .Values.secretMounts }} + - name: {{ $key }} + secret: + secretName: {{ $value.secretName }} + defaultMode: {{ $value.defaultMode }} + {{- end }} diff --git a/charts/envoy/templates/poddisruptionbudget.yaml b/charts/envoy/templates/poddisruptionbudget.yaml new file mode 100755 index 0000000..ece46fd --- /dev/null +++ b/charts/envoy/templates/poddisruptionbudget.yaml @@ -0,0 +1,15 @@ +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "envoy.fullname" . }} + labels: + app: {{ template "envoy.name" . }} + chart: {{ template "envoy.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + selector: + matchLabels: + app: {{ template "envoy.name" . }} + release: {{ .Release.Name }} +{{ .Values.podDisruptionBudget | indent 2 }} diff --git a/charts/envoy/templates/service.yaml b/charts/envoy/templates/service.yaml new file mode 100755 index 0000000..4cdee01 --- /dev/null +++ b/charts/envoy/templates/service.yaml @@ -0,0 +1,32 @@ +{{- if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Values.service.name }} + labels: + app: {{ template "envoy.name" . }} + chart: {{ template "envoy.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: +{{- with .Values.service.annotations }} +{{ toYaml . | indent 4 }} +{{- end }} +spec: + type: {{ .Values.service.type }} + {{- if ne .Values.service.loadBalancerIP "" }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + ports: + {{- range $key, $value := .Values.service.ports }} + - name: {{ $key }} +{{ toYaml $value | indent 6 }} + {{- end }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 6 }} + {{- end }} + selector: + app: {{ template "envoy.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/charts/envoy/templates/servicemonitor.yaml b/charts/envoy/templates/servicemonitor.yaml new file mode 100755 index 0000000..4e0f4da --- /dev/null +++ b/charts/envoy/templates/servicemonitor.yaml @@ -0,0 +1,38 @@ +{{- if and ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ( .Values.serviceMonitor.enabled ) }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + app: {{ template "envoy.name" . }} + chart: {{ template "envoy.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4}} +{{- end }} + name: {{ template "envoy.fullname" . }} +{{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace }} +{{- end }} +spec: + endpoints: + - targetPort: {{ .Values.ports.admin.containerPort }} + interval: {{ .Values.serviceMonitor.interval }} + path: "/stats/prometheus" + jobLabel: {{ template "envoy.fullname" . }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app: {{ template "envoy.name" . }} + release: {{ .Release.Name }} + {{- with .Values.serviceMonitor.targetLabels }} + targetLabels: +{{ toYaml . | trim | indent 4 -}} + {{- end }} + {{- with .Values.serviceMonitor.podTargetLabels }} + podTargetLabels: +{{ toYaml . | trim | indent 4 -}} + {{- end }} +{{- end }} diff --git a/charts/envoy/templates/xds.configmap.yaml b/charts/envoy/templates/xds.configmap.yaml new file mode 100755 index 0000000..97d1689 --- /dev/null +++ b/charts/envoy/templates/xds.configmap.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "envoy.fullname" . }}-xds + labels: + app: {{ template "envoy.name" . }} + chart: {{ template "envoy.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: +{{- range $filename, $content := .Values.xds }} + {{ tpl $filename $ }}: |- +{{ $valueWithDefault := default "" $content -}} +{{ tpl $valueWithDefault $ | indent 4 }} +{{- end -}} diff --git a/charts/envoy/values.yaml b/charts/envoy/values.yaml new file mode 100755 index 0000000..ae47a7f --- /dev/null +++ b/charts/envoy/values.yaml @@ -0,0 +1,351 @@ +atlas: + alertmanagerCount: 0 + +replicaCount: 1 + +podDisruptionBudget: | + maxUnavailable: 1 + +## ref: https://pracucci.com/graceful-shutdown-of-kubernetes-pods.html +terminationGracePeriodSeconds: 30 + +strategy: | + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + +image: + repository: envoyproxy/envoy + tag: v1.26.1 + pullPolicy: IfNotPresent + +command: + - /usr/local/bin/envoy +args: + - -l + - $loglevel + - -c + - /config/envoy.yaml + +## Args template allows you to use Chart template expressions to dynamically generate args +# argsTemplate: |- +# - -c +# - /docker-entrypoint.sh envoy --service-node ${POD_NAME} --service-cluster {{ template "envoy.fullname" . }} -l debug -c /config/envoy.yaml + +## Client service. +service: + enabled: true + ## Service name is user-configurable for maximum service discovery flexibility. + name: envoy + type: ClusterIP + ## Ignored if the type is not LoadBalancer or if the IP is empty string + loadBalancerIP: "" + annotations: + {} + ## AWS example for use with LoadBalancer service type. + # external-dns.alpha.kubernetes.io/hostname: envoy.cluster.local + # service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + ports: + n0: + port: 10000 + targetPort: n0 + protocol: TCP + ## Used to whitelist certain source CIDRs + # loadBalancerSourceRanges: + # - 0.0.0.0/0 + +ports: + admin: + containerPort: 9901 + protocol: TCP + n0: + containerPort: 10000 + protocol: TCP + +resources: + {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +priorityClassName: "" + +nodeSelector: {} + +tolerations: [] + +affinity: + {} + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - weight: 50 + # podAffinityTerm: + # topologyKey: failure-domain.beta.kubernetes.io/zone + # labelSelector: + # matchLabels: + # release: envoy + # requiredDuringSchedulingIgnoredDuringExecution: + # - weight: 40 + # topologyKey: "kubernetes.io/hostname" + # labelSelector: + # matchLabels: + # release: envoy + +## ref: https://github.com/envoyproxy/envoy/pull/2896 +podAnnotations: + {} + # prometheus.io/scrape: "true" + # prometheus.io/path: "/stats/prometheus" + # prometheus.io/port: "9901" + +podLabels: + {} + # team: "developers" + # service: "envoy" + +livenessProbe: + tcpSocket: + port: admin + initialDelaySeconds: 30 + # periodSeconds: 10 + # timeoutSeconds: 5 + # failureThreshold: 3 + # successThreshold: 1 + +readinessProbe: + tcpSocket: + port: admin + initialDelaySeconds: 30 + # periodSeconds: 10 + # timeoutSeconds: 5 + # failureThreshold: 3 + # successThreshold: 1 + +securityContext: {} + +env: {} + +## Create secrets out-of-band from Helm like this: +## +## $ kubectl create secret generic envoy --from-file=./some-secret.txt +## +secretMounts: + {} + # secret: + # secretName: envoy + # mountPath: /secret + # defaultMode: 256 # 256 in base10 == 0400 in octal + +files: + envoy.yaml: |- + ## refs: + ## - https://www.envoyproxy.io/docs/envoy/latest/start/start#quick-start-to-run-simple-example + ## - https://raw.githubusercontent.com/envoyproxy/envoy/master/configs/google_com_proxy.v2.yaml + admin: + access_log_path: /dev/stdout + address: + socket_address: + address: 0.0.0.0 + port_value: 9901 + + static_resources: + listeners: + - name: listener_0 + address: + socket_address: + address: 0.0.0.0 + port_value: 10000 + filter_chains: + - filters: + - name: envoy.http_connection_manager + config: + access_log: + - name: envoy.file_access_log + config: + path: /dev/stdout + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: local_service + domains: ["*"] + routes: + - match: + prefix: "/" + route: + host_rewrite: www.google.com + cluster: service_google + http_filters: + - name: envoy.router + clusters: + - name: service_google + connect_timeout: 0.25s + type: LOGICAL_DNS + dns_lookup_family: V4_ONLY + lb_policy: ROUND_ROBIN + hosts: + - socket_address: + address: google.com + port_value: 443 + tls_context: + sni: www.google.com + +## Uncomment this section to use helm values to dynamically generate enovy.yaml +# templates: +# envoy.yaml: |- +# ## refs: +# ## - https://www.envoyproxy.io/docs/envoy/latest/start/start#quick-start-to-run-simple-example +# ## - https://raw.githubusercontent.com/envoyproxy/envoy/master/configs/google_com_proxy.v2.yaml +# admin: +# access_log_path: /dev/stdout +# address: +# socket_address: +# address: 0.0.0.0 +# port_value: {{ .Values.ports.admin.containerPort }} + +# static_resources: +# listeners: +# - name: listener_0 +# address: +# socket_address: +# address: 0.0.0.0 +# port_value: {{ .Values.ports.n0.containerPort }} +# filter_chains: +# - filters: +# - name: envoy.http_connection_manager +# config: +# access_log: +# - name: envoy.file_access_log +# config: +# path: /dev/stdout +# stat_prefix: ingress_http +# route_config: +# name: local_route +# virtual_hosts: +# - name: local_service +# domains: ["*"] +# routes: +# - match: +# prefix: "/" +# route: +# host_rewrite: www.google.com +# cluster: service_google +# http_filters: +# - name: envoy.router +# clusters: +# - name: service_google +# connect_timeout: 0.25s +# type: LOGICAL_DNS +# dns_lookup_family: V4_ONLY +# lb_policy: ROUND_ROBIN +# hosts: +# - socket_address: +# address: google.com +# port_value: 443 +# tls_context: +# sni: www.google.com + +## Additional volumes to be added to Envoy pods +# volumes: +# - name: xds +# emptyDir: {} + +## Additional volume mounts to be added to Envoy containers(Primary containers of Envoy pods) +# volumeMounts: +# - name: xds +# mountPath: /srv/runtime + +## Init containers +# initContainersTemplate: |- +# - name: xds-init +# image: mumoshu/envoy-xds-configmap-loader:canary-6090275 +# command: +# - envoy-xds-configmap-loader +# args: +# - --configmap={{ template "envoy.fullname" . }}-xds +# - --onetime +# - --insecure +# env: +# - name: POD_NAMESPACE +# valueFrom: +# fieldRef: +# fieldPath: metadata.namespace +# volumeMounts: +# - name: xds +# mountPath: /srv/runtime + +## Sidecar containers +# sidecarContainersTemplate: |- +# - name: xds-update +# image: mumoshu/envoy-xds-configmap-loader:canary-6090275 +# command: +# - envoy-xds-configmap-loader +# args: +# - --configmap={{ template "envoy.fullname" . }}-xds +# - --sync-interval=5s +# - --insecure +# env: +# - name: POD_NAMESPACE +# valueFrom: +# fieldRef: +# fieldPath: metadata.namespace +# volumeMounts: +# - name: xds +# mountPath: /srv/runtime + +## ServiceMonitor consumed by prometheus-operator +serviceMonitor: + ## If the operator is installed in your cluster, set to true to create a Service Monitor Entry + enabled: false + interval: "15s" + targetLabels: [] + podTargetLabels: [] + ## Namespace in which the service monitor is created + # namespace: monitoring + # Added to the ServiceMonitor object so that prometheus-operator is able to discover it + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec + additionalLabels: {} + +### Lifecycle Events +lifecycle: {} +# preStop: +# exec: +# command: +# - sh +# - -c +# - "sleep 60" + +## PrometheusRule consumed by prometheus-operator +prometheusRule: + enabled: false + ## Namespace in which the prometheus rule is created + # namespace: monitoring + ## Define individual alerting rules as required + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#rulegroup + ## https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ + groups: + upstream-rules: + enabled: true + rules: + high4xxRate: + enabled: true + alert: High4xxRate + expr: sum(rate(envoy_cluster_upstream_rq_xx{response_code_class="4"}[1m])) / sum(rate(envoy_cluster_upstream_rq_xx[1m])) * 100 > 1 + for: 1m + labels: + severity: page + annotations: + summary: "4xx response rate above 1%" + description: "The 4xx error response rate for envoy cluster {{ $labels.envoy_cluster_name }} reported a service replication success rate of {{ $value }}% for more than 1 minute." + ## Added to the PrometheusRule object so that prometheus-operator is able to discover it + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec + additionalLabels: {} diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 0000000..02486b0 --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +docs.goatlas.io \ No newline at end of file diff --git a/docs/deployment.md b/docs/deployment.md index 87d932f..047e0ec 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -4,11 +4,24 @@ You should have at least two clusters to take full advantage of Atlas. One to ac Atlas should only be installed to the **observability** cluster. All downstream clusters will need an envoy instance deployed, Atlas will provide the necessary helm values to configure the downstream clusters. -## Step 0. Deploy Prometheus with Thanos Sidecar +!!! important + It is **HIGHLY** recommend using the same namespace for your observability components, it makes deployment management much easier. The default for atlas is `monitoring`. + +## Requirements + +- 1 Cluster to act as the Observability Cluster +- 1 Cluster to act as a Downstream Cluster +- Ability to install helm charts +- The envoy helm chart must be installed to an edge node (typically where an ingress instance would be deployed) + +### Deploy Prometheus with Thanos Sidecar It is recommended you use the same namespace like `monitoring` for the deployment of Prometheus and Atlas. -How you deploy Prometheus with the Thanos Sidecar is up to you, however I would recommend simply using the [kube-prometheus-stack]() helm chart as it makes this process very simple and takes care of the more complicated bits for you. If you want Thanos persisting to S3 you can pass your S3 credentials along as well. +How you deploy Prometheus with the Thanos Sidecar is up to you, however I would recommend simply using the [kube-prometheus-stack](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack) helm chart as it makes this process very simple and takes care of the more complicated bits for you. If you want Thanos persisting to S3 you can pass your S3 credentials along as well. + +!!! note + When using `kube-prometheus-stack` ensure `servicePerReplica` is enabled for both prometheus and alertmanager sections, this will allow proper routing to each individual instance. Once you have your Prometheus instances deployed, please make sure to note the service name as it will be necessary for configuring Atlas properly. If you are use `kube-prometheus-stack` most of the defaults will work out of the box. If you are using something non-standard, please make sure that the Prometheus Port and Thanos Sidecar ports are on the service. @@ -117,7 +130,7 @@ spec: atlas cluster-add --name "downstream1" --replicas 1 --external-ip "1.1.1.1" ``` -### Step 4. Deploy Envoy on Downstream Cluster +## Step 4. Deploy Envoy on Downstream Cluster Atlas generates helm values for the Atlas Envoy Helm Chart for every downstream cluster added. These values come with the necessary seed values to allow initial secure connections to be established. Once comms are established the Envoy Aggreggated Discovery capabilites take over ensuring the downstream envoy instance stays configure properly. @@ -127,6 +140,12 @@ Retrieve the downstream's helm values with the `atlas` or `kubectl` atlas cluster-values --name "downstream1" > downstream1.yaml ``` +**Note:** This command has `--format` option, the default is `raw` which is just values for helm. The other options are `helm-chart` and `helm-release` + +- `helm-chart` -- this is a feature from Rancher on K3S clusters +- `helm-release` -- this is for Flux V2 +- `raw` -- just values for helm install/upgrade commands + OR ```bash @@ -139,18 +158,26 @@ Once you have the values, install helm on your downstream cluster. Make sure you helm install envoy --values downstream1.yaml chart/ ``` -Once complete, this envoy proxy will come online and configure itself automatically. - -### Step 5. Repeat +## Step 5. Repeat If you have more than one downstream cluster, repeast steps 3 and 4 until you've added all your clusters. -1. Deploy Atlas with Helm -2. Modify `kube-system/coredns` configmap (ideally with giops) to forward altas TLD to atlas coredns server -3. Generate Downstream Envoy Helm Values -4. Deploy Downstream Envoy Helm Chart -5. Deploy Downstream Prometheus -6. Create Service for Downstream Cluster in Observability Cluster -7. Sit back and enjoy the metrics flowing in! +## Step 6. Configure Downstream Prometheus for Observability Alertmanagers -**Note:** when using `kube-prometheus-stack` ensure `servicePerReplica` is enabled for both prometheus and alertmanager sections. +To take full advantage of what Atlas offers, you can configure your downstream prometheus instances to talk to the alertmanagers in the observability cluster. + +You'll need to add an alertmanager entry per the number of alertmanagr instances that are on the observability cluster to the downstream prometheus instance. If you are using the prometheus operator then you can simple add an additional alert managers configuration like the following. + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: additional-alertmanager-configs + namespace: monitoring +data: + config.yaml: | + - scheme: http + static_configs: + - targets: + - %s +``` diff --git a/docs/quick-start.md b/docs/quick-start.md index 4ace35a..c431509 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -1,13 +1,31 @@ -# Quick Start +# Quick Start (aka Demo using Digital Ocean) -The easiest way to get started is to take the [deploy script](hack/deployment/deploy.sh) for a spin. It requires a Digital Ocean account. +!!! important + This script requires a Digital Ocean account. -To use this script you'll need a Digital Ocean API token. Once you have acquired the token, simply export `DIGITALOCEAN_ACCESS_TOKEN` to your shell and then from the root of the Atlas project run the following ... +The easiest way to get started is to take the [deploy script](examples/demo-do/deploy.sh) for a spin. + +This script spins up a fully working Atlas deployment with Prometheus and Thanos on several downstream clusters and automatically configures the downstream clusters for secure communication. + +## Preflight + +1. Obtain a Digital Ocean Access Token +2. Obtain the SSH Key ID of your SSH key in Digital Ocean +3. `export DIGITALOCEAN_ACCESS_TOKEN=` +4. `export DIGITALOCEAN_SSH_KEYS=` + +!!! note + I'd highly recommend the use of [direnv](https://direnv.net) for managing environment variables throughout directories. + +## Deploy ```bash -bash hack/deployment/deploy.sh up +bash examples/demo-do/deploy.sh up ``` +!!! note + This script takes approximately 5-7 minutes to run, depending on how fast Digital Ocean is. It's spinning up a total of 4 servers and installing [k3s](https://k3s.io), then using helm to install the necessary components like prometheus, thanos, envoy and atlas on the various servers. + This script will deploy four clusters: - observability @@ -15,6 +33,47 @@ This script will deploy four clusters: - downstream2 - downstream3 -Once the script is done running a set of details will be printed to the screen. If you want to see the details again simply re-run the script with `down` instead of `up`. +Once the script is done running a set of details will be printed to the screen. If you want to see the details again simply re-run the script with `details` instead of `up`. + +The details output will give you all the urls to the various components that can be interacted with on the observability cluster and the downstream clusters, see below for more details. + +Generally speaking by the time the details page shows up downstream1 and downstream2 will already be connected. Downstream3 will still be in the process of coming online, but should only take another minute or two at most. + +## Details + +In general your details will look something like the following ... + +```text +IP Addresses +----------------------------------------- +Observability: 143.198.182.161 + Downstream1: 198.211.117.92 + Downstream2: 143.244.174.92 + Downstream3: 137.184.97.135 + +Observability Cluster +------------------------------------------ +thanos-query: http://thanos-query.143.198.182.161.nip.io + prometheus: http://prometheus.143.198.182.161.nip.io + alerts: http://alerts.143.198.182.161.nip.io + +Accessing Downstream through Observability Cluster: + +Note: these use the Envoy Proxy Network provided by Atlas to allow secure +communications to downstream cluster components. + + downstream1: http://thanos-query.143.198.182.161.nip.io/prom/downstream1/graph + downstream2: http://thanos-query.143.198.182.161.nip.io/prom/downstream2/graph + downstream3: http://thanos-query.143.198.182.161.nip.io/prom/downstream3/graph + +Important: In a real-world scenario you'd gate access to thanos-query via an oauth2 proxy +or it would only be accessible on an internal network! +``` + +The link to thanos-query in the observability cluster is how you can see your thanos query connected to the sidecars. + +The downstream1-3 links all use the thanos-query and the ingress path prefix that allows accessing of the downstream clusters from the observability cluster. You can confirm this by going to each link and pulling up the prometheus configuration, you'll see the external labels differ for each one. + +## Teardown -When you are all done, `bash hack/deployment/depoy.sh down` to tear it all down. +When you are all done, `bash examples/demo-do/depoy.sh down` to tear it all down. diff --git a/hack/deployment/README.md b/examples/demo-do/README.md similarity index 100% rename from hack/deployment/README.md rename to examples/demo-do/README.md diff --git a/hack/deployment/deploy.sh b/examples/demo-do/deploy.sh similarity index 90% rename from hack/deployment/deploy.sh rename to examples/demo-do/deploy.sh index 47dd7b4..21bb26c 100644 --- a/hack/deployment/deploy.sh +++ b/examples/demo-do/deploy.sh @@ -11,12 +11,6 @@ DO_SIZE=${DO_SIZE:="s-2vcpu-4gb"} DO_IMAGE=${DO_IMAGE:="ubuntu-20-04-x64"} DIGITALOCEAN_SSH_KEYS=${DIGITALOCEAN_SSH_KEYS:-""} -HELM_TAG=${HELM_TAG:="master-5f87f6a"} -HELM_PULLSECRET=${HELM_PULLSECRET:=""} - -GITHUB_USERNAME=${GITHUB_USERNAME:-""} -GITHUB_TOKEN=${GITHUB_TOKEN:-""} - NAMESPACE=${NAMESPACE:="monitoring"} THANOS_VERSION=${THANOS_VERSION:="v0.23.1"} @@ -78,12 +72,6 @@ function setup_atlas_values { local ip_address=$1 cat > "observability/atlas-values.yaml" < "$name/am.yaml" < "$name/envoy-values.yaml" - helm upgrade --kubeconfig "$name/kubeconfig.yaml" -i -n $NAMESPACE --values "$name/envoy-values.yaml" atlas-envoy stable/envoy + helm upgrade --kubeconfig "$name/kubeconfig.yaml" -i -n $NAMESPACE --values "$name/envoy-values.yaml" atlas-envoy ../../charts/envoy } function build_downstream_cluster() { diff --git a/examples/README.md b/examples/resources/README.md similarity index 100% rename from examples/README.md rename to examples/resources/README.md diff --git a/examples/downstream-cluster.yaml b/examples/resources/downstream-cluster.yaml similarity index 100% rename from examples/downstream-cluster.yaml rename to examples/resources/downstream-cluster.yaml diff --git a/examples/internal-downstream-sidecar.yaml b/examples/resources/internal-downstream-sidecar.yaml similarity index 100% rename from examples/internal-downstream-sidecar.yaml rename to examples/resources/internal-downstream-sidecar.yaml diff --git a/go.mod b/go.mod index c704081..3dc7e22 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module github.com/ekristen/atlas +module github.com/goatlas-io/atlas go 1.16 @@ -16,7 +16,7 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 github.com/prometheus/client_golang v1.11.0 - github.com/rancher/wrangler v0.8.6 + github.com/rancher/wrangler v0.8.7 github.com/sirupsen/logrus v1.8.1 github.com/urfave/cli/v2 v2.3.0 google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect diff --git a/go.sum b/go.sum index a6dbf16..6080b02 100644 --- a/go.sum +++ b/go.sum @@ -431,8 +431,8 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T github.com/qri-io/starlib v0.4.2-0.20200213133954-ff2e8cd5ef8d/go.mod h1:7DPO4domFU579Ga6E61sB9VFNaniPVwJP5C4bBCu3wA= github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08 h1:NxR8Fh0eE7/5/5Zvlog9B5NVjWKqBSb1WYMUF7/IE5c= github.com/rancher/lasso v0.0.0-20210616224652-fc3ebd901c08/go.mod h1:9qZd/S8DqWzfKtjKGgSoHqGEByYmUE3qRaBaaAHwfEM= -github.com/rancher/wrangler v0.8.6 h1:z0PYRySnwEEPtybjSdcUbHlgznIuxQpseVP7OEsKOb0= -github.com/rancher/wrangler v0.8.6/go.mod h1:dKEaHNB4izxmPUtpq1Hvr3z3Oh+9k5pCZyFO9sUhlaY= +github.com/rancher/wrangler v0.8.7 h1:WN9EWycceZ9gP5hEqIRJMrwi7cprxETMyKk/qXl+9ZU= +github.com/rancher/wrangler v0.8.7/go.mod h1:dKEaHNB4izxmPUtpq1Hvr3z3Oh+9k5pCZyFO9sUhlaY= github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= diff --git a/main.go b/main.go index 696a1d6..862e911 100644 --- a/main.go +++ b/main.go @@ -7,8 +7,8 @@ import ( "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" - _ "github.com/ekristen/atlas/pkg/commands" - "github.com/ekristen/atlas/pkg/common" + _ "github.com/goatlas-io/atlas/pkg/commands" + "github.com/goatlas-io/atlas/pkg/common" ) func main() { diff --git a/mkdocs.yml b/mkdocs.yml index d276601..2f92fba 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,7 +1,7 @@ site_name: Atlas -site_url: https://ekristen.github.io/atlas/ -repo_name: ekristen/atlas -repo_url: https://github.com/ekristen/atlas +site_url: https://docs.goatlas.io/ +repo_name: goatlas-io/atlas +repo_url: https://github.com/goatlas-io/atlas edit_uri: "" site_dir: public diff --git a/pkg/commands/cluster-add.go b/pkg/commands/cluster-add.go index 90e5e52..aef797b 100644 --- a/pkg/commands/cluster-add.go +++ b/pkg/commands/cluster-add.go @@ -15,7 +15,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" - "github.com/ekristen/atlas/pkg/common" + "github.com/goatlas-io/atlas/pkg/common" ) type clusterAddCommand struct { diff --git a/pkg/commands/cluster-values.go b/pkg/commands/cluster-values.go index 6fd6dc2..73c3f30 100644 --- a/pkg/commands/cluster-values.go +++ b/pkg/commands/cluster-values.go @@ -17,7 +17,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - "github.com/ekristen/atlas/pkg/common" + "github.com/goatlas-io/atlas/pkg/common" ) //go:embed templates/* diff --git a/pkg/commands/controller.go b/pkg/commands/controller.go index 9e8b5f1..7369725 100644 --- a/pkg/commands/controller.go +++ b/pkg/commands/controller.go @@ -14,10 +14,10 @@ import ( "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes" - "github.com/ekristen/atlas/pkg/common" - "github.com/ekristen/atlas/pkg/config" - "github.com/ekristen/atlas/pkg/controllers/atlas" - "github.com/ekristen/atlas/pkg/metrics" + "github.com/goatlas-io/atlas/pkg/common" + "github.com/goatlas-io/atlas/pkg/config" + "github.com/goatlas-io/atlas/pkg/controllers/atlas" + "github.com/goatlas-io/atlas/pkg/metrics" ) type controlCommand struct{} diff --git a/pkg/commands/envoy-ads.go b/pkg/commands/envoy-ads.go index 0a4bbc3..3ec81ee 100644 --- a/pkg/commands/envoy-ads.go +++ b/pkg/commands/envoy-ads.go @@ -15,10 +15,10 @@ import ( "k8s.io/apimachinery/pkg/util/runtime" "k8s.io/client-go/kubernetes" - "github.com/ekristen/atlas/pkg/common" - "github.com/ekristen/atlas/pkg/config" - "github.com/ekristen/atlas/pkg/envoy" - "github.com/ekristen/atlas/pkg/metrics" + "github.com/goatlas-io/atlas/pkg/common" + "github.com/goatlas-io/atlas/pkg/config" + "github.com/goatlas-io/atlas/pkg/envoy" + "github.com/goatlas-io/atlas/pkg/metrics" ) type envoyADSCommand struct{} @@ -100,7 +100,7 @@ func init() { &cli.StringFlag{ Name: "alertmanager-selector", Usage: "Label Selector for AlertManager", - EnvVars: []string{"ALERTMANAGER_SELECTOR"}, + EnvVars: []string{"ATLAS_ALERTMANAGER_SELECTOR"}, Value: common.ObservabilityAlertManagerServiceLabel, }, &cli.StringFlag{ diff --git a/pkg/commands/templates/helm-chart.tmpl b/pkg/commands/templates/helm-chart.tmpl index 9c66cd4..b89ec7e 100644 --- a/pkg/commands/templates/helm-chart.tmpl +++ b/pkg/commands/templates/helm-chart.tmpl @@ -5,6 +5,6 @@ metadata: name: atlas-envoy namespace: {{ .Namespace }} spec: - chart: https://charts.helm.sh/stable/packages/envoy-1.9.4.tgz + chart: https://charts.goatlas.io/envoy-1.0.1.tgz valuesContent: | {{ .Values | indent 4 }} \ No newline at end of file diff --git a/pkg/commands/templates/helm-release.tmpl b/pkg/commands/templates/helm-release.tmpl index 196c017..7ea2874 100644 --- a/pkg/commands/templates/helm-release.tmpl +++ b/pkg/commands/templates/helm-release.tmpl @@ -2,26 +2,26 @@ apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: - name: atlas-helm-stable + name: atlas namespace: {{ .Namespace }} spec: - url: https://charts.helm.sh/stable + url: https://charts.goatlas.io interval: 24h --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: - name: atlas-thanos + name: atlas-envoy namespace: {{ .Namespace }} spec: - releaseName: atlas-thanos + releaseName: atlas-envoy interval: 2m chart: spec: chart: envoy - version: 1.9.4 + version: 1.2.1 sourceRef: kind: HelmRepository - name: atlas-helm-stable + name: atlas values: {{ .Values | indent 4 }} \ No newline at end of file diff --git a/pkg/common/version.go b/pkg/common/version.go index 1ce4871..4e9da2b 100644 --- a/pkg/common/version.go +++ b/pkg/common/version.go @@ -10,7 +10,7 @@ var SUMMARY = "0.1.0-dev" var BRANCH = "dev" // VERSION of Release -var VERSION = "0.1.0" +var VERSION = "0.3.1" // AppVersion -- var AppVersion AppVersionInfo diff --git a/pkg/controllers/atlas/controller.go b/pkg/controllers/atlas/controller.go index dedb3a8..aba07f2 100644 --- a/pkg/controllers/atlas/controller.go +++ b/pkg/controllers/atlas/controller.go @@ -28,6 +28,7 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/selection" @@ -36,8 +37,9 @@ import ( core "github.com/rancher/wrangler/pkg/generated/controllers/core/v1" "github.com/rancher/wrangler/pkg/relatedresource" - "github.com/ekristen/atlas/pkg/common" - "github.com/ekristen/atlas/pkg/config" + "github.com/goatlas-io/atlas/pkg/common" + "github.com/goatlas-io/atlas/pkg/config" + "github.com/goatlas-io/atlas/pkg/envoy" ) //go:embed templates/* @@ -64,6 +66,8 @@ type Controller struct { dnsUpdateLock sync.Mutex dnsLastHash string + + namespace string } func Register( @@ -79,7 +83,7 @@ func Register( c := Controller{ ctx: ctx, config: config, - log: log.WithField("component-type", "controller").WithField("component", common.MonitoringNamespace), + log: log.WithField("component-type", "controller").WithField("component", cli.String("namespace")), cli: cli, apply: apply, secrets: secrets, @@ -87,6 +91,7 @@ func Register( configmaps: configmaps, services: services, servicesCache: services.Cache(), + namespace: cli.String("namespace"), } c.secrets.OnChange(ctx, common.NAME, c.handleSecretChange) @@ -171,7 +176,7 @@ func (c *Controller) createObservabilityValues() error { s := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ObservabilityEnvoyValuesSecretName, - Namespace: common.MonitoringNamespace, + Namespace: c.namespace, }, StringData: map[string]string{ "values.yaml": string(buf.Bytes()), @@ -244,7 +249,7 @@ func (c *Controller) configureCA() error { var currentCASecret *corev1.Secret - caSecret, err := c.secrets.Get(common.MonitoringNamespace, common.CASecretName, metav1.GetOptions{}) + caSecret, err := c.secrets.Get(c.namespace, common.CASecretName, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { isNew = true @@ -295,7 +300,7 @@ func (c *Controller) configureCA() error { caSecret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.CASecretName, - Namespace: common.MonitoringNamespace, + Namespace: c.namespace, Annotations: map[string]string{}, Labels: map[string]string{ common.IsCALabel: "true", @@ -370,7 +375,7 @@ func (c *Controller) configureCA() error { func (c *Controller) setupPKI() error { doGenerate := false - ingressTLSSecret, err := c.secrets.Get(common.MonitoringNamespace, common.IngressTLSSecretName, metav1.GetOptions{}) + ingressTLSSecret, err := c.secrets.Get(c.namespace, common.IngressTLSSecretName, metav1.GetOptions{}) if err != nil && !apierrors.IsNotFound(err) { return err } else if err != nil && apierrors.IsNotFound(err) { @@ -382,7 +387,7 @@ func (c *Controller) setupPKI() error { } } - mtlsClientSecret, err := c.secrets.Get(common.MonitoringNamespace, common.ClientSecretName, metav1.GetOptions{}) + mtlsClientSecret, err := c.secrets.Get(c.namespace, common.ClientSecretName, metav1.GetOptions{}) if err != nil && !apierrors.IsNotFound(err) { return err } else if err != nil && apierrors.IsNotFound(err) { @@ -394,7 +399,7 @@ func (c *Controller) setupPKI() error { } } - mtlsServerSecret, err := c.secrets.Get(common.MonitoringNamespace, common.ServerSecretName, metav1.GetOptions{}) + mtlsServerSecret, err := c.secrets.Get(c.namespace, common.ServerSecretName, metav1.GetOptions{}) if err != nil && !apierrors.IsNotFound(err) { return err } else if err != nil && apierrors.IsNotFound(err) { @@ -440,7 +445,7 @@ func (c *Controller) setupPKI() error { ingressTLSSecret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.IngressTLSSecretName, - Namespace: common.MonitoringNamespace, + Namespace: c.namespace, Labels: map[string]string{ common.IsCertLabel: "true", common.CASerialLabel: fmt.Sprintf("%d", ingressSerial), @@ -458,7 +463,7 @@ func (c *Controller) setupPKI() error { mtlsClientSecret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ClientSecretName, - Namespace: common.MonitoringNamespace, + Namespace: c.namespace, Labels: map[string]string{ common.IsCertLabel: "true", common.CASerialLabel: fmt.Sprintf("%d", clientSerial), @@ -477,7 +482,7 @@ func (c *Controller) setupPKI() error { mtlsServerSecret = &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: common.ServerSecretName, - Namespace: common.MonitoringNamespace, + Namespace: c.namespace, Labels: map[string]string{ common.IsCertLabel: "true", common.CASerialLabel: fmt.Sprintf("%d", serverSerial), @@ -505,7 +510,7 @@ func (c *Controller) generateCert(extKeyUsage []x509.ExtKeyUsage, commonName str serial := big.NewInt(time.Now().UTC().Unix()) subject := pkix.Name{ - Organization: []string{"ekristen.github.io"}, + Organization: []string{"goatlas.io"}, OrganizationalUnit: []string{"Atlas"}, Country: []string{"US"}, Province: []string{"DC"}, @@ -562,7 +567,7 @@ func (c *Controller) generateCA() (*big.Int, *bytes.Buffer, *bytes.Buffer, error ca := &x509.Certificate{ SerialNumber: big.NewInt(time.Now().UTC().Unix()), Subject: pkix.Name{ - Organization: []string{"ekristen.github.io"}, + Organization: []string{"goatlas.io"}, OrganizationalUnit: []string{"Atlas"}, Country: []string{"US"}, Province: []string{"DC"}, @@ -696,7 +701,7 @@ func (c *Controller) handleServiceChangeforDNS(key string, service *corev1.Servi c.dnsUpdateLock.Lock() defer c.dnsUpdateLock.Unlock() - monitoringNamespace := common.MonitoringNamespace + monitoringNamespace := c.namespace requirement, err := labels.NewRequirement(common.SidecarLabel, selection.Exists, []string{}) if err != nil { @@ -773,7 +778,7 @@ func (c *Controller) handleServiceChangeforDNS(key string, service *corev1.Servi cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: c.cli.String("dns-config-map-name"), - Namespace: common.MonitoringNamespace, + Namespace: c.namespace, }, Data: map[string]string{ "atlas.zone": string(buf.Bytes()), @@ -789,39 +794,54 @@ func (c *Controller) handleServiceChangeforDNS(key string, service *corev1.Servi } func (c *Controller) generateEnvoyValuesSecret(service *corev1.Service) (*corev1.Secret, error) { - ca, err := c.secretsCache.Get(common.MonitoringNamespace, common.CASecretName) + ca, err := c.secretsCache.Get(c.namespace, common.CASecretName) if err != nil { return nil, err } - server, err := c.secretsCache.Get(common.MonitoringNamespace, common.ServerSecretName) + server, err := c.secretsCache.Get(c.namespace, common.ServerSecretName) if err != nil { return nil, err } - client, err := c.secretsCache.Get(common.MonitoringNamespace, common.ClientSecretName) + client, err := c.secretsCache.Get(c.namespace, common.ClientSecretName) if err != nil { return nil, err } + actualAMServices := []*corev1.Service{} + amServices, err := c.services.List(c.namespace, v1.ListOptions{ + LabelSelector: c.cli.String("alertmanager-selector"), + }) + if err != nil { + return nil, err + } + for _, service := range amServices.Items { + if _, ok := service.Spec.Selector["statefulset.kubernetes.io/pod-name"]; ok { + actualAMServices = append(actualAMServices, &service) + } + } + data := struct { - CA string - ServerCert string - ServerKey string - ClientCert string - ClientKey string - ClusterID string - EnvoyADSAddress string - EnvoyADSPort int64 + CA string + ServerCert string + ServerKey string + ClientCert string + ClientKey string + ClusterID string + EnvoyADSAddress string + EnvoyADSPort int64 + AlertmanagerCount int }{ - CA: string(ca.Data["ca.pem"]), - ServerCert: string(server.Data["tls.crt"]), - ServerKey: string(server.Data["tls.key"]), - ClientCert: string(client.Data["tls.crt"]), - ClientKey: string(client.Data["tls.key"]), - ClusterID: service.Name, - EnvoyADSAddress: c.config.ADSAddress, - EnvoyADSPort: c.config.ADSPort, + CA: string(envoy.CombineCAs(ca)), + ServerCert: string(server.Data["tls.crt"]), + ServerKey: string(server.Data["tls.key"]), + ClientCert: string(client.Data["tls.crt"]), + ClientKey: string(client.Data["tls.key"]), + ClusterID: service.Name, + EnvoyADSAddress: c.config.ADSAddress, + EnvoyADSPort: c.config.ADSPort, + AlertmanagerCount: len(actualAMServices), } d, err := templates.ReadFile("templates/envoy-downstream.tmpl") @@ -847,7 +867,7 @@ func (c *Controller) generateEnvoyValuesSecret(service *corev1.Service) (*corev1 s := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, - Namespace: common.MonitoringNamespace, + Namespace: c.namespace, }, StringData: map[string]string{ "values.yaml": string(buf.Bytes()), diff --git a/pkg/controllers/atlas/templates/envoy-downstream.tmpl b/pkg/controllers/atlas/templates/envoy-downstream.tmpl index 54347dc..e606b12 100644 --- a/pkg/controllers/atlas/templates/envoy-downstream.tmpl +++ b/pkg/controllers/atlas/templates/envoy-downstream.tmpl @@ -1,13 +1,11 @@ +atlas: + alertmanagerCount: {{ .AlertmanagerCount }} replicaCount: 1 args: - -l - info - -c - /config/envoy.yaml -image: - repository: envoyproxy/envoy - tag: v1.18.3 - pullPolicy: IfNotPresent service: enabled: true ports: diff --git a/pkg/envoy/helpers.go b/pkg/envoy/helpers.go index b135a5e..89fd7e2 100644 --- a/pkg/envoy/helpers.go +++ b/pkg/envoy/helpers.go @@ -334,7 +334,7 @@ func buildSecretTLSValidation(name string, ca []byte) *tls.Secret { } } -func combineCAs(ca *k8scorev1.Secret) []byte { +func CombineCAs(ca *k8scorev1.Secret) []byte { cas := [][]byte{} sep := []byte("\n") for k, v := range ca.Data { diff --git a/pkg/envoy/metrics.go b/pkg/envoy/metrics.go index 366cb1d..826016b 100644 --- a/pkg/envoy/metrics.go +++ b/pkg/envoy/metrics.go @@ -1,7 +1,7 @@ package envoy import ( - "github.com/ekristen/atlas/pkg/metrics" + "github.com/goatlas-io/atlas/pkg/metrics" "github.com/prometheus/client_golang/prometheus" ) diff --git a/pkg/envoy/server.go b/pkg/envoy/server.go index ffb139c..8b0f854 100644 --- a/pkg/envoy/server.go +++ b/pkg/envoy/server.go @@ -13,8 +13,8 @@ import ( "github.com/urfave/cli/v2" "google.golang.org/grpc" - "github.com/ekristen/atlas/pkg/common" - "github.com/ekristen/atlas/pkg/config" + "github.com/goatlas-io/atlas/pkg/common" + "github.com/goatlas-io/atlas/pkg/config" "github.com/rancher/wrangler/pkg/apply" wranglercorev1 "github.com/rancher/wrangler/pkg/generated/controllers/core/v1" @@ -73,6 +73,8 @@ type EnvoyADS struct { servicesCache wranglercorev1.ServiceCache secrets wranglercorev1.SecretController secretsCache wranglercorev1.SecretCache + + namespace string } func Register( @@ -95,6 +97,7 @@ func Register( apply: apply, cli: cliCtx, debugEnvoy: false, + namespace: cliCtx.String("namespace"), } return ads @@ -156,7 +159,7 @@ func (e *EnvoyADS) secretOnChange(key string, secret *k8scorev1.Secret) (*k8scor func (e *EnvoyADS) serviceOnChange(key string, service *k8scorev1.Service) (*k8scorev1.Service, error) { if service == nil { - if strings.Contains(key, common.MonitoringNamespace) { + if strings.Contains(key, e.namespace) { if err := e.Sync(); err != nil { e.log.WithError(err).Error("unable to sync") } @@ -200,22 +203,22 @@ func (e *EnvoyADS) Sync() error { func (e *EnvoyADS) SyncClusters(versionID string, clusters []*atlasCluster) error { actualAMServices := []*k8scorev1.Service{} - ca, err := e.secretsCache.Get(common.MonitoringNamespace, common.CASecretName) + ca, err := e.secretsCache.Get(e.namespace, common.CASecretName) if err != nil { return err } - server, err := e.secretsCache.Get(common.MonitoringNamespace, common.ServerSecretName) + server, err := e.secretsCache.Get(e.namespace, common.ServerSecretName) if err != nil { return err } - client, err := e.secretsCache.Get(common.MonitoringNamespace, common.ClientSecretName) + client, err := e.secretsCache.Get(e.namespace, common.ClientSecretName) if err != nil { return err } - amServices, err := e.services.List(common.MonitoringNamespace, v1.ListOptions{ + amServices, err := e.services.List(e.namespace, v1.ListOptions{ LabelSelector: e.cli.String("alertmanager-selector"), }) if err != nil { @@ -258,7 +261,7 @@ func (e *EnvoyADS) SyncClusters(versionID string, clusters []*atlasCluster) erro // Note: we do not send the client cert, because the is controlled by the // static cluster definition for the xds_cluster for dynamic discovery. dsclusterSecretResources := []types.Resource{ - buildSecretTLSValidation("validation", combineCAs(ca)), + buildSecretTLSValidation("validation", CombineCAs(ca)), buildSecretTLSCertificate("server", server.Data["tls.crt"], server.Data["tls.key"]), } @@ -288,7 +291,7 @@ func (e *EnvoyADS) SyncClusters(versionID string, clusters []*atlasCluster) erro } dsclusterSnapshot := cache.NewSnapshot( - versionID, + versionID, // version of snapshot []types.Resource{}, // endpoints dsclusterClusters, // clusters dsclusterRoutes, // routes @@ -322,23 +325,23 @@ func (e *EnvoyADS) SyncObservability(versionID string, clusters []*atlasCluster) addClientSecret = true } - ca, err := e.secretsCache.Get(common.MonitoringNamespace, common.CASecretName) + ca, err := e.secretsCache.Get(e.namespace, common.CASecretName) if err != nil { return err } - server, err := e.secretsCache.Get(common.MonitoringNamespace, common.ServerSecretName) + server, err := e.secretsCache.Get(e.namespace, common.ServerSecretName) if err != nil { return err } - client, err := e.secretsCache.Get(common.MonitoringNamespace, common.ClientSecretName) + client, err := e.secretsCache.Get(e.namespace, common.ClientSecretName) if err != nil { return err } secretResources := []types.Resource{ - buildSecretTLSValidation("validation", combineCAs(ca)), + buildSecretTLSValidation("validation", CombineCAs(ca)), buildSecretTLSCertificate("server", server.Data["tls.crt"], server.Data["tls.key"]), } @@ -526,7 +529,7 @@ func (e *EnvoyADS) getClusters() ([]*atlasCluster, error) { } selector := labels.NewSelector().Add(*requirement) - services, err := e.servicesCache.List(common.MonitoringNamespace, selector) + services, err := e.servicesCache.List(e.namespace, selector) if err != nil { return nil, err }