diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml new file mode 100644 index 0000000..9e515e8 --- /dev/null +++ b/.github/workflows/pr.yaml @@ -0,0 +1,42 @@ +name: Lint and Test Charts + +on: pull_request + +jobs: + lint-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Set up Helm + uses: azure/setup-helm@v1 + with: + version: v3.5.4 + + - uses: actions/setup-python@v2 + with: + python-version: 3.7 + + - name: Set up chart-testing + uses: helm/chart-testing-action@v2.0.1 + + - name: Run chart-testing (list-changed) + id: list-changed + run: | + changed=$(ct list-changed) + if [[ -n "$changed" ]]; then + echo "::set-output name=changed::true" + fi + + - name: Run chart-testing (lint) + run: ct lint +# +# - name: Create kind cluster +# uses: helm/kind-action@v1.0.0 +# if: steps.list-changed.outputs.changed == 'true' +# +# - name: Run chart-testing (install) +# run: ct install \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..fceea1d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,37 @@ +name: Release Charts + +on: + push: + branches: + - master + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + + - name: Install Helm + uses: azure/setup-helm@v1 + with: + version: v3.5.4 + + - name: Helm Repos + run: | + helm repo add grafana https://grafana.github.io/helm-charts + helm repo add presslabs https://presslabs.github.io/charts + helm repo add raphaelmonrouzeau https://raphaelmonrouzeau.github.io/charts/repository/ + helm repo add bitnami https://charts.bitnami.com/bitnami + + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.2.1 + env: + CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file diff --git a/Dockerfile.dapper b/Dockerfile.dapper new file mode 100644 index 0000000..b2f052b --- /dev/null +++ b/Dockerfile.dapper @@ -0,0 +1,8 @@ +FROM quay.io/helmpack/chart-testing:latest + +RUN apk add make + +ENV DAPPER_SOURCE /repo +WORKDIR ${DAPPER_SOURCE} + +ENTRYPOINT ["make"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..78b6e08 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +lint: + ct lint + +install: + ct install diff --git a/README.md b/README.md index 52224c3..f5db8b2 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,22 @@ -# Quickstart examples for Rancher +# Rancher Rodeo Helm Chart Repository -## Summary +This repository contains Helm charts that are used during Rancher Rodeo webinars and for demonstration purposes. -This repo contains scripts that will allow you to quickly deploy instances for use during a Rancher Rodeo. +**The Helm charts in this repository are not production ready and are meant for demonstration purposes only!** -The contents aren't intended for production but are here to get you up and running quickly during the rodeo session, either with DO, AWS, or Vagrant. - -## DO / AWS Quickstart - -The `do` folder and `aws` folder each contain Terraform scripts to stand up an instance for the Rancher Server and a configurable number of instances for the Kubernetes nodes. By default this number is set to one but can be set with `count_agent_all_nodes` in the `terraform.tfvars` file. - -### How to use - -- Clone this repository and go into the corresponding subfolder for your provider -- Move the file `terraform.tfvars.example` to `terraform.tfvars` and edit (see inline explanation) -- Run `terraform init` -- Run `terraform apply` - -When provisioning has finished you will have instances that you can use to deploy Rancher Server and Kubernetes. - -### How to Remove - -To remove the VMs that have been deployed run `terraform destroy --force` - -**Please be aware that you will be responsible for the usage charges with Digital Ocean and Amazon Web Services** - -## Vagrant Quickstart - -The `vagrant` folder contains the configuration to deploy a single VM for the Rancher Server and one or more VMs for the Kubernetes cluster. By default this number is set to one but can be changed by adjusting `count` under `node` in `config.yaml`. - -If you set `rodeo` to `false` in `config.yaml` the installation will provision a complete Rancher Server and Kubernetes cluster all at once. Use this to redeploy a Vagrant cluster quickly. +### How to Use -The prerequistes for this are [vagrant](https://www.vagrantup.com) and [virtualbox](https://www.virtualbox.org), installed on the PC you intend to run it on, and 6GB free memory +Helm CLI: -### How to Use +```shell +helm repo add rodeo https://rancher.github.io/rodeo +``` -- Clone this repository and go into the `vagrant` subfolder -- Edit `config.yaml` to set any values for the installation -- Run `vagrant up` +Rancher: -When provisioning is finished the Rancher Server will be available via SSH at `172.22.101.101` and the nodes will be available on sequential IPs starting at `172.22.101.111`. If you set `rodeo` to `false`, the Rancher Server UI will be available at https://172.22.101.101/. +* Go to the Apps Marketplace in Rancher +* Add a new Chart Repository to the HTTP(S) URL `https://rancher.github.io/rodeo` without authentication -### How to Remove +### How to Contribute -To remove the VMs that have been deployed run `vagrant destroy -f`. The configuration uses linked clones, so if you want to destroy the origin instance, open the VirtualBox Manager and remove the base `ubuntu-xenial` instance left behind. +Create a pull request to the master branch. Make sure to bump the chart version in the Chart.yaml. Once the pull request is merged, a Github Action workflow will automatically build and package a new release of the changed charts and publish them to the chart repository. diff --git a/aws/files/userdata_agent b/aws/files/userdata_agent deleted file mode 100644 index e772a2c..0000000 --- a/aws/files/userdata_agent +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/bash -x -export curlimage=appropriate/curl -export jqimage=stedolan/jq -export rancher_server_ip='${server_address}' - -if [ `command -v curl` ]; then - curl -sL https://releases.rancher.com/install-docker/${docker_version_agent}.sh | sh -elif [ `command -v wget` ]; then - wget -qO- https://releases.rancher.com/install-docker/${docker_version_agent}.sh | sh -fi - -for image in $curlimage $jqimage; do - until docker inspect $image > /dev/null 2>&1; do - docker pull $image - sleep 2 - done -done - -# stop here for rodeo -exit 0 - -while true; do - docker run --rm $curlimage -sLk https://$rancher_server_ip/ping && break - sleep 5 -done - -# Login -while true; do - - LOGINRESPONSE=$(docker run \ - --rm \ - $curlimage \ - -s "https://$rancher_server_ip/v3-public/localProviders/local?action=login" -H 'content-type: application/json' --data-binary '{"username":"admin","password":"${admin_password}"}' --insecure) - LOGINTOKEN=$(echo $LOGINRESPONSE | docker run --rm -i $jqimage -r .token) - - if [ "$LOGINTOKEN" != "null" ]; then - break - else - sleep 5 - fi -done - -# Get the Agent Image from the rancher server -while true; do - AGENTIMAGE=$(docker run \ - --rm \ - $curlimage \ - -sLk \ - -H "Authorization: Bearer $LOGINTOKEN" \ - "https://$rancher_server_ip/v3/settings/agent-image" | docker run --rm -i $jqimage -r '.value') - - if [ -n "$AGENTIMAGE" ]; then - break - else - sleep 5 - fi -done - -until docker inspect $AGENTIMAGE > /dev/null 2>&1; do - docker pull $AGENTIMAGE - sleep 2 -done - -# Test if cluster is created -while true; do - CLUSTERID=$(docker run \ - --rm \ - $curlimage \ - -sLk \ - -H "Authorization: Bearer $LOGINTOKEN" \ - "https://$rancher_server_ip/v3/clusters?name=${cluster_name}" | docker run --rm -i $jqimage -r '.data[].id') - - if [ -n "$CLUSTERID" ]; then - break - else - sleep 5 - fi -done - -# Get role flags from hostname -ROLEFLAG=`hostname | awk -F'-' '{ print $NF }'` -if [[ "$ROLEFLAG" == "all" ]]; then - ROLEFLAG="all-roles" -fi - -# Get token -# Test if cluster is created -while true; do - AGENTCMD=$(docker run \ - --rm \ - $curlimage \ - -sLk \ - -H "Authorization: Bearer $LOGINTOKEN" \ - "https://$rancher_server_ip/v3/clusterregistrationtoken?clusterId=$CLUSTERID" | docker run --rm -i $jqimage -r '.data[].nodeCommand' | head -1) - - if [ -n "$AGENTCMD" ]; then - break - else - sleep 5 - fi -done - -# Combine command and flags -COMPLETECMD="$AGENTCMD --address awspublic --internal-address awslocal --$ROLEFLAG" - -# Run command -$COMPLETECMD diff --git a/aws/files/userdata_server b/aws/files/userdata_server deleted file mode 100644 index 63f2517..0000000 --- a/aws/files/userdata_server +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -x -export curlimage=appropriate/curl -export jqimage=stedolan/jq - -if [ `command -v curl` ]; then - curl -sL https://releases.rancher.com/install-docker/${docker_version_server}.sh | sh -elif [ `command -v wget` ]; then - wget -qO- https://releases.rancher.com/install-docker/${docker_version_server}.sh | sh -fi - -for image in $curlimage $jqimage "rancher/rancher:${rancher_version}"; do - until docker inspect $image > /dev/null 2>&1; do - docker pull $image - sleep 2 - done -done - -# stop here for rodeo -exit 0 - -docker run -d --restart=unless-stopped -p 80:80 -p 443:443 -v /root/rancher:/var/lib/rancher rancher/rancher:${rancher_version} - -while true; do - docker run --rm --net=host $curlimage -sLk https://127.0.0.1/ping && break - sleep 5 -done - -# Login -while true; do - - LOGINRESPONSE=$(docker run \ - --rm \ - --net=host \ - $curlimage \ - -s "https://127.0.0.1/v3-public/localProviders/local?action=login" -H 'content-type: application/json' --data-binary '{"username":"admin","password":"admin"}' --insecure) - LOGINTOKEN=$(echo $LOGINRESPONSE | docker run --rm -i $jqimage -r .token) - echo "Login Token is $LOGINTOKEN" - if [ "$LOGINTOKEN" != "null" ]; then - break - else - sleep 5 - fi -done - - -# Change password -docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/users?action=changepassword' -H 'content-type: application/json' -H "Authorization: Bearer $LOGINTOKEN" --data-binary '{"currentPassword":"admin","newPassword":"${admin_password}"}' --insecure - -# Create API key -APIRESPONSE=$(docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/token' -H 'content-type: application/json' -H "Authorization: Bearer $LOGINTOKEN" --data-binary '{"type":"token","description":"automation"}' --insecure) - -# Extract and store token -APITOKEN=`echo $APIRESPONSE | docker run --rm -i $jqimage -r .token` - -# Configure server-url -RANCHER_SERVER="https://$(docker run --rm --net=host $curlimage -s http://169.254.169.254/latest/meta-data/public-ipv4)" -docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/settings/server-url' -H 'content-type: application/json' -H "Authorization: Bearer $APITOKEN" -X PUT --data-binary '{"name":"server-url","value":"'$RANCHER_SERVER'"}' --insecure - -# Create cluster -CLUSTERRESPONSE=$(docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/cluster' -H 'content-type: application/json' -H "Authorization: Bearer $APITOKEN" --data-binary '{"type":"cluster","rancherKubernetesEngineConfig":{"addonJobTimeout":30,"ignoreDockerVersion":true,"sshAgentAuth":false,"type":"rancherKubernetesEngineConfig","authentication":{"type":"authnConfig","strategy":"x509"},"network":{"type":"networkConfig","plugin":"canal"},"ingress":{"type":"ingressConfig","provider":"nginx"},"services":{"type":"rkeConfigServices","kubeApi":{"podSecurityPolicy":false,"type":"kubeAPIService"},"etcd":{"snapshot":false,"type":"etcdService","extraArgs":{"heartbeat-interval":500,"election-timeout":5000}}}},"name":"${cluster_name}"}' --insecure) - -# Extract clusterid to use for generating the docker run command -CLUSTERID=`echo $CLUSTERRESPONSE | docker run --rm -i $jqimage -r .id` - -# Generate registrationtoken -docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/clusterregistrationtoken' -H 'content-type: application/json' -H "Authorization: Bearer $APITOKEN" --data-binary '{"type":"clusterRegistrationToken","clusterId":"'$CLUSTERID'"}' --insecure diff --git a/aws/main.tf b/aws/main.tf deleted file mode 100644 index 850a2fd..0000000 --- a/aws/main.tf +++ /dev/null @@ -1,278 +0,0 @@ -# Configure the Amazon AWS Provider -provider "aws" { - access_key = "${var.aws_access_key}" - secret_key = "${var.aws_secret_key}" - region = "${var.region}" -} - -variable "aws_access_key" { - default = "xxx" - description = "Amazon AWS Access Key" -} - -variable "aws_secret_key" { - default = "xxx" - description = "Amazon AWS Secret Key" -} - -variable "prefix" { - default = "yourname" - description = "Cluster Prefix - All resources created by Terraform have this prefix prepended to them" -} - -variable "rancher_version" { - default = "latest" - description = "Rancher Server Version" -} - -variable "count_agent_all_nodes" { - default = "1" - description = "Number of Agent All Designation Nodes" -} - -variable "count_agent_etcd_nodes" { - default = "0" - description = "Number of ETCD Nodes" -} - -variable "count_agent_controlplane_nodes" { - default = "0" - description = "Number of K8s Control Plane Nodes" -} - -variable "count_agent_worker_nodes" { - default = "0" - description = "Number of Worker Nodes" -} - -variable "admin_password" { - default = "admin" - description = "Password to set for the admin account in Rancher" -} - -variable "cluster_name" { - default = "quickstart" - description = "Kubernetes Cluster Name" -} - -variable "region" { - default = "us-west-2" - description = "Amazon AWS Region for deployment" -} - -variable "type" { - default = "t3.medium" - description = "Amazon AWS Instance Type" -} - -variable "docker_version_server" { - default = "17.03" - description = "Docker Version to run on Rancher Server" -} - -variable "docker_version_agent" { - default = "17.03" - description = "Docker Version to run on Kubernetes Nodes" -} - -variable "ssh_key_name" { - default = "" - description = "Amazon AWS Key Pair Name" -} - -data "aws_ami" "ubuntu" { - most_recent = true - owners = ["099720109477"] # Canonical - - filter { - name = "name" - values = ["ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-*"] - } - - filter { - name = "virtualization-type" - values = ["hvm"] - } -} - -resource "aws_security_group" "rancher_sg_allowall" { - name = "${var.prefix}-allowall" - - ingress { - from_port = "0" - to_port = "0" - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = "0" - to_port = "0" - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } -} - -data "template_cloudinit_config" "rancherserver-cloudinit" { - part { - content_type = "text/cloud-config" - content = "hostname: ${var.prefix}-rancherserver\nmanage_etc_hosts: true" - } - - part { - content_type = "text/x-shellscript" - content = "${data.template_file.userdata_server.rendered}" - } -} - -resource "aws_instance" "rancherserver" { - ami = "${data.aws_ami.ubuntu.id}" - instance_type = "${var.type}" - key_name = "${var.ssh_key_name}" - security_groups = ["${aws_security_group.rancher_sg_allowall.name}"] - user_data = "${data.template_cloudinit_config.rancherserver-cloudinit.rendered}" - - tags = { - Name = "${var.prefix}-rancherserver" - } -} - -data "template_cloudinit_config" "rancheragent-all-cloudinit" { - count = "${var.count_agent_all_nodes}" - - part { - content_type = "text/cloud-config" - content = "hostname: ${var.prefix}-rancheragent-${count.index}-all\nmanage_etc_hosts: true" - } - - part { - content_type = "text/x-shellscript" - content = "${data.template_file.userdata_agent.rendered}" - } -} - -resource "aws_instance" "rancheragent-all" { - count = "${var.count_agent_all_nodes}" - ami = "${data.aws_ami.ubuntu.id}" - instance_type = "${var.type}" - key_name = "${var.ssh_key_name}" - security_groups = ["${aws_security_group.rancher_sg_allowall.name}"] - user_data = "${data.template_cloudinit_config.rancheragent-all-cloudinit.*.rendered[count.index]}" - - tags = { - Name = "${var.prefix}-rancheragent-${count.index}-all" - } -} - -data "template_cloudinit_config" "rancheragent-etcd-cloudinit" { - count = "${var.count_agent_etcd_nodes}" - - part { - content_type = "text/cloud-config" - content = "hostname: ${var.prefix}-rancheragent-${count.index}-etcd\nmanage_etc_hosts: true" - } - - part { - content_type = "text/x-shellscript" - content = "${data.template_file.userdata_agent.rendered}" - } -} - -resource "aws_instance" "rancheragent-etcd" { - count = "${var.count_agent_etcd_nodes}" - ami = "${data.aws_ami.ubuntu.id}" - instance_type = "${var.type}" - key_name = "${var.ssh_key_name}" - security_groups = ["${aws_security_group.rancher_sg_allowall.name}"] - user_data = "${data.template_cloudinit_config.rancheragent-etcd-cloudinit.*.rendered[count.index]}" - - tags = { - Name = "${var.prefix}-rancheragent-${count.index}-etcd" - } -} - -data "template_cloudinit_config" "rancheragent-controlplane-cloudinit" { - count = "${var.count_agent_controlplane_nodes}" - - part { - content_type = "text/cloud-config" - content = "hostname: ${var.prefix}-rancheragent-${count.index}-controlplane\nmanage_etc_hosts: true" - } - - part { - content_type = "text/x-shellscript" - content = "${data.template_file.userdata_agent.rendered}" - } -} - -resource "aws_instance" "rancheragent-controlplane" { - count = "${var.count_agent_controlplane_nodes}" - ami = "${data.aws_ami.ubuntu.id}" - instance_type = "${var.type}" - key_name = "${var.ssh_key_name}" - security_groups = ["${aws_security_group.rancher_sg_allowall.name}"] - user_data = "${data.template_cloudinit_config.rancheragent-controlplane-cloudinit.*.rendered[count.index]}" - - tags = { - Name = "${var.prefix}-rancheragent-${count.index}-controlplane" - } -} - -data "template_cloudinit_config" "rancheragent-worker-cloudinit" { - count = "${var.count_agent_worker_nodes}" - - part { - content_type = "text/cloud-config" - content = "hostname: ${var.prefix}-rancheragent-${count.index}-worker\nmanage_etc_hosts: true" - } - - part { - content_type = "text/x-shellscript" - content = "${data.template_file.userdata_agent.rendered}" - } -} - -resource "aws_instance" "rancheragent-worker" { - count = "${var.count_agent_worker_nodes}" - ami = "${data.aws_ami.ubuntu.id}" - instance_type = "${var.type}" - key_name = "${var.ssh_key_name}" - security_groups = ["${aws_security_group.rancher_sg_allowall.name}"] - user_data = "${data.template_cloudinit_config.rancheragent-worker-cloudinit.*.rendered[count.index]}" - - tags = { - Name = "${var.prefix}-rancheragent-${count.index}-worker" - } -} - -data "template_file" "userdata_server" { - template = "${file("files/userdata_server")}" - - vars = { - admin_password = "${var.admin_password}" - cluster_name = "${var.cluster_name}" - docker_version_server = "${var.docker_version_server}" - rancher_version = "${var.rancher_version}" - } -} - - -data "template_file" "userdata_agent" { - template = "${file("files/userdata_agent")}" - - vars = { - admin_password = "${var.admin_password}" - cluster_name = "${var.cluster_name}" - docker_version_agent = "${var.docker_version_agent}" - rancher_version = "${var.rancher_version}" - server_address = "${aws_instance.rancherserver.public_ip}" - } -} - -output "rancher-server-ip" { - value = ["${aws_instance.rancherserver.public_ip}"] -} - -output "rancher-agent-ips" { - value = ["${aws_instance.rancheragent-all.*.public_ip}"] -} diff --git a/aws/terraform.tfvars.example b/aws/terraform.tfvars.example deleted file mode 100644 index 736fe6d..0000000 --- a/aws/terraform.tfvars.example +++ /dev/null @@ -1,28 +0,0 @@ -# Amazon AWS Access Key -aws_access_key = "your-aws-access-key" -# Amazon AWS Secret Key -aws_secret_key = "your-aws-secret-key" -# Amazon AWS Key Pair Name -ssh_key_name = "your-aws-key-pair-name" -# Region where resources should be created -region = "us-west-2" -# Resources will be prefixed with this to avoid clashing names -prefix = "myname" -# Admin password to access Rancher -admin_password = "admin" -# rancher/rancher image tag to use -rancher_version = "latest" -# Count of agent nodes with role all -count_agent_all_nodes = "1" -# Count of agent nodes with role etcd -count_agent_etcd_nodes = "0" -# Count of agent nodes with role controlplane -count_agent_controlplane_nodes = "0" -# Count of agent nodes with role worker -count_agent_worker_nodes = "0" -# Docker version of host running `rancher/rancher` -docker_version_server = "17.03" -# Docker version of host being added to a cluster (running `rancher/rancher-agent`) -docker_version_agent = "17.03" -# AWS Instance Type -type = "t3.medium" diff --git a/charts/bookinfo/Chart.yaml b/charts/bookinfo/Chart.yaml new file mode 100644 index 0000000..4158d7a --- /dev/null +++ b/charts/bookinfo/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +name: bookinfo +description: Istio bookinfo app +type: application +version: 0.2.1 +appVersion: "1.16.2" +icon: https://upload.wikimedia.org/wikipedia/commons/a/a1/Istio-bluelogo-nobackground-unframed.svg +maintainers: + - name: Rancher + url: https://github.com/rancher diff --git a/charts/bookinfo/questions.yml b/charts/bookinfo/questions.yml new file mode 100644 index 0000000..e69de29 diff --git a/charts/bookinfo/templates/bookinfo.yaml b/charts/bookinfo/templates/bookinfo.yaml new file mode 100644 index 0000000..f14a58b --- /dev/null +++ b/charts/bookinfo/templates/bookinfo.yaml @@ -0,0 +1,343 @@ +# Copyright Istio Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +################################################################################################## +# This file defines the services, service accounts, and deployments for the Bookinfo sample. +# +# To apply all 4 Bookinfo services, their corresponding service accounts, and deployments: +# +# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml +# +# Alternatively, you can deploy any resource separately: +# +# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l service=reviews # reviews Service +# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l account=reviews # reviews ServiceAccount +# kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -l app=reviews,version=v3 # reviews-v3 Deployment +################################################################################################## + +################################################################################################## +# Details service +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: details + labels: + app: details + service: details +spec: + ports: + - port: 9080 + name: http + selector: + app: details +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bookinfo-details + labels: + account: details +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: details-v1 + labels: + app: details + version: v1 +spec: + replicas: 1 + selector: + matchLabels: + app: details + version: v1 + template: + metadata: + labels: + app: details + version: v1 + spec: + serviceAccountName: bookinfo-details + containers: + - name: details + image: docker.io/istio/examples-bookinfo-details-v1:1.16.2 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 + securityContext: + runAsUser: 1000 +--- +################################################################################################## +# Ratings service +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: ratings + labels: + app: ratings + service: ratings +spec: + ports: + - port: 9080 + name: http + selector: + app: ratings +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bookinfo-ratings + labels: + account: ratings +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ratings-v1 + labels: + app: ratings + version: v1 +spec: + replicas: 1 + selector: + matchLabels: + app: ratings + version: v1 + template: + metadata: + labels: + app: ratings + version: v1 + spec: + serviceAccountName: bookinfo-ratings + containers: + - name: ratings + image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 + securityContext: + runAsUser: 1000 +--- +################################################################################################## +# Reviews service +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: reviews + labels: + app: reviews + service: reviews +spec: + ports: + - port: 9080 + name: http + selector: + app: reviews +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bookinfo-reviews + labels: + account: reviews +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reviews-v1 + labels: + app: reviews + version: v1 +spec: + replicas: 1 + selector: + matchLabels: + app: reviews + version: v1 + template: + metadata: + labels: + app: reviews + version: v1 + spec: + serviceAccountName: bookinfo-reviews + containers: + - name: reviews + image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2 + imagePullPolicy: IfNotPresent + env: + - name: LOG_DIR + value: "/tmp/logs" + ports: + - containerPort: 9080 + volumeMounts: + - name: tmp + mountPath: /tmp + - name: wlp-output + mountPath: /opt/ibm/wlp/output + securityContext: + runAsUser: 1000 + volumes: + - name: wlp-output + emptyDir: {} + - name: tmp + emptyDir: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reviews-v2 + labels: + app: reviews + version: v2 +spec: + replicas: 1 + selector: + matchLabels: + app: reviews + version: v2 + template: + metadata: + labels: + app: reviews + version: v2 + spec: + serviceAccountName: bookinfo-reviews + containers: + - name: reviews + image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2 + imagePullPolicy: IfNotPresent + env: + - name: LOG_DIR + value: "/tmp/logs" + ports: + - containerPort: 9080 + volumeMounts: + - name: tmp + mountPath: /tmp + - name: wlp-output + mountPath: /opt/ibm/wlp/output + securityContext: + runAsUser: 1000 + volumes: + - name: wlp-output + emptyDir: {} + - name: tmp + emptyDir: {} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: reviews-v3 + labels: + app: reviews + version: v3 +spec: + replicas: 1 + selector: + matchLabels: + app: reviews + version: v3 + template: + metadata: + labels: + app: reviews + version: v3 + spec: + serviceAccountName: bookinfo-reviews + containers: + - name: reviews + image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2 + imagePullPolicy: IfNotPresent + env: + - name: LOG_DIR + value: "/tmp/logs" + ports: + - containerPort: 9080 + volumeMounts: + - name: tmp + mountPath: /tmp + - name: wlp-output + mountPath: /opt/ibm/wlp/output + securityContext: + runAsUser: 1000 + volumes: + - name: wlp-output + emptyDir: {} + - name: tmp + emptyDir: {} +--- +################################################################################################## +# Productpage services +################################################################################################## +apiVersion: v1 +kind: Service +metadata: + name: productpage + labels: + app: productpage + service: productpage +spec: + ports: + - port: 9080 + name: http + selector: + app: productpage +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: bookinfo-productpage + labels: + account: productpage +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: productpage-v1 + labels: + app: productpage + version: v1 +spec: + replicas: 1 + selector: + matchLabels: + app: productpage + version: v1 + template: + metadata: + labels: + app: productpage + version: v1 + spec: + serviceAccountName: bookinfo-productpage + containers: + - name: productpage + image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2 + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9080 + volumeMounts: + - name: tmp + mountPath: /tmp + securityContext: + runAsUser: 1000 + volumes: + - name: tmp + emptyDir: {} +--- diff --git a/charts/bookinfo/templates/destination-rule-all.yaml b/charts/bookinfo/templates/destination-rule-all.yaml new file mode 100644 index 0000000..96be699 --- /dev/null +++ b/charts/bookinfo/templates/destination-rule-all.yaml @@ -0,0 +1,62 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: productpage +spec: + host: productpage + subsets: + - name: v1 + labels: + version: v1 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: reviews +spec: + host: reviews + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v3 + labels: + version: v3 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: ratings +spec: + host: ratings + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v2-mysql + labels: + version: v2-mysql + - name: v2-mysql-vm + labels: + version: v2-mysql-vm +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: details +spec: + host: details + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 +--- diff --git a/charts/bookinfo/templates/ingress-gateway.yaml b/charts/bookinfo/templates/ingress-gateway.yaml new file mode 100644 index 0000000..b645d40 --- /dev/null +++ b/charts/bookinfo/templates/ingress-gateway.yaml @@ -0,0 +1,41 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: bookinfo-gateway +spec: + selector: + istio: ingressgateway + servers: + - port: + number: 80 + name: http + protocol: HTTP + hosts: + - "*" +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: bookinfo +spec: + hosts: + - "*" + gateways: + - bookinfo-gateway + http: + - match: + - uri: + exact: /productpage + - uri: + prefix: /static + - uri: + exact: /login + - uri: + exact: /logout + - uri: + prefix: /api/v1/products + route: + - destination: + host: productpage + port: + number: 9080 \ No newline at end of file diff --git a/charts/bookinfo/values.yaml b/charts/bookinfo/values.yaml new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/charts/bookinfo/values.yaml @@ -0,0 +1 @@ + diff --git a/charts/loki/Chart.lock b/charts/loki/Chart.lock new file mode 100644 index 0000000..b6e7f59 --- /dev/null +++ b/charts/loki/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: loki + repository: https://grafana.github.io/helm-charts + version: 2.5.0 +digest: sha256:85efd49f43db6a4a0a07e4b01534f0a92874d095760fe8753695823f5b369ea1 +generated: "2021-06-07T15:21:29.067236+02:00" diff --git a/charts/loki/Chart.yaml b/charts/loki/Chart.yaml new file mode 100644 index 0000000..66a24bf --- /dev/null +++ b/charts/loki/Chart.yaml @@ -0,0 +1,19 @@ +apiVersion: v2 +name: loki +type: application +version: 2.5.2 +appVersion: v2.2.0 +description: "Loki: like Prometheus, but for logs." +home: https://grafana.com/loki +icon: https://raw.githubusercontent.com/grafana/loki/master/docs/sources/logo.png +sources: + - https://github.com/grafana/loki +maintainers: + - name: Grafana + email: lokiproject@googlegroups.com + - name: Rancher + url: https://github.com/rancher +dependencies: + - name: loki + version: "2.x.x" + repository: https://grafana.github.io/helm-charts diff --git a/charts/loki/charts/loki-2.5.0.tgz b/charts/loki/charts/loki-2.5.0.tgz new file mode 100644 index 0000000..49b019f Binary files /dev/null and b/charts/loki/charts/loki-2.5.0.tgz differ diff --git a/charts/loki/questions.yml b/charts/loki/questions.yml new file mode 100644 index 0000000..5d9300d --- /dev/null +++ b/charts/loki/questions.yml @@ -0,0 +1,50 @@ +questions: + - variable: loki.serviceMonitor.enabled + default: true + type: boolean + label: Create ServiceMonitor + group: Rancher Integration + - variable: rancher.createOutput + default: true + type: boolean + label: Create Logging Output + group: Rancher Integration + - variable: rancher.createFlow + default: true + type: boolean + label: Create Logging Flow + group: Rancher Integration + - variable: rancher.addGrafanaDatasource + default: true + type: boolean + label: Add Grafana datasource + group: Rancher Integration + - variable: rancher.createGrafanaDashboard + default: true + type: boolean + label: Create Grafana dashboard + group: Rancher Integration + - variable: loki.persistence.enabled + default: false + description: "Enable persistent volume for Loki" + type: boolean + required: true + label: Loki Persistent Volume Enabled + show_subquestion_if: true + group: "Storage Settings" + subquestions: + - variable: loki.persistence.size + default: "10Gi" + description: "Loki Persistent Volume Size" + type: string + label: Loki Volume Size + - variable: loki.persistence.storageClass + default: "" + description: "If undefined or null, uses the default StorageClass. Default to null" + type: storageclass + label: Default StorageClass for Loki + - variable: loki.persistence.existingClaim + default: "" + description: "If not empty, uses the specified existing PVC instead of creating new one" + type: pvc + label: Existing Persistent Volume Claim for Loki \ No newline at end of file diff --git a/charts/loki/templates/_helpers.tpl b/charts/loki/templates/_helpers.tpl new file mode 100644 index 0000000..fe4bc4e --- /dev/null +++ b/charts/loki/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "loki.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 "loki.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 "loki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "loki.labels" -}} +helm.sh/chart: {{ include "loki.chart" . }} +{{ include "loki.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "loki.selectorLabels" -}} +app.kubernetes.io/name: {{ include "loki.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "loki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "loki.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/loki/templates/dashboard.yaml b/charts/loki/templates/dashboard.yaml new file mode 100644 index 0000000..46eb4f0 --- /dev/null +++ b/charts/loki/templates/dashboard.yaml @@ -0,0 +1,278 @@ +{{- if .Values.rancher.createGrafanaDashboard }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: loki-dashboard + namespace: cattle-dashboards + labels: + grafana_dashboard: "1" +data: + loki.json: | + { + "annotations": { + "list": [ + { + "$$hashKey": "object:75", + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Loki logs panel with prometheus variables ", + "editable": true, + "gnetId": 12019, + "graphTooltip": 0, + "id": 45, + "iteration": 1623242856351, + "links": [], + "panels": [ + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "Loki", + "fieldConfig": { + "defaults": { + "custom": {}, + "links": [] + }, + "overrides": [] + }, + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 3, + "w": 24, + "x": 0, + "y": 0 + }, + "hiddenSeries": false, + "id": 6, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "nullPointMode": "null", + "options": { + "alertThreshold": true + }, + "percentage": false, + "pluginVersion": "7.4.5", + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(count_over_time({namespace=\"$namespace\", pod=~\"$pod\"} |~ \"$search\"[$__interval]))", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "$$hashKey": "object:168", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + }, + { + "$$hashKey": "object:169", + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "datasource": "Loki", + "fieldConfig": { + "defaults": { + "custom": {} + }, + "overrides": [] + }, + "gridPos": { + "h": 25, + "w": 24, + "x": 0, + "y": 3 + }, + "id": 2, + "maxDataPoints": "", + "options": { + "showLabels": true, + "showTime": true, + "sortOrder": "Descending", + "wrapLogMessage": true + }, + "targets": [ + { + "expr": "{namespace=\"$namespace\", pod=~\"$pod\"} |~ \"$search\"", + "refId": "A" + } + ], + "timeFrom": null, + "timeShift": null, + "title": "Logs Panel", + "type": "logs" + } + ], + "schemaVersion": 27, + "style": "dark", + "tags": [], + "templating": { + "list": [ + { + "allValue": null, + "current": { + "selected": false, + "text": "cattle-system", + "value": "cattle-system" + }, + "datasource": "Prometheus", + "definition": "label_values(kube_pod_info, namespace)", + "description": null, + "error": null, + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "namespace", + "options": [], + "query": { + "query": "label_values(kube_pod_info, namespace)", + "refId": "Prometheus-namespace-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "allValue": ".*", + "current": { + "selected": false, + "text": "All", + "value": "$__all" + }, + "datasource": "Prometheus", + "definition": "label_values(container_network_receive_bytes_total{namespace=~\"$namespace\"},pod)", + "description": null, + "error": null, + "hide": 0, + "includeAll": true, + "label": null, + "multi": true, + "name": "pod", + "options": [], + "query": { + "query": "label_values(container_network_receive_bytes_total{namespace=~\"$namespace\"},pod)", + "refId": "Prometheus-pod-Variable-Query" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + }, + { + "current": { + "selected": false, + "text": "", + "value": "" + }, + "description": null, + "error": null, + "hide": 0, + "label": null, + "name": "search", + "options": [ + { + "selected": true, + "text": "", + "value": "" + } + ], + "query": "", + "skipUrlSync": false, + "type": "textbox" + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ] + }, + "timezone": "", + "title": "Loki quick search", + "uid": "liz0yRCZz", + "version": 1 + } +{{- end }} diff --git a/charts/loki/templates/datasource.yaml b/charts/loki/templates/datasource.yaml new file mode 100644 index 0000000..c707b86 --- /dev/null +++ b/charts/loki/templates/datasource.yaml @@ -0,0 +1,18 @@ +{{- if .Values.rancher.addGrafanaDatasource }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "loki.fullname" . }}-datasource + namespace: cattle-monitoring-system + labels: + grafana_datasource: "1" +data: + loki-stack-datasource.yaml: |- + apiVersion: 1 + datasources: + - name: Loki + type: loki + access: proxy + url: http://{{ include "loki.fullname" . }}.{{ .Release.Namespace }}:3100 + version: 1 +{{- end }} diff --git a/charts/loki/templates/logging-flow.yaml b/charts/loki/templates/logging-flow.yaml new file mode 100644 index 0000000..82fb7aa --- /dev/null +++ b/charts/loki/templates/logging-flow.yaml @@ -0,0 +1,10 @@ +{{- if .Values.rancher.createFlow }} +apiVersion: logging.banzaicloud.io/v1beta1 +kind: ClusterFlow +metadata: + name: all-logs-to-{{ include "loki.fullname" . }} + namespace: cattle-logging-system +spec: + globalOutputRefs: + - {{ include "loki.fullname" . }} +{{- end }} diff --git a/charts/loki/templates/logging-output.yaml b/charts/loki/templates/logging-output.yaml new file mode 100644 index 0000000..432dfbd --- /dev/null +++ b/charts/loki/templates/logging-output.yaml @@ -0,0 +1,11 @@ +{{- if .Values.rancher.createOutput }} +apiVersion: logging.banzaicloud.io/v1beta1 +kind: ClusterOutput +metadata: + name: {{ include "loki.fullname" . }} + namespace: cattle-logging-system +spec: + loki: + url: http://{{ include "loki.fullname" . }}.{{ .Release.Namespace }}:3100 + configure_kubernetes_labels: true +{{- end }} diff --git a/charts/loki/templates/post-install-hook.yaml b/charts/loki/templates/post-install-hook.yaml new file mode 100644 index 0000000..0b95934 --- /dev/null +++ b/charts/loki/templates/post-install-hook.yaml @@ -0,0 +1,55 @@ +{{- if .Values.rancher.addGrafanaDatasource }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "loki.fullname" . }}-restart-grafana + labels: + {{- include "loki.labels" . | nindent 4 }} + annotations: + helm.sh/hook: post-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded +spec: + template: + spec: + containers: + - name: labeler + image: bitnami/kubectl:latest + command: + - kubectl + - rollout + - restart + - deployment + - -n + - cattle-monitoring-system + - rancher-monitoring-grafana + restartPolicy: Never + serviceAccountName: {{ include "loki.fullname" . }}-installer +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "loki.fullname" . }}-installer + annotations: + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook: post-install + labels: + {{- include "loki.labels" . | nindent 4 }} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "loki.fullname" . }}-installer + annotations: + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook: post-install + labels: + {{- include "loki.labels" . | nindent 4 }} +subjects: +- kind: ServiceAccount + name: {{ include "loki.fullname" . }}-installer + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/charts/loki/values.yaml b/charts/loki/values.yaml new file mode 100644 index 0000000..b37536d --- /dev/null +++ b/charts/loki/values.yaml @@ -0,0 +1,18 @@ +loki: + persistence: + enabled: false + serviceMonitor: + enabled: true + resources: + limits: + cpu: 200m + memory: 256Mi + requests: + cpu: 100m + memory: 128Mi + +rancher: + createOutput: true + createFlow: true + addGrafanaDatasource: true + createGrafanaDashboard: true diff --git a/charts/mysql-operator/Chart.lock b/charts/mysql-operator/Chart.lock new file mode 100644 index 0000000..41e276a --- /dev/null +++ b/charts/mysql-operator/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: mysql-operator + repository: https://presslabs.github.io/charts + version: 0.4.0 +digest: sha256:7ff03a44958c628aa5f19b9f87fd7cf2ef718e5bf2b0de054e9e3e64f95e4d87 +generated: "2021-06-07T16:12:03.969168+02:00" diff --git a/charts/mysql-operator/Chart.yaml b/charts/mysql-operator/Chart.yaml new file mode 100644 index 0000000..dbeb6e5 --- /dev/null +++ b/charts/mysql-operator/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +name: mysql-operator +description: MySQL Operator from Presslabs +type: application +version: 0.4.3 +appVersion: "0.4.0" +icon: https://upload.wikimedia.org/wikipedia/en/d/dd/MySQL_logo.svg +keywords: + - mysql + - percona + - orchestrator + - presslabs +home: https://github.com/presslabs/mysql-operator +sources: + - https://github.com/presslabs/mysql-operator.git +maintainers: + - name: Rancher + url: https://github.com/rancher +dependencies: + - name: mysql-operator + version: "0.x.x" + repository: https://presslabs.github.io/charts diff --git a/charts/mysql-operator/charts/mysql-operator-0.4.0.tgz b/charts/mysql-operator/charts/mysql-operator-0.4.0.tgz new file mode 100644 index 0000000..cb6f098 Binary files /dev/null and b/charts/mysql-operator/charts/mysql-operator-0.4.0.tgz differ diff --git a/charts/mysql-operator/questions.yml b/charts/mysql-operator/questions.yml new file mode 100644 index 0000000..5557fe0 --- /dev/null +++ b/charts/mysql-operator/questions.yml @@ -0,0 +1,80 @@ +questions: + - variable: mysql-operator.ingress.enabled + default: true + type: boolean + label: Expose app using Layer 7 Load Balancer + show_subquestion_if: true + group: "Services and Load Balancing" + subquestions: + - variable: mysql-operator.ingress.hosts.0.host + default: "sslip.io" + type: hostname + required: true + label: Hostname + - variable: ingress.auth.user + default: "admin" + type: string + required: true + label: Authentication user name + - variable: ingress.auth.password + default: "admin" + type: string + required: true + label: Authentication password + - variable: database.create + default: true + type: boolean + label: Create initial database + show_subquestion_if: true + group: "Database" + subquestions: + - variable: database.name + default: "db" + type: string + required: true + label: Cluster name + - variable: database.size + default: "1Gi" + type: string + required: true + label: Storage size + - variable: database.replicas + default: 3 + type: int + required: true + label: Replicas + - variable: database.rootPassword + default: "" + type: string + required: true + label: Root password + - variable: database.appDatabase + default: "" + type: string + required: false + label: App database name + - variable: database.appUser + default: "" + type: string + required: false + label: App user name + - variable: database.appPassword + default: "" + type: string + required: false + label: App user password + - variable: mysql-operator.serviceMonitor.enabled + default: true + type: boolean + label: Create ServiceMonitor + group: Rancher Integration + - variable: rancher.createGrafanaDashboard + default: true + type: boolean + label: Create Grafana dashboard + group: Rancher Integration + - variable: rancher.createAlerts + default: true + type: boolean + label: Create Alerts + group: Rancher Integration diff --git a/charts/mysql-operator/templates/basic-auth.yaml b/charts/mysql-operator/templates/basic-auth.yaml new file mode 100644 index 0000000..9475408 --- /dev/null +++ b/charts/mysql-operator/templates/basic-auth.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +stringData: + auth: {{ .Values.ingress.auth.user }}:{{ .Values.ingress.auth.password }} +kind: Secret +metadata: + name: basic-auth + namespace: {{ .Release.Namespace }} +type: Opaque \ No newline at end of file diff --git a/charts/mysql-operator/templates/cluster.yaml b/charts/mysql-operator/templates/cluster.yaml new file mode 100644 index 0000000..15d5d3b --- /dev/null +++ b/charts/mysql-operator/templates/cluster.yaml @@ -0,0 +1,40 @@ +{{- if .Values.database.create }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Values.database.name }}-secret + namespace: {{ .Release.Namespace }} +type: Opaque +data: + ROOT_PASSWORD: {{ required ".rootPassword is missing" .Values.database.rootPassword | b64enc | quote }} + DATABASE: {{ .Values.database.appDatabase | b64enc | quote }} + USER: {{ .Values.database.appUser | b64enc | quote }} + PASSWORD: {{ .Values.database.appPassword | b64enc | quote }} +--- +apiVersion: mysql.presslabs.org/v1alpha1 +kind: MysqlCluster +metadata: + name: {{ .Values.database.name }} + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.database.replicas }} + secretName: {{ .Values.database.name }}-secret + mysqlVersion: "5.7" + minAvailable: "50%" + mysqlConf: + max_connections: "200" + innodb-buffer-pool-size: "256M" + tmp_table_size: 256M + max_heap_table_size: 256M + podSpec: + resources: + requests: + memory: 256Mi + cpu: 200m + volumeSpec: + persistentVolumeClaim: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: {{ .Values.database.size }} +{{- end }} diff --git a/charts/mysql-operator/templates/dashboard.yaml b/charts/mysql-operator/templates/dashboard.yaml new file mode 100644 index 0000000..896e347 --- /dev/null +++ b/charts/mysql-operator/templates/dashboard.yaml @@ -0,0 +1,1125 @@ +{{- if .Values.rancher.createGrafanaDashboard }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-mysql + namespace: cattle-dashboards + labels: + grafana_dashboard: "1" +data: + mysql.json: {{`| + { + "__inputs": [ + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "5.1.2" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "5.0.0" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "5.0.0" + }, + { + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "5.0.0" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": 6239, + "graphTooltip": 0, + "id": null, + "iteration": 1527084642291, + "links": [], + "panels": [ + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 17, + "panels": [], + "title": "Global status", + "type": "row" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": {}, + "mappings": [ + { + "id": 0, + "op": "=", + "text": "N/A", + "type": 1, + "value": "null" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#bf1b00", + "value": null + }, + { + "color": "#508642", + "value": 1 + }, + { + "color": "#ef843c", + "value": 2 + } + ] + }, + "unit": "none" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 0, + "y": 1 + }, + "id": 11, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.4.5", + "targets": [ + { + "expr": "mysql_up{pod=\"$pod\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Instance Up", + "type": "stat" + }, + { + "cacheTimeout": null, + "datasource": "Prometheus", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "custom": {}, + "mappings": [ + { + "id": 0, + "op": "=", + "text": "N/A", + "type": 1, + "value": "null" + } + ], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "#d44a3a", + "value": null + }, + { + "color": "rgba(237, 129, 40, 0.89)", + "value": 25200 + }, + { + "color": "#508642", + "value": 32400 + } + ] + }, + "unit": "s" + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 6, + "x": 6, + "y": 1 + }, + "id": 15, + "interval": null, + "links": [], + "maxDataPoints": 100, + "options": { + "colorMode": "background", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "lastNotNull" + ], + "fields": "", + "values": false + }, + "text": {}, + "textMode": "auto" + }, + "pluginVersion": "7.4.5", + "targets": [ + { + "expr": "mysql_global_status_uptime{pod=\"$pod\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "title": "Uptime", + "type": "stat" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 1 + }, + "id": 29, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "mysql_global_status_max_used_connections{pod=\"$pod\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "current", + "refId": "A" + }, + { + "expr": "mysql_global_variables_max_connections{pod=\"$pod\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Max", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Mysql Connections", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 8 + }, + "id": 19, + "panels": [], + "title": "I/O", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 9 + }, + "id": 5, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "write", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(mysql_global_status_innodb_data_reads{pod=\"$pod\"}[10m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "reads", + "refId": "A" + }, + { + "expr": "irate(mysql_global_status_innodb_data_writes{pod=\"$pod\"}[10m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "write", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "mysql disk reads vs writes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 9 + }, + "id": 9, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "/sent/", + "transform": "negative-Y" + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(mysql_global_status_bytes_received{pod=\"$pod\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "received", + "refId": "A" + }, + { + "expr": "irate(mysql_global_status_bytes_sent{pod=\"$pod\"}[5m])", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "sent", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "mysql network received vs sent", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 18 + }, + "id": 2, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(mysql_global_status_commands_total{pod=\"$pod\"}[5m]) > 0", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ command }} - {{ pod }}", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Query rates", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 18 + }, + "id": 25, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "mysql_global_status_threads_running{pod=\"$pod\"} ", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Running Threads", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": "15", + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 25 + }, + "id": 21, + "panels": [], + "title": "Errors", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The number of connections that were aborted because the client died without closing the connection properly. See Section B.5.2.10, “Communication Errors and Aborted Connections”.", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 26 + }, + "id": 13, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "mysql_global_status_aborted_clients{pod=\"$pod\"}", + "format": "time_series", + "intervalFactor": 1, + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Aborted clients", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "description": "The number of failed attempts to connect to the MySQL server. See Section B.5.2.10, “Communication Errors and Aborted Connections”.\n\nFor additional connection-related information, check the Connection_errors_xxx status variables and the host_cache table.", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 26 + }, + "id": 4, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "mysql_global_status_aborted_connects{pod=\"$pod\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "", + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "mysql aborted Connects", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "collapsed": false, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 35 + }, + "id": 23, + "panels": [], + "title": "Disk usage", + "type": "row" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 0, + "y": 36 + }, + "id": 27, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(mysql_info_schema_table_size{component=\"data_length\",pod=\"$pod\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Tables", + "refId": "A" + }, + { + "expr": "sum(mysql_info_schema_table_size{component=\"index_length\",pod=\"$pod\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "Indexes", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Disk usage tables / indexes", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "gridPos": { + "h": 9, + "w": 12, + "x": 12, + "y": 36 + }, + "id": 7, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(mysql_info_schema_table_rows{pod=\"$pod\"})", + "format": "time_series", + "intervalFactor": 1, + "refId": "A" + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Sum of all rows", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "decimals": null, + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "schemaVersion": 16, + "style": "dark", + "tags": [ + "Databases", + "backgroundpods" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "hide": 0, + "includeAll": false, + "label": null, + "multi": false, + "name": "pod", + "options": [], + "query": "label_values(mysql_up,pod)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-1h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "", + "title": "Mysql - Prometheus", + "uid": "6-kPlS7ik", + "version": 16, + "description": "Basic Mysql dashboard for the prometheus exporter " + }`}} +{{- end }} diff --git a/charts/mysql-operator/templates/rules.yaml b/charts/mysql-operator/templates/rules.yaml new file mode 100644 index 0000000..2221282 --- /dev/null +++ b/charts/mysql-operator/templates/rules.yaml @@ -0,0 +1,45 @@ +{{- if .Values.rancher.createAlerts }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: mysql-rules + namespace: default +spec: + groups: + - name: mysql.rules + rules: + - alert: MySQLReplicationNotRunning + expr: mysql_slave_status_slave_io_running == 0 or mysql_slave_status_slave_sql_running + == 0 + for: 2m + labels: + severity: critical + annotations: + description: Slave replication (IO or SQL) has been down for more than 2 minutes. + summary: Slave replication is not running + - alert: MySQLReplicationLag + expr: (mysql_slave_lag_seconds > 30) and on(instance) (predict_linear(mysql_slave_lag_seconds[5m], + 60 * 2) > 0) + for: 1m + labels: + severity: critical + annotations: + description: The mysql slave replication has fallen behind and is not recovering + summary: MySQL slave replication is lagging + - alert: MySQLReplicationLag + expr: (mysql_heartbeat_lag_seconds > 30) and on(instance) (predict_linear(mysql_heartbeat_lag_seconds[5m], + 60 * 2) > 0) + for: 1m + labels: + severity: critical + annotations: + description: The mysql slave replication has fallen behind and is not recovering + summary: MySQL slave replication is lagging + - alert: MySQLInnoDBLogWaits + expr: rate(mysql_global_status_innodb_log_waits[15m]) > 10 + labels: + severity: warning + annotations: + description: {{`The innodb logs are waiting for disk at a rate of {{$value}} / second`}} + summary: MySQL innodb log writes stalling +{{- end }} diff --git a/charts/mysql-operator/values.yaml b/charts/mysql-operator/values.yaml new file mode 100644 index 0000000..7079308 --- /dev/null +++ b/charts/mysql-operator/values.yaml @@ -0,0 +1,35 @@ +mysql-operator: + serviceMonitor: + enabled: true + orchestrator: + config: + # `reset slave all` and `set read_only=0` on promoted master + ApplyMySQLPromotionAfterMasterFailover: true + ingress: + enabled: true + annotations: + nginx.ingress.kubernetes.io/auth-type: basic + nginx.ingress.kubernetes.io/auth-secret: basic-auth + hosts: + - host: sslip.io + paths: + - / + +database: + name: "db" + create: true + size: 1Gi + replicas: 3 + rootPassword: "" + appDatabase: "" + appUser: "" + appPassword: "" + +rancher: + createGrafanaDashboard: true + createAlerts: true + +ingress: + auth: + user: admin + password: admin diff --git a/charts/nfs-server-provisioner/Chart.lock b/charts/nfs-server-provisioner/Chart.lock new file mode 100644 index 0000000..e2f08da --- /dev/null +++ b/charts/nfs-server-provisioner/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: nfs-server-provisioner + repository: https://raphaelmonrouzeau.github.io/charts/repository/ + version: 1.3.0 +digest: sha256:cc49c23b7ed77773d39a3805d40868ba7dff0b31b363637b5c4e5419d575a99a +generated: "2021-06-07T12:57:21.260754+02:00" diff --git a/charts/nfs-server-provisioner/Chart.yaml b/charts/nfs-server-provisioner/Chart.yaml new file mode 100644 index 0000000..06b3697 --- /dev/null +++ b/charts/nfs-server-provisioner/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +appVersion: 2.3.0 +description: nfs-server-provisioner is an out-of-tree dynamic provisioner for Kubernetes. You can use it to quickly & easily deploy shared storage that works almost anywhere. +name: nfs-server-provisioner +version: 1.2.3 +maintainers: +- name: kiall + email: kiall@macinnes.ie +- name: kvaps + email: kvapss@gmail.com +- name: joaocc + email: joaocc-dev@live.com +- name: Rancher + url: https://github.com/rancher +home: https://github.com/kubernetes-sigs/nfs-ganesha-server-and-external-provisioner +sources: +- https://github.com/kubernetes-sigs/nfs-ganesha-server-and-external-provisioner/tree/master/deploy/helm +keywords: +- nfs +- storage +type: application +dependencies: + - name: nfs-server-provisioner + version: "1.x.x" + repository: https://raphaelmonrouzeau.github.io/charts/repository/ diff --git a/charts/nfs-server-provisioner/charts/nfs-server-provisioner-1.3.0.tgz b/charts/nfs-server-provisioner/charts/nfs-server-provisioner-1.3.0.tgz new file mode 100644 index 0000000..16230bd Binary files /dev/null and b/charts/nfs-server-provisioner/charts/nfs-server-provisioner-1.3.0.tgz differ diff --git a/charts/nfs-server-provisioner/questions.yml b/charts/nfs-server-provisioner/questions.yml new file mode 100644 index 0000000..edbda1f --- /dev/null +++ b/charts/nfs-server-provisioner/questions.yml @@ -0,0 +1,6 @@ +questions: + - variable: nfs-server-provisioner.storageClass.defaultClass + default: true + type: boolean + label: Set StorageClass as default + group: "StorageClass" diff --git a/charts/nfs-server-provisioner/values.yaml b/charts/nfs-server-provisioner/values.yaml new file mode 100644 index 0000000..a1f6d29 --- /dev/null +++ b/charts/nfs-server-provisioner/values.yaml @@ -0,0 +1,6 @@ +nfs-server-provisioner: + storageClass: + defaultClass: true + mountOptions: + - vers=3 + - nolock diff --git a/charts/nginx/.helmignore b/charts/nginx/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/nginx/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/nginx/Chart.yaml b/charts/nginx/Chart.yaml new file mode 100644 index 0000000..d7df935 --- /dev/null +++ b/charts/nginx/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +name: nginx +description: A plain nginx +type: application +version: 0.2.2 +appVersion: "1.21.0" +icon: https://upload.wikimedia.org/wikipedia/commons/c/c5/Nginx_logo.svg +maintainers: + - name: Rancher + url: https://github.com/rancher diff --git a/charts/nginx/questions.yml b/charts/nginx/questions.yml new file mode 100644 index 0000000..fe5bbe0 --- /dev/null +++ b/charts/nginx/questions.yml @@ -0,0 +1,40 @@ +questions: + - variable: ingress.enabled + default: true + type: boolean + label: Expose app using Layer 7 Load Balancer + show_subquestion_if: true + group: "Services and Load Balancing" + subquestions: + - variable: ingress.hosts.0.host + default: "sslip.io" + type: hostname + required: true + label: Hostname + - variable: autoscaling.enabled + default: false + type: boolean + label: Enable autoscaling + show_subquestion_if: true + group: "Autoscaling" + subquestions: + - variable: autoscaling.minReplicas + default: 1 + type: int + required: true + label: Min replicas + - variable: autoscaling.maxReplicas + default: 100 + type: int + required: true + label: Max replicas + - variable: autoscaling.targetCPUUtilizationPercentage + default: "80" + type: string + required: false + label: Target CPU utilization percentage + - variable: autoscaling.targetMemoryUtilizationPercentage + default: "" + type: string + required: false + label: Target memory utilization percentage \ No newline at end of file diff --git a/charts/nginx/templates/NOTES.txt b/charts/nginx/templates/NOTES.txt new file mode 100644 index 0000000..918bb64 --- /dev/null +++ b/charts/nginx/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nginx.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "nginx.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nginx.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nginx.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/charts/nginx/templates/_helpers.tpl b/charts/nginx/templates/_helpers.tpl new file mode 100644 index 0000000..ad9f432 --- /dev/null +++ b/charts/nginx/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "nginx.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 "nginx.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 "nginx.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "nginx.labels" -}} +helm.sh/chart: {{ include "nginx.chart" . }} +{{ include "nginx.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "nginx.selectorLabels" -}} +app.kubernetes.io/name: {{ include "nginx.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "nginx.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "nginx.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/nginx/templates/deployment.yaml b/charts/nginx/templates/deployment.yaml new file mode 100644 index 0000000..27a46f8 --- /dev/null +++ b/charts/nginx/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "nginx.fullname" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "nginx.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "nginx.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "nginx.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/nginx/templates/hpa.yaml b/charts/nginx/templates/hpa.yaml new file mode 100644 index 0000000..9af6c1b --- /dev/null +++ b/charts/nginx/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "nginx.fullname" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "nginx.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/charts/nginx/templates/ingress.yaml b/charts/nginx/templates/ingress.yaml new file mode 100644 index 0000000..fc6576a --- /dev/null +++ b/charts/nginx/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "nginx.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "nginx.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/charts/nginx/templates/service.yaml b/charts/nginx/templates/service.yaml new file mode 100644 index 0000000..7183073 --- /dev/null +++ b/charts/nginx/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "nginx.fullname" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "nginx.selectorLabels" . | nindent 4 }} diff --git a/charts/nginx/templates/serviceaccount.yaml b/charts/nginx/templates/serviceaccount.yaml new file mode 100644 index 0000000..3650603 --- /dev/null +++ b/charts/nginx/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "nginx.serviceAccountName" . }} + labels: + {{- include "nginx.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/nginx/templates/tests/test-connection.yaml b/charts/nginx/templates/tests/test-connection.yaml new file mode 100644 index 0000000..5879b4f --- /dev/null +++ b/charts/nginx/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "nginx.fullname" . }}-test-connection" + labels: + {{- include "nginx.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "nginx.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/charts/nginx/values.yaml b/charts/nginx/values.yaml new file mode 100644 index 0000000..f3499b9 --- /dev/null +++ b/charts/nginx/values.yaml @@ -0,0 +1,82 @@ +# Default values for nginx. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: nginx + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: true + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: sslip.io + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +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 + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/charts/online-boutique/Chart.yaml b/charts/online-boutique/Chart.yaml new file mode 100644 index 0000000..cc943ea --- /dev/null +++ b/charts/online-boutique/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +name: online-boutique +description: A microservice online-boutique web shop to demo Istio +type: application +version: 0.3.2 +appVersion: "v0.2.3" +icon: https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/master/src/frontend/static/icons/Hipster_HeroLogoCyan.svg +maintainers: + - name: Rancher + url: https://github.com/rancher diff --git a/charts/online-boutique/questions.yml b/charts/online-boutique/questions.yml new file mode 100644 index 0000000..93e9eb1 --- /dev/null +++ b/charts/online-boutique/questions.yml @@ -0,0 +1,23 @@ +questions: + - variable: ingress.enabled + default: true + type: boolean + label: Expose app using Layer 7 Load Balancer + show_subquestion_if: true + group: "Services and Load Balancing" + subquestions: + - variable: ingress.host + default: "sslip.io" + type: hostname + required: true + label: Hostname + - variable: loadGenerator.enabled + default: true + type: boolean + label: Deploy load generator + group: Features + - variable: monitoring.enabled + default: true + type: boolean + label: Configure Monitoring + group: Features diff --git a/charts/online-boutique/templates/_helpers.tpl b/charts/online-boutique/templates/_helpers.tpl new file mode 100644 index 0000000..189329c --- /dev/null +++ b/charts/online-boutique/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "online-boutique.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 "online-boutique.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 "online-boutique.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "online-boutique.labels" -}} +helm.sh/chart: {{ include "online-boutique.chart" . }} +{{ include "online-boutique.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "online-boutique.selectorLabels" -}} +app.kubernetes.io/name: {{ include "online-boutique.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "online-boutique.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "online-boutique.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/online-boutique/templates/adservice.yaml b/charts/online-boutique/templates/adservice.yaml new file mode 100644 index 0000000..aa29151 --- /dev/null +++ b/charts/online-boutique/templates/adservice.yaml @@ -0,0 +1,77 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-adservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: adservice + template: + metadata: + labels: + app: adservice + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/adservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 9555 + env: + - name: PORT + value: "9555" + # - name: DISABLE_STATS + # value: "1" + # - name: DISABLE_TRACING + # value: "1" + - name: JAEGER_SERVICE_ADDR + value: "jaeger-collector.istio-system:14268" + resources: + requests: + cpu: 200m + memory: 180Mi + limits: + cpu: 300m + memory: 300Mi + readinessProbe: + initialDelaySeconds: 20 + periodSeconds: 15 + exec: + command: ["/bin/grpc_health_probe", "-addr=:9555"] + livenessProbe: + initialDelaySeconds: 20 + periodSeconds: 15 + exec: + command: ["/bin/grpc_health_probe", "-addr=:9555"] +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-adservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: adservice + ports: + - name: grpc + port: 9555 + targetPort: 9555 diff --git a/charts/online-boutique/templates/cartservice.yaml b/charts/online-boutique/templates/cartservice.yaml new file mode 100644 index 0000000..0a9430d --- /dev/null +++ b/charts/online-boutique/templates/cartservice.yaml @@ -0,0 +1,70 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-cartservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: cartservice + template: + metadata: + labels: + app: cartservice + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/cartservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 7070 + env: + - name: REDIS_ADDR + value: "{{ include "online-boutique.fullname" . }}-redis-cart:6379" + resources: + requests: + cpu: 200m + memory: 64Mi + limits: + cpu: 300m + memory: 128Mi + readinessProbe: + initialDelaySeconds: 15 + exec: + command: ["/bin/grpc_health_probe", "-addr=:7070", "-rpc-timeout=5s"] + livenessProbe: + initialDelaySeconds: 15 + periodSeconds: 10 + exec: + command: ["/bin/grpc_health_probe", "-addr=:7070", "-rpc-timeout=5s"] +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-cartservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: cartservice + ports: + - name: grpc + port: 7070 + targetPort: 7070 diff --git a/charts/online-boutique/templates/checkoutservice.yaml b/charts/online-boutique/templates/checkoutservice.yaml new file mode 100644 index 0000000..07f6ee9 --- /dev/null +++ b/charts/online-boutique/templates/checkoutservice.yaml @@ -0,0 +1,86 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-checkoutservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: checkoutservice + template: + metadata: + labels: + app: checkoutservice + spec: + serviceAccountName: default + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/checkoutservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 5050 + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:5050"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:5050"] + env: + - name: PORT + value: "5050" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-productcatalogservice:3550" + - name: SHIPPING_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-shippingservice:50051" + - name: PAYMENT_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-paymentservice:50051" + - name: EMAIL_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-emailservice:5000" + - name: CURRENCY_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-currencyservice:7000" + - name: CART_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-cartservice:7070" + # - name: DISABLE_STATS + # value: "1" + # - name: DISABLE_TRACING + # value: "1" + # - name: DISABLE_PROFILER + # value: "1" + - name: JAEGER_SERVICE_ADDR + value: "jaeger-collector.istio-system:14268" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-checkoutservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: checkoutservice + ports: + - name: grpc + port: 5050 + targetPort: 5050 diff --git a/charts/online-boutique/templates/currencyservice.yaml b/charts/online-boutique/templates/currencyservice.yaml new file mode 100644 index 0000000..ec82507 --- /dev/null +++ b/charts/online-boutique/templates/currencyservice.yaml @@ -0,0 +1,74 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-currencyservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: currencyservice + template: + metadata: + labels: + app: currencyservice + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/currencyservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - name: grpc + containerPort: 7000 + env: + - name: PORT + value: "7000" + # - name: DISABLE_TRACING + # value: "1" + # - name: DISABLE_PROFILER + # value: "1" + # - name: DISABLE_DEBUGGER + # value: "1" + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:7000"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:7000"] + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-currencyservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: currencyservice + ports: + - name: grpc + port: 7000 + targetPort: 7000 diff --git a/charts/online-boutique/templates/emailservice.yaml b/charts/online-boutique/templates/emailservice.yaml new file mode 100644 index 0000000..2faabaa --- /dev/null +++ b/charts/online-boutique/templates/emailservice.yaml @@ -0,0 +1,75 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-emailservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: emailservice + template: + metadata: + labels: + app: emailservice + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/emailservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 8080 + env: + - name: PORT + value: "8080" + # - name: DISABLE_TRACING + # value: "1" + - name: DISABLE_PROFILER + value: "1" + - name: JAEGER_SERVICE_ADDR + value: "jaeger-collector.istio-system:14268" + readinessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:8080"] + livenessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:8080"] + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-emailservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: emailservice + ports: + - name: grpc + port: 5000 + targetPort: 8080 diff --git a/charts/online-boutique/templates/frontend.yaml b/charts/online-boutique/templates/frontend.yaml new file mode 100644 index 0000000..aac1c10 --- /dev/null +++ b/charts/online-boutique/templates/frontend.yaml @@ -0,0 +1,103 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-frontend + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: frontend + template: + metadata: + labels: + app: frontend + annotations: + sidecar.istio.io/rewriteAppHTTPProbers: "true" + spec: + serviceAccountName: default + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/frontend:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 8080 + readinessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + httpHeaders: + - name: "Cookie" + value: "shop_session-id=x-readiness-probe" + livenessProbe: + initialDelaySeconds: 10 + httpGet: + path: "/_healthz" + port: 8080 + httpHeaders: + - name: "Cookie" + value: "shop_session-id=x-liveness-probe" + env: + - name: PORT + value: "8080" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-productcatalogservice:3550" + - name: CURRENCY_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-currencyservice:7000" + - name: CART_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-cartservice:7070" + - name: RECOMMENDATION_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-recommendationservice:8080" + - name: SHIPPING_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-shippingservice:50051" + - name: CHECKOUT_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-checkoutservice:5050" + - name: AD_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-adservice:9555" + # # ENV_PLATFORM: One of: local, gcp, aws, azure, onprem + # # When not set, defaults to "local" unless running in GKE, otherwies auto-sets to gcp + # - name: ENV_PLATFORM + # value: "aws" + # - name: DISABLE_TRACING + # value: "1" + # - name: DISABLE_PROFILER + # value: "1" + - name: JAEGER_SERVICE_ADDR + value: "jaeger-collector.istio-system:14268" + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-frontend + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: frontend + ports: + - name: http + port: 80 + targetPort: 8080 + diff --git a/charts/online-boutique/templates/ingress.yaml b/charts/online-boutique/templates/ingress.yaml new file mode 100755 index 0000000..817c574 --- /dev/null +++ b/charts/online-boutique/templates/ingress.yaml @@ -0,0 +1,35 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "online-boutique.fullname" . -}} +{{- $ingressPaths := .Values.ingress.paths -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "online-boutique.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + - host: {{ .Values.ingress.host | quote }} + http: + paths: + - pathType: ImplementationSpecific + backend: + service: + name: {{ include "online-boutique.fullname" . }}-frontend + port: + name: http +{{- end }} diff --git a/charts/online-boutique/templates/loadgenerator.yaml b/charts/online-boutique/templates/loadgenerator.yaml new file mode 100644 index 0000000..3a07db9 --- /dev/null +++ b/charts/online-boutique/templates/loadgenerator.yaml @@ -0,0 +1,51 @@ +{{- if .Values.loadGenerator.enabled -}} +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-loadgenerator + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: loadgenerator + replicas: 1 + template: + metadata: + labels: + app: loadgenerator + annotations: + sidecar.istio.io/rewriteAppHTTPProbers: "true" + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + restartPolicy: Always + containers: + - name: main + image: "gcr.io/google-samples/microservices-demo/loadgenerator:{{ .Values.image.tag | default .Chart.AppVersion }}" + env: + - name: FRONTEND_ADDR + value: "{{ include "online-boutique.fullname" . }}-frontend:80" + - name: USERS + value: "10" + resources: + requests: + cpu: 300m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi +{{- end }} diff --git a/charts/online-boutique/templates/paymentservice.yaml b/charts/online-boutique/templates/paymentservice.yaml new file mode 100644 index 0000000..2159ac1 --- /dev/null +++ b/charts/online-boutique/templates/paymentservice.yaml @@ -0,0 +1,67 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-paymentservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: paymentservice + template: + metadata: + labels: + app: paymentservice + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/paymentservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 50051 + env: + - name: PORT + value: "50051" + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:50051"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:50051"] + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-paymentservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: paymentservice + ports: + - name: grpc + port: 50051 + targetPort: 50051 diff --git a/charts/online-boutique/templates/pre-install-hook.yaml b/charts/online-boutique/templates/pre-install-hook.yaml new file mode 100644 index 0000000..c60d4f9 --- /dev/null +++ b/charts/online-boutique/templates/pre-install-hook.yaml @@ -0,0 +1,51 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "online-boutique.fullname" . }}-label-namespace + labels: + {{- include "online-boutique.labels" . | nindent 4 }} + annotations: + helm.sh/hook: pre-install + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded +spec: + template: + spec: + containers: + - name: labeler + image: bitnami/kubectl:latest + command: + - kubectl + - label + - namespace + - {{ .Release.Namespace }} + - istio-injection=enabled + restartPolicy: Never + serviceAccountName: {{ include "online-boutique.fullname" . }}-installer +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "online-boutique.fullname" . }}-installer + annotations: + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook: pre-install + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "online-boutique.fullname" . }}-installer + annotations: + helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded + helm.sh/hook: pre-install + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +subjects: +- kind: ServiceAccount + name: {{ include "online-boutique.fullname" . }}-installer + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io diff --git a/charts/online-boutique/templates/productcatalogservice.yaml b/charts/online-boutique/templates/productcatalogservice.yaml new file mode 100644 index 0000000..a93f37c --- /dev/null +++ b/charts/online-boutique/templates/productcatalogservice.yaml @@ -0,0 +1,75 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-productcatalogservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: productcatalogservice + template: + metadata: + labels: + app: productcatalogservice + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/productcatalogservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 3550 + env: + - name: PORT + value: "3550" + # - name: DISABLE_STATS + # value: "1" + # - name: DISABLE_TRACING + # value: "1" + # - name: DISABLE_PROFILER + # value: "1" + - name: JAEGER_SERVICE_ADDR + value: "jaeger-collector.istio-system:14268" + readinessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:3550"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:3550"] + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-productcatalogservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: productcatalogservice + ports: + - name: grpc + port: 3550 + targetPort: 3550 diff --git a/charts/online-boutique/templates/recommendationservice.yaml b/charts/online-boutique/templates/recommendationservice.yaml new file mode 100644 index 0000000..5ecda04 --- /dev/null +++ b/charts/online-boutique/templates/recommendationservice.yaml @@ -0,0 +1,77 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-recommendationservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: recommendationservice + template: + metadata: + labels: + app: recommendationservice + spec: + serviceAccountName: default + terminationGracePeriodSeconds: 5 + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/recommendationservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 8080 + readinessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:8080"] + livenessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:8080"] + env: + - name: PORT + value: "8080" + - name: PRODUCT_CATALOG_SERVICE_ADDR + value: "{{ include "online-boutique.fullname" . }}-productcatalogservice:3550" + # - name: DISABLE_TRACING + # value: "1" + # - name: DISABLE_PROFILER + # value: "1" + # - name: DISABLE_DEBUGGER + # value: "1" + resources: + requests: + cpu: 100m + memory: 220Mi + limits: + cpu: 200m + memory: 450Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-recommendationservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: recommendationservice + ports: + - name: grpc + port: 8080 + targetPort: 8080 diff --git a/charts/online-boutique/templates/redis-grafana-dashboard.yaml b/charts/online-boutique/templates/redis-grafana-dashboard.yaml new file mode 100644 index 0000000..405c4cf --- /dev/null +++ b/charts/online-boutique/templates/redis-grafana-dashboard.yaml @@ -0,0 +1,1453 @@ +{{- if .Values.monitoring.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-redis-cart + namespace: cattle-dashboards + labels: + grafana_dashboard: "1" +data: + redis.json: {{`| + { + "__inputs": [ + ], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "3.1.1" + }, + { + "type": "panel", + "id": "graph", + "name": "Graph", + "version": "" + }, + { + "type": "datasource", + "id": "prometheus", + "name": "Prometheus", + "version": "1.0.0" + }, + { + "type": "panel", + "id": "singlestat", + "name": "Singlestat", + "version": "" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "description": "Redis Dashboard for Prometheus Redis Exporter 1.x", + "editable": true, + "gnetId": 763, + "graphTooltip": 1, + "id": null, + "iteration": 1583850456553, + "links": [], + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "decimals": 0, + "editable": true, + "error": false, + "format": "s", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 0, + "y": 0 + }, + "id": 9, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "options": {}, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "max(max_over_time(redis_uptime_in_seconds{instance=~\"$instance\"}[$__interval]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 1800 + } + ], + "thresholds": "", + "title": "Max Uptime", + "type": "singlestat", + "valueFontSize": "70%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(245, 54, 54, 0.9)", + "rgba(237, 129, 40, 0.89)", + "rgba(50, 172, 45, 0.97)" + ], + "datasource": "Prometheus", + "decimals": 0, + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 7, + "w": 2, + "x": 3, + "y": 0 + }, + "hideTimeOverride": true, + "id": 12, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "options": {}, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(redis_connected_clients{instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 2 + } + ], + "thresholds": "", + "timeFrom": "1m", + "timeShift": null, + "title": "Clients", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "Prometheus", + "decimals": 0, + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "gridPos": { + "h": 7, + "w": 3, + "x": 5, + "y": 0 + }, + "hideTimeOverride": true, + "id": 11, + "interval": null, + "isNew": true, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "options": {}, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": true + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum(100 * (redis_memory_used_bytes{instance=~\"$instance\"} / redis_memory_max_bytes{instance=~\"$instance\"}))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 2 + } + ], + "thresholds": "80,95", + "timeFrom": "1m", + "timeShift": null, + "title": "Memory Usage", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 8, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 0 + }, + "hiddenSeries": false, + "id": 18, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(redis_commands_total{instance=~\"$instance\"} [1m])) by (cmd)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ cmd }}", + "metric": "redis_command_calls_total", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total Commands / sec", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 0 + }, + "hiddenSeries": false, + "id": 1, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": true, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(redis_keyspace_hits_total{instance=~\"$instance\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "hits, {{ instance }}", + "metric": "", + "refId": "A", + "step": 240, + "target": "" + }, + { + "expr": "irate(redis_keyspace_misses_total{instance=~\"$instance\"}[5m])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "misses, {{ instance }}", + "metric": "", + "refId": "B", + "step": 240, + "target": "" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Hits / Misses per Sec", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": "", + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "max": "#BF1B00" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 7 + }, + "hiddenSeries": false, + "id": 7, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "null as zero", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "redis_memory_used_bytes{instance=~\"$instance\"}", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "used, {{ instance }}", + "metric": "", + "refId": "A", + "step": 240, + "target": "" + }, + { + "expr": "redis_memory_max_bytes{instance=~\"$instance\"}", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "max, {{ instance }}", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total Memory Usage", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": 0, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 7 + }, + "hiddenSeries": false, + "id": 10, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(redis_net_input_bytes_total{instance=~\"$instance\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ input }}", + "refId": "A", + "step": 240 + }, + { + "expr": "sum(rate(redis_net_output_bytes_total{instance=~\"$instance\"}[5m]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ output }}", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Network I/O", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 7, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 14 + }, + "hiddenSeries": false, + "id": 5, + "isNew": true, + "legend": { + "alignAsTable": false, + "avg": false, + "current": true, + "hideEmpty": false, + "hideZero": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum (redis_db_keys{instance=~\"$instance\"}) by (db, instance)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ db }}, {{ instance }}", + "refId": "A", + "step": 240, + "target": "" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total Items per DB", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 7, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 14 + }, + "hiddenSeries": false, + "id": 13, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum (redis_db_keys{instance=~\"$instance\"}) by (instance) - sum (redis_db_keys_expiring{instance=~\"$instance\"}) by (instance)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "not expiring, {{ instance }}", + "refId": "A", + "step": 240, + "target": "" + }, + { + "expr": "sum (redis_db_keys_expiring{instance=~\"$instance\"}) by (instance)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "expiring, {{ instance }}", + "metric": "", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Expiring vs Not-Expiring Keys", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": { + "evicts": "#890F02", + "memcached_items_evicted_total{instance=\"172.17.0.1:9150\",job=\"prometheus\"}": "#890F02", + "reclaims": "#3F6833" + }, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 1, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 21 + }, + "hiddenSeries": false, + "id": 8, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [ + { + "alias": "reclaims", + "yaxis": 2 + } + ], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(rate(redis_expired_keys_total{instance=~\"$instance\"}[5m])) by (instance)", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "expired, {{ instance }}", + "metric": "", + "refId": "A", + "step": 240, + "target": "" + }, + { + "expr": "sum(rate(redis_evicted_keys_total{instance=~\"$instance\"}[5m])) by (instance)", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "evicted, {{ instance }}", + "refId": "B", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Expired/Evicted Keys", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "fill": 1, + "fillGradient": 0, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 21 + }, + "hiddenSeries": false, + "id": 16, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 2, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(redis_connected_clients{instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "connected", + "refId": "A" + }, + { + "expr": "sum(redis_blocked_clients{instance=~\"$instance\"})", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "blocked", + "refId": "B" + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Connected/Blocked Clients", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 2, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 28 + }, + "hiddenSeries": false, + "id": 20, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": true, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(redis_commands_duration_seconds_total{instance =~ \"$instance\"}[1m])) by (cmd)\n /\nsum(irate(redis_commands_total{instance =~ \"$instance\"}[1m])) by (cmd)\n", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ cmd }}", + "metric": "redis_command_calls_total", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Average Time Spent by Command / sec", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "Prometheus", + "editable": true, + "error": false, + "fill": 8, + "fillGradient": 0, + "grid": {}, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 28 + }, + "hiddenSeries": false, + "id": 14, + "isNew": true, + "legend": { + "avg": false, + "current": false, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "connected", + "options": { + "dataLinks": [] + }, + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "stack": true, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(redis_commands_duration_seconds_total{instance=~\"$instance\"}[1m])) by (cmd) != 0", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{ cmd }}", + "metric": "redis_command_calls_total", + "refId": "A", + "step": 240 + } + ], + "thresholds": [], + "timeFrom": null, + "timeRegions": [], + "timeShift": null, + "title": "Total Time Spent by Command / sec", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ], + "yaxis": { + "align": false, + "alignLevel": null + } + } + ], + "refresh": false, + "schemaVersion": 22, + "style": "dark", + "tags": [ + "prometheus", + "redis" + ], + "templating": { + "list": [ + { + "allValue": null, + "current": {}, + "datasource": "Prometheus", + "definition": "label_values(redis_up, instance)", + "hide": 0, + "includeAll": false, + "label": null, + "multi": true, + "name": "instance", + "options": [], + "query": "label_values(redis_up, instance)", + "refresh": 2, + "regex": "", + "skipUrlSync": false, + "sort": 1, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-24h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "Redis Dashboard for Prometheus Redis Exporter 1.x", + "version": 14 + }`}} +{{- end }} diff --git a/charts/online-boutique/templates/redis-prometheus-rules.yaml b/charts/online-boutique/templates/redis-prometheus-rules.yaml new file mode 100644 index 0000000..d08b420 --- /dev/null +++ b/charts/online-boutique/templates/redis-prometheus-rules.yaml @@ -0,0 +1,38 @@ +{{- if .Values.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: redis-rules +spec: + groups: + - name: redis_rules + rules: + - record: redis_memory_fragmentation_ratio + expr: redis_memory_used_rss_bytes / redis_memory_used_bytes + - name: redis + rules: + - alert: RedisDown + expr: redis_up == 0 + for: 5m + labels: + severity: critical + annotations: + summary: {{`"Redis down (instance {{ $labels.instance }})"`}} + description: {{`"Redis instance is down\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"`}} + - alert: RedisOutOfMemory + expr: redis_memory_used_bytes / redis_total_system_memory_bytes * 100 > 90 + for: 5m + labels: + severity: warning + annotations: + summary: {{`"Redis out of memory (instance {{ $labels.instance }})"`}} + description: {{`"Redis is running out of memory (> 90%)\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"`}} + - alert: RedisTooManyConnections + expr: redis_connected_clients > 100 + for: 5m + labels: + severity: warning + annotations: + summary: {{`"Redis too many connections (instance {{ $labels.instance }})"`}} + description: {{`"Redis instance has too many connections\n VALUE = {{ $value }}\n LABELS: {{ $labels }}"`}} +{{- end }} diff --git a/charts/online-boutique/templates/redis-servicemonitor.yaml b/charts/online-boutique/templates/redis-servicemonitor.yaml new file mode 100644 index 0000000..a169949 --- /dev/null +++ b/charts/online-boutique/templates/redis-servicemonitor.yaml @@ -0,0 +1,18 @@ +{{- if .Values.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: redis-cart +spec: + endpoints: + - interval: 30s + scrapeTimeout: 20s + path: "/metrics" + targetPort: metrics + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app: redis-cart +{{- end }} diff --git a/charts/online-boutique/templates/redis.yaml b/charts/online-boutique/templates/redis.yaml new file mode 100644 index 0000000..5c56374 --- /dev/null +++ b/charts/online-boutique/templates/redis.yaml @@ -0,0 +1,87 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-redis-cart + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: redis-cart + template: + metadata: + labels: + app: redis-cart + spec: + containers: + - name: redis + image: redis:alpine + ports: + - containerPort: 6379 + readinessProbe: + periodSeconds: 5 + tcpSocket: + port: 6379 + livenessProbe: + periodSeconds: 5 + tcpSocket: + port: 6379 + volumeMounts: + - mountPath: /data + name: redis-data + resources: + limits: + memory: 256Mi + cpu: 125m + requests: + cpu: 70m + memory: 200Mi +{{- if .Values.monitoring.enabled}} + - name: redis-exporter + image: oliver006/redis_exporter:latest + ports: + - containerPort: 9121 + name: metrics + readinessProbe: + periodSeconds: 5 + tcpSocket: + port: 9121 +{{- end }} + volumes: + - name: redis-data + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-redis-cart + labels: + app: redis-cart + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: redis-cart + ports: + - name: redis + port: 6379 + targetPort: 6379 +{{- if .Values.monitoring.enabled}} + - name: metrics + port: 9121 + targetPort: 9121 +{{- end }} diff --git a/charts/online-boutique/templates/shippingservice.yaml b/charts/online-boutique/templates/shippingservice.yaml new file mode 100644 index 0000000..c05c2b4 --- /dev/null +++ b/charts/online-boutique/templates/shippingservice.yaml @@ -0,0 +1,75 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "online-boutique.fullname" . }}-shippingservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + app: shippingservice + template: + metadata: + labels: + app: shippingservice + spec: + serviceAccountName: default + containers: + - name: server + image: "gcr.io/google-samples/microservices-demo/shippingservice:{{ .Values.image.tag | default .Chart.AppVersion }}" + ports: + - containerPort: 50051 + env: + - name: PORT + value: "50051" + # - name: DISABLE_STATS + # value: "1" + # - name: DISABLE_TRACING + # value: "1" + # - name: DISABLE_PROFILER + # value: "1" + - name: JAEGER_SERVICE_ADDR + value: "jaeger-collector.istio-system:14268" + readinessProbe: + periodSeconds: 5 + exec: + command: ["/bin/grpc_health_probe", "-addr=:50051"] + livenessProbe: + exec: + command: ["/bin/grpc_health_probe", "-addr=:50051"] + resources: + requests: + cpu: 100m + memory: 64Mi + limits: + cpu: 200m + memory: 128Mi +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "online-boutique.fullname" . }}-shippingservice + labels: + {{- include "online-boutique.labels" . | nindent 4 }} +spec: + type: ClusterIP + selector: + app: shippingservice + ports: + - name: grpc + port: 50051 + targetPort: 50051 diff --git a/charts/online-boutique/values.yaml b/charts/online-boutique/values.yaml new file mode 100644 index 0000000..27f2896 --- /dev/null +++ b/charts/online-boutique/values.yaml @@ -0,0 +1,20 @@ +image: + tag: "" + +ingress: + enabled: true + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + paths: [] + host: sslip.io + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +loadGenerator: + enabled: true + +monitoring: + enabled: true diff --git a/charts/quake-kube/Chart.yaml b/charts/quake-kube/Chart.yaml new file mode 100644 index 0000000..299d709 --- /dev/null +++ b/charts/quake-kube/Chart.yaml @@ -0,0 +1,10 @@ +apiVersion: v2 +name: quake-kube +description: Quake 3 Arena in a browser +type: application +version: 0.2.1 +appVersion: "v1.0.7" +icon: https://upload.wikimedia.org/wikipedia/de/7/78/Quake_III_Arena_Logo.svg +maintainers: + - name: Rancher + url: https://github.com/rancher diff --git a/charts/quake-kube/questions.yml b/charts/quake-kube/questions.yml new file mode 100644 index 0000000..e69de29 diff --git a/charts/quake-kube/templates/_helpers.tpl b/charts/quake-kube/templates/_helpers.tpl new file mode 100644 index 0000000..d3cb4e8 --- /dev/null +++ b/charts/quake-kube/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "quake-kube.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 "quake-kube.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 "quake-kube.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "quake-kube.labels" -}} +helm.sh/chart: {{ include "quake-kube.chart" . }} +{{ include "quake-kube.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "quake-kube.selectorLabels" -}} +app.kubernetes.io/name: {{ include "quake-kube.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "quake-kube.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "quake-kube.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/quake-kube/templates/configmap.yaml b/charts/quake-kube/templates/configmap.yaml new file mode 100644 index 0000000..1349304 --- /dev/null +++ b/charts/quake-kube/templates/configmap.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "quake-kube.fullname" . }}-server-config + labels: + {{- include "quake-kube.labels" . | nindent 4 }} +data: + config.yaml: | + fragLimit: {{ .Values.fragLimit }} + timeLimit: {{ .Values.timeLimit }} + bot: + minPlayers: {{ .Values.bot.minPlayers }} + game: + motd: "Welcome to Quake Kube" + type: {{ .Values.game.type }} + forceRespawn: {{ .Values.game.forceRespawn }} + inactivity: {{ .Values.game.inactivity }} + quadFactor: {{ .Values.game.quadFactor }} + weaponRespawn: {{ .Values.game.weaponRespawn }} + server: + hostname: "quakekube" + maxClients: {{ .Values.game.maxClients }} + password: {{ .Values.server.password }} + commands: + {{- toYaml .Values.commands | nindent 6 }} + maps: + {{- toYaml .Values.maps | nindent 6 }} diff --git a/charts/quake-kube/templates/deployment.yaml b/charts/quake-kube/templates/deployment.yaml new file mode 100644 index 0000000..dba4394 --- /dev/null +++ b/charts/quake-kube/templates/deployment.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "quake-kube.fullname" . }} + labels: + {{- include "quake-kube.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "quake-kube.selectorLabels" . | nindent 6 }} + replicas: 1 + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "quake-kube.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - command: + - q3 + - server + - --config=/config/config.yaml + - --content-server=http://127.0.0.1:9090 + - --agree-eula + image: "criticalstack/quake:{{ .Values.image.tag | default .Chart.AppVersion }}" + name: server + ports: + - containerPort: 8080 + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 5 + volumeMounts: + - name: quake3-server-config + mountPath: /config + - name: quake3-content + mountPath: /assets + - command: + - q3 + - content + - --seed-content-url=http://content.quakejs.com + image: "criticalstack/quake:{{ .Values.image.tag | default .Chart.AppVersion }}" + name: content-server + ports: + - containerPort: 9090 + volumeMounts: + - name: quake3-content + mountPath: /assets + volumes: + - name: quake3-server-config + configMap: + name: {{ include "quake-kube.fullname" . }}-server-config + - name: quake3-content + emptyDir: {} diff --git a/charts/quake-kube/templates/service.yaml b/charts/quake-kube/templates/service.yaml new file mode 100644 index 0000000..fa98893 --- /dev/null +++ b/charts/quake-kube/templates/service.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "quake-kube.fullname" . }} + labels: + {{- include "quake-kube.labels" . | nindent 4 }} +spec: + type: NodePort + selector: + {{- include "quake-kube.selectorLabels" . | nindent 6 }} + ports: + - port: 8080 + targetPort: 8080 + nodePort: 30001 + name: client + - port: 27960 + targetPort: 27960 + nodePort: 30003 + name: server + - port: 9090 + targetPort: 9090 + nodePort: 30002 + name: content diff --git a/charts/quake-kube/values.yaml b/charts/quake-kube/values.yaml new file mode 100644 index 0000000..e191b04 --- /dev/null +++ b/charts/quake-kube/values.yaml @@ -0,0 +1,37 @@ +image: + tag: "" + +server: + password: changeme + maxClients: 12 + +fragLimit: 25 +timeLimit: 15m +bot: + minPlayers: 3 + +game: + type: FreeForAll + forceRespawn: false + inactivity: 10m + quadFactor: 3 + weaponRespawn: 3 + +commands: +- addbot sarge 2 +maps: +- name: q3dm7 + type: FreeForAll + timeLimit: 10m +- name: q3dm17 + type: FreeForAll +- name: q3wctf1 + type: CaptureTheFlag + captureLimit: 8 +- name: q3tourney2 + type: Tournament +- name: q3wctf3 + type: CaptureTheFlag + captureLimit: 8 +- name: ztn3tourney1 + type: Tournament diff --git a/charts/rancher-demo/Chart.yaml b/charts/rancher-demo/Chart.yaml new file mode 100755 index 0000000..1e375f5 --- /dev/null +++ b/charts/rancher-demo/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +appVersion: 1.0.6 +description: Rancher demo application, web UI showing scale of containers +name: rancher-demo +version: 2.1.2 +icon: https://rancher.com/img/brand-guidelines/assets/logos/png/color/rancher-logo-stacked-color.png +maintainers: + - name: Rancher + url: https://github.com/rancher diff --git a/charts/rancher-demo/questions.yml b/charts/rancher-demo/questions.yml new file mode 100644 index 0000000..d30ed9e --- /dev/null +++ b/charts/rancher-demo/questions.yml @@ -0,0 +1,53 @@ +questions: +- variable: ingress.enabled + default: "true" + description: "Create an ingress endpoint for this app" + label: Enable Ingress + show_subquestion_if: true + type: boolean + group: "Ingress Configuration" + subquestions: + - variable: ingress.host + default: "sslip.io" + description: "Enter the DNS name for the ingress endpoint. Leave the default to automatically generate a valid DNS name." + type: string + label: Ingress Endpoint DNS +- variable: app.localization.title + default: "Rancher Demo App" + description: "Customize the title displayed in the application UI" + type: string + label: Localized Title + group: "App Configuration" +- variable: app.localization.pets + default: "cows" + description: "Pick your favourite container pet!" + type: enum + options: + - "cows" + - "chameleons" + - "cowmeleons" + label: "Container Pet" + group: "App Configuration" +- variable: app.localization.color + default: "black" + description: "Add some color to the mix (specify a CSS color name)" + type: string + label: Container Color + group: "App Configuration" +- variable: defaultImage + default: true + label: Use Default Image + type: boolean + show_subquestion_if: false + group: "Container Images" + subquestions: + - variable: image.repository + default: "bashofmann/rancher-demo" + description: "Specify the container image repository name" + type: string + label: Image Repository + - variable: image.tag + default: "" + description: "Specify the container image tag" + type: string + label: Image Tag diff --git a/charts/rancher-demo/templates/NOTES.txt b/charts/rancher-demo/templates/NOTES.txt new file mode 100755 index 0000000..4973d37 --- /dev/null +++ b/charts/rancher-demo/templates/NOTES.txt @@ -0,0 +1,21 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range $.Values.ingress.paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host }}{{ . }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "rancher-demo.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc -w {{ include "rancher-demo.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "rancher-demo.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "rancher-demo.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/charts/rancher-demo/templates/_helpers.tpl b/charts/rancher-demo/templates/_helpers.tpl new file mode 100755 index 0000000..c920b7b --- /dev/null +++ b/charts/rancher-demo/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "rancher-demo.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 "rancher-demo.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 "rancher-demo.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/charts/rancher-demo/templates/deployment.yaml b/charts/rancher-demo/templates/deployment.yaml new file mode 100755 index 0000000..53ce3a4 --- /dev/null +++ b/charts/rancher-demo/templates/deployment.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "rancher-demo.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "rancher-demo.name" . }} + helm.sh/chart: {{ include "rancher-demo.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "rancher-demo.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "rancher-demo.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: TITLE + value: {{ .Values.app.localization.title | quote }} + - name: CONTAINER_COLOR + value: {{ .Values.app.localization.color | quote }} + - name: PETS + value: {{ .Values.app.localization.pets | quote }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: /ping + port: http + readinessProbe: + httpGet: + path: /ping + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/rancher-demo/templates/ingress.yaml b/charts/rancher-demo/templates/ingress.yaml new file mode 100755 index 0000000..693f729 --- /dev/null +++ b/charts/rancher-demo/templates/ingress.yaml @@ -0,0 +1,35 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "rancher-demo.fullname" . -}} +{{- $ingressPaths := .Values.ingress.paths -}} +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app.kubernetes.io/name: {{ include "rancher-demo.name" . }} + helm.sh/chart: {{ include "rancher-demo.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + - host: {{ .Values.ingress.host | quote }} + http: + paths: + - backend: + serviceName: {{ $fullName }} + servicePort: http +{{- end }} diff --git a/charts/rancher-demo/templates/service.yaml b/charts/rancher-demo/templates/service.yaml new file mode 100755 index 0000000..076c99d --- /dev/null +++ b/charts/rancher-demo/templates/service.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "rancher-demo.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "rancher-demo.name" . }} + helm.sh/chart: {{ include "rancher-demo.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 8080 + protocol: TCP + name: http +{{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} +{{- end }} + selector: + app.kubernetes.io/name: {{ include "rancher-demo.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/charts/rancher-demo/templates/tests/test-connection.yaml b/charts/rancher-demo/templates/tests/test-connection.yaml new file mode 100755 index 0000000..f586582 --- /dev/null +++ b/charts/rancher-demo/templates/tests/test-connection.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "rancher-demo.fullname" . }}-test-connection" + labels: + app.kubernetes.io/name: {{ include "rancher-demo.name" . }} + helm.sh/chart: {{ include "rancher-demo.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "rancher-demo.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/charts/rancher-demo/values.yaml b/charts/rancher-demo/values.yaml new file mode 100755 index 0000000..c513306 --- /dev/null +++ b/charts/rancher-demo/values.yaml @@ -0,0 +1,51 @@ +replicaCount: 5 + +image: + repository: bashofmann/rancher-demo + tag: "" + pullPolicy: IfNotPresent + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +app: + localization: + title: "Rancher Demo App" + pets: "cows" # available pets include 'cows' and 'chameleons' and possibly 'cowmeleons' + color: "black" # container background color (any color name from the CSS pallete) + +service: + type: ClusterIP + port: 80 + nodePort: "" + +ingress: + enabled: true + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + paths: [] + host: sslip.io + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +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 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/charts/wordpress/Chart.lock b/charts/wordpress/Chart.lock new file mode 100644 index 0000000..f512042 --- /dev/null +++ b/charts/wordpress/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: wordpress + repository: https://charts.bitnami.com/bitnami + version: 11.0.13 +digest: sha256:fadf70f3c8633dd7c48ffc77e294e1c6de1214bacc8d1ed0d2d35a649570a8d1 +generated: "2021-06-07T12:49:12.956651+02:00" diff --git a/charts/wordpress/Chart.yaml b/charts/wordpress/Chart.yaml new file mode 100644 index 0000000..03bd675 --- /dev/null +++ b/charts/wordpress/Chart.yaml @@ -0,0 +1,29 @@ +annotations: + category: CMS +apiVersion: v2 +appVersion: 5.7.2 +dependencies: + - name: wordpress + repository: https://charts.bitnami.com/bitnami + version: 11.x.x +description: Web publishing platform for building blogs and websites. +home: https://github.com/bitnami/charts/tree/master/bitnami/wordpress +icon: https://bitnami.com/assets/stacks/wordpress/img/wordpress-stack-220x234.png +keywords: + - application + - blog + - cms + - http + - php + - web + - wordpress +maintainers: + - email: containers@bitnami.com + name: Bitnami + - name: Rancher + url: https://github.com/rancher +name: wordpress +sources: + - https://github.com/bitnami/bitnami-docker-wordpress + - https://wordpress.org/ +version: 11.0.18 diff --git a/charts/wordpress/charts/wordpress-11.0.13.tgz b/charts/wordpress/charts/wordpress-11.0.13.tgz new file mode 100644 index 0000000..4811327 Binary files /dev/null and b/charts/wordpress/charts/wordpress-11.0.13.tgz differ diff --git a/charts/wordpress/questions.yml b/charts/wordpress/questions.yml new file mode 100644 index 0000000..ca8413e --- /dev/null +++ b/charts/wordpress/questions.yml @@ -0,0 +1,201 @@ +labels: + io.cattle.role: cluster # options are cluster/project + io.rancher.app_min_version: 7.3.8 +categories: +- Blog +- CMS +questions: +- variable: defaultImage + default: true + label: Use Default Image + type: boolean + show_subquestion_if: false + group: "Container Images" + subquestions: + - variable: wordpress.image.repository + default: "bitnami/wordpress" + description: "WordPress image name" + type: string + label: WordPress Image Name + - variable: wordpress.image.tag + default: "5.7.2-debian-10-r18" + type: string + label: WordPress Image Tag + - variable: wordpress.mariadb.image.repository + default: "bitnami/mariadb" + type: string + label: MariaDB Image Name + - variable: wordpress.mariadb.image.tag + default: "10.3.22-debian-10-r44" + type: string + label: MariaDB Image Tag +- variable: wordpress.wordpressUsername + default: "user" + description: "User of the application" + type: string + required: true + label: WordPress Usernname + group: "WordPress Settings" +- variable: wordpress.wordpressPassword + default: "" + description: "Password, will be auto-generated if not specified" + type: password + label: WordPress Password + group: "WordPress Settings" +- variable: wordpress.wordpressEmail + default: "user@example.com" + description: "Admin email" + type: string + required: true + label: WordPress Admin Email + group: "WordPress Settings" +- variable: wordpress.mariadb.enabled + default: true + description: "Deploy a database server as part of this deployment, or set to false and configure an external database connection." + type: boolean + required: true + label: Install MariaDB + show_subquestion_if: true + group: "Database Settings" + subquestions: + - variable: wordpress.mariadb.db.name + default: "wordpress" + description: "Database name to create" + type: string + label: MariaDB Database + - variable: wordpress.mariadb.db.user + default: "wordpress" + description: "Database user to create" + type: string + label: MariaDB User + - variable: wordpress.mariadb.db.password + default: "" + description: "Password, will be auto-generated if not specified" + type: password + label: MariaDB Password + - variable: wordpress.mariadb.rootUser.password + default: "" + description: "Root user password, will be auto-generated if not specified" + type: password + label: MariaDB Root Password +- variable: wordpress.externalDatabase.host + default: "" + description: "Host of the external database" + type: string + label: External Database Host + show_if: "wordpress.mariadb.enabled=false" + group: "Database Settings" +- variable: wordpress.externalDatabase.user + default: "" + description: "Existing username in the external DB" + type: string + label: External Database username + show_if: "wordpress.mariadb.enabled=false" + group: "Database Settings" +- variable: wordpress.externalDatabase.password + default: "" + description: "External database password" + type: password + label: External Database password + show_if: "wordpress.mariadb.enabled=false" + group: "Database Settings" +- variable: wordpress.externalDatabase.database + default: "" + description: "Name of the existing database" + type: string + label: External Database + show_if: "wordpress.mariadb.enabled=false" + group: "Database Settings" +- variable: wordpress.externalDatabase.port + default: "3306" + description: "External database port number" + type: string + label: External Database Port + show_if: "wordpress.mariadb.enabled=false" + group: "Database Settings" +- variable: wordpress.mariadb.primary.persistence.enabled + default: false + description: "Enable persistent volume for MariaDB" + type: boolean + required: true + label: MariaDB Persistent Volume Enabled + show_if: "wordpress.mariadb.enabled=true" + show_subquestion_if: true + group: "Database Settings" + subquestions: + - variable: wordpress.mariadb.primary.persistence.size + default: "8Gi" + description: "MariaDB Persistent Volume Size" + type: string + label: MariaDB Volume Size + - variable: wordpress.mariadb.primary.persistence.storageClass + default: "" + description: "If undefined or null, uses the default StorageClass. Default to null" + type: storageclass + label: Default StorageClass for MariaDB +- variable: wordpress.persistence.enabled + default: false + description: "Enable persistent volume for WordPress" + type: boolean + required: true + label: WordPress Persistent Volume Enabled + show_subquestion_if: true + group: "WordPress Settings" + subquestions: + - variable: wordpress.persistence.size + default: "10Gi" + description: "WordPress Persistent Volume Size" + type: string + label: WordPress Volume Size + - variable: wordpress.persistence.storageClass + default: "" + description: "If undefined or null, uses the default StorageClass. Default to null" + type: storageclass + label: Default StorageClass for WordPress + - variable: wordpress.persistence.existingClaim + default: "" + description: "If not empty, uses the specified existing PVC instead of creating new one" + type: pvc + label: Existing Persistent Volume Claim for Wordpress +- variable: wordpress.ingress.enabled + default: true + description: "Expose app using Layer 7 Load Balancer - ingress" + type: boolean + label: Expose app using Layer 7 Load Balancer + show_subquestion_if: true + group: "Services and Load Balancing" + subquestions: + - variable: wordpress.ingress.hostname + default: "sslip.io" + description: "Hostname to your WordPress installation" + type: hostname + required: true + label: Hostname +- variable: wordpress.service.type + default: "ClusterIP" + description: "WordPress Service type" + type: enum + show_if: "wordpress.ingress.enabled=false" + options: + - "ClusterIP" + - "NodePort" + - "LoadBalancer" + required: true + label: WordPress Service Type + show_subquestion_if: "NodePort" + group: "Services and Load Balancing" + subquestions: + - variable: wordpress.service.nodePorts.http + default: "" + description: "NodePort http port (to set explicitly, choose port between 30000-32767)" + type: int + min: 30000 + max: 32767 + label: NodePort Http Port + - variable: wordpress.service.nodePorts.https + default: "" + description: "NodePort https port (to set explicitly, choose port between 30000-32767)" + type: int + min: 30000 + max: 32767 + label: NodePort Https Port \ No newline at end of file diff --git a/charts/wordpress/values.yaml b/charts/wordpress/values.yaml new file mode 100644 index 0000000..d0b4150 --- /dev/null +++ b/charts/wordpress/values.yaml @@ -0,0 +1,13 @@ +wordpress: + service: + type: ClusterIP + + ingress: + enabled: true + hostname: sslip.io + annotations: + # https://github.com/bitnami/charts/issues/2111 + nginx.ingress.kubernetes.io/configuration-snippet: | + location ~ /wp-admin$ { + return 301 /wp-admin/; + } diff --git a/do/files/userdata_agent b/do/files/userdata_agent deleted file mode 100644 index 2575650..0000000 --- a/do/files/userdata_agent +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/bash -x -export curlimage=appropriate/curl -export jqimage=stedolan/jq -export rancher_server_ip='${server_address}' - -if [ `command -v curl` ]; then - curl -sL https://releases.rancher.com/install-docker/${docker_version_agent}.sh | sh -elif [ `command -v wget` ]; then - wget -qO- https://releases.rancher.com/install-docker/${docker_version_agent}.sh | sh -fi - -for image in $curlimage $jqimage; do - until docker inspect $image > /dev/null 2>&1; do - docker pull $image - sleep 2 - done -done - -# stop here for rodeo -exit 0 - -while true; do - docker run --rm $curlimage -sLk https://$rancher_server_ip/ping && break - sleep 5 -done - -# Login -while true; do - - LOGINRESPONSE=$(docker run \ - --rm \ - $curlimage \ - -s "https://$rancher_server_ip/v3-public/localProviders/local?action=login" -H 'content-type: application/json' --data-binary '{"username":"admin","password":"${admin_password}"}' --insecure) - LOGINTOKEN=$(echo $LOGINRESPONSE | docker run --rm -i $jqimage -r .token) - - if [ "$LOGINTOKEN" != "null" ]; then - break - else - sleep 5 - fi -done - -# Get the Agent Image from the rancher server -while true; do - AGENTIMAGE=$(docker run \ - --rm \ - $curlimage \ - -sLk \ - -H "Authorization: Bearer $LOGINTOKEN" \ - "https://$rancher_server_ip/v3/settings/agent-image" | docker run --rm -i $jqimage -r '.value') - - if [ -n "$AGENTIMAGE" ]; then - break - else - sleep 5 - fi -done - -until docker inspect $AGENTIMAGE > /dev/null 2>&1; do - docker pull $AGENTIMAGE - sleep 2 -done - -# Test if cluster is created -while true; do - CLUSTERID=$(docker run \ - --rm \ - $curlimage \ - -sLk \ - -H "Authorization: Bearer $LOGINTOKEN" \ - "https://$rancher_server_ip/v3/clusters?name=${cluster_name}" | docker run --rm -i $jqimage -r '.data[].id') - - if [ -n "$CLUSTERID" ]; then - break - else - sleep 5 - fi -done - -# Get role flags from hostname -ROLEFLAG=`hostname | awk -F'-' '{ print $NF }'` -if [[ "$ROLEFLAG" == "all" ]]; then - ROLEFLAG="all-roles" -fi - -# Get token -# Test if cluster is created -while true; do - AGENTCMD=$(docker run \ - --rm \ - $curlimage \ - -sLk \ - -H "Authorization: Bearer $LOGINTOKEN" \ - "https://$rancher_server_ip/v3/clusterregistrationtoken?clusterId=$CLUSTERID" | docker run --rm -i $jqimage -r '.data[].nodeCommand' | head -1) - - if [ -n "$AGENTCMD" ]; then - break - else - sleep 5 - fi -done - -# Combine command and flags -COMPLETECMD="$AGENTCMD --$ROLEFLAG" - -# Run command -$COMPLETECMD diff --git a/do/files/userdata_server b/do/files/userdata_server deleted file mode 100644 index 62eea62..0000000 --- a/do/files/userdata_server +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/bash -x -export curlimage=appropriate/curl -export jqimage=stedolan/jq - -if [ `command -v curl` ]; then - curl -sL https://releases.rancher.com/install-docker/${docker_version_server}.sh | sh -elif [ `command -v wget` ]; then - wget -qO- https://releases.rancher.com/install-docker/${docker_version_server}.sh | sh -fi - -for image in $curlimage $jqimage "rancher/rancher:${rancher_version}"; do - until docker inspect $image > /dev/null 2>&1; do - docker pull $image - sleep 2 - done -done - -# stop here for rodeo -exit 0 - -docker run -d --restart=unless-stopped -p 80:80 -p 443:443 -v /root/rancher:/var/lib/rancher rancher/rancher:${rancher_version} - -while true; do - docker run --rm --net=host $curlimage -sLk https://127.0.0.1/ping && break - sleep 5 -done - -# Login -while true; do - - LOGINRESPONSE=$(docker run \ - --rm \ - --net=host \ - $curlimage \ - -s "https://127.0.0.1/v3-public/localProviders/local?action=login" -H 'content-type: application/json' --data-binary '{"username":"admin","password":"admin"}' --insecure) - LOGINTOKEN=$(echo $LOGINRESPONSE | docker run --rm -i $jqimage -r .token) - echo "Login Token is $LOGINTOKEN" - if [ "$LOGINTOKEN" != "null" ]; then - break - else - sleep 5 - fi -done - - -# Change password -docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/users?action=changepassword' -H 'content-type: application/json' -H "Authorization: Bearer $LOGINTOKEN" --data-binary '{"currentPassword":"admin","newPassword":"${admin_password}"}' --insecure - -# Create API key -APIRESPONSE=$(docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/token' -H 'content-type: application/json' -H "Authorization: Bearer $LOGINTOKEN" --data-binary '{"type":"token","description":"automation"}' --insecure) - -# Extract and store token -APITOKEN=`echo $APIRESPONSE | docker run --rm -i $jqimage -r .token` - -# Configure server-url -RANCHER_SERVER="https://$(docker run --rm --net=host $curlimage -s http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address)" -docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/settings/server-url' -H 'content-type: application/json' -H "Authorization: Bearer $APITOKEN" -X PUT --data-binary '{"name":"server-url","value":"'$RANCHER_SERVER'"}' --insecure - -# Create cluster -CLUSTERRESPONSE=$(docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/cluster' -H 'content-type: application/json' -H "Authorization: Bearer $APITOKEN" --data-binary '{"type":"cluster","rancherKubernetesEngineConfig":{"addonJobTimeout":30,"ignoreDockerVersion":true,"sshAgentAuth":false,"type":"rancherKubernetesEngineConfig","authentication":{"type":"authnConfig","strategy":"x509"},"network":{"type":"networkConfig","plugin":"canal"},"ingress":{"type":"ingressConfig","provider":"nginx"},"services":{"type":"rkeConfigServices","kubeApi":{"podSecurityPolicy":false,"type":"kubeAPIService"},"etcd":{"snapshot":false,"type":"etcdService","extraArgs":{"heartbeat-interval":500,"election-timeout":5000}}}},"name":"${cluster_name}"}' --insecure) - -# Extract clusterid to use for generating the docker run command -CLUSTERID=`echo $CLUSTERRESPONSE | docker run --rm -i $jqimage -r .id` - -# Generate registrationtoken -docker run --rm --net=host $curlimage -s 'https://127.0.0.1/v3/clusterregistrationtoken' -H 'content-type: application/json' -H "Authorization: Bearer $APITOKEN" --data-binary '{"type":"clusterRegistrationToken","clusterId":"'$CLUSTERID'"}' --insecure diff --git a/do/main.tf b/do/main.tf deleted file mode 100644 index 132a5fb..0000000 --- a/do/main.tf +++ /dev/null @@ -1,140 +0,0 @@ -# Configure the DigitalOcean Provider -provider "digitalocean" { - token = "${var.do_token}" -} - -variable "do_token" { - default = "xxx" -} - -variable "prefix" { - default = "yourname" -} - -variable "rancher_version" { - default = "latest" -} - -variable "count_agent_all_nodes" { - default = "3" -} - -variable "count_agent_etcd_nodes" { - default = "0" -} - -variable "count_agent_controlplane_nodes" { - default = "0" -} - -variable "count_agent_worker_nodes" { - default = "0" -} - -variable "admin_password" { - default = "admin" -} - -variable "cluster_name" { - default = "quickstart" -} - -variable "region" { - default = "ams3" -} - -variable "size" { - default = "s-2vcpu-4gb" -} - -variable "docker_version_server" { - default = "17.03" -} - -variable "docker_version_agent" { - default = "17.03" -} - -variable "ssh_keys" { - default = [] -} - -resource "digitalocean_droplet" "rancherserver" { - image = "ubuntu-16-04-x64" - name = "${var.prefix}-rancherserver" - region = "${var.region}" - size = "${var.size}" - user_data = "${data.template_file.userdata_server.rendered}" - ssh_keys = "${var.ssh_keys}" -} - -resource "digitalocean_droplet" "rancheragent-all" { - count = "${var.count_agent_all_nodes}" - image = "ubuntu-16-04-x64" - name = "${var.prefix}-rancheragent-${count.index}-all" - region = "${var.region}" - size = "${var.size}" - user_data = "${data.template_file.userdata_agent.rendered}" - ssh_keys = "${var.ssh_keys}" -} - -resource "digitalocean_droplet" "rancheragent-etcd" { - count = "${var.count_agent_etcd_nodes}" - image = "ubuntu-16-04-x64" - name = "${var.prefix}-rancheragent-${count.index}-etcd" - region = "${var.region}" - size = "${var.size}" - user_data = "${data.template_file.userdata_agent.rendered}" - ssh_keys = "${var.ssh_keys}" -} - -resource "digitalocean_droplet" "rancheragent-controlplane" { - count = "${var.count_agent_controlplane_nodes}" - image = "ubuntu-16-04-x64" - name = "${var.prefix}-rancheragent-${count.index}-controlplane" - region = "${var.region}" - size = "${var.size}" - user_data = "${data.template_file.userdata_agent.rendered}" - ssh_keys = "${var.ssh_keys}" -} - -resource "digitalocean_droplet" "rancheragent-worker" { - count = "${var.count_agent_worker_nodes}" - image = "ubuntu-16-04-x64" - name = "${var.prefix}-rancheragent-${count.index}-worker" - region = "${var.region}" - size = "${var.size}" - user_data = "${data.template_file.userdata_agent.rendered}" - ssh_keys = "${var.ssh_keys}" -} - -data "template_file" "userdata_server" { - template = "${file("files/userdata_server")}" - - vars = { - admin_password = "${var.admin_password}" - cluster_name = "${var.cluster_name}" - docker_version_server = "${var.docker_version_server}" - rancher_version = "${var.rancher_version}" - } -} - -data "template_file" "userdata_agent" { - template = "${file("files/userdata_agent")}" - - vars = { - admin_password = "${var.admin_password}" - cluster_name = "${var.cluster_name}" - docker_version_agent = "${var.docker_version_agent}" - rancher_version = "${var.rancher_version}" - server_address = "${digitalocean_droplet.rancherserver.ipv4_address}" - } -} - -output "rancher-server-ip" { - value = ["${digitalocean_droplet.rancherserver.ipv4_address}"] -} - -output "rancher-agent-ips" { - value = ["${digitalocean_droplet.rancheragent-all.*.ipv4_address}"] -} diff --git a/do/terraform.tfvars.example b/do/terraform.tfvars.example deleted file mode 100644 index 72b9801..0000000 --- a/do/terraform.tfvars.example +++ /dev/null @@ -1,28 +0,0 @@ -# DigitalOcean API token -do_token = "your_token" -# Admin password to access Rancher -admin_password = "admin" -# Resources will be prefixed with this to avoid clashing names -prefix = "myname" -# rancher/rancher image tag to use -rancher_version = "latest" -# Region where resources should be created -region = "lon1" -# Count of agent nodes with role all -count_agent_all_nodes = "1" -# Count of agent nodes with role etcd -count_agent_etcd_nodes = "0" -# Count of agent nodes with role controlplane -count_agent_controlplane_nodes = "0" -# Count of agent nodes with role worker -count_agent_worker_nodes = "0" -# Docker version of host running `rancher/rancher` -docker_version_server = "17.03" -# Docker version of host being added to a cluster (running `rancher/rancher-agent`) -docker_version_agent = "17.03" -# Droplet size -size = "s-2vcpu-4gb" -# DigitalOcean ssh-keyid: retrieve using `curl -s -X GET -H "Content-Type: application/json" -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" "https://api.digitalocean.com/v2/account/keys?per_page=200" | jq -r '.ssh_keys[] | select(.name=="YOUR_KEY_NAME") | .id'` -# ssh_keys = [ "your_key_id" ] -# If this is not specified, you will get an email with the root password -ssh_keys = [] diff --git a/guide/deploying-rancher-server.md b/guide/deploying-rancher-server.md deleted file mode 100644 index 96fdcba..0000000 --- a/guide/deploying-rancher-server.md +++ /dev/null @@ -1,12 +0,0 @@ -# Deploying Rancher Server - -Rancher Server will run as a Docker container. - -- SSH into the host where the server will run and launch the container: - - ```bash - docker run -d --restart=unless-stopped \ - -p 80:80 -p 443:443 \ - -v /opt/rancher:/var/lib/rancher \ - rancher/rancher:stable - ``` diff --git a/guide/nfs-deployment.md b/guide/nfs-deployment.md deleted file mode 100644 index 751aa82..0000000 --- a/guide/nfs-deployment.md +++ /dev/null @@ -1,35 +0,0 @@ -# Building an NFS StorageClass Provisioner - -## Part One: Deploying the NFS Server - -On the Rancher Server, make a directory to hold persistent data, and then share that directory via an NFS server container: - -```bash -sudo apt -qq -y install nfs-kernel-server - -sudo systemctl stop nfs-kernel-server - -sudo systemctl disable nfs-kernel-server - -sudo mkdir -p /opt/nfs - -sudo docker run -d --name nfs --restart=always \ - --privileged --net=host -v /opt/nfs:/exports -e \ - SHARED_DIRECTORY=/exports itsthenetwork/nfs-server-alpine:4 -``` - -If you haven't already opened port 2049/tcp on the server, do so now in your security policy configuration. - -## Part Two: Deploying the Provisioner - -In the Rancher UI, Select the System project and create a new Namespace called `nfs-client-provisioner`. - -Next, import the `provisioner.yaml` file from the k8s folder in the `rancher/rodeo` github repository. Change the NFS server address in both places to match your NFS server location. - -Verify the installation was successful: - -```bash -$ kubectl -n nfs-client-provisioner get po -NAME READY STATUS RESTARTS AGE -nfs-client-provisioner-865b7bc646-n7zjs 1/1 Running 0 2m -``` diff --git a/guide/provisioning.md b/guide/provisioning.md deleted file mode 100644 index 06ec0d9..0000000 --- a/guide/provisioning.md +++ /dev/null @@ -1,114 +0,0 @@ -# Machine Provisioning - -## Vagrant - -Clone the repository and deploy the virtual machines - -```bash -git clone https://github.com/rancher/rodeo && cd rodeo/vagrant -vagrant up -``` - -The server where we install rancher will be availiable via SSH. - -You can test status and connectivity to the created nodes. A successful provisioning operation should look like this. - -```bash -$ vagrant status -Config: {"default_password"=>"admin", "rancher_version"=>"v2.1.1", "cluster_name"=>"rodeo", "rodeo"=>true, "docker_version"=>{"server"=>"17.03", "node"=>"17.03"}, "server"=>{"cpus"=>1, "memory"=>2000}, "node"=>{"count"=>1, "cpus"=>2, "memory"=>3000}, "ip"=>{"server"=>"172.22.101.101", "node"=>"172.22.101.111"}, "linked_clones"=>true, "net"=>{"private_nic_type"=>"82545EM", "network_type"=>"private_network"}, "roles"=>{"node-01"=>"all"}} - -Current machine states: - -server-01 running (virtualbox) -node-01 running (virtualbox) - -This environment represents multiple VMs. The VMs are all listed -above with their current state. For more information about a specific -VM, run `vagrant status NAME`. -$ vagrant ssh server-01 -Config: {"default_password"=>"admin", "rancher_version"=>"v2.1.1", "cluster_name"=>"rodeo", "rodeo"=>true, "docker_version"=>{"server"=>"17.03", "node"=>"17.03"}, "server"=>{"cpus"=>1, "memory"=>2000}, "node"=>{"count"=>1, "cpus"=>2, "memory"=>3000}, "ip"=>{"server"=>"172.22.101.101", "node"=>"172.22.101.111"}, "linked_clones"=>true, "net"=>{"private_nic_type"=>"82545EM", "network_type"=>"private_network"}, "roles"=>{"node-01"=>"all"}} - -Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-142-generic x86_64) - - * Documentation: https://help.ubuntu.com - * Management: https://landscape.canonical.com - * Support: https://ubuntu.com/advantage - - Get cloud support with Ubuntu Advantage Cloud Guest: - http://www.ubuntu.com/business/services/cloud - -4 packages can be updated. -0 updates are security updates. - -New release '18.04.1 LTS' available. -Run 'do-release-upgrade' to upgrade to it. - - -vagrant@server-01:~$ exit -logout -Connection to 127.0.0.1 closed. -$ vagrant ssh node-01 -Config: {"default_password"=>"admin", "rancher_version"=>"v2.1.1", "cluster_name"=>"rodeo", "rodeo"=>true, "docker_version"=>{"server"=>"17.03", "node"=>"17.03"}, "server"=>{"cpus"=>1, "memory"=>2000}, "node"=>{"count"=>1, "cpus"=>2, "memory"=>3000}, "ip"=>{"server"=>"172.22.101.101", "node"=>"172.22.101.111"}, "linked_clones"=>true, "net"=>{"private_nic_type"=>"82545EM", "network_type"=>"private_network"}, "roles"=>{"node-01"=>"all"}} - -Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-142-generic x86_64) - - * Documentation: https://help.ubuntu.com - * Management: https://landscape.canonical.com - * Support: https://ubuntu.com/advantage - - Get cloud support with Ubuntu Advantage Cloud Guest: - http://www.ubuntu.com/business/services/cloud - -4 packages can be updated. -0 updates are security updates. - -New release '18.04.1 LTS' available. -Run 'do-release-upgrade' to upgrade to it. - - -vagrant@node-01:~$ exit -logout -Connection to 127.0.0.1 closed. -``` - -## Digital Ocean - -Clone the repository and rename the tfvars file. - -```bash -git clone https://github.com/rancher/rodeo && cd rodeo/do -mv terraform.tfvars.example terraform.tfvars -``` - -Edit terraform.tfvars and then deploy the instances. - -```bash -terraform init -terraform apply -``` - -This will: - -- Start a droplet for the server -- Start `{count_agent_all_nodes}` amount of droplets for Kubernetes - -## AWS - -Clone the repository and rename the tfvars file. - -```bash -git clone https://github.com/rancher/rodeo && cd rodeo/aws -mv terraform.tfvars.example terraform.tfvars -``` - -Edit terraform.tfvars and then deploy the instances. - -```bash -terraform init -terraform apply -``` - -This will: - -- Start an EC2 instance for the server -- Start `{count_agent_all_nodes}` amount of EC2 instances for Kubernetes diff --git a/guide/upgrade-workload.md b/guide/upgrade-workload.md deleted file mode 100644 index 579df6b..0000000 --- a/guide/upgrade-workload.md +++ /dev/null @@ -1,9 +0,0 @@ -# Using `kubectl` to Upgrade a Workload - -Use the following commands to upgrade your rodeo deployment to a different image. - -``` -kubectl set image deploy/rodeo rodeo=apache:alpine -kubectl get pods -kubectl rollout status deploy/rodeo -``` \ No newline at end of file diff --git a/k8s/nfs-client-provisioner.yaml b/k8s/nfs-client-provisioner.yaml deleted file mode 100644 index ee36bf8..0000000 --- a/k8s/nfs-client-provisioner.yaml +++ /dev/null @@ -1,81 +0,0 @@ ---- -apiVersion: storage.k8s.io/v1 -kind: StorageClass -metadata: - name: managed-nfs-storage - annotations: - storageclass.kubernetes.io/is-default-class: "true" -provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME' ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: nfs-client-provisioner-serviceaccount ---- -kind: ClusterRole -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: nfs-client-provisioner-clusterrole -rules: - - apiGroups: [""] - resources: ["persistentvolumes"] - verbs: ["get", "list", "watch", "create", "delete"] - - apiGroups: [""] - resources: ["persistentvolumeclaims"] - verbs: ["get", "list", "watch", "update"] - - apiGroups: ["storage.k8s.io"] - resources: ["storageclasses"] - verbs: ["get", "list", "watch"] - - apiGroups: [""] - resources: ["events"] - verbs: ["create", "update", "patch"] - - apiGroups: [""] - resources: ["endpoints"] - verbs: ["get", "list", "watch", "create", "update", "patch"] ---- -kind: ClusterRoleBinding -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: nfs-client-provisioner-clusterrolebinding -subjects: - - kind: ServiceAccount - name: nfs-client-provisioner-serviceaccount - namespace: nfs-client-provisioner -roleRef: - kind: ClusterRole - name: nfs-client-provisioner-clusterrole - apiGroup: rbac.authorization.k8s.io ---- -kind: Deployment -apiVersion: extensions/v1beta1 -metadata: - name: nfs-client-provisioner - namespace: nfs-client-provisioner -spec: - replicas: 1 - strategy: - type: Recreate - template: - metadata: - labels: - app: nfs-client-provisioner - spec: - serviceAccountName: nfs-client-provisioner-serviceaccount - containers: - - name: nfs-client-provisioner - image: quay.io/external_storage/nfs-client-provisioner:v2.0.1 - volumeMounts: - - name: nfs-client-root - mountPath: /persistentvolumes - env: - - name: PROVISIONER_NAME - value: fuseim.pri/ifs - - name: NFS_SERVER - value: 172.22.101.101 - - name: NFS_PATH - value: / - volumes: - - name: nfs-client-root - nfs: - server: 172.22.101.101 - path: / diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile deleted file mode 100644 index eb45445..0000000 --- a/vagrant/Vagrantfile +++ /dev/null @@ -1,68 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : -require 'ipaddr' -require 'yaml' - -x = YAML.load_file('config.yaml') -puts "Config: #{x.inspect}\n\n" - -$private_nic_type = x.fetch('net').fetch('private_nic_type') - -Vagrant.configure(2) do |config| - - config.vm.define "server-01" do |server| - c = x.fetch('server') - server.vm.box= "ubuntu/xenial64" - # server.vm.guest = :linux - server.vm.provider :virtualbox do |v| - v.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] - v.cpus = c.fetch('cpus') - v.linked_clone = true if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0') and x.fetch('linked_clones') - v.memory = c.fetch('memory') - v.name = "server-01" - end - server.vm.network x.fetch('net').fetch('network_type'), ip: x.fetch('ip').fetch('server') , nic_type: $private_nic_type - server.vm.hostname = "server-01" - server.vm.provision "shell", path: "scripts/configure_rancher.sh", - env: { - 'admin_password' => x.fetch('default_password'), - 'docker_version' => x.fetch('docker_version').fetch('server'), - 'rancher_version' => x.fetch('rancher_version'), - 'cluster_name' => x.fetch('cluster_name'), - 'rodeo' => x.fetch('rodeo'), - 'rancher_role' => 'server', - 'rancher_server_ip' => x.fetch('ip').fetch('server') - } - end - - node_ip_start = IPAddr.new(x.fetch('ip').fetch('node')) - - (1..x.fetch('node').fetch('count')).each do |i| - c = x.fetch('node') - hostname = "node-%02d" % i - node_ip = IPAddr.new(node_ip_start.to_i + i - 1, Socket::AF_INET).to_s - config.vm.define hostname do |node| - node.vm.box = "ubuntu/xenial64" - # node.vm.guest = :linux - node.vm.provider "virtualbox" do |v| - v.cpus = c.fetch('cpus') - v.linked_clone = true if Gem::Version.new(Vagrant::VERSION) >= Gem::Version.new('1.8.0') and x.fetch('linked_clones') - v.memory = c.fetch('memory') - v.name = hostname - end - node.vm.network x.fetch('net').fetch('network_type'), ip: node_ip, nic_type: $private_nic_type - node.vm.hostname = hostname - node.vm.provision "shell", path: "scripts/configure_rancher.sh", - env: { - 'admin_password' => x.fetch('default_password'), - 'docker_version' => x.fetch('docker_version').fetch('node'), - 'cluster_name' => x.fetch('cluster_name'), - 'rodeo' => x.fetch('rodeo'), - 'rancher_role' => x.fetch('roles').fetch(hostname, 'all'), - 'rancher_server_ip' => x.fetch('ip').fetch('server'), - 'node_ip' => node_ip - } - end - end - -end \ No newline at end of file diff --git a/vagrant/config.yaml b/vagrant/config.yaml deleted file mode 100644 index 01428f2..0000000 --- a/vagrant/config.yaml +++ /dev/null @@ -1,23 +0,0 @@ -default_password: admin -rancher_version: v2.2.4 -cluster_name: rodeo -rodeo: true -docker_version: - server: "18.09" - node: "18.09" -server: - cpus: 1 - memory: 2560 -node: - count: 1 - cpus: 2 - memory: 3000 -ip: - server: 172.22.101.101 - node: 172.22.101.111 -linked_clones: true -net: - private_nic_type: 82545EM - network_type: private_network -roles: - node-01: all diff --git a/vagrant/scripts/configure_rancher.sh b/vagrant/scripts/configure_rancher.sh deleted file mode 100644 index 1064824..0000000 --- a/vagrant/scripts/configure_rancher.sh +++ /dev/null @@ -1,209 +0,0 @@ -#!/bin/bash - -set -xeu - -export curlimage=appropriate/curl -export jqimage=stedolan/jq - -function do_login() { - local count=0 - local max_count=12 - local password - - if [[ -n ${1+x} ]]; then - password=$1 - else - password=${admin_password} - fi - - while true; do - - LOGINRESPONSE=$(docker run \ - --rm \ - --net=host \ - ${curlimage} \ - -s "https://${rancher_server_ip}/v3-public/localProviders/local?action=login" -H 'content-type: application/json' --data-binary '{"username":"admin","password":"'"${password}"'"}' --insecure) - LOGINTOKEN=$(echo ${LOGINRESPONSE} | docker run --rm -i ${jqimage} -r .token) - echo "Login Token is ${LOGINTOKEN}" - if [ "${LOGINTOKEN}" != "null" ]; then - break - else - sleep 5 - count=$(( ${count} + 1 )) - - if [[ ${count} -eq ${max_count} ]]; then - echo "Unable to login within ${max_count} tries." - exit 1 - fi - fi - done -} - -function build_server() { - # install NFS support - apt-get -qq -y install nfs-kernel-server - - docker run -d --restart=unless-stopped -p 80:80 -p 443:443 -v /opt/rancher:/var/lib/rancher rancher/rancher:${rancher_version} - - while true; do - docker run --rm --net=host ${curlimage} -sLk https://127.0.0.1/ping && break - sleep 5 - done - - # do initial login with default password - do_login "admin" - - # Change password - docker run --rm --net=host ${curlimage} -s 'https://127.0.0.1/v3/users?action=changepassword' -H 'content-type: application/json' -H "Authorization: Bearer ${LOGINTOKEN}" --data-binary '{"currentPassword":"admin","newPassword":"'"${admin_password}"'"}' --insecure - - # Create API key - APIRESPONSE=$(docker run --rm --net=host ${curlimage} -s 'https://127.0.0.1/v3/token' -H 'content-type: application/json' -H "Authorization: Bearer ${LOGINTOKEN}" --data-binary '{"type":"token","description":"automation"}' --insecure) - - # Extract and store token - APITOKEN=`echo ${APIRESPONSE} | docker run --rm -i ${jqimage} -r .token` - - # Configure server-url - docker run --rm --net=host ${curlimage} -s 'https://127.0.0.1/v3/settings/server-url' -H 'content-type: application/json' -H "Authorization: Bearer ${APITOKEN}" -X PUT --data-binary '{"name":"server-url","value":"https://'"${rancher_server_ip}"'/"}' --insecure - - # Create cluster - CLUSTERRESPONSE=$(docker run --rm --net=host ${curlimage} -s 'https://127.0.0.1/v3/cluster' -H 'content-type: application/json' -H "Authorization: Bearer ${APITOKEN}" --data-binary '{"type":"cluster","rancherKubernetesEngineConfig":{"addonJobTimeout":30,"ignoreDockerVersion":true,"sshAgentAuth":false,"type":"rancherKubernetesEngineConfig","authentication":{"type":"authnConfig","strategy":"x509"},"network":{"type":"networkConfig","plugin":"canal"},"ingress":{"type":"ingressConfig","provider":"nginx"},"services":{"type":"rkeConfigServices","kubeApi":{"podSecurityPolicy":false,"type":"kubeAPIService"},"etcd":{"snapshot":false,"type":"etcdService","extraArgs":{"heartbeat-interval":500,"election-timeout":5000}}}},"name":"'"${cluster_name}"'"}' --insecure) - - # Extract clusterid to use for generating the docker run command - CLUSTERID=`echo ${CLUSTERRESPONSE} | docker run --rm -i ${jqimage} -r .id` - - # Generate registrationtoken - docker run --rm --net=host ${curlimage} -s 'https://127.0.0.1/v3/clusterregistrationtoken' -H 'content-type: application/json' -H "Authorization: Bearer ${APITOKEN}" --data-binary '{"type":"clusterRegistrationToken","clusterId":"'"${CLUSTERID}"'"}' --insecure - -} - -function build_node() { - while true; do - docker run --rm ${curlimage} -sLk https://${rancher_server_ip}/ping && break - sleep 5 - done - - # Login - do_login - - # Get the Agent Image from the rancher server - while true; do - AGENTIMAGE=$(docker run \ - --rm \ - ${curlimage} \ - -sLk \ - -H "Authorization: Bearer ${LOGINTOKEN}" \ - "https://${rancher_server_ip}/v3/settings/agent-image" | docker run --rm -i ${jqimage} -r '.value') - - if [ -n "${AGENTIMAGE}" ]; then - break - else - sleep 5 - fi - done - - until docker inspect ${AGENTIMAGE} > /dev/null 2>&1; do - docker pull ${AGENTIMAGE} - sleep 2 - done - - # Test if cluster is created - while true; do - CLUSTERID=$(docker run \ - --rm \ - ${curlimage} \ - -sLk \ - -H "Authorization: Bearer ${LOGINTOKEN}" \ - "https://${rancher_server_ip}/v3/clusters?name=${cluster_name}" | docker run --rm -i ${jqimage} -r '.data[].id') - - if [ -n "${CLUSTERID}" ]; then - break - else - sleep 5 - fi - done - - # Get role flags from hostname - ROLEFLAG=${rancher_role} - if [[ "${ROLEFLAG}" == "all" ]]; then - ROLEFLAG="all-roles" - fi - - # Get token - # Test if cluster is created - while true; do - AGENTCMD=$(docker run \ - --rm \ - ${curlimage} \ - -sLk \ - -H "Authorization: Bearer ${LOGINTOKEN}" \ - "https://${rancher_server_ip}/v3/clusterregistrationtoken?clusterId=${CLUSTERID}" | docker run --rm -i ${jqimage} -r '.data[].nodeCommand' | head -1) - - if [ -n "${AGENTCMD}" ]; then - break - else - sleep 5 - fi - done - - # Combine command and flags - COMPLETECMD="${AGENTCMD} --${ROLEFLAG} --address ${node_ip}" - - # Run command - ${COMPLETECMD} - -} - -function install_docker() { - set +e - which docker > /dev/null - docker_installed=$? - - if [[ ${docker_installed} -ne 0 ]]; then - # install docker - if [ `command -v curl` ]; then - curl -sL https://releases.rancher.com/install-docker/${docker_version}.sh | sh - elif [ `command -v wget` ]; then - wget -qO- https://releases.rancher.com/install-docker/${docker_version}.sh | sh - fi - usermod -aG docker vagrant - else - echo "Skipping Docker install." - fi - - set -e -} - -function install_prereqs() { - for image in ${curlimage} ${jqimage}; do - until docker inspect ${image} > /dev/null 2>&1; do - docker pull ${image} - sleep 2 - done - done -} - -# main execution - -# Make sure we have Docker installed before continuing -install_docker - -# If we're in a rodeo, we don't want to build the cluster for them. -if [[ -z ${rodeo} || ${rodeo} == "true" ]]; then - exit 0 -fi - -install_prereqs - -case ${rancher_role} in - server ) - build_server - ;; - node|all|controlplane|worker|etcd ) - build_node - ;; - *) - echo "Unknown role ${rancher_role}." - exit 1 -esac - -exit 0 diff --git a/vagrant/vagrant-provision-reboot-plugin.rb b/vagrant/vagrant-provision-reboot-plugin.rb deleted file mode 100644 index 3c33048..0000000 --- a/vagrant/vagrant-provision-reboot-plugin.rb +++ /dev/null @@ -1,179 +0,0 @@ -# A quick hack to allow rebooting of a Vagrant VM during provisioning. -# -# This is tested with Vagrant 1.4.3 and 1.6.1. It may work with slightly earlier -# versions, but definitely won't work with 1.3.* or earlier. The code is fragile -# with respect to internal changes in Vagrant, as there is no useful public API -# that allows a reboot to be engineered. -# -# Originally adapted from: https://gist.github.com/ukabu/6780121 -# -# This file should be placed into the same folder as your Vagrantfile. Then in -# your Vagrantfile, you'll want to do something like the following: -# -# ---------------------------------------------------------------------------- -# -# require './vagrant-provision-reboot-plugin' -# -# Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| -# -# # Run your pre-reboot provisioning block. -# #config.vm.provision :chef_solo do |chef| -# # ... -# #end -# -# # Run a reboot of a *NIX guest. -# config.vm.provision :unix_reboot -# # Run a reboot of a Windows guest, assuming that you are set up with the -# # relevant plugins and configurations to manage a Windows guest in Vagrant. -# #config.vm.provision :windows_reboot -# -# # Run your post-reboot provisioning block. -# #config.vm.provision :chef_solo do |chef| -# # ... -# #end -# -# ---------------------------------------------------------------------------- -# -# The provisioner takes care of remounting the synced folders. -# -# This will work for the VirtualBox provider. For other providers, a -# 'remount_synced_folders' action must be added to the provider implementation. - -require 'vagrant' - -# Monkey-patch the VirtualBox provider to be able to remap synced folders after -# reboot. This is the tricky part. -# -# This involves pulling out some code fragments from the existing SyncedFolders -# class - which is unpleasant, but there are no usefully exposed methods such -# that we can run only what we need to. -module VagrantPlugins - module ProviderVirtualBox - module Action - - class RemountSyncedFolders < SyncedFolders - - def initialize(app, env) - super(app, env) - end - - def call(env) - @env = env - @app.call(env) - - # Copied out of /lib/vagrant/action/builtin/synced_folders.rb in - # Vagrant 1.4.3, and surprisingly still working in 1.6.1. - # - # This is going to be fragile with respect to future changes, but - # that's just the way the cookie crumbles. - # - # We can't just run the whole SyncedFolders.call() method because - # it undertakes a lot more setup and will error out if invoked twice - # during "vagrant up" or "vagrant provision". - folders = synced_folders(env[:machine]) - folders.each do |impl_name, fs| - plugins[impl_name.to_sym][0].new.enable(env[:machine], fs, impl_opts(impl_name, env)) - end - end - end - - def self.action_remount_synced_folders - Vagrant::Action::Builder.new.tap do |b| - b.use RemountSyncedFolders - end - end - - end - end -end - -# Define the plugin. -class RebootPlugin < Vagrant.plugin('2') - name 'Reboot Plugin' - - # This plugin provides a provisioner called unix_reboot. - provisioner 'unix_reboot' do - - # Create a provisioner. - class RebootProvisioner < Vagrant.plugin('2', :provisioner) - # Initialization, define internal state. Nothing needed. - def initialize(machine, config) - super(machine, config) - end - - # Configuration changes to be done. Nothing needed here either. - def configure(root_config) - super(root_config) - end - - # Run the provisioning. - def provision - command = 'shutdown -r now' - @machine.ui.info("Issuing command: #{command}") - @machine.communicate.sudo(command) do |type, data| - #if type == :stderr - # @machine.ui.error(data); - #end - end - - begin - sleep 5 - end until @machine.communicate.ready? - - # Now the machine is up again, perform the necessary tasks. - @machine.ui.info("Launching remount_synced_folders action...") - @machine.action('remount_synced_folders') - end - - # Nothing needs to be done on cleanup. - def cleanup - super - end - end - RebootProvisioner - - end - - # This plugin provides a provisioner called windows_reboot. - provisioner 'windows_reboot' do - - # Create a provisioner. - class RebootProvisioner < Vagrant.plugin('2', :provisioner) - # Initialization, define internal state. Nothing needed. - def initialize(machine, config) - super(machine, config) - end - - # Configuration changes to be done. Nothing needed here either. - def configure(root_config) - super(root_config) - end - - # Run the provisioning. - def provision - command = 'shutdown -t 0 -r -f' - @machine.ui.info("Issuing command: #{command}") - @machine.communicate.execute(command) do - # if type == :stderr - # @machine.ui.error(data); - # end - end - - begin - sleep 5 - end until @machine.communicate.ready? - - # Now the machine is up again, perform the necessary tasks. - @machine.ui.info("Launching remount_synced_folders action...") - @machine.action('remount_synced_folders') - end - - # Nothing needs to be done on cleanup. - def cleanup - super - end - end - RebootProvisioner - - end -end \ No newline at end of file