first commit
|
|
@ -0,0 +1,30 @@
|
|||
# Copyright 2018 Google LLC All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
runtime: go116
|
||||
service: ${SERVICE}
|
||||
|
||||
handlers:
|
||||
- url: /site/$
|
||||
static_files: public/index.html
|
||||
upload: public/index.html
|
||||
- url: /site/(.*)/$
|
||||
static_files: public/\1/index.html
|
||||
upload: public/.*/index.html
|
||||
- url: /site
|
||||
static_dir: public
|
||||
secure: always
|
||||
- url: /.*
|
||||
secure: always
|
||||
script: auto
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="64px" height="64px" viewBox="0 0 64 64" version="1.1">
|
||||
<g id="surface1">
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(22.352941%,43.921569%,89.411765%);fill-opacity:1;" d="M 28.3125 0.964844 C 29.824219 0.214844 31.59375 0.214844 33.105469 0.964844 L 52.265625 10.425781 C 53.734375 11.152344 54.796875 12.503906 55.152344 14.105469 L 59.933594 35.59375 C 60.285156 37.167969 59.914062 38.816406 58.921875 40.09375 L 45.585938 57.246094 C 44.5625 58.5625 42.984375 59.335938 41.3125 59.335938 L 20.105469 59.335938 C 18.433594 59.335938 16.855469 58.5625 15.832031 57.246094 L 2.496094 40.09375 C 1.503906 38.816406 1.132812 37.167969 1.484375 35.59375 L 6.265625 14.105469 C 6.621094 12.503906 7.683594 11.152344 9.152344 10.425781 Z M 28.3125 0.964844 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 20.03125 17.519531 C 20.03125 17.519531 17.417969 17.808594 15.675781 18 C 15.519531 18.019531 15.378906 18.125 15.328125 18.285156 C 15.277344 18.445312 15.328125 18.609375 15.445312 18.714844 C 16.738281 19.898438 18.683594 21.667969 18.683594 21.667969 C 18.683594 21.667969 18.152344 24.242188 17.796875 25.957031 C 17.765625 26.113281 17.824219 26.277344 17.957031 26.378906 C 18.09375 26.476562 18.265625 26.476562 18.402344 26.402344 C 19.929688 25.535156 22.210938 24.230469 22.210938 24.230469 C 22.210938 24.230469 24.496094 25.535156 26.019531 26.402344 C 26.160156 26.476562 26.332031 26.476562 26.46875 26.378906 C 26.601562 26.277344 26.660156 26.113281 26.628906 25.960938 C 26.273438 24.242188 25.742188 21.667969 25.742188 21.667969 C 25.742188 21.667969 27.6875 19.898438 28.984375 18.71875 C 29.097656 18.609375 29.152344 18.445312 29.097656 18.285156 C 29.046875 18.125 28.910156 18.019531 28.753906 18.003906 C 27.007812 17.808594 24.394531 17.519531 24.394531 17.519531 C 24.394531 17.519531 23.3125 15.121094 22.589844 13.523438 C 22.523438 13.382812 22.378906 13.28125 22.210938 13.28125 C 22.046875 13.28125 21.902344 13.382812 21.839844 13.523438 C 21.117188 15.121094 20.03125 17.519531 20.03125 17.519531 Z M 20.03125 17.519531 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 35.113281 14.746094 L 46.824219 14.746094 L 46.824219 26.453125 L 35.113281 26.453125 Z M 35.113281 14.746094 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 29.121094 38.957031 C 29.121094 42.722656 26.066406 45.773438 22.304688 45.773438 C 18.539062 45.773438 15.488281 42.722656 15.488281 38.957031 C 15.488281 35.195312 18.539062 32.144531 22.304688 32.144531 C 26.066406 32.144531 29.121094 35.195312 29.121094 38.957031 Z M 29.121094 38.957031 "/>
|
||||
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 46.363281 44.078125 L 34.386719 44.078125 C 34.226562 44.078125 34.074219 43.992188 33.992188 43.851562 C 33.910156 43.714844 33.90625 43.542969 33.984375 43.398438 L 39.972656 32.34375 C 40.050781 32.195312 40.207031 32.101562 40.375 32.101562 C 40.542969 32.101562 40.699219 32.195312 40.78125 32.34375 L 46.769531 43.398438 C 46.847656 43.542969 46.84375 43.714844 46.757812 43.851562 C 46.675781 43.992188 46.527344 44.078125 46.363281 44.078125 Z M 46.363281 44.078125 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
|
||||
Add styles or override variables from the theme here.
|
||||
|
||||
*/
|
||||
|
||||
$display1-weight: 500 !default;
|
||||
$display2-weight: 100 !default;
|
||||
|
||||
|
||||
$primary: rgb(255, 255,255) !default;
|
||||
$primary-light: lighten($primary, 75%) !default;
|
||||
$secondary: #2D70DE !default;
|
||||
$light: rgb(255, 255,255) !default;
|
||||
$grey: #888 !default;
|
||||
$orange: $secondary;
|
||||
$td-sidebar-tree-root-color: #222 !default;
|
||||
|
||||
.nav-shadow {
|
||||
box-shadow: 0 2px 2px -2px rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
color: black !important
|
||||
}
|
||||
|
||||
.navbar-bg-onscroll {
|
||||
box-shadow: 0 2px 2px -2px rgba(0,0,0,.2);
|
||||
#agones-top {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
|
||||
.control-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.asciinema-theme-asciinema .asciinema-terminal {
|
||||
color: #cccccc;
|
||||
background-color: #121314;
|
||||
border-color: #121314;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.asciinema-theme-asciinema .bg-fg {
|
||||
background-color:black !important;
|
||||
}
|
||||
|
||||
#agones-search {
|
||||
background: rgba(190, 185, 185, 0.3);
|
||||
}
|
||||
input[type="search"]::placeholder {
|
||||
color: #9B9595 !important;
|
||||
}
|
||||
|
||||
.td-box--secondary p > a:hover {
|
||||
color: #121314 !important;
|
||||
}
|
||||
|
||||
#community a {
|
||||
color: #121314 !important;
|
||||
}
|
||||
|
||||
.showcase img {
|
||||
margin: 0 30px;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"hideMemberFields": [
|
||||
"TypeMeta"
|
||||
],
|
||||
"hideTypePatterns": [
|
||||
"ParseError$",
|
||||
"List$"
|
||||
],
|
||||
"externalPackages": [
|
||||
{
|
||||
"typeMatchPrefix": "^k8s\\.io/apimachinery/pkg/apis/meta/v1\\.Duration$",
|
||||
"docsURLTemplate": "https://godoc.org/k8s.io/apimachinery/pkg/apis/meta/v1#Duration"
|
||||
},
|
||||
{
|
||||
"typeMatchPrefix": "^k8s\\.io/(api|apimachinery/pkg/apis)/",
|
||||
"docsURLTemplate": "https://v1-23.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#{{lower .TypeIdentifier}}-{{arrIndex .PackageSegments -1}}-{{arrIndex .PackageSegments -2}}"
|
||||
},
|
||||
{
|
||||
"typeMatchPrefix": "^github\\.com/knative/pkg/apis/duck/",
|
||||
"docsURLTemplate": "https://godoc.org/github.com/knative/pkg/apis/duck/{{arrIndex .PackageSegments -1}}#{{.TypeIdentifier}}"
|
||||
}
|
||||
],
|
||||
"typeDisplayNamePrefixOverrides": {
|
||||
"k8s.io/api/": "Kubernetes ",
|
||||
"k8s.io/apimachinery/pkg/apis/": "Kubernetes "
|
||||
},
|
||||
"markdownDisabled": false
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
{{ define "packages" }}
|
||||
|
||||
{{ with .packages}}
|
||||
<p>Packages:</p>
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li>
|
||||
<a href="#{{- packageAnchorID . -}}">{{ packageDisplayName . }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end}}
|
||||
|
||||
{{ range .packages }}
|
||||
<h2 id="{{- packageAnchorID . -}}">
|
||||
{{- packageDisplayName . -}}
|
||||
</h2>
|
||||
|
||||
{{ with (index .GoPackages 0 )}}
|
||||
{{ with .DocComments }}
|
||||
<p>
|
||||
{{ safe (renderComments .) }}
|
||||
</p>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
Resource Types:
|
||||
<ul>
|
||||
{{- range (visibleTypes (sortedTypes .Types)) -}}
|
||||
{{ if isExportedType . -}}
|
||||
<li>
|
||||
<a href="{{ linkForType . }}">{{ typeDisplayName . }}</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
</ul>
|
||||
|
||||
{{ range (visibleTypes (sortedTypes .Types))}}
|
||||
{{ template "type" . }}
|
||||
{{ end }}
|
||||
<hr/>
|
||||
{{ end }}
|
||||
|
||||
<p><em>
|
||||
Generated with <code>gen-crd-api-reference-docs</code>.
|
||||
</em></p>
|
||||
|
||||
{{ end }}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
# Copyright 2019 Google LLC All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
#
|
||||
# Google Cloud Builder -- Push site to production
|
||||
# on merge with main
|
||||
#
|
||||
|
||||
steps:
|
||||
|
||||
#
|
||||
# Creates the initial make + docker build platform
|
||||
#
|
||||
|
||||
- name: "ubuntu"
|
||||
args: ["bash", "-c", "echo 'FROM gcr.io/cloud-builders/docker\nRUN apt-get install make\nENTRYPOINT [\"/usr/bin/make\"]' > Dockerfile.build"]
|
||||
- name: "gcr.io/cloud-builders/docker"
|
||||
args: ['build', '-f', 'Dockerfile.build', '-t', 'make-docker', '.'] # we need docker and make to run everything.
|
||||
- name: "make-docker"
|
||||
dir: "build"
|
||||
args: ["pull-build-image"] # since we are past CI build, we can assume that the build image exists.
|
||||
|
||||
#
|
||||
# Build production site and deploy
|
||||
#
|
||||
|
||||
- name: "make-docker" # build production version of the site
|
||||
dir: "build"
|
||||
args: ["site-static", "site-gen-app-yaml", "ENV=HUGO_ENV=production"]
|
||||
- name: "gcr.io/cloud-builders/gcloud" # deploy the website
|
||||
dir: "site"
|
||||
args: ["app", "deploy", ".app.yaml", "--promote", "--version=$SHORT_SHA"]
|
||||
env:
|
||||
- GOPATH=/workspace/go
|
||||
- GO111MODULE=on
|
||||
|
||||
#
|
||||
# Build development site and deploy
|
||||
#
|
||||
|
||||
|
||||
- name: "make-docker" # build a preview of the website
|
||||
dir: "build"
|
||||
args: ["site-static-preview", "site-gen-app-yaml", "SERVICE=development"]
|
||||
- name: "gcr.io/cloud-builders/gcloud" # deploy the preview of the website
|
||||
dir: "site"
|
||||
args: ["app", "deploy", ".app.yaml", "--promote", "--version=$SHORT_SHA"]
|
||||
env:
|
||||
- GOPATH=/workspace/go
|
||||
- GO111MODULE=on
|
||||
|
||||
tags: ["site"]
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
# Copyright 2018 Google LLC All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
baseURL = "/"
|
||||
title = "Redis Operator"
|
||||
enableRobotsTXT = true
|
||||
|
||||
# Hugo allows theme composition (and inheritance). The precedence is from left to right.
|
||||
theme = ["docsy"]
|
||||
|
||||
# Will give values to .Lastmod etc.
|
||||
enableGitInfo = true
|
||||
|
||||
# Language settings
|
||||
contentDir = "content/en"
|
||||
defaultContentLanguage = "en"
|
||||
defaultContentLanguageInSubdir = false
|
||||
# Useful when translating.
|
||||
enableMissingTranslationPlaceholders = true
|
||||
|
||||
disableKinds = ["taxonomy", "taxonomyTerm"]
|
||||
|
||||
# Highlighting config
|
||||
pygmentsCodeFences = true
|
||||
pygmentsUseClasses = false
|
||||
# Use the new Chroma Go highlighter in Hugo.
|
||||
pygmentsUseClassic = false
|
||||
#pygmentsOptions = "linenos=table"
|
||||
# See https://help.farbox.com/pygments.html
|
||||
pygmentsStyle = "tango"
|
||||
|
||||
# First one is picked as the Twitter card image if not set on page.
|
||||
#images = ["images/project-illustration.png"]
|
||||
|
||||
# Configure how URLs look like per section.
|
||||
[permalinks]
|
||||
blog = "/:section/:year/:month/:day/:slug/"
|
||||
|
||||
[markup.goldmark.renderer]
|
||||
unsafe = true
|
||||
|
||||
# Image processing configuration.
|
||||
[imaging]
|
||||
resampleFilter = "CatmullRom"
|
||||
quality = 75
|
||||
anchor = "smart"
|
||||
|
||||
[services]
|
||||
[services.googleAnalytics]
|
||||
# Comment out the next line to disable GA tracking. Also disables the feature described in [params.ui.feedback].
|
||||
# id = "UA-132708785-1"
|
||||
|
||||
# Language configuration
|
||||
|
||||
[languages]
|
||||
[languages.en]
|
||||
title = "Redis Operator"
|
||||
description = "Redis Operator is an operator to deploy and manage Redis setup."
|
||||
languageName ="English"
|
||||
# Weight used for sorting.
|
||||
weight = 1
|
||||
|
||||
# Everything below this are Site Params
|
||||
|
||||
[params]
|
||||
copyright = "Copyright Opstree Solutions"
|
||||
github_repo = "https://github.com/ot-container-kit/redis-operator"
|
||||
|
||||
# Google Custom Search Engine ID. Remove or comment out to disable search.
|
||||
gcs_engine_id = "016691298986124624340:x7qv2dywdao"
|
||||
|
||||
# current release branch. Never is rc.
|
||||
release_branch = "release-1.27.0"
|
||||
# the main version. Never is rc.
|
||||
release_version = "0.12.0"
|
||||
|
||||
# shown for production
|
||||
supported_k8s = "1.23"
|
||||
aks_minor_supported_k8s = "8"
|
||||
minikube_minor_supported_k8s = "9"
|
||||
# shown in development (or the next version that will be supported)
|
||||
dev_supported_k8s = "1.23"
|
||||
dev_aks_minor_supported_k8s = "8"
|
||||
dev_minikube_minor_supported_k8s = "9"
|
||||
|
||||
# example tag
|
||||
example_image_tag = "gcr.io/agones-images/simple-game-server:0.14"
|
||||
|
||||
# Enable syntax highlighting and copy buttons on code blocks with Prism
|
||||
prism_syntax_highlighting = true
|
||||
|
||||
# User interface configuration
|
||||
[params.ui]
|
||||
# Enable to show the side bar menu in its compact state.
|
||||
sidebar_menu_compact = false
|
||||
# Set to true to disable breadcrumb navigation.
|
||||
breadcrumb_disable = false
|
||||
|
||||
# Adds a H2 section titled "Feedback" to the bottom of each doc. The responses are sent to Google Analytics as events.
|
||||
# This feature depends on [services.googleAnalytics] and will be disabled if "services.googleAnalytics.id" is not set.
|
||||
# If you want this feature, but occasionally need to remove the "Feedback" section from a single page,
|
||||
# add "hide_feedback: true" to the page's front matter.
|
||||
[params.ui.feedback]
|
||||
enable = false
|
||||
# The responses that the user sees after clicking "yes" (the page was helpful) or "no" (the page was not helpful).
|
||||
|
||||
[params.links]
|
||||
# End user relevant links. These will show up on left side of footer and in the community page if you have one.
|
||||
[[params.links.user]]
|
||||
name = "Slack"
|
||||
url = "https://join.slack.com/t/opstree/shared_invite/zt-3o8jp35x-UGMU2Cy0WSBk3Lbzqa2wVw"
|
||||
icon = "fab fa-slack"
|
||||
desc = "Chat with other project users in #users"
|
||||
[[params.links.user]]
|
||||
name = "User mailing list"
|
||||
url = "https://github.com/OT-CONTAINER-KIT/redis-operator/discussions"
|
||||
icon = "fa fa-envelope"
|
||||
desc = "Discussion and help from your fellow users"
|
||||
[[params.links.user]]
|
||||
name ="Twitter"
|
||||
url = "https://twitter.com/opstreedevops"
|
||||
icon = "fab fa-twitter"
|
||||
desc = "Follow us on Twitter to get the latest news!"
|
||||
# Developer relevant links. These will show up on right side of footer and in the community page if you have one.
|
||||
[[params.links.developer]]
|
||||
name = "GitHub"
|
||||
url = "https://github.com/OT-CONTAINER-KIT/redis-operator"
|
||||
icon = "fab fa-github"
|
||||
desc = "Development takes place here!"
|
||||
[[params.links.developer]]
|
||||
name = "Slack"
|
||||
url = "https://join.slack.com/t/opstree/shared_invite/zt-3o8jp35x-UGMU2Cy0WSBk3Lbzqa2wVw"
|
||||
icon = "fab fa-slack"
|
||||
desc = "Chat with other project developers in #developers"
|
||||
|
||||
[security]
|
||||
enableInlineShortcodes = false
|
||||
|
||||
[security.exec]
|
||||
allow = ['^dart-sass-embedded$', '^go$', '^npx$', '^postcss$']
|
||||
osEnv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM)$']
|
||||
|
||||
[security.funcs]
|
||||
getenv = ['^HUGO_', 'RELEASE_BRANCH', 'RELEASE_VERSION']
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
+++
|
||||
title = "Redis Operator"
|
||||
linkTitle = "Redis Operator"
|
||||
|
||||
+++
|
||||
|
||||
{{< blocks/cover title="" image_anchor="top" height="min" color="white" >}}
|
||||
<div class="mx-auto">
|
||||
<a class="btn btn-lg btn-secondary mr-3 mb-4" href="{{< relref "/docs" >}}">
|
||||
Learn More <i class="fas fa-arrow-alt-circle-right ml-2"></i>
|
||||
</a>
|
||||
<a class="btn btn-lg btn-secondary mr-3 mb-4" href="https://github.com/ot-container-kit/redis-operator/releases">
|
||||
Releases <i class="fab fa-github ml-2 "></i>
|
||||
</a>
|
||||
<p class="lead mt-4">Run Redis setup on any Kubernetes cluster</p>
|
||||
<div class="mx-auto mt-5">
|
||||
{{< blocks/link-down color="light-secondary" >}}
|
||||
</div>
|
||||
</div>
|
||||
{{< /blocks/cover >}}
|
||||
|
||||
{{% blocks/lead color="secondary" %}}
|
||||
<strong>What is Redis Operator?</strong>
|
||||
|
||||
A Golang based redis operator that will make/oversee Redis standalone and cluster mode setup on top of the Kubernetes.
|
||||
It can create a redis cluster setup with best practices on Cloud as well as the Bare metal environment.
|
||||
Also, it provides an in-built monitoring capability using redis-exporter.
|
||||
{{% /blocks/lead %}}
|
||||
|
||||
{{< blocks/section color="secondary" >}}
|
||||
{{% blocks/feature icon="fab fa-slack" title="Join us on Slack" url="https://join.slack.com/t/opstree/shared_invite/zt-3o8jp35x-UGMU2Cy0WSBk3Lbzqa2wVw" url_text="Join us" %}}
|
||||
Join the community on Slack
|
||||
{{% /blocks/feature %}}
|
||||
|
||||
{{% blocks/feature icon="fab fa-github" title="Contributions welcome!" url="https://github.com/OT-CONTAINER-KIT/redis-operator" url_text="Contribute to Redis Operator" %}}
|
||||
We do a [Pull Request](https://github.com/OT-CONTAINER-KIT/redis-operator/pulls) contributions workflow on **GitHub**.
|
||||
|
||||
New users are always welcome!
|
||||
{{% /blocks/feature %}}
|
||||
|
||||
|
||||
{{% blocks/feature icon="fab fa-twitter" title="Follow us on Twitter!" url="https://twitter.com/opstreedevops" url_text="Follow us" %}}
|
||||
For announcement of the latest features etc.
|
||||
{{% /blocks/feature %}}
|
||||
|
||||
{{< /blocks/section >}}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: Community
|
||||
menu:
|
||||
main:
|
||||
weight: 40
|
||||
---
|
||||
|
||||
<!--add blocks of content here to add more sections to the community page -->
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
---
|
||||
title: "Exposing Redis Service"
|
||||
linkTitle: "Exposing Redis Service"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for exposing redis outside Kubernetes cluster
|
||||
---
|
||||
|
||||
By default, the nature of Redis standalone/cluster setup is private and limited to the Kubernetes cluster only. But we do have a provision to expose it using the Kubernetes "Service" object. If we can expose the service by doing some configuration inside the helm values for redis standalone and cluster setup. This will create another service in parallel to the internal redis service to expose redis.
|
||||
|
||||
The service can be exposed with these service types:
|
||||
|
||||
- **NodePort:** Exposes the Service on each Node's IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You'll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
|
||||
- **LoadBalancer:** Exposes the Service externally using a cloud provider's load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.
|
||||
|
||||
## Exposing Service
|
||||
|
||||
Customize or create the values file with the following content. The externalService configuration is a common method of exposing service for redis standalone and cluster setup:
|
||||
|
||||
```yaml
|
||||
externalService:
|
||||
enabled: true
|
||||
annotations:
|
||||
service.beta.kubernetes.io/aws-load-balancer-internal: 0.0.0.0/0
|
||||
serviceType: LoadBalancer
|
||||
port: 6379
|
||||
```
|
||||
|
||||
Once the values file is customized or created we can apply or upgrade the redis setup. We need to pass the created file as an argument to the `helm` command.
|
||||
|
||||
```shell
|
||||
# redis standalone
|
||||
$ helm upgrade redis ot-helm/redis -f custom-values.yaml \
|
||||
--install --namespace ot-operators
|
||||
|
||||
# redis cluster
|
||||
$ helm upgrade redis-cluster ot-helm/redis-cluster -f custom-values.yaml \
|
||||
--set redisCluster.clusterSize=3 --install --namespace ot-operators
|
||||
```
|
||||
|
||||
Once helm command is completed successfully, we can verify the external service by kubectl command. As we can see in the output, there is an IP in the "EXTERNAL-IP" coloumn.
|
||||
|
||||
```shell
|
||||
$ kubectl get svc -n ot-operators
|
||||
...
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
redis-external-service LoadBalancer 10.103.9.171 164.52.207.101 6379:32247/TCP,9121:30708/TCP 4d20h
|
||||
```
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
---
|
||||
title: "TLS and Security"
|
||||
linkTitle: "TLS and Security"
|
||||
weight: 30
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for configuring TLS and security by Redis Operator
|
||||
---
|
||||
|
||||
## Securing redis setup with password
|
||||
|
||||
If we want to use password based authentication inside Redis, we need to create a secret for it. By default, operator doesn't apply password on standalone or cluster. We need to enable the password login via `helm` command or `YAML` manifests.
|
||||
|
||||
```shell
|
||||
$ kubectl create secret generic redis-secret \
|
||||
--from-literal=password=password -n ot-operators
|
||||
```
|
||||
|
||||
For users that are managing Redis setup using `YAML` manifest, they need to define `redisSecret` inside the object of Redis and RedisCluster. For further details, please check [here](../../crd-reference/redis-api/#existingpasswordsecret).
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
kubernetesConfig:
|
||||
redisSecret:
|
||||
name: redis-secret
|
||||
key: password
|
||||
```
|
||||
|
||||
With `helm`, the password configuration can be defined inside the values file and also can be passed using `helm --set` command.
|
||||
|
||||
Password configuration for Redis standalone:
|
||||
|
||||
```shell
|
||||
$ helm install redis ot-helm/redis --namespace ot-operators \
|
||||
--set redisStandalone.redisSecret.secretName=redis-secret \
|
||||
--set redisStandalone.redisSecret.secretKey=password
|
||||
```
|
||||
|
||||
Password configuration for Redis cluster:
|
||||
|
||||
```shell
|
||||
$ helm install redis ot-helm/redis-cluster --namespace ot-operators \
|
||||
--set redisCluster.redisSecret.secretName=redis-secret \
|
||||
--set redisCluster.redisSecret.secretKey=password
|
||||
```
|
||||
|
||||
Once the password configuration is applied to the redis setup, we can perform the validation using the combination of `kubectl` and `redis-cli`.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-0 -n ot-operators -c redis -- redis-cli info
|
||||
...
|
||||
NOAUTH Authentication required.
|
||||
```
|
||||
|
||||
Try passing the password to the redis setup:
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-0 -n ot-operators -c redis -- redis-cli -a password info
|
||||
...
|
||||
# Server
|
||||
redis_version:7.0.5
|
||||
redis_git_sha1:00000000
|
||||
redis_git_dirty:0
|
||||
redis_build_id:90d2ef529791ba03
|
||||
redis_mode:standalone
|
||||
os:Linux 5.4.209-116.367.amzn2.x86_64 x86_64
|
||||
arch_bits:64
|
||||
.......
|
||||
```
|
||||
|
||||
## TLS configuration for redis setup
|
||||
|
||||
TLS is a security protocol that makes packet and network transfer encrypted between server and client architecture. In the redis setup, we can add TLS as a part of an additional security layer, and along with username and password, the TLS parameters also need to be passed to the client for server authentication.
|
||||
|
||||
The architecture with TLS setup looks like this:
|
||||
|
||||
<div align="center">
|
||||
<img src="../../../images/redis-tls.png">
|
||||
</div>
|
||||
|
||||
### Certificate creation
|
||||
|
||||
TLS certificates can be purchased or self-signed, but both can be integrated with the redis setup. In Kubernetes, we can install [cert-manager,](https://cert-manager.io/docs/) and it can be used for generating the certificates inside Kubernetes for redis and different other applications.
|
||||
|
||||
First, we need to create an issuer inside the Kubernetes to issue the certificates for redis TLS integration.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: selfsigned-issuer
|
||||
spec:
|
||||
selfSigned: {}
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: redis-tls-ca
|
||||
spec:
|
||||
ca:
|
||||
secretName: redis-tls-ca-cert
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f issuer.yaml -n ot-operators
|
||||
...
|
||||
issuer.cert-manager.io/redis-tls-ca created
|
||||
```
|
||||
|
||||
Verify the issuer by using `kubectl` command:
|
||||
|
||||
```shell
|
||||
$ kubectl get issuers -n ot-operators
|
||||
```
|
||||
|
||||
Once the issuer configuration is done, we need to create a `Certificate` object to create certificate for Redis.
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: redis-tls-ca
|
||||
spec:
|
||||
isCA: true
|
||||
commonName: redis
|
||||
secretName: redis-tls-ca-cert
|
||||
issuerRef:
|
||||
name: selfsigned-issuer
|
||||
kind: Issuer
|
||||
group: cert-manager.io
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: redis-tls # this name should match the one appeared in kustomizeconfig.yaml
|
||||
spec:
|
||||
dnsNames:
|
||||
- redis-headless.ot-operators.svc.cluster.local
|
||||
- redis-headless.ot-operators.svc
|
||||
- redis-headless
|
||||
issuerRef:
|
||||
kind: Issuer
|
||||
name: redis-tls-ca
|
||||
group: cert-manager.io
|
||||
secretName: redis-tls-cert
|
||||
```
|
||||
|
||||
Create the defined `YAML` object inside the Kubernetes cluster using `kubectl` command:
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f certificate.yaml -n ot-operators
|
||||
...
|
||||
certificate.cert-manager.io/redis-tls-ca created
|
||||
certificate.cert-manager.io/redis-tls created
|
||||
```
|
||||
|
||||
Once the certificates are in ready, we can verify if the TLS secret is created or not by cert-manager.
|
||||
|
||||
```shell
|
||||
$ kubectl get certificates -n ot-operators
|
||||
...
|
||||
NAME READY SECRET AGE
|
||||
redis-tls True redis-tls-cert 108s
|
||||
redis-tls-ca True redis-tls-ca-cert 109s
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl get secrets -n ot-operators
|
||||
...
|
||||
NAME TYPE DATA AGE
|
||||
redis-tls-cert kubernetes.io/tls 3 18m
|
||||
```
|
||||
|
||||
### Redis TLS configuration
|
||||
|
||||
Redis TLS configuration can be done via `YAML` manifests and `helm` values file. We need to add details about the certificate to the Redis and RedisCluster objects.
|
||||
|
||||
For `YAML` manifest configuration, we need to define the TLS block like this:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
TLS:
|
||||
secret:
|
||||
secretName: redis-tls-cert
|
||||
optional: false
|
||||
```
|
||||
|
||||
For `helm upgrade` method we need to update the values file of `Redis` and `RedisCluster`.
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
---
|
||||
title: "Upgrading Redis and RedisCluster"
|
||||
linkTitle: "Upgrading Redis and RedisCluster"
|
||||
weight: 20
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for upgrading the redis and redis cluster
|
||||
---
|
||||
|
||||
The upgrade strategy for standalone Redis includes the downtime of the system but for cluster setup mode any application will not face any type of issues or downtime. The operator uses the rolling deployment strategy for cluster setup where it will upgrade the redis leader pods and once the leader is upgraded it will follow the same strategy for redis follower pods.
|
||||
|
||||
## Upgrade of standalone setup
|
||||
|
||||
For upgrading the standalone setup of Redis, first we need to identify the current version of it and that can be done via combination of `kubectl` and `redis-server` command.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-0 -n ot-operators -c redis -- redis-server --version
|
||||
...
|
||||
Redis server v=6.2.5 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=3e393a4e624651a3
|
||||
```
|
||||
|
||||
Now let's say the new version, we want to migrate is `7.0.5`. In that case, we can simply use `helm upgrade` command to upgrade the redis cluster.
|
||||
|
||||
```shell
|
||||
$ helm upgrade redis ot-helm/redis --namespace ot-operators \
|
||||
--set redisStandalone.tag=v7.0.5
|
||||
...
|
||||
Release "redis" has been upgraded. Happy Helming!
|
||||
NAME: redis
|
||||
LAST DEPLOYED: Wed Nov 2 19:58:42 2022
|
||||
NAMESPACE: ot-operators
|
||||
STATUS: deployed
|
||||
REVISION: 2
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
Once the upgrade strategy is completed, we can verify the redis pod status by executing:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-0 2/2 Running 0 6m26s
|
||||
```
|
||||
|
||||
Verify the version of redis pod by using the same cli command.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-0 -n ot-operators -c redis -- redis-server --version
|
||||
...
|
||||
Redis server v=7.0.5 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=90d2ef529791ba03
|
||||
```
|
||||
|
||||
For YAML manifest based upgrade, please update the `spec` section of Redis Object. For further details check [here](../../crd-reference/redis-api/#kubernetesconfig).
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
kubernetesConfig:
|
||||
image: "quay.io/opstree/redis:v7.0.5"
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
```
|
||||
|
||||
**Things to keep in mind:**
|
||||
|
||||
{{< alert color="info" title="Note" >}}
|
||||
- Standalone upgrade introduces downtime, so make sure you have strategy in-place. A better option could be deploying a new redis standalone alongside and point the application to it.
|
||||
- Your applications should be compatible with the new version of Redis on which you are upgrading.
|
||||
{{< /alert >}}
|
||||
|
||||
## Upgrading cluster setup
|
||||
|
||||
Similar to standalone setup upgrade, the cluster setup upgrade can also be performed by `helm` command. But again first we need to verify the version of existing cluster setup.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-cluster-follower-0 2/2 Running 0 2m22s
|
||||
redis-cluster-follower-1 2/2 Running 0 2m9s
|
||||
redis-cluster-follower-2 2/2 Running 0 102s
|
||||
redis-cluster-leader-0 2/2 Running 0 2m22s
|
||||
redis-cluster-leader-1 2/2 Running 0 2m9s
|
||||
redis-cluster-leader-2 2/2 Running 0 101s
|
||||
```
|
||||
|
||||
As an initial step of Redis cluster upgrade, first we need to check the version of `redis` and also the health of cluster. Again this can be achieved by `kubectl` and `redis-cli`.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -c redis-cluster-leader \
|
||||
-n ot-operators -- redis-server --version
|
||||
...
|
||||
Redis server v=6.2.5 sha=00000000:0 malloc=jemalloc-5.1.0 bits=64 build=3e393a4e624651a3
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -c redis-cluster-leader \
|
||||
-n ot-operators -- redis-cli cluster nodes
|
||||
...
|
||||
be337e56dbcbdcf47af569e53a0f0316f8e5cd28 192.168.94.6:6379@16379 slave af958687b0048c734b13cef5632ab2b46e386fb1 0 1667400526029 3 connected
|
||||
2321a671fba363fe55821cd133d4b70fbdeba713 192.168.3.127:6379@16379 myself,master - 0 1667400527000 1 connected 0-5460
|
||||
93eb534f0e748b04ff4be6fe984173cdc65703eb 192.168.37.210:6379@16379 slave 670c7c36d3d89c93d4bc546e6ee02b2b843d8801 0 1667400527536 2 connected
|
||||
a00493797d566f2cb1f861962e94fee453d23857 192.168.2.131:6379@16379 slave 2321a671fba363fe55821cd133d4b70fbdeba713 0 1667400527033 1 connected
|
||||
670c7c36d3d89c93d4bc546e6ee02b2b843d8801 192.168.33.178:6379@16379 master - 0 1667400526000 2 connected 5461-10922
|
||||
af958687b0048c734b13cef5632ab2b46e386fb1 192.168.72.57:6379@16379 master - 0 1667400527000 3 connected 10923-16383
|
||||
```
|
||||
|
||||
Once the version and cluster health is verified, we can trigger the upgrade of the cluster by using `helm` command. Let's upgrade the cluster version to v7.
|
||||
|
||||
```shell
|
||||
$ helm upgrade redis-cluster ot-helm/redis-cluster \
|
||||
--set redisCluster.clusterSize=3 --install --namespace ot-operators \
|
||||
--set redisCluster.tag=v7.0.5 --set redisCluster.clusterVersion=v7
|
||||
...
|
||||
Release "redis-cluster" has been upgraded. Happy Helming!
|
||||
NAME: redis-cluster
|
||||
LAST DEPLOYED: Wed Nov 2 20:21:35 2022
|
||||
NAMESPACE: ot-operators
|
||||
STATUS: deployed
|
||||
REVISION: 2
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
Once the upgrade using helm is completed, we need to verify the redis cluster pod status. Also, we need to check the version and health of redis cluster to verify the upgrade is successful or not.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-cluster-follower-0 2/2 Running 0 78s
|
||||
redis-cluster-follower-1 2/2 Running 0 2m5s
|
||||
redis-cluster-follower-2 2/2 Running 0 2m49s
|
||||
redis-cluster-leader-0 2/2 Running 0 77s
|
||||
redis-cluster-leader-1 2/2 Running 0 2m4s
|
||||
redis-cluster-leader-2 2/2 Running 0 2m50s
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -c redis-cluster-leader \
|
||||
-n ot-operators -- redis-server --version
|
||||
...
|
||||
Redis server v=7.0.5 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=90d2ef529791ba03
|
||||
```
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -c redis-cluster-leader \
|
||||
-n ot-operators -- redis-cli cluster nodes
|
||||
...
|
||||
af958687b0048c734b13cef5632ab2b46e386fb1 192.168.90.191:6379@16379 master - 0 1667400984185 3 connected 10923-16383
|
||||
be337e56dbcbdcf47af569e53a0f0316f8e5cd28 192.168.65.215:6379@16379 slave af958687b0048c734b13cef5632ab2b46e386fb1 0 1667400983000 3 connected
|
||||
a00493797d566f2cb1f861962e94fee453d23857 192.168.8.246:6379@16379 slave 2321a671fba363fe55821cd133d4b70fbdeba713 0 1667400984184 1 connected
|
||||
670c7c36d3d89c93d4bc546e6ee02b2b843d8801 192.168.32.65:6379@16379 master - 0 1667400983180 2 connected 5461-10922
|
||||
2321a671fba363fe55821cd133d4b70fbdeba713 192.168.2.134:6379@16379 myself,master - 0 1667400983000 1 connected 0-5460
|
||||
93eb534f0e748b04ff4be6fe984173cdc65703eb 192.168.52.229:6379@16379 slave 670c7c36d3d89c93d4bc546e6ee02b2b843d8801 0 1667400984687 2 connected
|
||||
```
|
||||
|
||||
For YAML manifest based upgrade, please update the `spec` section of Redis Object. For further details check [here](../../crd-reference/redis-api/#kubernetesconfig).
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
kubernetesConfig:
|
||||
image: "quay.io/opstree/redis:v7.0.5"
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
```
|
||||
|
||||
|
||||
**Things to keep in mind:**
|
||||
|
||||
{{< alert color="info" title="Note" >}}
|
||||
- Cluster upgrade doesn't cause any kind of downtime because of rolling update strategy of Kubernetes, there will be always a redis available to serve application requests.
|
||||
- If application is highly critical, in such scenarios it would make sense to create a new cluster and migrate the application pointing to it
|
||||
{{< /alert >}}
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "Advance Configuration"
|
||||
linkTitle: "Advance Configuration"
|
||||
weight: 7
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for advance configuration and use-cases for Redis Operator
|
||||
---
|
||||
|
|
@ -0,0 +1,377 @@
|
|||
---
|
||||
title: "Custom Resource Object API"
|
||||
linkTitle: "Custom Resource Object API"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
CRD Schema details for Redis and Redis Cluster Reference API
|
||||
---
|
||||
|
||||
# API Reference
|
||||
|
||||
## Packages
|
||||
|
||||
- [redis.redis.opstreelabs.in/v1beta1](#redisredisopstreelabsinv1beta1)
|
||||
|
||||
## redis.redis.opstreelabs.in/v1beta1
|
||||
|
||||
Package v1beta1 contains API Schema definitions for the redis v1beta1 API group
|
||||
|
||||
### Resource Types
|
||||
|
||||
- [Redis](#redis)
|
||||
- [RedisCluster](#rediscluster)
|
||||
- [RedisReplication](#redisreplication)
|
||||
- [RedisSentinel](#redissentinel)
|
||||
|
||||
#### ExistingPasswordSecret
|
||||
|
||||
ExistingPasswordSecret is the struct to access the existing secret
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [KubernetesConfig](#kubernetesconfig)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `name` _string_ | |
|
||||
| `key` _string_ | |
|
||||
|
||||
#### KubernetesConfig
|
||||
|
||||
KubernetesConfig will be the JSON struct for Basic Redis Config
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisClusterSpec](#redisclusterspec)
|
||||
- [RedisSpec](#redisspec)
|
||||
- [RedisReplicationSpec](#redisreplicationspec)
|
||||
- [RedisSentinel](#redissentinelspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `image` _string_ | |
|
||||
| `imagePullPolicy` _[PullPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#pullpolicy-v1-core)_ | |
|
||||
| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#resourcerequirements-v1-core)_ | |
|
||||
| `redisSecret` _[ExistingPasswordSecret](#existingpasswordsecret)_ | |
|
||||
| `imagePullSecrets` _[LocalObjectReference](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#localobjectreference-v1-core)_ | |
|
||||
| `updateStrategy` _[StatefulSetUpdateStrategy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#statefulsetupdatestrategy-v1-apps)_ | |
|
||||
|
||||
#### Probe
|
||||
|
||||
Probe is a interface for ReadinessProbe and LivenessProbe
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisFollower](#redisfollower)
|
||||
- [RedisLeader](#redisleader)
|
||||
- [RedisSpec](#redisspec)
|
||||
- [RedisReplicationSpec](#redisreplicationspec)
|
||||
- [RedisSentinel](#redissentinelspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `initialDelaySeconds` _integer_ | |
|
||||
| `timeoutSeconds` _integer_ | |
|
||||
| `periodSeconds` _integer_ | |
|
||||
| `successThreshold` _integer_ | |
|
||||
| `failureThreshold` _integer_ | |
|
||||
|
||||
#### Redis
|
||||
|
||||
Redis is the Schema for the redis API
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `apiVersion` _string_ | `redis.redis.opstreelabs.in/v1beta1`
|
||||
| `kind` _string_ | `Redis`
|
||||
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
|
||||
| `spec` _[RedisSpec](#redisspec)_ | |
|
||||
|
||||
#### RedisCluster
|
||||
|
||||
RedisCluster is the Schema for the redisclusters API
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `apiVersion` _string_ | `redis.redis.opstreelabs.in/v1beta1`
|
||||
| `kind` _string_ | `RedisCluster`
|
||||
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
|
||||
| `spec` _[RedisClusterSpec](#redisclusterspec)_ | |
|
||||
|
||||
#### RedisReplication
|
||||
|
||||
RedisReplication is the Schema for the redisreplication API
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `apiVersion` _string_ | `redis.redis.opstreelabs.in/v1beta1`
|
||||
| `kind` _string_ | `RedisReplication`
|
||||
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
|
||||
| `spec` _[RedisReplicationSpec](#redisreplicationspec)_ | |
|
||||
|
||||
#### RedisSentinel
|
||||
|
||||
RedisSentinel is the Schema for the redissentinel API
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `apiVersion` _string_ | `redis.redis.opstreelabs.in/v1beta1`
|
||||
| `kind` _string_ | `RedisSentinel`
|
||||
| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. |
|
||||
| `spec` _[RedisSentinelSpec](#redissentinelspec)_ | |
|
||||
|
||||
#### RedisClusterSpec
|
||||
|
||||
RedisClusterSpec defines the desired state of RedisCluster
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisCluster](#rediscluster)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `clusterSize` _integer_ | |
|
||||
| `kubernetesConfig` _[KubernetesConfig](#kubernetesconfig)_ | |
|
||||
| `clusterVersion` _string_ | |
|
||||
| `redisLeader` _[RedisLeader](#redisleader)_ | |
|
||||
| `redisFollower` _[RedisFollower](#redisfollower)_ | |
|
||||
| `redisExporter` _[RedisExporter](#redisexporter)_ | |
|
||||
| `storage` _[Storage](#storage)_ | |
|
||||
| `nodeSelector` _object (keys:string, values:string)_ | |
|
||||
| `securityContext` _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core)_ | |
|
||||
| `priorityClassName` _string_ | |
|
||||
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#toleration-v1-core)_ | |
|
||||
| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#resourcerequirements-v1-core)_ | |
|
||||
| `TLS` _[TLSConfig](#tlsconfig)_ | |
|
||||
| `sidecars` _[Sidecar](#sidecar)_ | |
|
||||
| `serviceAccountName` _string_ | |
|
||||
| `persistenceEnabled` _boolean_ | |
|
||||
|
||||
#### RedisSpec
|
||||
|
||||
RedisSpec defines the desired state of Redis
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [Redis](#redis)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `kubernetesConfig` _[KubernetesConfig](#kubernetesconfig)_ | |
|
||||
| `redisExporter` _[RedisExporter](#redisexporter)_ | |
|
||||
| `redisConfig` _[RedisConfig](#redisconfig)_ | |
|
||||
| `storage` _[Storage](#storage)_ | |
|
||||
| `nodeSelector` _object (keys:string, values:string)_ | |
|
||||
| `securityContext` _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core)_ | |
|
||||
| `priorityClassName` _string_ | |
|
||||
| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#affinity-v1-core)_ | |
|
||||
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#toleration-v1-core)_ | |
|
||||
| `TLS` _[TLSConfig](#tlsconfig)_ | |
|
||||
| `readinessProbe` _[Probe](#probe)_ | |
|
||||
| `livenessProbe` _[Probe](#probe)_ | |
|
||||
| `sidecars` _[Sidecar](#sidecar)_ | |
|
||||
| `serviceAccountName` _string_ | |
|
||||
|
||||
#### RedisReplicationSpec
|
||||
|
||||
RedisReplicationSpec defines the desired state of RedisReplication
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisReplication](#redisreplication)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `clusterSize` _integer_ | |
|
||||
| `kubernetesConfig` _[KubernetesConfig](#kubernetesconfig)_ | |
|
||||
| `redisExporter` _[RedisExporter](#redisexporter)_ | |
|
||||
| `redisConfig` _[RedisConfig](#redisconfig)_ | |
|
||||
| `storage` _[Storage](#storage)_ | |
|
||||
| `nodeSelector` _object (keys:string, values:string)_ | |
|
||||
| `securityContext` _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core)_ | |
|
||||
| `priorityClassName` _string_ | |
|
||||
| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#affinity-v1-core)_ | |
|
||||
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#toleration-v1-core)_ | |
|
||||
| `TLS` _[TLSConfig](#tlsconfig)_ | |
|
||||
| `readinessProbe` _[Probe](#probe)_ | |
|
||||
| `livenessProbe` _[Probe](#probe)_ | |
|
||||
| `sidecars` _[Sidecar](#sidecar)_ | |
|
||||
| `serviceAccountName` _string_ | |
|
||||
|
||||
#### RedisSentinelSpec
|
||||
|
||||
RedisSentinelSpec defines the desired state of RedisSentinel
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisSentinel](#redissentinel)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `clusterSize` _integer_ | |
|
||||
| `kubernetesConfig` _[KubernetesConfig](#kubernetesconfig)_ | |
|
||||
| `redisSentinelConfig` _[RedisSentinelConfig](#redissentinelconfig)_ | |
|
||||
| `nodeSelector` _object (keys:string, values:string)_ | |
|
||||
| `securityContext` _[PodSecurityContext](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#podsecuritycontext-v1-core)_ | |
|
||||
| `priorityClassName` _string_ | |
|
||||
| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#affinity-v1-core)_ | |
|
||||
| `tolerations` _[Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#toleration-v1-core)_ | |
|
||||
| `TLS` _[TLSConfig](#tlsconfig)_ | |
|
||||
| `readinessProbe` _[Probe](#probe)_ | |
|
||||
| `livenessProbe` _[Probe](#probe)_ | |
|
||||
| `sidecars` _[Sidecar](#sidecar)_ | |
|
||||
| `serviceAccountName` _string_ | |
|
||||
|
||||
#### RedisConfig
|
||||
|
||||
RedisConfig defines the external configuration of Redis
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisFollower](#redisfollower)
|
||||
- [RedisLeader](#redisleader)
|
||||
- [RedisSpec](#redisspec)
|
||||
- [RedisReplicationSpec](#redisreplicationspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `additionalRedisConfig` _string_ | |
|
||||
|
||||
#### RedisSentinelConfig
|
||||
|
||||
RedisSentinelConfig defines the external configuration of RedisSentinel
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisSentinelSpec](#redissentinelspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `additionalRedisConfig` _string_ | |
|
||||
| `masterGroupName` _string_ | |
|
||||
| `redisPort` _string_ | |
|
||||
| `quorum` _string_ | |
|
||||
| `parallelSyncs` _string_ | |
|
||||
| `failoverTimeout` _string_ | |
|
||||
| `downAfterMilliseconds` _string_ | |
|
||||
|
||||
#### RedisExporter
|
||||
|
||||
RedisExporter interface will have the information for redis exporter related stuff
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisClusterSpec](#redisclusterspec)
|
||||
- [RedisSpec](#redisspec)
|
||||
- [RedisReplicationSpec](#redisreplicationspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `enabled` _boolean_ | |
|
||||
| `image` _string_ | |
|
||||
| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#resourcerequirements-v1-core)_ | |
|
||||
| `imagePullPolicy` _[PullPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#pullpolicy-v1-core)_ | |
|
||||
| `env` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#envvar-v1-core)_ | |
|
||||
|
||||
#### RedisFollower
|
||||
|
||||
RedisFollower interface will have the redis follower configuration
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisClusterSpec](#redisclusterspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `replicas` _integer_ | |
|
||||
| `redisConfig` _[RedisConfig](#redisconfig)_ | |
|
||||
| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#affinity-v1-core)_ | |
|
||||
| `pdb` _[RedisPodDisruptionBudget](#redispoddisruptionbudget)_ | |
|
||||
| `readinessProbe` _[Probe](#probe)_ | |
|
||||
| `livenessProbe` _[Probe](#probe)_ | |
|
||||
|
||||
#### RedisLeader
|
||||
|
||||
RedisLeader interface will have the redis leader configuration
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisClusterSpec](#redisclusterspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `replicas` _integer_ | |
|
||||
| `redisConfig` _[RedisConfig](#redisconfig)_ | |
|
||||
| `affinity` _[Affinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#affinity-v1-core)_ | |
|
||||
| `pdb` _[RedisPodDisruptionBudget](#redispoddisruptionbudget)_ | |
|
||||
| `readinessProbe` _[Probe](#probe)_ | |
|
||||
| `livenessProbe` _[Probe](#probe)_ | |
|
||||
|
||||
#### RedisPodDisruptionBudget
|
||||
|
||||
RedisPodDisruptionBudget configure a PodDisruptionBudget on the resource (leader/follower)
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisFollower](#redisfollower)
|
||||
- [RedisLeader](#redisleader)
|
||||
- [RedisReplication](#redisreplicationspec)
|
||||
- [RedisSentinel](#redissentinelspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `enabled` _boolean_ | |
|
||||
| `minAvailable` _integer_ | |
|
||||
| `maxUnavailable` _integer_ | |
|
||||
|
||||
#### Sidecar
|
||||
|
||||
Sidecar for each Redis pods
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisClusterSpec](#redisclusterspec)
|
||||
- [RedisSpec](#redisspec)
|
||||
- [RedisReplicationSpec](#redisreplicationspec)
|
||||
- [RedisSentinel](#redissentinelspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `name` _string_ | |
|
||||
| `image` _string_ | |
|
||||
| `imagePullPolicy` _[PullPolicy](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#pullpolicy-v1-core)_ | |
|
||||
| `resources` _[ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#resourcerequirements-v1-core)_ | |
|
||||
| `env` _[EnvVar](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#envvar-v1-core)_ | |
|
||||
|
||||
#### Storage
|
||||
|
||||
Storage is the inteface to add pvc and pv support in redis
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisClusterSpec](#redisclusterspec)
|
||||
- [RedisSpec](#redisspec)
|
||||
- [RedisReplicationSpec](#redisreplicationspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `volumeClaimTemplate` _[PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#persistentvolumeclaim-v1-core)_ | |
|
||||
|
||||
#### TLSConfig
|
||||
|
||||
TLS Configuration for redis instances
|
||||
|
||||
_Appears in:_
|
||||
|
||||
- [RedisClusterSpec](#redisclusterspec)
|
||||
- [RedisSpec](#redisspec)
|
||||
- [RedisReplicationSpec](#redisreplicationspec)
|
||||
- [RedisSentinel](#redissentinelspec)
|
||||
|
||||
| Field | Description |
|
||||
| --- | --- |
|
||||
| `ca` _string_ | |
|
||||
| `cert` _string_ | |
|
||||
| `key` _string_ | |
|
||||
| `secret` _[SecretVolumeSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#secretvolumesource-v1-core)_ | Reference to secret which contains the certificates |
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
title: "CRD Reference"
|
||||
linkTitle: "CRD Reference"
|
||||
weight: 6
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Reference documentation for CRD spec of Redis and Redis cluster
|
||||
---
|
||||
|
||||
A resource in the Kubernetes API is an endpoint that persists a collection of a particular type of object. For example, several built-in objects, like pods and deployments, are exposed via an endpoint, and the API server manages their lifecycle. Kubernetes provides you with an option of extending your object using CRD so that you can introduce your API to the Kubernetes cluster per your requirement. Using CRD on Kubernetes, you are free to define, create, and persist any custom object.
|
||||
|
||||
<div align="center">
|
||||
<img src="../../../images/crd-architecture.png">
|
||||
</div>
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
title: "Redis"
|
||||
linkTitle: "Redis"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Configurations and parameters for Redis standalone
|
||||
---
|
||||
|
||||
Redis standalone configuration can be customized by [values.yaml](https://github.com/OT-CONTAINER-KIT/helm-charts/blob/main/charts/redis/values.yaml). The recommended way of managing the setup is using `helm` but if the setup is not maintained by it, `YAML` CRD parameters can be modified in the manifest.
|
||||
|
||||
## Helm Configuration Parameters
|
||||
|
||||
| **Name** | **Value** | **Description** |
|
||||
|-----------------------------------|--------------------------------|-----------------------------------------------------------------------------------------------|
|
||||
| `imagePullSecrets` | [] | List of image pull secrets, in case redis image is getting pull from private registry |
|
||||
| `redisStandalone.secretName` | redis-secret | Name of the existing secret in Kubernetes |
|
||||
| `redisStandalone.secretKey` | password | Name of the existing secret key in Kubernetes |
|
||||
| `redisStandalone.image` | quay.io/opstree/redis | Name of the redis image |
|
||||
| `redisStandalone.tag` | v7.0.5 | Tag of the redis image |
|
||||
| `redisStandalone.imagePullPolicy` | IfNotPresent | Image Pull Policy of the redis image |
|
||||
| `redisStandalone.resources` | {} | Request and limits for redis statefulset |
|
||||
| `externalService.enabled` | false | If redis service needs to be exposed using LoadBalancer or NodePort |
|
||||
| `externalService.annotations` | {} | Kubernetes service related annotations |
|
||||
| `externalService.serviceType` | NodePort | Kubernetes service type for exposing service, values - ClusterIP, NodePort, and LoadBalancer |
|
||||
| `externalService.port` | 6379 | Port number on which redis external service should be exposed |
|
||||
| `serviceMonitor.enabled` | false | Servicemonitor to monitor redis with Prometheus |
|
||||
| `serviceMonitor.interval` | 30s | Interval at which metrics should be scraped. |
|
||||
| `serviceMonitor.scrapeTimeout` | 10s | Timeout after which the scrape is ended |
|
||||
| `serviceMonitor.namespace` | monitoring | Namespace in which Prometheus operator is running |
|
||||
| `redisExporter.enabled` | true | Redis exporter should be deployed or not |
|
||||
| `redisExporter.image` | quay.io/opstree/redis-exporter | Name of the redis exporter image |
|
||||
| `redisExporter.tag` | v1.44.0 | Tag of the redis exporter image |
|
||||
| `redisExporter.imagePullPolicy` | IfNotPresent | Image Pull Policy of the redis exporter image |
|
||||
| `redisExporter.env` | [] | Extra environment variables which needs to be added in redis exporter |
|
||||
| `nodeSelector` | {} | NodeSelector for redis statefulset |
|
||||
| `priorityClassName` | "" | Priority class name for the redis statefulset |
|
||||
| `storageSpec` | {} | Storage configuration for redis setup |
|
||||
| `securityContext` | {} | Security Context for redis pods for changing system or kernel level parameters |
|
||||
| `affinity` | {} | Affinity for node and pod for redis statefulset |
|
||||
| `tolerations` | [] | Tolerations for redis statefulset |
|
||||
| `sidecars` | [] | Sidecar containers to run alongside Redis pods |
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
title: "RedisCluster"
|
||||
linkTitle: "RedisCluster"
|
||||
weight: 20
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Configurations and parameters for Redis cluster
|
||||
---
|
||||
|
||||
Redis cluster can be customized by [values.yaml](https://github.com/OT-CONTAINER-KIT/helm-charts/blob/main/charts/redis-cluster/values.yaml). The recommended way of managing the setup is using `helm` but if the setup is not maintained by it, `YAML` CRD parameters can be modified in the manifest.
|
||||
|
||||
## Helm Configuration Parameters
|
||||
|
||||
| **Name** | **Default Value** | **Description** |
|
||||
|------------------------------------|--------------------------------|----------------------------------------------------------------------------------------------|
|
||||
| `imagePullSecrets` | [] | List of image pull secrets, in case redis image is getting pull from private registry |
|
||||
| `redisCluster.clusterSize` | 3 | Size of the redis cluster leader and follower nodes |
|
||||
| `redisCluster.clusterVersion` | v7 | Major version of Redis setup, values can be v6 or v7 |
|
||||
| `redisCluster.persistenceEnabled` | true | Persistence should be enabled or not in the Redis cluster setup |
|
||||
| `redisCluster.secretName` | redis-secret | Name of the existing secret in Kubernetes |
|
||||
| `redisCluster.secretKey` | password | Name of the existing secret key in Kubernetes |
|
||||
| `redisCluster.image` | quay.io/opstree/redis | Name of the redis image |
|
||||
| `redisCluster.tag` | v7.0.5 | Tag of the redis image |
|
||||
| `redisCluster.imagePullPolicy` | IfNotPresent | Image Pull Policy of the redis image |
|
||||
| `redisCluster.leaderServiceType` | ClusterIP | Kubernetes service type for Redis Leader |
|
||||
| `redisCluster.followerServiceType` | ClusterIP | Kubernetes service type for Redis Follower |
|
||||
| `externalService.enabled` | false | If redis service needs to be exposed using LoadBalancer or NodePort |
|
||||
| `externalService.annotations` | {} | Kubernetes service related annotations |
|
||||
| `externalService.serviceType` | NodePort | Kubernetes service type for exposing service, values - ClusterIP, NodePort, and LoadBalancer |
|
||||
| `externalService.port` | 6379 | Port number on which redis external service should be exposed |
|
||||
| `serviceMonitor.enabled` | false | Servicemonitor to monitor redis with Prometheus |
|
||||
| `serviceMonitor.interval` | 30s | Interval at which metrics should be scraped. |
|
||||
| `serviceMonitor.scrapeTimeout` | 10s | Timeout after which the scrape is ended |
|
||||
| `serviceMonitor.namespace` | monitoring | Namespace in which Prometheus operator is running |
|
||||
| `redisExporter.enabled` | true | Redis exporter should be deployed or not |
|
||||
| `redisExporter.image` | quay.io/opstree/redis-exporter | Name of the redis exporter image |
|
||||
| `redisExporter.tag` | v1.44.0 | Tag of the redis exporter image |
|
||||
| `redisExporter.imagePullPolicy` | IfNotPresent | Image Pull Policy of the redis exporter image |
|
||||
| `redisExporter.env` | [] | Extra environment variables which needs to be added in redis exporter |
|
||||
| `sidecars` | [] | Sidecar container to run alongside Redis pods |
|
||||
| `nodeSelector` | {} | NodeSelector for redis statefulset |
|
||||
| `priorityClassName` | "" | Priority class name for the redis statefulset |
|
||||
| `storageSpec` | {} | Storage configuration for redis setup |
|
||||
| `securityContext` | {} | Security Context for redis pods for changing system or kernel level parameters |
|
||||
| `affinity` | {} | Affinity for node and pods for redis statefulset |
|
||||
| `tolerations` | [] | Tolerations for redis statefulset management |
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
title: "RedisReplication"
|
||||
linkTitle: "RedisReplication"
|
||||
weight: 10
|
||||
date: 2023-04-05T19:00:00Z
|
||||
description: >
|
||||
Configurations and parameters for Redis replication
|
||||
---
|
||||
|
||||
Redis replication configuration can be customized by [values.yaml](https://github.com/OT-CONTAINER-KIT/helm-charts/blob/main/charts/redis-replication/values.yaml). The recommended way of managing the setup is using `helm` but if the setup is not maintained by it, `YAML` CRD parameters can be modified in the manifest.
|
||||
|
||||
## Helm Configuration Parameters
|
||||
|
||||
| **Name** | **Value** | **Description** |
|
||||
|-----------------------------------|--------------------------------|-----------------------------------------------------------------------------------------------|
|
||||
| `imagePullSecrets` | [] | List of image pull secrets, in case redis image is getting pull from private registry |
|
||||
| `redisReplication.secretName` | redis-secret | Name of the existing secret in Kubernetes |
|
||||
| `redisReplication.secretKey` | password | Name of the existing secret key in Kubernetes |
|
||||
| `redisReplication.image` | quay.io/opstree/redis | Name of the redis image |
|
||||
| `redisReplication.tag` | v7.0.5 | Tag of the redis image |
|
||||
| `redisReplication.imagePullPolicy` | IfNotPresent | Image Pull Policy of the redis image |
|
||||
| `redisReplication.resources` | {} | Request and limits for redis statefulset |
|
||||
| `externalService.enabled` | false | If redis service needs to be exposed using LoadBalancer or NodePort |
|
||||
| `externalService.annotations` | {} | Kubernetes service related annotations |
|
||||
| `externalService.serviceType` | NodePort | Kubernetes service type for exposing service, values - ClusterIP, NodePort, and LoadBalancer |
|
||||
| `externalService.port` | 6379 | Port number on which redis external service should be exposed |
|
||||
| `serviceMonitor.enabled` | false | Servicemonitor to monitor redis with Prometheus |
|
||||
| `serviceMonitor.interval` | 30s | Interval at which metrics should be scraped. |
|
||||
| `serviceMonitor.scrapeTimeout` | 10s | Timeout after which the scrape is ended |
|
||||
| `serviceMonitor.namespace` | monitoring | Namespace in which Prometheus operator is running |
|
||||
| `redisExporter.enabled` | true | Redis exporter should be deployed or not |
|
||||
| `redisExporter.image` | quay.io/opstree/redis-exporter | Name of the redis exporter image |
|
||||
| `redisExporter.tag` | v1.44.0 | Tag of the redis exporter image |
|
||||
| `redisExporter.imagePullPolicy` | IfNotPresent | Image Pull Policy of the redis exporter image |
|
||||
| `redisExporter.env` | [] | Extra environment variables which needs to be added in redis exporter |
|
||||
| `nodeSelector` | {} | NodeSelector for redis statefulset |
|
||||
| `priorityClassName` | "" | Priority class name for the redis statefulset |
|
||||
| `storageSpec` | {} | Storage configuration for redis setup |
|
||||
| `securityContext` | {} | Security Context for redis pods for changing system or kernel level parameters |
|
||||
| `affinity` | {} | Affinity for node and pod for redis statefulset |
|
||||
| `tolerations` | [] | Tolerations for redis statefulset |
|
||||
| `sidecars` | [] | Sidecar containers to run alongside Redis pods |
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
title: "Configuration"
|
||||
linkTitle: "Configuration"
|
||||
weight: 5
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for configuration of Redis standalone and cluster setup.
|
||||
---
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
---
|
||||
title: "Contribute"
|
||||
linkTitle: "Contribute"
|
||||
weight: 9
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
How to contribute to the Redis Operator
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Kubernetes Cluster](https://kubernetes.io)
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
- [Go](https://golang.org/dl/)
|
||||
- [Docker](https://docs.docker.com/install/)
|
||||
- [Operator SDK](https://github.com/operator-framework/operator-sdk/releases)
|
||||
- [Make](https://www.gnu.org/software/make/manual/make.html)
|
||||
- [Eksctl](https://eksctl.io/)
|
||||
|
||||
## Local Kubernetes Cluster
|
||||
|
||||
For development and testing of operator on local system, we need to set up a [Minikube](https://minikube.sigs.k8s.io/docs/start/) or local Kubernetes cluster.
|
||||
|
||||
Minikube is a single node Kubernetes cluster that generally gets used for the development and testing on Kubernetes. For creating a Minkube cluster we need to simply run:
|
||||
|
||||
```shell
|
||||
$ minikube start --vm-driver virtualbox
|
||||
...
|
||||
😄 minikube v1.0.1 on linux (amd64)
|
||||
🤹 Downloading Kubernetes v1.14.1 images in the background ...
|
||||
🔥 Creating kvm2 VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...
|
||||
📶 "minikube" IP address is 192.168.39.240
|
||||
🐳 Configuring Docker as the container runtime ...
|
||||
🐳 Version of container runtime is 18.06.3-ce
|
||||
⌛ Waiting for image downloads to complete ...
|
||||
✨ Preparing Kubernetes environment ...
|
||||
🚜 Pulling images required by Kubernetes v1.14.1 ...
|
||||
🚀 Launching Kubernetes v1.14.1 using kubeadm ...
|
||||
⌛ Waiting for pods: apiserver proxy etcd scheduler controller dns
|
||||
🔑 Configuring cluster permissions ...
|
||||
🤔 Verifying component health .....
|
||||
💗 kubectl is now configured to use "minikube"
|
||||
🏄 Done! Thank you for using minikube!
|
||||
```
|
||||
|
||||
## Cloud Kubernetes Cluster
|
||||
|
||||
For cloud based Kubernetes cluster we can use any type of platforms like [Amazon Web Service](https://aws.amazon.com/), [Azure Cloud](https://azure.microsoft.com/en-in/), or [Google Cloud Platform](https://cloud.google.com/). We have provided an [eks-cluster.yaml](./example/eks-cluster.yaml) file for creating an Elastic Kubernetes Service(EKS) using [eksctl](https://eksctl.io/).
|
||||
|
||||
`eksctl` is a cli tool to create a Kubernetes cluster on EKS by a single command. It supports creation of Ipv4 and Ipv6 based Kubernetes clusters for development.
|
||||
|
||||
```shell
|
||||
$ eksctl create cluster -f example/eks-cluster.yaml
|
||||
...
|
||||
2022-10-30 19:47:44 [ℹ] eksctl version 0.114.0
|
||||
2022-10-30 19:47:44 [ℹ] using region us-west-2
|
||||
2022-10-30 19:47:45 [ℹ] setting availability zones to [us-west-2d us-west-2c us-west-2a]
|
||||
2022-10-30 19:47:45 [ℹ] subnets for us-west-2d - public:192.168.0.0/19 private:192.168.96.0/19
|
||||
2022-10-30 19:47:45 [ℹ] subnets for us-west-2c - public:192.168.32.0/19 private:192.168.128.0/19
|
||||
2022-10-30 19:47:45 [ℹ] subnets for us-west-2a - public:192.168.64.0/19 private:192.168.160.0/19
|
||||
2022-10-30 19:47:45 [ℹ] nodegroup "ng-1" will use "" [AmazonLinux2/1.22]
|
||||
2022-10-30 19:47:45 [ℹ] using SSH public key "/Users/abhishekdubey/.ssh/id_rsa.pub" as "eksctl-operator-testing-nodegroup-ng-1-8b:2b:b2:fc:4c:7f:9c:0d:54:14:70:39:25:b5:6d:60"
|
||||
2022-10-30 19:47:47 [ℹ] using Kubernetes version 1.22
|
||||
2022-10-30 19:47:47 [ℹ] creating EKS cluster "operator-testing" in "us-west-2" region with managed nodes
|
||||
2022-10-30 19:47:47 [ℹ] 1 nodegroup (ng-1) was included (based on the include/exclude rules)
|
||||
2022-10-30 19:47:47 [ℹ] will create a CloudFormation stack for cluster itself and 0 nodegroup stack(s)
|
||||
2022-10-30 19:47:47 [ℹ] will create a CloudFormation stack for cluster itself and 1 managed nodegroup stack(s)
|
||||
2022-10-30 19:47:47 [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=us-west-2 --cluster=operator-testing'
|
||||
2022-10-30 19:47:47 [ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "operator-testing" in "us-west-2"
|
||||
2022-10-30 19:47:47 [ℹ] CloudWatch logging will not be enabled for cluster "operator-testing" in "us-west-2"
|
||||
2022-10-30 19:47:47 [ℹ] you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=us-west-2 --cluster=operator-testing'
|
||||
2022-10-30 19:47:47 [ℹ]
|
||||
2 sequential tasks: { create cluster control plane "operator-testing",
|
||||
2 sequential sub-tasks: {
|
||||
5 sequential sub-tasks: {
|
||||
wait for control plane to become ready,
|
||||
associate IAM OIDC provider,
|
||||
no tasks,
|
||||
restart daemonset "kube-system/aws-node",
|
||||
1 task: { create addons },
|
||||
},
|
||||
create managed nodegroup "ng-1",
|
||||
}
|
||||
}
|
||||
2022-10-30 19:47:47 [ℹ] building cluster stack "eksctl-operator-testing-cluster"
|
||||
2022-10-30 19:47:50 [ℹ] deploying stack "eksctl-operator-testing-cluster"
|
||||
2022-10-30 20:01:17 [ℹ] daemonset "kube-system/aws-node" restarted
|
||||
2022-10-30 20:01:18 [ℹ] creating role using recommended policies
|
||||
2022-10-30 20:01:20 [ℹ] deploying stack "eksctl-operator-testing-addon-vpc-cni"
|
||||
2022-10-30 20:01:20 [ℹ] waiting for CloudFormation stack "eksctl-operator-testing-addon-vpc-cni"
|
||||
2022-10-30 20:01:52 [ℹ] waiting for CloudFormation stack "eksctl-operator-testing-addon-vpc-cni"
|
||||
2022-10-30 20:02:24 [ℹ] waiting for CloudFormation stack "eksctl-operator-testing-addon-vpc-cni"
|
||||
2022-10-30 20:02:26 [ℹ] creating addon
|
||||
2022-10-30 20:02:37 [ℹ] addon "vpc-cni" active
|
||||
2022-10-30 20:02:39 [ℹ] building managed nodegroup stack "eksctl-operator-testing-nodegroup-ng-1"
|
||||
```
|
||||
|
||||
For setting up the Ipv4 or Ipv6 cluster with eksctl, we need to modify this configuration in the [eks-cluster.yaml](./example/eks-cluster.yaml):
|
||||
|
||||
```yaml
|
||||
kubernetesNetworkConfig:
|
||||
ipFamily: IPv4
|
||||
# ipFamily: IPv6
|
||||
```
|
||||
|
||||
## Operator structure
|
||||
|
||||
The structure for Redis operator includes different module's directory. The codebase include these major directories:
|
||||
|
||||
```shell
|
||||
redis-operator/
|
||||
|-- api
|
||||
| |-- v1beta1
|
||||
|-- bin
|
||||
|-- config
|
||||
| |-- certmanager
|
||||
| |-- crd
|
||||
| | |-- bases
|
||||
| | |-- patches
|
||||
| |-- default
|
||||
| |-- manager
|
||||
| |-- prometheus
|
||||
| |-- rbac
|
||||
| |-- samples
|
||||
| |-- scorecard
|
||||
| |-- bases
|
||||
| |-- patches
|
||||
|-- controllers
|
||||
|-- hack
|
||||
|-- k8sutils
|
||||
```
|
||||
|
||||
As part of the development, generally, we modify the codebase in API, controllers, and k8sutils. The API modules hold the interface and structure for CRD definition, the controllers are the watch controllers that create, update, and delete the resources. The k8sutils is a module in which all the Kubernetes resources(Statefulsets, Services, etc.) codebase is present.
|
||||
|
||||
### Building Operator
|
||||
|
||||
For building operator, we can execute make command to create binary and docker image:
|
||||
|
||||
```shell
|
||||
$ make manager
|
||||
$ make docker-build
|
||||
```
|
||||
|
||||
For any change inside the `api` module, we need to recreate the CRD schema because of interface changes. To generate the CRD manifest and RBAC policies updated by operator:
|
||||
|
||||
```shell
|
||||
$ make manifests
|
||||
```
|
||||
|
||||
### Deploying Operator
|
||||
|
||||
The operator deployment can be done via `helm` cli, we just need to define the custom image name and tag for testing the operator functionality:
|
||||
|
||||
```shell
|
||||
$ helm upgrade redis-operator ot-helm/redis-operator \
|
||||
--install --namespace ot-operators --set redisOperator.imageName=<custom-url> \
|
||||
--set redisOperator.imageTag=<customTag>
|
||||
```
|
||||
|
||||
```shell
|
||||
# For deploying standalone redis
|
||||
$ helm upgrade redis ot-helm/redis --namespace ot-operators
|
||||
|
||||
# For deploying cluster redis
|
||||
$ helm upgrade redis-cluster ot-helm/redis-cluster \n
|
||||
--set redisCluster.clusterSize=3 --install --namespace ot-operators \
|
||||
--set pdb.enabled=false --set redisCluster.tag=v7.0.5-beta
|
||||
```
|
||||
|
||||
## Docker Image Development
|
||||
|
||||
Development of redis docker image is maintained inside a different repository - https://github.com/OT-CONTAINER-KIT/redis. To make any change or suggestion related to Redis docker image, please refer to this repository and make required changes.
|
||||
|
||||
In the repository, we have `Dockerfile` for [Redis](https://github.com/OT-CONTAINER-KIT/redis/blob/master/Dockerfile) and [Redis Exporter](https://github.com/OT-CONTAINER-KIT/redis/blob/master/Dockerfile.exporter)
|
||||
|
||||
For building the docker image for redis and redis exporter, there are simple make commands:
|
||||
|
||||
```shell
|
||||
$ make build-redis
|
||||
$ make build-redis-exporter
|
||||
```
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
---
|
||||
title: "Cluster"
|
||||
linkTitle: "Cluster"
|
||||
weight: 20
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for setting up Redis cluster
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
A Redis cluster is simply a [data sharding strategy](https://www.digitalocean.com/community/tutorials/understanding-database-sharding). It automatically partitions data across multiple Redis nodes. It is an advanced feature of Redis which achieves distributed storage and prevents a single point of failure.
|
||||
|
||||
In case of any redis node failure, a follower pod will automatically promote as the leader and whenever the old follower node will come back online, it will start acting as a follower. There are a minimum of 3 nodes required to build a Redis-sharded cluster with leader-only architecture. If we include followers as well, there will be at least 6 pods/processes of Redis.
|
||||
|
||||
<div align="center" class="mb-0">
|
||||
<img src="../../../images/cluster-redis.png">
|
||||
</div>
|
||||
|
||||
## Helm Installation
|
||||
|
||||
For redis cluster setup we can use `helm` command with the reference of cluster helm chart and additional properties:
|
||||
|
||||
```shell
|
||||
$ helm install redis-cluster ot-helm/redis-cluster \
|
||||
--set redisCluster.clusterSize=3 --namespace ot-operators
|
||||
...
|
||||
Release "redis-cluster" does not exist. Installing it now.
|
||||
NAME: redis-cluster
|
||||
LAST DEPLOYED: Sun May 2 16:11:38 2021
|
||||
NAMESPACE: ot-operators
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
Verify the cluster by checking the pod status of leader and follower pods.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-cluster-follower-0 1/1 Running 0 149m
|
||||
redis-cluster-follower-1 1/1 Running 0 150m
|
||||
redis-cluster-follower-2 1/1 Running 0 151m
|
||||
redis-cluster-leader-0 1/1 Running 0 149m
|
||||
redis-cluster-leader-1 1/1 Running 0 150m
|
||||
redis-cluster-leader-2 1/1 Running 0 151m
|
||||
```
|
||||
|
||||
If all the pods are in the running state of leader and follower Statefulsets, then we can check the health of the redis cluster by using redis-cli.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -n ot-operators -- redis-cli -a Opstree@1234 cluster nodes
|
||||
...
|
||||
Defaulting container name to redis-leader.
|
||||
Use 'kubectl describe pod/redis-leader-0 -n ot-operators' to see all of the containers in this pod.
|
||||
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
|
||||
528438a759cee4528c3071d17d75b27b0818555d 10.42.0.219:6379@16379 myself,master - 0 1619952294000 1 connected 0-5460
|
||||
8ec7812903b7e046bec2f2a7bce4a9ccadfa4188 10.42.0.221:6379@16379 slave d0ff3892d2eba0b2707199cb5df57adbba214bcd 0 1619952297241 3 connected
|
||||
60f932272322bafbd8c3e16328d26af676aeb8d6 10.42.0.220:6379@16379 slave 6e80da4902802ebffa94cbac9b7d98e9fd74121f 0 1619952297000 2 connected
|
||||
6e80da4902802ebffa94cbac9b7d98e9fd74121f 10.42.2.178:6379@16379 master - 0 1619952297000 2 connected 5461-10922
|
||||
d0ff3892d2eba0b2707199cb5df57adbba214bcd 10.42.1.178:6379@16379 master - 0 1619952298245 3 connected 10923-16383
|
||||
c2b74bd2a360068db01dfc8f00b8d0b012e21215 10.42.1.177:6379@16379 slave 528438a759cee4528c3071d17d75b27b0818555d 0 1619952297000 1 connected
|
||||
```
|
||||
|
||||
## YAML Installation
|
||||
|
||||
[Examples](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example) folder has different types of manifests for different scenarios and features. There are these YAML examples present in this directory:
|
||||
|
||||
- [additional_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/additional_config)
|
||||
- [advance_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/advance_config)
|
||||
- [affinity](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/affinity)
|
||||
- [disruption_budget](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/disruption_budget)
|
||||
- [external_service](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/external_service)
|
||||
- [password_protected](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/password_protected)
|
||||
- [private_registry](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/private_registry)
|
||||
- [probes](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/probes)
|
||||
- [redis_monitoring](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/redis_monitoring)
|
||||
- [tls_enabled](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/tls_enabled)
|
||||
- [upgrade_strategy](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/upgrade-strategy)
|
||||
|
||||
A sample manifest for deploying redis cluster:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: redis.redis.opstreelabs.in/v1beta1
|
||||
kind: RedisCluster
|
||||
metadata:
|
||||
name: redis-cluster
|
||||
spec:
|
||||
clusterSize: 3
|
||||
clusterVersion: v7
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
persistenceEnabled: true
|
||||
kubernetesConfig:
|
||||
image: quay.io/opstree/redis:v7.0.5
|
||||
imagePullPolicy: Always
|
||||
storage:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
The yaml manifest can easily get applied by using `kubectl`.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f cluster.yaml
|
||||
```
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
title: "Failover Testing"
|
||||
linkTitle: "Failover Testing"
|
||||
weight: 30
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for testing the failover of Redis cluster
|
||||
---
|
||||
|
||||
For cluster setup, testing can be performed to validate the failover functionality of Redis. In the failover testing, we can set some random keys inside the redis cluster and then delete one or two pods from the redis cluster. At that particular time, we can make some calls to redis for fetching the key to observing its failover mechanism of it.
|
||||
|
||||
Before failover testing, we have to write some dummy data inside the Redis cluster, we can write the dummy data using the `redis-cli`.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -n ot-operators \
|
||||
-- redis-cli -c set tony stark
|
||||
...
|
||||
OK
|
||||
```
|
||||
|
||||
Verify the key has been inserted properly inside the redis by fetching its value. Again we will use `redis-cli` for fetching the key from redis.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -n ot-operators \
|
||||
-- redis-cli -c get tony
|
||||
...
|
||||
"stark"
|
||||
```
|
||||
|
||||
To validate the failover functionality, we need to delete few of the pods from the redis cluster. `kubectl` cli could be use for deleting pods from the cluster.
|
||||
|
||||
```shell
|
||||
$ kubectl delete pod redis-cluster-leader-0 -n ot-operators
|
||||
...
|
||||
pod "redis-cluster-leader-0" deleted
|
||||
```
|
||||
|
||||
Since we have restarted `redis-cluster-leader-0` pod, we will again list out the redis nodes using `redis-cli` to see if follower node attached to it is promoted as leader or not. Also, the leader role should have been changed to follower role.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-leader-0 -n ot-operators \
|
||||
-- redis-cli cluster nodes
|
||||
...
|
||||
eef84b7dada737051c32d592bd66652b9af0cb35 10.42.2.184:6379@16379 slave 0a36dc5064b0a61afa8bd850e93ff0a1c2267704 0 1619958171517 3 connected
|
||||
a7c424b5ec0e696aa7be15a691846c8820e48cd1 10.42.1.181:6379@16379 master - 0 1619958172520 4 connected 0-5460
|
||||
118dbe4f49fa224b7d48fbe71990d054c7e9e853 10.42.0.228:6379@16379 slave 85747fe5cabf96e00fd0365737996a93e05cf947 0 1619958173523 2 connected
|
||||
50c3f58a1e2911a68b614f6a1a766cc4a7063e95 10.42.0.229:6379@16379 myself,slave a7c424b5ec0e696aa7be15a691846c8820e48cd1 0 1619958172000 4 connected
|
||||
0a36dc5064b0a61afa8bd850e93ff0a1c2267704 10.42.1.183:6379@16379 master - 0 1619958173000 3 connected 10923-16383
|
||||
85747fe5cabf96e00fd0365737996a93e05cf947 10.42.2.182:6379@16379 master - 0 1619958173523 2 connected 5461-10922
|
||||
```
|
||||
|
||||
So if you notice the output of cluster nodes command, the node IP is updated, and it’s connected as a leader.
|
||||
|
||||
```shell
|
||||
$ kubectl exec -it redis-cluster-follower-1 -n ot-operators \
|
||||
-- redis-cli -c get tony
|
||||
...
|
||||
"stark"
|
||||
```
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
title: "Replication"
|
||||
linkTitle: "Replication"
|
||||
weight: 10
|
||||
date: 2023-04-05T19:00:00Z
|
||||
description: >
|
||||
Instructions for setting up Redis Replication
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
Redis is an in-memory key-value store that can be used as a database, cache, and message broker. Redis replication is the process of synchronizing data from a Redis leader node to one or more Redis follower nodes.
|
||||
|
||||
In Redis replication, the leader node is responsible for receiving write requests and propagating the changes to one or more follower nodes. The follower nodes receive the data changes from the leader and apply them locally, thereby creating a replica of the leader's dataset.
|
||||
|
||||
Redis replication uses asynchronous replication, which means that the leader node does not wait for the follower nodes to apply the changes before sending new updates. Instead, the follower nodes catch up with the leader node as soon as they can, based on the available network bandwidth and the capacity of the hardware.
|
||||
|
||||
Redis replication is a powerful feature that enhances the durability and scalability of Redis applications. By using Redis replication, you can distribute the workload across multiple nodes, improve the read performance, and ensure data availability in case of a node failure.
|
||||
|
||||
<div align="center" class="mb-0">
|
||||
<img src="../../../images/replication-redis.png">
|
||||
</div>
|
||||
|
||||
> **Note:** By using Redis Sentinel, you can ensure that your Redis Replication remains available even if one or more nodes go down, improving the resilience and reliability of your application.
|
||||
|
||||
## Helm Installation
|
||||
|
||||
For redis replication setup we can use `helm` command with the reference of replication helm chart and additional properties:
|
||||
|
||||
```shell
|
||||
$ helm install redis-replication ot-helm/redis-replication \
|
||||
--set redisreplication.clusterSize=3 --namespace ot-operators
|
||||
...
|
||||
NAME: redis-replication
|
||||
LAST DEPLOYED: Tue Mar 21 22:47:44 2023
|
||||
NAMESPACE: ot-operators
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
Verify the replication-cluster by checking the pod status of pods.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-replication-0 1/1 Running 0 2m23s
|
||||
redis-replication-1 1/1 Running 0 99s
|
||||
redis-replication-2 1/1 Running 0 59s
|
||||
```
|
||||
|
||||
If all the pods are in the running, then we can check the health of the redis replication-cluster by using redis-cli. Here by default the 0th index redis pod is promoted to master.
|
||||
|
||||
## YAML Installation
|
||||
|
||||
[Examples](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example) folder has different types of manifests for different scenarios and features. There are these YAML examples present in this directory:
|
||||
|
||||
- [additional_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/additional_config)
|
||||
- [advance_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/advance_config)
|
||||
- [affinity](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/affinity)
|
||||
- [disruption_budget](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/disruption_budget)
|
||||
- [external_service](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/external_service)
|
||||
- [password_protected](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/password_protected)
|
||||
- [private_registry](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/private_registry)
|
||||
- [probes](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/probes)
|
||||
- [redis_monitoring](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/redis_monitoring)
|
||||
- [tls_enabled](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/tls_enabled)
|
||||
- [upgrade_strategy](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/upgrade-strategy)
|
||||
|
||||
A sample manifest for deploying redis replication-cluster:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: redis.redis.opstreelabs.in/v1beta1
|
||||
kind: RedisReplication
|
||||
metadata:
|
||||
name: redis-replication
|
||||
spec:
|
||||
clusterSize: 3
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
kubernetesConfig:
|
||||
image: quay.io/opstree/redis:v7.0.5
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
requests:
|
||||
cpu: 101m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 101m
|
||||
memory: 128Mi
|
||||
storage:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
# storageClassName: standard
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
The yaml manifest can easily get applied by using `kubectl`.
|
||||
|
||||
```shell
|
||||
kubectl apply -f replication.yaml
|
||||
```
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
---
|
||||
title: "Sentinel"
|
||||
linkTitle: "sentinel"
|
||||
weight: 20
|
||||
date: 2023-04-05T19:00:00Z
|
||||
description: >
|
||||
Instructions for setting up Redis sentinel
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
Redis Sentinel is a tool that provides automatic failover and monitoring for Redis nodes. It works by running separate processes that communicate with each other and with Redis nodes to detect failures, elect a new master node, and configure the other nodes to replicate from the new master. Sentinel can also perform additional tasks such as sending notifications and managing configuration changes. Redis Sentinel is a flexible and robust solution for implementing high availability in Redis.
|
||||
|
||||
<div align="center" class="mb-0">
|
||||
<img src="../../../images/sentinel-redis.png">
|
||||
</div>
|
||||
|
||||
## Helm Installation
|
||||
|
||||
In redis sentinel mode, we deploy redis as a single StatefulSet pod that means ease of setup but no complexity, no high availability, and no resilience.
|
||||
|
||||
Installation can be easily done via `helm` command:
|
||||
|
||||
```shell
|
||||
$ helm install redis-sentinel ot-helm/redis-sentinel \
|
||||
--set redissentinel.clusterSize=3 --namespace ot-operators \
|
||||
--set redisSentinelConfig.redisReplicationName="redis-replication"
|
||||
...
|
||||
NAME: redis-sentinel
|
||||
LAST DEPLOYED: Tue Mar 21 23:11:57 2023
|
||||
NAMESPACE: ot-operators
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
Verify the sentinel redis setup by kubectl command line.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-sentinel-0 1/1 Running 0 3m40s
|
||||
redis-sentinel-1 1/1 Running 0 2m55s
|
||||
redis-sentinel-2 1/1 Running 0 2m10s
|
||||
```
|
||||
|
||||
## YAML Installation
|
||||
|
||||
[Examples](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example) folder has different types of manifests for different scenarios and features. There are these YAML examples present in this directory:
|
||||
|
||||
- [additional_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/additional_config)
|
||||
- [advance_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/advance_config)
|
||||
- [affinity](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/affinity)
|
||||
- [disruption_budget](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/disruption_budget)
|
||||
- [external_service](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/external_service)
|
||||
- [password_protected](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/password_protected)
|
||||
- [private_registry](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/private_registry)
|
||||
- [probes](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/probes)
|
||||
- [redis_monitoring](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/redis_monitoring)
|
||||
- [tls_enabled](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/tls_enabled)
|
||||
- [upgrade_strategy](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/upgrade-strategy)
|
||||
|
||||
A basic sample manifest for sentinel redis:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: redis.redis.opstreelabs.in/v1beta1
|
||||
kind: RedisSentinel
|
||||
metadata:
|
||||
name: redis-sentinel
|
||||
spec:
|
||||
clusterSize: 3
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
redisSentinelConfig:
|
||||
redisReplicationName : redis-replication
|
||||
kubernetesConfig:
|
||||
image: quay.io/opstree/redis-sentinel:v7.0.7
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
requests:
|
||||
cpu: 101m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 101m
|
||||
memory: 128Mi
|
||||
```
|
||||
|
||||
The yaml manifest can easily get applied by using `kubectl`.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f sentinel.yaml
|
||||
```
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
---
|
||||
title: "Standalone"
|
||||
linkTitle: "Standalone"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for setting up Redis standalone
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
Redis standalone is a single process-based redis pod that can manage your keys inside it. Multiple applications can consume this redis with a Kubernetes endpoint or service. Since this standalone setup is running inside Kubernetes, the auto-heal feature will be automatically part of it. The only drawback of a standalone setup is that it doesn't stand on the high availability principle.
|
||||
|
||||
<div align="center" class="mb-0">
|
||||
<img src="../../../images/standalone-redis.png">
|
||||
</div>
|
||||
|
||||
## Helm Installation
|
||||
|
||||
In redis standalone mode, we deploy redis as a single StatefulSet pod that means ease of setup but no complexity, no high availability, and no resilience.
|
||||
|
||||
Installation can be easily done via `helm` command:
|
||||
|
||||
```shell
|
||||
$ helm install redis ot-helm/redis --namespace ot-operators
|
||||
...
|
||||
Release "redis" does not exist. Installing it now.
|
||||
NAME: redis
|
||||
LAST DEPLOYED: Sun May 2 15:59:48 2021
|
||||
NAMESPACE: ot-operators
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
Verify the standalone redis setup by kubectl command line.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-standalone-0 2/2 Running 0 56s
|
||||
```
|
||||
|
||||
## YAML Installation
|
||||
|
||||
[Examples](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example) folder has different types of manifests for different scenarios and features. There are these YAML examples present in this directory:
|
||||
|
||||
- [additional_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/additional_config)
|
||||
- [advance_config](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/advance_config)
|
||||
- [affinity](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/affinity)
|
||||
- [disruption_budget](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/disruption_budget)
|
||||
- [external_service](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/external_service)
|
||||
- [password_protected](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/password_protected)
|
||||
- [private_registry](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/private_registry)
|
||||
- [probes](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/probes)
|
||||
- [redis_monitoring](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/redis_monitoring)
|
||||
- [tls_enabled](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/tls_enabled)
|
||||
- [upgrade_strategy](https://github.com/OT-CONTAINER-KIT/redis-operator/tree/master/example/upgrade-strategy)
|
||||
|
||||
A basic sample manifest for standalone redis:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: redis.redis.opstreelabs.in/v1beta1
|
||||
kind: Redis
|
||||
metadata:
|
||||
name: redis-standalone
|
||||
spec:
|
||||
kubernetesConfig:
|
||||
image: quay.io/opstree/redis:v7.0.5
|
||||
imagePullPolicy: IfNotPresent
|
||||
storage:
|
||||
volumeClaimTemplate:
|
||||
spec:
|
||||
# storageClassName: standard
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
fsGroup: 1000
|
||||
```
|
||||
|
||||
The yaml manifest can easily get applied by using `kubectl`.
|
||||
|
||||
```shell
|
||||
$ kubectl apply -f standalone.yaml
|
||||
```
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
title: "Getting Started"
|
||||
linkTitle: "Getting Started"
|
||||
weight: 4
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for getting started on Redis and Redis cluster setup
|
||||
---
|
||||
|
||||
The redis operator supports below deployment strategies for redis:-
|
||||
|
||||
- Cluster setup
|
||||
- Standalone setup
|
||||
- Replication setup
|
||||
- Sentinel setup
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
---
|
||||
title: "Create Cluster"
|
||||
linkTitle: "Create Cluster"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for creating a Kubernetes cluster and installing Redis Operator on it
|
||||
---
|
||||
|
||||
Redis Operator needs a Kubernetes or Openshift cluster for provisioning a Redis setup. This guide helps in setting up a Kubernetes cluster from a quickstart perspective.
|
||||
|
||||
Tools involved in this kind of setup:
|
||||
|
||||
- [Eksctl](https://eksctl.io/)
|
||||
- [Minikube](https://minikube.sigs.k8s.io/docs/start/)
|
||||
|
||||
## Amazon EKS Cluster
|
||||
|
||||
To create a Kubernetes cluster on AWS, we need to download and install the [eksctl](https://eksctl.io/) on the local system and then [eks-cluster.yaml](https://github.com/OT-CONTAINER-KIT/redis-operator/blob/master/example/eks-cluster.yaml) can be executed with it for cluster creation.
|
||||
|
||||
The content of [eks-cluster.yaml](https://github.com/OT-CONTAINER-KIT/redis-operator/blob/master/example/eks-cluster.yaml) looks like:
|
||||
|
||||
```yaml
|
||||
apiVersion: eksctl.io/v1alpha5
|
||||
kind: ClusterConfig
|
||||
metadata:
|
||||
name: operator-testing
|
||||
region: us-west-2
|
||||
version: "1.22"
|
||||
managedNodeGroups:
|
||||
- name: ng-1
|
||||
instanceType: t3a.medium
|
||||
desiredCapacity: 3
|
||||
volumeSize: 30
|
||||
ssh:
|
||||
allow: true
|
||||
volumeType: gp3
|
||||
kubernetesNetworkConfig:
|
||||
ipFamily: IPv4
|
||||
# ipFamily: IPv6
|
||||
addons:
|
||||
- name: vpc-cni
|
||||
- name: coredns
|
||||
- name: kube-proxy
|
||||
iam:
|
||||
withOIDC: true
|
||||
```
|
||||
|
||||
```shell
|
||||
$ eksctl create cluster -f example/eks-cluster.yaml
|
||||
...
|
||||
2022-11-01 12:49:15 [ℹ] eksctl version 0.114.0
|
||||
2022-11-01 12:49:15 [ℹ] using region us-west-2
|
||||
2022-11-01 12:49:16 [ℹ] setting availability zones to [us-west-2b us-west-2a us-west-2d]
|
||||
2022-11-01 12:49:16 [ℹ] subnets for us-west-2b - public:192.168.0.0/19 private:192.168.96.0/19
|
||||
2022-11-01 12:49:16 [ℹ] subnets for us-west-2a - public:192.168.32.0/19 private:192.168.128.0/19
|
||||
2022-11-01 12:49:16 [ℹ] subnets for us-west-2d - public:192.168.64.0/19 private:192.168.160.0/19
|
||||
2022-11-01 12:49:16 [ℹ] nodegroup "ng-1" will use "" [AmazonLinux2/1.22]
|
||||
2022-11-01 12:49:16 [ℹ] using SSH public key "/Users/abhishekdubey/.ssh/id_rsa.pub" as "eksctl-operator-testing-nodegroup-ng-1-8b:2b:b2:fc:4c:7f:9c:0d:54:14:70:39:25:b5:6d:60"
|
||||
2022-11-01 12:49:18 [ℹ] using Kubernetes version 1.22
|
||||
2022-11-01 12:49:18 [ℹ] creating EKS cluster "operator-testing" in "us-west-2" region with managed nodes
|
||||
2022-11-01 12:49:18 [ℹ] 1 nodegroup (ng-1) was included (based on the include/exclude rules)
|
||||
2022-11-01 12:49:18 [ℹ] will create a CloudFormation stack for cluster itself and 0 nodegroup stack(s)
|
||||
2022-11-01 12:49:18 [ℹ] will create a CloudFormation stack for cluster itself and 1 managed nodegroup stack(s)
|
||||
2022-11-01 12:49:18 [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=us-west-2 --cluster=operator-testing'
|
||||
2022-11-01 12:49:18 [ℹ] Kubernetes API endpoint access will use default of {publicAccess=true, privateAccess=false} for cluster "operator-testing" in "us-west-2"
|
||||
2022-11-01 12:49:18 [ℹ] CloudWatch logging will not be enabled for cluster "operator-testing" in "us-west-2"
|
||||
2022-11-01 12:49:18 [ℹ] you can enable it with 'eksctl utils update-cluster-logging --enable-types={SPECIFY-YOUR-LOG-TYPES-HERE (e.g. all)} --region=us-west-2 --cluster=operator-testing'
|
||||
2022-11-01 13:08:05 [ℹ] waiting for CloudFormation stack "eksctl-operator-testing-nodegroup-ng-1"
|
||||
2022-11-01 13:08:05 [ℹ] waiting for the control plane to become ready
|
||||
2022-11-01 13:08:06 [✔] saved kubeconfig as "/Users/abhishekdubey/.kube/lab-config"
|
||||
2022-11-01 13:08:06 [ℹ] no tasks
|
||||
2022-11-01 13:08:06 [✔] all EKS cluster resources for "operator-testing" have been created
|
||||
2022-11-01 13:08:08 [ℹ] nodegroup "ng-1" has 3 node(s)
|
||||
2022-11-01 13:08:08 [ℹ] node "ip-192-168-25-130.us-west-2.compute.internal" is ready
|
||||
2022-11-01 13:08:08 [ℹ] node "ip-192-168-38-199.us-west-2.compute.internal" is ready
|
||||
2022-11-01 13:08:08 [ℹ] node "ip-192-168-89-35.us-west-2.compute.internal" is ready
|
||||
2022-11-01 13:08:08 [ℹ] waiting for at least 3 node(s) to become ready in "ng-1"
|
||||
2022-11-01 13:08:08 [ℹ] nodegroup "ng-1" has 3 node(s)
|
||||
2022-11-01 13:08:08 [ℹ] node "ip-192-168-25-130.us-west-2.compute.internal" is ready
|
||||
2022-11-01 13:08:08 [ℹ] node "ip-192-168-38-199.us-west-2.compute.internal" is ready
|
||||
2022-11-01 13:08:08 [ℹ] node "ip-192-168-89-35.us-west-2.compute.internal" is ready
|
||||
2022-11-01 13:08:11 [ℹ] no recommended policies found, proceeding without any IAM
|
||||
```
|
||||
|
||||
## Minikube
|
||||
|
||||
Minikube is a tool for creation of Kubernetes on local system for Development purpose. It requires a [Docker](https://docker.com) compatible system or virtual machine environment.
|
||||
|
||||
```shell
|
||||
$ minikube start --vm-driver virtualbox
|
||||
...
|
||||
😄 minikube v1.0.1 on linux (amd64)
|
||||
🤹 Downloading Kubernetes v1.14.1 images in the background ...
|
||||
🔥 Creating kvm2 VM (CPUs=2, Memory=2048MB, Disk=20000MB) ...
|
||||
📶 "minikube" IP address is 192.168.39.240
|
||||
🐳 Configuring Docker as the container runtime ...
|
||||
🐳 Version of container runtime is 18.06.3-ce
|
||||
⌛ Waiting for image downloads to complete ...
|
||||
✨ Preparing Kubernetes environment ...
|
||||
🚜 Pulling images required by Kubernetes v1.14.1 ...
|
||||
🚀 Launching Kubernetes v1.14.1 using kubeadm ...
|
||||
⌛ Waiting for pods: apiserver proxy etcd scheduler controller dns
|
||||
🔑 Configuring cluster permissions ...
|
||||
🤔 Verifying component health .....
|
||||
💗 kubectl is now configured to use "minikube"
|
||||
🏄 Done! Thank you for using minikube!
|
||||
```
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
title: "Installation"
|
||||
linkTitle: "Installation"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for installation of Redis Operator.
|
||||
---
|
||||
|
||||
Redis Operator is developed as CRD(Custom Resource Definition) to deploy and manage Redis in standalone/cluster mode. So CRD is an amazing feature of Kubernetes which allows us to create our own resources and APIs in Kubernetes. For further information about CRD, please go through the [official documentation](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/).
|
||||
|
||||
There are four different Objects available under `redis.redis.opstreelabs.in/v1beta1`:
|
||||
|
||||
- Redis
|
||||
- Redis Cluster
|
||||
- Redis Replication
|
||||
- Redis Sentinel
|
||||
|
||||
For [OperatorHub](https://operatorhub.io) installation:
|
||||
|
||||
https://operatorhub.io/operator/redis-operator
|
||||
|
||||
So for deploying the redis-operator and setup we need a Kubernetes cluster 1.18+ and that’s it. Let’s deploy the redis operator first.
|
||||
|
||||
The easiest way to install a redis operator is using Helm chart. The operator helm chart is developed on the `helm=>3.0.0` version. The [values.yaml](https://github.com/OT-CONTAINER-KIT/helm-charts/blob/main/charts/redis-operator/values.yaml) can be modified.
|
||||
|
||||
## Helm Installation
|
||||
|
||||
```shell
|
||||
$ helm repo add ot-helm https://ot-container-kit.github.io/helm-charts/
|
||||
$ helm install redis-operator ot-helm/redis-operator --namespace ot-operators
|
||||
...
|
||||
Release "redis-operator" does not exist. Installing it now.
|
||||
NAME: redis-operator
|
||||
LAST DEPLOYED: Sun May 2 14:42:23 2021
|
||||
NAMESPACE: ot-operators
|
||||
STATUS: deployed
|
||||
REVISION: 1
|
||||
TEST SUITE: None
|
||||
```
|
||||
|
||||
## YAML Installation
|
||||
|
||||
{{< alert title="Warning" color="warning">}}
|
||||
YAML installation is not a recommended way for installation, this can only be used for development practices only.
|
||||
{{< /alert >}}
|
||||
|
||||
```shell
|
||||
$ bash install-operator.sh
|
||||
...
|
||||
customresourcedefinition.apiextensions.k8s.io/redis.redis.redis.opstreelabs.in created
|
||||
customresourcedefinition.apiextensions.k8s.io/redisclusters.redis.redis.opstreelabs.in created
|
||||
namespace/ot-operators created
|
||||
deployment.apps/redis-operator created
|
||||
serviceaccount/redis-operator created
|
||||
clusterrole.rbac.authorization.k8s.io/redis-operator created
|
||||
clusterrolebinding.rbac.authorization.k8s.io/redis-operator created
|
||||
```
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
title: "Upgrade"
|
||||
linkTitle: "Upgrade"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for upgrading Redis Operator
|
||||
---
|
||||
|
||||
{{< alert color="info" title="Note" >}}
|
||||
Whichever approach you take to upgrading Redis Operator, make sure to test it in your development environment
|
||||
before applying it to production.
|
||||
{{< /alert >}}
|
||||
|
||||
## Upgrading Operator
|
||||
|
||||
The following are strategies for safely upgrading Redis Operator from one version to another. They may require adjustment to your particular game architecture but should provide a solid foundation for updating Agones safely.
|
||||
|
||||
Ideally we should disable the reconcillation on all the Redis setup managed by operator. To disable the reconcillation, we need to add an annotation on all the `Redis` and `Redis Cluster` object.
|
||||
|
||||
For `Redis` standalone object:
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
redis.opstreelabs.in/skip-reconcile: "true"
|
||||
```
|
||||
|
||||
For `RedisCluster` object:
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
rediscluster.opstreelabs.in/skip-reconcile: "true"
|
||||
```
|
||||
|
||||
For `RedisReplication` object:
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
redisReplication.opstreelabs.in/skip-reconcile: "true"
|
||||
```
|
||||
|
||||
For `RedisSentinel` object:
|
||||
|
||||
```yaml
|
||||
annotations:
|
||||
redisSentinel.opstreelabs.in/skip-reconcile: "true"
|
||||
```
|
||||
|
||||
### Upgrading with Helm
|
||||
|
||||
Helm features capabilities for upgrading to newer versions of Agones without having to uninstall Redis Operator completely.
|
||||
|
||||
For details on how to use Helm for upgrades, see the [helm upgrade](https://v2.helm.sh/docs/helm/#helm-upgrade) documentation.
|
||||
|
||||
```shell
|
||||
$ helm install redis-operator ot-helm/redis-operator \
|
||||
--namespace ot-operators --version <desired_version>
|
||||
```
|
||||
|
||||
Once upgrading activity is completed, again validate the setup by steps defined in [Validation](../validation).
|
||||
|
||||
### Upgrading with YAML
|
||||
|
||||
If you installed Redis Operator with [install-operator.sh](https://github.com/OT-CONTAINER-KIT/redis-operator/blob/master/install-operator.sh), we need to update the image tag version inside the [deployment manifest](https://github.com/OT-CONTAINER-KIT/redis-operator/blob/master/config/manager/manager.yaml) of operator and again run the same script.
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- command:
|
||||
- /manager
|
||||
args:
|
||||
- --leader-elect
|
||||
- -zap-log-level=info
|
||||
image: quay.io/opstree/redis-operator:<desired_version>
|
||||
imagePullPolicy: Always
|
||||
```
|
||||
|
||||
```shell
|
||||
$ bash install-operator.sh
|
||||
```
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
---
|
||||
title: "Installation Validation"
|
||||
linkTitle: "Installation Validation"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for validating installation of Operator
|
||||
---
|
||||
|
||||
To confirm Redis Operator is up and running, run the following command:
|
||||
|
||||
```shell
|
||||
$ kubectl describe --namespace ot-operators pods
|
||||
```
|
||||
|
||||
It should describe one pod created in the ot-operators namespace, with no error messages or status. All Conditions sections should look like this:
|
||||
|
||||
```yaml
|
||||
Conditions:
|
||||
Type Status
|
||||
Initialized True
|
||||
Ready True
|
||||
ContainersReady True
|
||||
PodScheduled True
|
||||
```
|
||||
|
||||
The operator pod should be in a RUNNING state:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods -n ot-operators
|
||||
...
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
redis-operator-74b6cbf5c5-td8t7 1/1 Running 0 2m11s
|
||||
```
|
||||
|
||||
That’s it!
|
||||
|
||||
Now with Redis Operator installed, you can utilise its [Custom Resource Definitions](https://kubernetes.io/docs/concepts/api-extension/custom-resources/) to create resources of type Redis, RedisCluster and more!
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
title: "Installation"
|
||||
linkTitle: "Installation"
|
||||
weight: 3
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Instructions for installation of Kubernetes cluster and Redis Operator
|
||||
---
|
||||
|
||||
## Usage Requirements
|
||||
|
||||
- **Kubernetes cluster version > 1.18**
|
||||
- All Kubernetes platform are supported like: [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/), [Azure Kubernetes Service](https://azure.microsoft.com/en-us/services/kubernetes-service/), [Amazon EKS](https://aws.amazon.com/eks/) and [Minikube](https://github.com/kubernetes/minikube).
|
||||
- Redis cluster needs persistence support in Kubernetes cluster
|
||||
|
||||
## Supported Container Architectures
|
||||
|
||||
The following container operating systems and architectures can be utilised with Redis Operaror:
|
||||
|
||||
| OS | Architecture | Support |
|
||||
|-------|--------------|----------|
|
||||
| linux | amd64 | stable |
|
||||
| linux | arm64 | stable |
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
---
|
||||
title: "Monitoring"
|
||||
linkTitle: "Monitoring"
|
||||
weight: 8
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Monitoring of Redis standalone and cluster setup using Prometheus
|
||||
---
|
||||
|
||||
The redis-operator uses [redis-exporter](https://github.com/oliver006/redis_exporter) to expose metrics of redis setup in Prometheus format. This exporter captures metrics for both redis standalone and cluster setup.
|
||||
|
||||
The monitoring architecture is illustrated in the diagram:
|
||||
|
||||

|
||||
|
||||
For the helm chart installation of redis setup, we can simply enable the redis exporter by creating a custom values file for helm chart. The content of the values file will look like this:
|
||||
|
||||
```yaml
|
||||
redisExporter:
|
||||
enabled: true
|
||||
image: quay.io/opstree/redis-exporter:1.0
|
||||
imagePullPolicy: Always
|
||||
```
|
||||
|
||||
When we have defined the redis-exporter related config in values file, we can apply or upgrade the redis setup. We need to pass the created file as an argument to the `helm` command.
|
||||
|
||||
Enabling monitoring for standalone setup:
|
||||
|
||||
```shell
|
||||
$ helm upgrade redis ot-helm/redis -f monitoring-values.yaml \
|
||||
--install --namespace ot-operators
|
||||
```
|
||||
|
||||
Enabling monitoring for cluster setup:
|
||||
|
||||
```shell
|
||||
$ helm upgrade redis-cluster ot-helm/redis-cluster -f monitoring-values.yaml \
|
||||
--set redisCluster.clusterSize=3 --install --namespace ot-operators
|
||||
```
|
||||
|
||||
## ServiceMonitor
|
||||
|
||||
Once the exporter is configured, we may have to update Prometheus to monitor this endpoint. For [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator), we have to create a CRD based object called ServiceMonitor. We can apply the CRD definition as well using the helm command.
|
||||
|
||||
```yaml
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
interval: 30s
|
||||
scrapeTimeout: 10s
|
||||
namespace: monitoring
|
||||
```
|
||||
|
||||
For kubectl related configuration, we may have to create `ServiceMonitor` definition in a YAML manifest and apply it using `kubectl` command.
|
||||
|
||||
ServiceMonitor for Redis cluster setup:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: redis-cluster
|
||||
labels:
|
||||
redis-operator: "true"
|
||||
env: production
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
redis_setup_type: cluster
|
||||
endpoints:
|
||||
- port: redis-exporter
|
||||
interval: 30s
|
||||
scrapeTimeout: 10s
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- monitoring
|
||||
```
|
||||
|
||||
ServiceMonitor for Redis standalone setup:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: redis-standalone
|
||||
labels:
|
||||
redis-operator: "true"
|
||||
env: production
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
redis_setup_type: standalone
|
||||
endpoints:
|
||||
- port: redis-exporter
|
||||
interval: 30s
|
||||
scrapeTimeout: 10s
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- monitoring
|
||||
```
|
||||
|
||||
## Grafana Dashboards
|
||||
|
||||
There is detailed dashboard created for Redis cluster monitoring setup. Refer to that dashboard once the metrics are available inside Prometheus setup.
|
||||
|
||||
[Redis Operator Cluster Dashboard for Prometheus](https://github.com/OT-CONTAINER-KIT/redis-operator/blob/master/dashboards/redis-operator-cluster.json)
|
||||
|
||||

|
||||
|
|
@ -0,0 +1,52 @@
|
|||
---
|
||||
title: "Overview"
|
||||
linkTitle: "Overview"
|
||||
weight: 1
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Redis Operator is a software to set up and manage Redis on [Kubernetes](https://kubernetes.io).
|
||||
---
|
||||
|
||||
A Golang based redis operator that will make/oversee Redis standalone/cluster/replication/sentinel mode setup on top of the Kubernetes. It can create a redis cluster setup with best practices on Cloud as well as the Bare-metal environment. Also, it provides an in-built monitoring capability using redis-exporter.
|
||||
|
||||
Documentation is available here:- https://ot-container-kit.github.io/redis-operator/
|
||||
|
||||
The type of Redis setup which is currently supported:-
|
||||
|
||||
- Redis Cluster
|
||||
- Redis Standalone
|
||||
- Redis Replication
|
||||
- Redis Sentinel
|
||||
|
||||
This operator only supports versions of redis `=>6`.
|
||||
|
||||
## Purpose
|
||||
|
||||
There are multiple problems that people face while setting up redis setup on Kubernetes, specially cluster type setup. The purpose of creating this opperator is to provide an easy and production ready interface for redis setup that include best-practices, security controls, monitoring, and management.
|
||||
|
||||
## Why Redis Operator?
|
||||
|
||||
Here the features which are supported by this operator:-
|
||||
|
||||
- Redis cluster, replication and standalone mode setup
|
||||
- Redis cluster and replication failover and recovery
|
||||
- Inbuilt monitoring with redis exporter
|
||||
- Password and password-less setup of redis
|
||||
- TLS support for additional security layer
|
||||
- Ipv4 and Ipv6 support for redis setup
|
||||
- Detailed monitoring grafana dashboard
|
||||
|
||||
## Architecture
|
||||
|
||||

|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Participation in this project comes under the [CONTRIBUTING.md](https://github.com/OT-CONTAINER-KIT/redis-operator/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## What's Next
|
||||
|
||||
- Installation of Redis Operator
|
||||
- Setup of Redis standalone, cluster, replication and sentinel mode
|
||||
- Monitoring of Redis setup
|
||||
- Configuration and advance cofiguration of Operator
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
title: "Redis Overview"
|
||||
linkTitle: "Redis Overview"
|
||||
weight: 2
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
[Redis](https://redis.io/) is an in-memory cache and database that can be used for improving system design.
|
||||
---
|
||||
|
||||
Redis is a popular and opensource in-memory database that supports multiple data structures like strings, hashes, lists, and sets. But similar to other tools, we can scale standalone redis to a particular extent and not beyond that. That’s why we have a cluster mode setup in which we can scale Redis nodes horizontally and then distribute data among those nodes.
|
||||
|
||||
Use cases of redis:
|
||||
|
||||
- Caching
|
||||
- Database
|
||||
- Chat, messaging, and queues
|
||||
- Gaming leaderboards
|
||||
- Session store
|
||||
- Rich media streaming
|
||||
- Geospatial
|
||||
|
||||
Sometimes getting data from disks can be time-consuming. In order to increase the performance, we can put the requests those either need to be served first or rapidly in Redis memory and then the Redis service there will keep rest of the data in the main database. So the whole architecture will look like this:
|
||||
|
||||
<div align="center">
|
||||
<img src="../../../images/redis-cache.png">
|
||||
</div>
|
||||
|
||||
## Sharding vs Replication
|
||||
|
||||
This operator generally focuses on two different types of setup i.e. standalone and cluster. In cluster mode, it focuses on sharded cluster only as of now.
|
||||
|
||||
There are two models of setting up cluster in redis:
|
||||
|
||||
- Sharding
|
||||
- Replication
|
||||
|
||||
Replication is also known as mirroring of data. In replication, all the data get copied from the leader node to the follower node. Sharding is also known as partitioning. It splits up the data by the key to multiple nodes.
|
||||
|
||||
<div align="center">
|
||||
<img src="../../../images/replication.png">
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
<img src="../../../images/sharding.png">
|
||||
</div>
|
||||
|
||||
In sharding, the keys are getting distributed across both machine A and B. That is, the machine A will hold the 1, 3 key and machine B will hold 2, 4 key:
|
||||
|
||||
<div align="center">
|
||||
<img src="https://blog2opstree.files.wordpress.com/2019/06/08d40-1ylzieskl-3rvar6kleoziq.png">
|
||||
</div>
|
||||
|
||||
## Redis cluster challenges on Kubernetes
|
||||
|
||||
Kubernetes has made the deployment of stateful application quite easy by StatefulSets. By using StatefulSets, we can easily deploy and scale any kind of stateful applications like Kafka, Zookeeper, etc. But in the case of redis, the setup is not straightforward, there are some additional things which needs to be taken care:-
|
||||
|
||||
- We have to use the headless service of Redis because it’s a TCP based service and normal service is HTTP(Layer 7) based Loadbalancer. So in case of headless service, no ClusterIP will be used, and we have to rely on Pod IP.
|
||||
- Redis doesn’t use DNS to form clusters instead of that it uses IP. So we cannot use the internal DNS name of headless service, instead of that, we have to use Pod IP to form a Redis cluster.
|
||||
- In Kubernetes, Pod IP is dynamic and it can change after the pod restart, so in case of the restart the cluster will be malformed and the restarted pod will act as a lost node.
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
---
|
||||
title: "Release History"
|
||||
linkTitle: "Release History"
|
||||
weight: 10
|
||||
date: 2022-11-02T00:19:19Z
|
||||
description: >
|
||||
Release versions and their description about Redis Operator
|
||||
---
|
||||
|
||||
### v0.13.0
|
||||
##### November 10, 2022
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fixed multiple follower logic for redis cluster
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Updated all examples for Redis v7
|
||||
- Revamped documentation with the latest information
|
||||
- Added pause option for reconcilations
|
||||
- Added support for arm64
|
||||
- Added update strategy for statefulset
|
||||
- Added logic for updating follower replicas
|
||||
- Added TLS feature for standalone
|
||||
|
||||
### v0.12.0
|
||||
##### October 12, 2022
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- PDB (Pod disruption budget) creation issue
|
||||
- Fixed cluster recovery logic
|
||||
- Fixed IP check and conversion logic
|
||||
- Persistence issue fix
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Added pvc, pv clusterrole fix
|
||||
- Support for defining serviceAccount
|
||||
- Closing of redis client connection
|
||||
- Added finalizer for statefulset
|
||||
- Added Prometheus service annotation
|
||||
- Added support for Redis 7 with DNS hostname
|
||||
|
||||
### v0.11.0
|
||||
**July 5, 2022**
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fix Redis cluster and Redis CRD
|
||||
- Fixed TLS authentication between redis cluster
|
||||
- Fixed RBAC policy for PDB
|
||||
- Redis exporter exception handled
|
||||
- External service fix
|
||||
|
||||
### v0.10.0
|
||||
**January 26, 2022**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Added custom probes capability
|
||||
- Added sidecar support for redis
|
||||
- Added option for namespaced operator
|
||||
- Added finalizers for Kubernetes resources
|
||||
- Adding PodDisruptionBudget support
|
||||
- Added TLS cluster support
|
||||
- Pass through Annotations and Labels to all Child resources
|
||||
- Adding Rudimentry IPv6 Support
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fix up RedisClusterStatus Spec being incorrect object
|
||||
- Fixed invalid RBAC kustomization
|
||||
- Fixed RBAC role for operator
|
||||
- Fixed service creation for leader and follower
|
||||
|
||||
### v0.9.0
|
||||
**November 13, 2021**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Added RBAC policies for redis operator with least privileges
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fix and updated documentation dependencies
|
||||
- Test pointers before dereferencing
|
||||
- Fix panic error of golang for redis exporter
|
||||
- Fix resource block nil exception for redis exporter
|
||||
|
||||
### v0.8.0
|
||||
**September 3, 2021**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Added external configuration capability for follower and leader
|
||||
- Streamlined examples folder with different examples for standalone and cluster
|
||||
- Added the capability for affinity for leader and follower
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fix bug for non-defined storage
|
||||
- Fixed secret nil exception bug
|
||||
- Fixed bug for making redis exporter optional
|
||||
|
||||
### v0.7.0
|
||||
**August 12, 2021**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Remove all the vulnerable dependencies from docs(NodeJS)
|
||||
- Added a new grafana dashboard for better monitoring visualization
|
||||
- Added environment variable support for redis exporter
|
||||
- Added Image Pull Secret support for private registeries
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fix bug for non-defined storage
|
||||
- Fixed secret nil exception bug
|
||||
- Fixed bug for making redis exporter optional
|
||||
|
||||
### v0.6.0
|
||||
**June 12, 2021**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Breaked the CRDs into Redis standalone cluster setup
|
||||
- Optimized code configuration for creating Redis cluster
|
||||
- Removed string secret type and secret type password is only supported
|
||||
- Structured and optimized golang based codebase
|
||||
- Removed divisive terminlogies
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fixed logic for service and statefulset comparison in K8s
|
||||
- Removed the monitor label to resolve service endpoint issue
|
||||
|
||||
### v0.5.0
|
||||
**May 1, 2021**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Added support for recovering redis nodes from failover
|
||||
- Added toleration support for redis statefuls
|
||||
- Added capability to use existing secret created inside K8s
|
||||
|
||||
**🐞Bug Fixes**
|
||||
|
||||
- Fixed logic for service and statefulset comparison in K8s
|
||||
|
||||
### v0.4.0
|
||||
**February 6, 2021**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Add Nodeport support for Kubernetes service
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Updated helm chart with latest CRD configuration
|
||||
- Optimized helm chart
|
||||
- RBAC issus fixed
|
||||
|
||||
### v0.3.0
|
||||
**Decemeber 30, 2020**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Upgraded operator-sdk version to v1.0.3
|
||||
- Added capability to watch multiple namespaces
|
||||
- Added CI workflow pipeline for golang
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Password updation bug https://github.com/OT-CONTAINER-KIT/redis-operator/issues/21
|
||||
- POD recovery, Can't Sync pods IP to nodes.conf https://github.com/OT-CONTAINER-KIT/redis-operator/issues/20
|
||||
- Directory creation (permission issue) https://github.com/OT-CONTAINER-KIT/redis-operator/issues/19
|
||||
|
||||
### v0.2.0
|
||||
**July 1, 2020**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Added documentation site for better management
|
||||
- Added YAML validation for redis resource
|
||||
- Added resources in redis exporter
|
||||
- Structured complete YAML manifests
|
||||
- Added service type for redis service
|
||||
- Updated helm chart with better practices
|
||||
|
||||
**🐞 Bug Fixes**
|
||||
|
||||
- Fixed redis cluster failover bug
|
||||
|
||||
### v0.1.0
|
||||
**February 21, 2020**
|
||||
|
||||
**🎉 Features**
|
||||
|
||||
- Cluster/Standalone redis setup
|
||||
- Password and password-less setup
|
||||
- Node selector and affinity
|
||||
- SecurityContext
|
||||
- Priority Class
|
||||
- Monitoring support
|
||||
- PVC and resources support
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
---
|
||||
|
||||
title: "Redis Operator"
|
||||
|
||||
linkTitle: Documentation
|
||||
|
||||
weight: 20
|
||||
|
||||
menu:
|
||||
main:
|
||||
weight: 20
|
||||
|
||||
date: 2022-11-02T00:19:19Z
|
||||
|
||||
description: >
|
||||
Documentation and usage guides on how to deploy redis operator on top of Kubernetes.
|
||||
|
||||
---
|
||||
Release version: {{< release-version >}}
|
||||
|
||||
These pages show you how to get up and running as quickly as possible in Agones.
|
||||
|
||||
If you are new to Redis Operator, start with [Overview]({{< relref "./Overview/_index.md" >}}) to get familiar with its
|
||||
features and services.
|
||||
|
||||
The [Installation]({{< relref "./Installation/_index.md" >}}) guide will take you through creating a Kubernetes
|
||||
cluster and getting Redis Operator installed.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Search Results
|
||||
layout: search
|
||||
|
||||
---
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Go Vanity URLs, original code: https://github.com/GoogleCloudPlatform/govanityurls
|
||||
Background image: https://www.google.com.au/about/datacenters/gallery/index.html#/all/68
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Copyright 2019 Google LLC All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
set -ex
|
||||
|
||||
#Reinstall Go 1.15 since the version upon it won't work with gen-crd-api-reference-docs
|
||||
rm -rf /usr/local/go
|
||||
GO_VERSION=1.15.13
|
||||
cd /usr/local
|
||||
wget -q https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz && \
|
||||
tar -xzf go${GO_VERSION}.linux-amd64.tar.gz && rm go${GO_VERSION}.linux-amd64.tar.gz
|
||||
|
||||
export GOPROXY=http://proxy.golang.org
|
||||
echo "using go proxy as a workaround for git.agache.org being down: $GOPROXY"
|
||||
|
||||
cd /go/src/github.com/ahmetb/gen-crd-api-reference-docs
|
||||
|
||||
#Use local version of agones
|
||||
go mod edit --replace=agones.dev/agones@latest=../../../agones.dev/agones/
|
||||
go build
|
||||
|
||||
cp /go/src/agones.dev/agones/site/assets/templates/pkg.tpl ./template
|
||||
|
||||
FILE=${FILE:-/go/src/agones.dev/agones/site/content/en/docs/Reference/agones_crd_api_reference.html}
|
||||
VERSION=${VERSION:-"0.9.0"}
|
||||
|
||||
# +++ Title section
|
||||
TITLE="/tmp/title.html"
|
||||
# Current ExpiryVersion
|
||||
EXPIRY_DOC="/tmp/expiry.html"
|
||||
# Previous Publish Version after release
|
||||
PUBLISH_DOC="/tmp/publish.html"
|
||||
# Output of the gen-crd-api-reference-docs
|
||||
RESULT="/tmp/agones_crd_api_reference.html"
|
||||
# Version to compare
|
||||
OLD="/tmp/old_docs.html"
|
||||
|
||||
./gen-crd-api-reference-docs --config ../../../agones.dev/agones/site/assets/templates/crd-doc-config.json --api-dir ../../../agones.dev/agones/pkg/apis/ --out-file $RESULT
|
||||
awk '/\ feature\ publishVersion/{flag=1;next}/\ \/feature/{flag=0}flag' $FILE > $OLD
|
||||
|
||||
# Get the title lines from +++ till empty string
|
||||
awk '/\+\+\+/ {ok=1} /^$/ {ok=0} {if(ok){print $0}}' $FILE > $TITLE
|
||||
printf "\n" >> $TITLE
|
||||
|
||||
doc_version=$(grep 'feature publishVersion=' $FILE )
|
||||
echo $doc_version
|
||||
publish='{{% feature publishVersion="'$VERSION'" %}}'
|
||||
expiry='{{% feature expiryVersion="'$VERSION'" %}}'
|
||||
|
||||
#Get previous expiry version tag
|
||||
sed '/\ expiryVersion="'$VERSION'"/,/%\ \/feature/!d;/%\ \/feature/q' $FILE > $EXPIRY_DOC
|
||||
sed '/\ publishVersion=/,/%\ \/feature/!d;/%\ \/feature/q' $FILE > $PUBLISH_DOC
|
||||
|
||||
function sedeasy {
|
||||
sed -i "s/$(echo $1 | sed -e 's/\([[\/.*]\|\]\)/\\&/g')/$(echo $2 | sed -e 's/[\/&]/\\&/g')/g" $3
|
||||
}
|
||||
|
||||
# do we have changes in generated API docs compared to previous version
|
||||
if ! diff <(sort $RESULT) <(sort $OLD);
|
||||
then
|
||||
echo "Output to a file $FILE"
|
||||
|
||||
if [ "$publish" != "$doc_version" ]
|
||||
then
|
||||
echo "Tagging old publishVersion section with expiryVersion shortcode"
|
||||
|
||||
sedeasy "$doc_version" "$expiry" $PUBLISH_DOC
|
||||
cat $PUBLISH_DOC >> $TITLE
|
||||
else
|
||||
echo "expiry version left unchanged"
|
||||
cat $EXPIRY_DOC >> $TITLE
|
||||
fi
|
||||
cat $TITLE > $FILE
|
||||
echo -e '{{% feature publishVersion="'$VERSION'" %}}' >> $FILE
|
||||
cat $RESULT >> $FILE
|
||||
echo -e '{{% /feature %}}\n' >> $FILE
|
||||
fi
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module github.com/agones/agones/site
|
||||
|
||||
go 1.19
|
||||
|
||||
require gopkg.in/yaml.v2 v2.2.8
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
// Copyright 2017 Google LLC All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// govanityurls serves Go vanity URLs.
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
type handler struct {
|
||||
host string
|
||||
cacheControl string
|
||||
paths pathConfigSet
|
||||
}
|
||||
|
||||
type pathConfig struct {
|
||||
path string
|
||||
repo string
|
||||
display string
|
||||
vcs string
|
||||
}
|
||||
|
||||
func newHandler(config []byte) (*handler, error) {
|
||||
var parsed struct {
|
||||
Host string `yaml:"host,omitempty"`
|
||||
CacheAge *int64 `yaml:"cache_max_age,omitempty"`
|
||||
Paths map[string]struct {
|
||||
Repo string `yaml:"repo,omitempty"`
|
||||
Display string `yaml:"display,omitempty"`
|
||||
VCS string `yaml:"vcs,omitempty"`
|
||||
} `yaml:"paths,omitempty"`
|
||||
}
|
||||
if err := yaml.Unmarshal(config, &parsed); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h := &handler{host: parsed.Host}
|
||||
cacheAge := int64(86400) // 24 hours (in seconds)
|
||||
if parsed.CacheAge != nil {
|
||||
cacheAge = *parsed.CacheAge
|
||||
if cacheAge < 0 {
|
||||
return nil, errors.New("cache_max_age is negative")
|
||||
}
|
||||
}
|
||||
h.cacheControl = fmt.Sprintf("public, max-age=%d", cacheAge)
|
||||
for path, e := range parsed.Paths {
|
||||
pc := pathConfig{
|
||||
path: strings.TrimSuffix(path, "/"),
|
||||
repo: e.Repo,
|
||||
display: e.Display,
|
||||
vcs: e.VCS,
|
||||
}
|
||||
switch {
|
||||
case e.Display != "":
|
||||
// Already filled in.
|
||||
case strings.HasPrefix(e.Repo, "https://github.com/"):
|
||||
pc.display = fmt.Sprintf("%v %v/tree/main{/dir} %v/blob/main{/dir}/{file}#L{line}", e.Repo, e.Repo, e.Repo)
|
||||
case strings.HasPrefix(e.Repo, "https://bitbucket.org"):
|
||||
pc.display = fmt.Sprintf("%v %v/src/default{/dir} %v/src/default{/dir}/{file}#{file}-{line}", e.Repo, e.Repo, e.Repo)
|
||||
}
|
||||
switch {
|
||||
case e.VCS != "":
|
||||
// Already filled in.
|
||||
if e.VCS != "bzr" && e.VCS != "git" && e.VCS != "hg" && e.VCS != "svn" {
|
||||
return nil, fmt.Errorf("configuration for %v: unknown VCS %s", path, e.VCS)
|
||||
}
|
||||
case strings.HasPrefix(e.Repo, "https://github.com/"):
|
||||
pc.vcs = "git"
|
||||
default:
|
||||
return nil, fmt.Errorf("configuration for %v: cannot infer VCS from %s", path, e.Repo)
|
||||
}
|
||||
h.paths = append(h.paths, pc)
|
||||
}
|
||||
sort.Sort(h.paths)
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
current := r.URL.Path
|
||||
pc, subpath := h.paths.find(current)
|
||||
if pc == nil && current == "/" {
|
||||
h.serveIndex(w, r)
|
||||
return
|
||||
}
|
||||
if pc == nil && strings.Contains(current, "/chart/stable") {
|
||||
path := strings.Replace(current, "/chart/stable", "", 1)
|
||||
h.serveChart(w, r, path)
|
||||
return
|
||||
}
|
||||
if pc == nil {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Cache-Control", h.cacheControl)
|
||||
if err := vanityTmpl.Execute(w, struct {
|
||||
Import string
|
||||
Subpath string
|
||||
Repo string
|
||||
Display string
|
||||
VCS string
|
||||
}{
|
||||
Import: h.Host(r) + pc.path,
|
||||
Subpath: subpath,
|
||||
Repo: pc.repo,
|
||||
Display: pc.display,
|
||||
VCS: pc.vcs,
|
||||
}); err != nil {
|
||||
http.Error(w, "cannot render the page", http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *handler) serveIndex(w http.ResponseWriter, r *http.Request) {
|
||||
// Just redirect to the first one
|
||||
// just commenting out, in case we want to soft launch
|
||||
// http.Redirect(w, r, h.paths[0].repo, http.StatusTemporaryRedirect)
|
||||
http.Redirect(w, r, "/site/", http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func (h *handler) serveChart(w http.ResponseWriter, r *http.Request, path string) {
|
||||
root := "https://storage.googleapis.com/agones-chart"
|
||||
http.Redirect(w, r, root+path, http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func (h *handler) Host(r *http.Request) string {
|
||||
host := h.host
|
||||
if host == "" {
|
||||
host = defaultHost(r)
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
var vanityTmpl = template.Must(template.New("vanity").Parse(`<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<meta name="go-import" content="{{.Import}} {{.VCS}} {{.Repo}}">
|
||||
<meta name="go-source" content="{{.Import}} {{.Display}}">
|
||||
<meta http-equiv="refresh" content="0; url=https://godoc.org/{{.Import}}/{{.Subpath}}">
|
||||
</head>
|
||||
<body>
|
||||
Nothing to see here; <a href="https://godoc.org/{{.Import}}/{{.Subpath}}">see the package on godoc</a>.
|
||||
</body>
|
||||
</html>`))
|
||||
|
||||
type pathConfigSet []pathConfig
|
||||
|
||||
func (pset pathConfigSet) Len() int {
|
||||
return len(pset)
|
||||
}
|
||||
|
||||
func (pset pathConfigSet) Less(i, j int) bool {
|
||||
return pset[i].path < pset[j].path
|
||||
}
|
||||
|
||||
func (pset pathConfigSet) Swap(i, j int) {
|
||||
pset[i], pset[j] = pset[j], pset[i]
|
||||
}
|
||||
|
||||
func (pset pathConfigSet) find(path string) (pc *pathConfig, subpath string) {
|
||||
i := sort.Search(len(pset), func(i int) bool {
|
||||
return pset[i].path >= path
|
||||
})
|
||||
if i < len(pset) && pset[i].path == path {
|
||||
return &pset[i], ""
|
||||
}
|
||||
if i > 0 && strings.HasPrefix(path, pset[i-1].path+"/") {
|
||||
return &pset[i-1], path[len(pset[i-1].path)+1:]
|
||||
}
|
||||
return nil, ""
|
||||
}
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
// Copyright 2017 Google LLC All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"sort"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHandler(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config string
|
||||
path string
|
||||
|
||||
goImport string
|
||||
goSource string
|
||||
}{
|
||||
{
|
||||
name: "explicit display",
|
||||
config: "host: example.com\n" +
|
||||
"paths:\n" +
|
||||
" /portmidi:\n" +
|
||||
" repo: https://github.com/rakyll/portmidi\n" +
|
||||
" display: https://github.com/rakyll/portmidi _ _\n",
|
||||
path: "/portmidi",
|
||||
goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
|
||||
goSource: "example.com/portmidi https://github.com/rakyll/portmidi _ _",
|
||||
},
|
||||
{
|
||||
name: "display GitHub inference",
|
||||
config: "host: example.com\n" +
|
||||
"paths:\n" +
|
||||
" /portmidi:\n" +
|
||||
" repo: https://github.com/rakyll/portmidi\n",
|
||||
path: "/portmidi",
|
||||
goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
|
||||
goSource: "example.com/portmidi https://github.com/rakyll/portmidi https://github.com/rakyll/portmidi/tree/main{/dir} https://github.com/rakyll/portmidi/blob/main{/dir}/{file}#L{line}",
|
||||
},
|
||||
{
|
||||
name: "Bitbucket Mercurial",
|
||||
config: "host: example.com\n" +
|
||||
"paths:\n" +
|
||||
" /gopdf:\n" +
|
||||
" repo: https://bitbucket.org/zombiezen/gopdf\n" +
|
||||
" vcs: hg\n",
|
||||
path: "/gopdf",
|
||||
goImport: "example.com/gopdf hg https://bitbucket.org/zombiezen/gopdf",
|
||||
goSource: "example.com/gopdf https://bitbucket.org/zombiezen/gopdf https://bitbucket.org/zombiezen/gopdf/src/default{/dir} https://bitbucket.org/zombiezen/gopdf/src/default{/dir}/{file}#{file}-{line}",
|
||||
},
|
||||
{
|
||||
name: "Bitbucket Git",
|
||||
config: "host: example.com\n" +
|
||||
"paths:\n" +
|
||||
" /mygit:\n" +
|
||||
" repo: https://bitbucket.org/zombiezen/mygit\n" +
|
||||
" vcs: git\n",
|
||||
path: "/mygit",
|
||||
goImport: "example.com/mygit git https://bitbucket.org/zombiezen/mygit",
|
||||
goSource: "example.com/mygit https://bitbucket.org/zombiezen/mygit https://bitbucket.org/zombiezen/mygit/src/default{/dir} https://bitbucket.org/zombiezen/mygit/src/default{/dir}/{file}#{file}-{line}",
|
||||
},
|
||||
{
|
||||
name: "subpath",
|
||||
config: "host: example.com\n" +
|
||||
"paths:\n" +
|
||||
" /portmidi:\n" +
|
||||
" repo: https://github.com/rakyll/portmidi\n" +
|
||||
" display: https://github.com/rakyll/portmidi _ _\n",
|
||||
path: "/portmidi/foo",
|
||||
goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
|
||||
goSource: "example.com/portmidi https://github.com/rakyll/portmidi _ _",
|
||||
},
|
||||
{
|
||||
name: "subpath with trailing config slash",
|
||||
config: "host: example.com\n" +
|
||||
"paths:\n" +
|
||||
" /portmidi/:\n" +
|
||||
" repo: https://github.com/rakyll/portmidi\n" +
|
||||
" display: https://github.com/rakyll/portmidi _ _\n",
|
||||
path: "/portmidi/foo",
|
||||
goImport: "example.com/portmidi git https://github.com/rakyll/portmidi",
|
||||
goSource: "example.com/portmidi https://github.com/rakyll/portmidi _ _",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
h, err := newHandler([]byte(test.config))
|
||||
if err != nil {
|
||||
t.Errorf("%s: newHandler: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
s := httptest.NewServer(h)
|
||||
resp, err := http.Get(s.URL + test.path)
|
||||
if err != nil {
|
||||
s.Close()
|
||||
t.Errorf("%s: http.Get: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
data, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Errorf("Could not read all: %s", err)
|
||||
continue
|
||||
}
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
t.Errorf("Could not close body: %s", err)
|
||||
continue
|
||||
}
|
||||
s.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("%s: status code = %s; want 200 OK", test.name, resp.Status)
|
||||
}
|
||||
if got := findMeta(data, "go-import"); got != test.goImport {
|
||||
t.Errorf("%s: meta go-import = %q; want %q", test.name, got, test.goImport)
|
||||
}
|
||||
if got := findMeta(data, "go-source"); got != test.goSource {
|
||||
t.Errorf("%s: meta go-source = %q; want %q", test.name, got, test.goSource)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadConfigs(t *testing.T) {
|
||||
badConfigs := []string{
|
||||
"paths:\n" +
|
||||
" /missingvcs:\n" +
|
||||
" repo: https://bitbucket.org/zombiezen/gopdf\n",
|
||||
"paths:\n" +
|
||||
" /unknownvcs:\n" +
|
||||
" repo: https://bitbucket.org/zombiezen/gopdf\n" +
|
||||
" vcs: xyzzy\n",
|
||||
"cache_max_age: -1\n" +
|
||||
"paths:\n" +
|
||||
" /portmidi:\n" +
|
||||
" repo: https://github.com/rakyll/portmidi\n",
|
||||
}
|
||||
for _, config := range badConfigs {
|
||||
_, err := newHandler([]byte(config))
|
||||
if err == nil {
|
||||
t.Errorf("expected config to produce an error, but did not:\n%s", config)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func findMeta(data []byte, name string) string {
|
||||
var sep []byte
|
||||
sep = append(sep, `<meta name="`...)
|
||||
sep = append(sep, name...)
|
||||
sep = append(sep, `" content="`...)
|
||||
i := bytes.Index(data, sep)
|
||||
if i == -1 {
|
||||
return ""
|
||||
}
|
||||
content := data[i+len(sep):]
|
||||
j := bytes.IndexByte(content, '"')
|
||||
if j == -1 {
|
||||
return ""
|
||||
}
|
||||
return string(content[:j])
|
||||
}
|
||||
|
||||
func TestPathConfigSetFind(t *testing.T) {
|
||||
tests := []struct {
|
||||
paths []string
|
||||
query string
|
||||
want string
|
||||
subpath string
|
||||
}{
|
||||
{
|
||||
paths: []string{"/portmidi"},
|
||||
query: "/portmidi",
|
||||
want: "/portmidi",
|
||||
},
|
||||
{
|
||||
paths: []string{"/portmidi"},
|
||||
query: "/portmidi/",
|
||||
want: "/portmidi",
|
||||
},
|
||||
{
|
||||
paths: []string{"/portmidi"},
|
||||
query: "/foo",
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
paths: []string{"/portmidi"},
|
||||
query: "/zzz",
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
paths: []string{"/abc", "/portmidi", "/xyz"},
|
||||
query: "/portmidi",
|
||||
want: "/portmidi",
|
||||
},
|
||||
{
|
||||
paths: []string{"/abc", "/portmidi", "/xyz"},
|
||||
query: "/portmidi/foo",
|
||||
want: "/portmidi",
|
||||
subpath: "foo",
|
||||
},
|
||||
}
|
||||
emptyToNil := func(s string) string {
|
||||
if s == "" {
|
||||
return "<nil>"
|
||||
}
|
||||
return s
|
||||
}
|
||||
for _, test := range tests {
|
||||
pset := make(pathConfigSet, len(test.paths))
|
||||
for i := range test.paths {
|
||||
pset[i].path = test.paths[i]
|
||||
}
|
||||
sort.Sort(pset)
|
||||
pc, subpath := pset.find(test.query)
|
||||
var got string
|
||||
if pc != nil {
|
||||
got = pc.path
|
||||
}
|
||||
if got != test.want || subpath != test.subpath {
|
||||
t.Errorf("pathConfigSet(%v).find(%q) = %v, %v; want %v, %v",
|
||||
test.paths, test.query, emptyToNil(got), subpath, emptyToNil(test.want), test.subpath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCacheHeader(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config string
|
||||
cacheControl string
|
||||
}{
|
||||
{
|
||||
name: "default",
|
||||
cacheControl: "public, max-age=86400",
|
||||
},
|
||||
{
|
||||
name: "specify time",
|
||||
config: "cache_max_age: 60\n",
|
||||
cacheControl: "public, max-age=60",
|
||||
},
|
||||
{
|
||||
name: "zero",
|
||||
config: "cache_max_age: 0\n",
|
||||
cacheControl: "public, max-age=0",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
h, err := newHandler([]byte("paths:\n /portmidi:\n repo: https://github.com/rakyll/portmidi\n" +
|
||||
test.config))
|
||||
if err != nil {
|
||||
t.Errorf("%s: newHandler: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
s := httptest.NewServer(h)
|
||||
resp, err := http.Get(s.URL + "/portmidi")
|
||||
if err != nil {
|
||||
t.Errorf("%s: http.Get: %v", test.name, err)
|
||||
continue
|
||||
}
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
t.Errorf("could not close the body: %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
got := resp.Header.Get("Cache-Control")
|
||||
if got != test.cacheControl {
|
||||
t.Errorf("%s: Cache-Control header = %q; want %q", test.name, got, test.cacheControl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2019 Google LLC All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
TestFilesConcurrently: false
|
||||
IgnoreInternalEmptyHash: true
|
||||
OutputDir: /go/src/agones.dev/agones/site/tmp
|
||||
OutputLogFile: .htmltest.log
|
||||
CheckExternal: true
|
||||
ExternalTimeout: 60
|
||||
IgnoreURLs:
|
||||
- http://localhost
|
||||
HTTPHeaders:
|
||||
User-Agent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36"
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
{{ $links := .Site.Params.links }}
|
||||
|
||||
<section id="community" class="row td-box td-box--2 td-box--gradient td-box--height-auto">
|
||||
<div class="col-sm-12 col-md-6 p-5">
|
||||
<h2>Learn and Connect</h2>
|
||||
<p>Using or want to use {{ .Site.Title }}? Find out more here:
|
||||
{{ with index $links "user"}}
|
||||
{{ template "community-links-list" . }}
|
||||
{{ end }}
|
||||
</div>
|
||||
<div class=" col-sm-12 col-md-6 p-5">
|
||||
<h2>Develop and Contribute</h2>
|
||||
<p>If you want to get more involved by contributing to {{ .Site.Title }}, join us here:
|
||||
{{ with index $links "developer"}}
|
||||
{{ template "community-links-list" . }}
|
||||
{{ end }}
|
||||
<p>You can find out how to contribute to these docs in our <a href="{{ "/docs/contribute/" | relURL}}">Contribution Guidelines</a>.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ define "community-links-list" }}
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li title="{{ .name }}">
|
||||
<a target="_blank" href="{{ .url }}"><i class="{{ .icon }}"></i> {{ .name }}:</a> {{ .desc | safeHTML }}
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
<!-- Favicons as generated by http://cthedot.de/icongen -->
|
||||
<link rel="shortcut icon" href="{{ "favicons/favicon.ico?v=1" | relURL }}" >
|
||||
<link rel="apple-touch-icon" href="{{ "favicons/favicon.ico?v=1" | relURL }}" sizes="180x180">
|
||||
<link rel="icon" type="image/png" href="{{ "favicons/favicon.ico?v=1" | relURL }}" sizes="16x16">
|
||||
<link rel="icon" type="image/png" href="{{ "favicons/favicon.ico?v=1" | relURL }}" sizes="32x32">
|
||||
<link rel="apple-touch-icon" href="{{ "favicons/favicon.ico?v=1" | relURL }}" sizes="180x180">
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
{{ hugo.Generator }}
|
||||
{{ if eq (getenv "HUGO_ENV") "production" }}
|
||||
<META NAME="ROBOTS" CONTENT="INDEX, FOLLOW">
|
||||
{{ else }}
|
||||
<META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
|
||||
{{ end }}
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
||||
{{ end -}}
|
||||
{{ partialCached "favicons.html" . }}
|
||||
<title>{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ with .Title }}{{ . }} | {{ end }}{{ .Site.Title }}{{ end }}</title>
|
||||
{{- template "_internal/opengraph.html" . -}}
|
||||
{{- template "_internal/google_news.html" . -}}
|
||||
{{- template "_internal/schema.html" . -}}
|
||||
{{- template "_internal/twitter_cards.html" . -}}
|
||||
{{ if eq (getenv "HUGO_ENV") "production" }}
|
||||
{{ template "_internal/google_analytics_async.html" . }}
|
||||
{{ end }}
|
||||
{{ if .Site.Params.prism_syntax_highlighting }}
|
||||
<!-- stylesheet for Prism -->
|
||||
<link rel="stylesheet" href="{{ "/css/prism.css" | relURL }}"/>
|
||||
{{ end }}
|
||||
{{ partialCached "head-css.html" . "asdf" }}
|
||||
<link rel="stylesheet" type="text/css" href={{ "css/asciinema-player.css" | absURL }} />
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.3.1.min.js"
|
||||
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
|
||||
crossorigin="anonymous"></script>
|
||||
{{ partial "hooks/head-end.html" . }}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<script src={{ "js/asciinema-player.js" | absURL }}></script>
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{{ $cover := .HasShortcode "blocks/cover" }}
|
||||
<nav class="js-navbar-scroll navbar navbar-expand navbar-light {{ if not $cover }} nav-shadow {{ end }}flex-column flex-md-row td-navbar">
|
||||
|
||||
<a id="agones-top" {{ if $cover }} style="display: none;" {{end}} class="navbar-brand" href="{{ .Site.Home.RelPermalink }}">
|
||||
{{ with resources.Get "icons/logo.svg" }}{{ ( . | minify).Content | safeHTML }} {{ end }}<span class="text-uppercase font-weight-bold">{{ .Site.Title }}</span>
|
||||
</a>
|
||||
|
||||
<div class="td-navbar-nav-scroll ml-md-auto" id="main_navbar">
|
||||
<ul class="navbar-nav mt-2 mt-lg-0">
|
||||
{{ $p := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
<li class="nav-item mr-4 mb-2 mb-lg-0">
|
||||
{{ $active := or ($p.IsMenuCurrent "main" .) ($p.HasMenuCurrent "main" .) }}
|
||||
{{ with .Page }}
|
||||
{{ $active = or $active ( $.IsDescendant .) }}
|
||||
{{ end }}
|
||||
<a class="nav-link{{if $active }} active{{end}}" href="{{ with .Page }}{{ .RelPermalink }}{{ else }}{{ .URL | relLangURL }}{{ end }}"><span{{if $active }} class="active"{{end}}>{{ .Name }}</span></a>
|
||||
</li>
|
||||
{{ end }}
|
||||
<li class="nav-item mr-4 mb-2 mb-lg-0">
|
||||
<a class="nav-link" href="{{ .Site.Params.github_repo }}">GitHub</a>
|
||||
</li>
|
||||
{{ if (gt (len .Site.Home.Translations) 0) }}
|
||||
<li class="nav-item dropdown d-none d-lg-block">
|
||||
{{ partial "navbar-lang-selector.html" . }}
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-nav mx-lg-2 d-none d-lg-block">{{ partial "search-input.html" . }}</div>
|
||||
</nav>
|
||||
|
|
@ -0,0 +1 @@
|
|||
{{ T "post_last_mod"}} {{ .Lastmod.Format .Site.Params.time_format_default }}{{ with .GitInfo }}: <a data-proofer-ignore href="{{ $.Site.Params.github_repo }}/commit/{{ .Hash }}">{{ .Subject }} ({{ .AbbreviatedHash }})</a>{{end }}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{{ if .Path }}
|
||||
{{ $gh_repo := ($.Param "github_repo") }}
|
||||
{{ if $gh_repo }}
|
||||
<div class="td-page-meta ml-2 pb-1 pt-2 mb-0">
|
||||
{{ $editURL := printf "%s/edit/main/site/content/%s/%s" $gh_repo ($.Site.Language.Lang) .Path }}
|
||||
{{ $issuesURL := printf "%s/issues/new?title=%s" $gh_repo (htmlEscape $.Title )}}
|
||||
<a href="{{ $editURL }}" data-proofer-ignore target="_blank"><i class="fa fa-edit fa-fw"></i> {{ T "post_edit_this" }}</a>
|
||||
<a href="{{ $issuesURL }}" target="_blank"><i class="fab fa-github fa-fw"></i> {{ T "post_create_issue" }}</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{{ $pag := $.Paginator }}
|
||||
{{ if gt $pag.TotalPages 1 }}
|
||||
<ul class="pagination">
|
||||
{{ with $pag.First }}
|
||||
<li class="page-item">
|
||||
<a href="{{ .URL }}" class="page-link" aria-label="First"><span aria-hidden="true">««</span></a>
|
||||
</li>
|
||||
{{ end }}
|
||||
<li class="page-item{{ if not $pag.HasPrev }} disabled{{ end }}">
|
||||
<a {{ if $pag.HasPrev }}href="{{ $pag.Prev.URL }}"{{ end }} class="page-link" aria-label="Previous"><span aria-hidden="true">«</span></a>
|
||||
</li>
|
||||
{{ $ellipsed := false }}
|
||||
{{ $shouldEllipse := false }}
|
||||
{{ range $pag.Pagers }}
|
||||
{{ $right := sub .TotalPages .PageNumber }}
|
||||
{{ $showNumber := or (le .PageNumber 3) (eq $right 0) }}
|
||||
{{ $showNumber := or $showNumber (and (gt .PageNumber (sub $pag.PageNumber 2)) (lt .PageNumber (add $pag.PageNumber 2))) }}
|
||||
{{ if $showNumber }}
|
||||
{{ $ellipsed = false }}
|
||||
{{ $shouldEllipse = false }}
|
||||
{{ else }}
|
||||
{{ $shouldEllipse = not $ellipsed }}
|
||||
{{ $ellipsed = true }}
|
||||
{{ end }}
|
||||
{{ if $showNumber }}
|
||||
<li class="page-item{{ if eq . $pag }} active{{ end }}"><a class="page-link" href="{{ .URL }}">{{ .PageNumber }}</a></li>
|
||||
{{ else if $shouldEllipse }}
|
||||
<li class="page-item disabled"><span aria-hidden="true"> … </span></li>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<li class="page-item{{ if not $pag.HasNext }} disabled{{ end }}">
|
||||
<a {{ if $pag.HasNext }}href="{{ $pag.Next.URL }}"{{ end }} class="page-link" aria-label="Next"><span aria-hidden="true">»</span></a>
|
||||
</li>
|
||||
{{ with $pag.Last }}
|
||||
<li class="page-item">
|
||||
<a href="{{ .URL }}" class="page-link" aria-label="Last"><span aria-hidden="true">»»</span></a>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{{ with .Site.Params.gcs_engine_id }}
|
||||
<input id="agones-search" type="search" class="form-control td-search-input" placeholder=" {{ T "ui_search" }}" aria-label="{{ T "ui_search" }}" autocomplete="off">
|
||||
{{ end }}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{{- if eq (getenv "HUGO_ENV") "production" }}
|
||||
{{- $.Page.Site.Params.aks_minor_supported_k8s }}
|
||||
{{- else }}
|
||||
{{- $.Page.Site.Params.dev_aks_minor_supported_k8s }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
{{- $gate := split (.Get "gate") "," }}
|
||||
{{- $len_gate := len $gate }}
|
||||
{{- $title := .Get "title" }}
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<h4 class="alert-heading">Warning</h4>
|
||||
<p>The {{ $title }} {{- if gt $len_gate 1 }} features are{{ else }} feature is{{ end }} currently <strong><a href="{{ ref . "/docs/Guides/feature-stages.md#alpha" }}">Alpha</a></strong>,
|
||||
not enabled by default, and may change in the future.</p>
|
||||
<p>Use the Feature {{- if gt $len_gate 1 }}Gates{{- else}}Gate{{- end }} {{ range $index, $value := first (sub $len_gate 1) $gate }} <code>{{- $value }}</code>, {{ end }}{{ if gt $len_gate 1 }}and{{ end }}{{ range (last 1 $gate) }} <code>{{ . }}</code>{{ end }}
|
||||
to enable and test {{ if gt $len_gate 1 }}these features{{else}}this feature{{ end }}.</p>
|
||||
<p>See the <a href="{{ ref . "/docs/Guides/feature-stages.md#feature-gates" }}">Feature Gate documentation</a> for details on how to enable features.</p>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{{- $gate := .Get "gate" }}
|
||||
{{- $title := .Get "title" }}
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<h4 class="alert-heading">Warning</h4>
|
||||
<p>The {{ $title }} feature is currently <strong><a href="{{ ref . "/docs/Guides/feature-stages.md#beta" }}">Beta</a></strong>,
|
||||
and while it is enabled by default it may change in the future.</p>
|
||||
<p>Use the Feature Gate <code>{{- $gate }}</code> to disable this feature.</p>
|
||||
<p>See the <a href="{{ ref . "/docs/Guides/feature-stages.md#feature-gates" }}">Feature Gate documentation</a> for details on how to disable features.</p>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{{ $col_id := .Get "color" | default "dark" }}
|
||||
{{/* Height can be one of: auto, min, med, max, full. */}}
|
||||
{{ $height := .Get "height" | default "max" }}
|
||||
<section class="row td-cover-block td-cover-block--height-{{ $height }} js-td-cover td-overlay td-overlay--light -bg-{{ $col_id }}">
|
||||
<div class="container td-overlay__inner">
|
||||
<div class="row align-items-end">
|
||||
<div class="col-lg-6">
|
||||
<h1 class="display-1 mt-0 pb-3">
|
||||
<img alt="agones" width="98" src="images/logo.svg" />
|
||||
Redis Operator
|
||||
</h1>
|
||||
<p class="display-2 mb-0">Host, Run and Scale Redis cluster on Kubernetes</p>
|
||||
</div>
|
||||
<div class="col-lg-6 mt-5 mt-lg-3 d-sm-block" style="display: none">
|
||||
<asciinema-player
|
||||
loop autoplay font-size="12px" rows=12 cols=75
|
||||
src="redis-operator.cast"></asciinema-player>
|
||||
</div>
|
||||
<div class="col-12 pt-3">
|
||||
<div class="pt-3 lead text-center">
|
||||
{{ .Inner }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
|
@ -0,0 +1 @@
|
|||
{{- $.Page.Site.Params.example_image_tag }}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
{{- $version := getenv "RELEASE_VERSION" | default $.Page.Site.Params.release_version }}
|
||||
{{- with or (.Get "publishVersion") (.Get "expiryVersion")}}
|
||||
{{- else }}
|
||||
{{ errorf "missing value for either publishVersion or expiryVersion: %s" .Position}}
|
||||
{{- end}}
|
||||
{{- $publishVersion := (.Get "publishVersion" ) | default "0.0.0" }}
|
||||
{{- $expiryVersion := (.Get "expiryVersion") | default "9999.0.0"}}
|
||||
{{- $publDigits := split $publishVersion "." }}
|
||||
{{- $curDigits := split $version "." }}
|
||||
{{- $expDigits := split $expiryVersion "." }}
|
||||
{{- $multiplier := 10000 }}
|
||||
{{- $current := 0}}
|
||||
{{- $publish := 0}}
|
||||
{{- $expire := 0}}
|
||||
{{- $index := 0}}
|
||||
|
||||
{{- /*Generate initial shift for most significant number*/}}
|
||||
{{- $shift := 1 }}
|
||||
{{- range $curDigits}}
|
||||
{{- $shift = mul $shift $multiplier }}
|
||||
{{- end}}
|
||||
{{- $shift = div $shift $multiplier }}
|
||||
|
||||
{{- /* loop three times */}}
|
||||
{{- range $curDigits}}
|
||||
{{- /* Get integer from dot separated string at index */}}
|
||||
{{- $c := int (index $curDigits $index)}}
|
||||
{{- $p := int (index $publDigits $index)}}
|
||||
{{- $e := int (index $expDigits $index)}}
|
||||
{{- /* current += digit * shift */}}
|
||||
{{- $current = (add $current (mul $c $shift ))}}
|
||||
{{- $publish = (add $publish (mul $p $shift ))}}
|
||||
{{- $expire = (add $expire (mul $e $shift ))}}
|
||||
{{- $shift = (div $shift $multiplier)}}
|
||||
|
||||
{{- $index = (add $index 1) }}
|
||||
{{- end}}
|
||||
{{- if and (ge $current $publish) (lt $current $expire) }}
|
||||
{{.Inner}}
|
||||
{{- end}}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{{- $branch := .Get "branch" | default (getenv "RELEASE_BRANCH") | default $.Page.Site.Params.release_branch }}
|
||||
{{- $test := eq (.Get "link_test") "true" | default true }}
|
||||
<a href="{{$.Page.Site.Params.github_repo}}/blob/{{ $branch }}/{{.Get "href"}}" target="_blank" {{if not $test}}data-proofer-ignore{{end}}>{{.Inner}}</a>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{{- $version := .Get "version" | default (getenv "RELEASE_VERSION") | default $.Page.Site.Params.release_version }}
|
||||
{{- $test := eq (.Get "link_test") "true" | default true }}
|
||||
<a href="{{$.Page.Site.Params.github_repo}}/releases/download/v{{ $version }}/{{ .Get "file_prefix" }}-{{ $version }}.zip" {{if not $test}}data-proofer-ignore{{end}}>{{ .Get "file_prefix" }}-{{ $version }}.zip</a>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{{- $branch := .Get "branch" | default (getenv "RELEASE_BRANCH") | default $.Page.Site.Params.release_branch }}
|
||||
{{- $test := eq (.Get "link_test") "true" | default true }}
|
||||
<p>The following prerequisites are required to create a GameServer:</p>
|
||||
<ol>
|
||||
<li>A Kubernetes cluster with the UDP port range 7000-8000 open on each node.</li>
|
||||
<li>Agones controller installed in the targeted cluster</li>
|
||||
<li>kubectl properly configured</li>
|
||||
<li>Netcat which is already installed on most Linux/macOS distributions, for windows you can use <a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10">WSL</a>.</li>
|
||||
</ol>
|
||||
<p>If you don’t have a Kubernetes cluster you can follow <a href="/site/docs/installation/">these instructions</a> to create a cluster on Google Kubernetes Engine (GKE), Minikube or Azure Kubernetes Service (AKS), and install Agones.</p>
|
||||
<p>For the purpose of this guide we’re going to use the
|
||||
<a href="{{$.Page.Site.Params.github_repo}}/blob/{{ $branch }}/examples/simple-game-server/" target="_blank" {{if not $test}}data-proofer-ignore{{end}}>simple-game-server</a>
|
||||
example as the GameServer container. This example is a very simple UDP server written in Go. Don’t hesitate to look at the code of this example for more information.</p>
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
{{- $version := cond (eq (getenv "HUGO_ENV") "production") $.Page.Site.Params.supported_k8s $.Page.Site.Params.dev_supported_k8s }}
|
||||
{{- $prefix := replace $version "." "-" }}https://v{{- $prefix }}.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v{{- $version }}/{{- .Get "href" }}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{{- if eq (getenv "HUGO_ENV") "production" }}
|
||||
{{- $.Page.Site.Params.supported_k8s }}
|
||||
{{- else }}
|
||||
{{- $.Page.Site.Params.dev_supported_k8s }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{{- if eq (getenv "HUGO_ENV") "production" }}
|
||||
{{- $.Page.Site.Params.minikube_minor_supported_k8s }}
|
||||
{{- else }}
|
||||
{{- $.Page.Site.Params.dev_minikube_minor_supported_k8s }}
|
||||
{{- end }}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
{{- $branch := getenv "RELEASE_BRANCH" | default $.Page.Site.Params.release_branch }}
|
||||
{{- $branch }}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
{{- $version := getenv "RELEASE_VERSION" | default $.Page.Site.Params.release_version }}
|
||||
{{- $version }}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
<iframe width="640" height="360" class="p-2" src="https://www.youtube.com/embed/{{ .Get 0 }}"
|
||||
frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright 2017 Google LLC All Rights Reserved.
|
||||
//
|
||||
// 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.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
func main() {
|
||||
port := os.Getenv("PORT")
|
||||
if port == "" {
|
||||
port = "8080"
|
||||
log.Printf("Defaulting to port %s", port)
|
||||
}
|
||||
|
||||
var configPath string
|
||||
switch len(os.Args) {
|
||||
case 1:
|
||||
configPath = "vanity.yaml"
|
||||
case 2:
|
||||
configPath = os.Args[1]
|
||||
default:
|
||||
log.Fatal("usage: govanityurls [CONFIG]")
|
||||
}
|
||||
log.Printf("loading: %s", configPath)
|
||||
|
||||
vanity, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
h, err := newHandler(vanity)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
http.Handle("/", h)
|
||||
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
|
||||
}
|
||||
|
||||
func defaultHost(r *http.Request) string {
|
||||
return r.Host
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
[build]
|
||||
[build.environment]
|
||||
HUGO_VERSION = "0.88.1"
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"postcss-cli": "8.3.1",
|
||||
"postcss": "8.2.9",
|
||||
"autoprefixer": "10.2.5"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
@startuml
|
||||
'https://plantuml.com/sequence-diagram
|
||||
|
||||
actor "Player One" as Player1
|
||||
actor "Player Two" as Player2
|
||||
participant Matchmaker
|
||||
participant Agones
|
||||
participant "GameServer\nResource" as GameServer
|
||||
box "Game Server Pod"
|
||||
participant "Game Server\nProcess" as Binary
|
||||
participant SDK
|
||||
end box
|
||||
|
||||
activate GameServer
|
||||
|
||||
== No allocated <i>GameServers</i> ==
|
||||
|
||||
Player1 -> Matchmaker: Requests a game session
|
||||
Matchmaker -> Agones: Create: <i>GameServerAllocation</i>
|
||||
note left
|
||||
<i>GameServerAllocation</i> implemented to
|
||||
optionally select an already allocated <i>GameServer</i>
|
||||
if one exists. At this stage, one does not, so
|
||||
Agones will allocate a <i>Ready</i> <i>GameServer</i>.
|
||||
end note
|
||||
Agones -> GameServer: Finds a <i>Ready</i> <i>GameServer</i>,\nsets it to <i>Allocated</i> State
|
||||
Matchmaker <-- Agones : <i>GameServerAllocation</i> is returned\nwith <i>GameServer</i> details\nincluding IP and port to connect to.
|
||||
Player1 <-- Matchmaker : Returns <i>GameServer</i> connection information
|
||||
Player1 -> Binary : Connects to game server process
|
||||
Binary -> SDK : SDK.Alpha.PlayerConnect(id)
|
||||
note right
|
||||
Process calls <i>PlayerConnect(...)</i>
|
||||
on player client connection.
|
||||
end note
|
||||
GameServer <-- SDK : Increments <i>Status.Players.Count</i>\nand add <i>id</i> to <i>Status.Players.Ids</i>
|
||||
|
||||
== Allocated <i>GameServers</i> with player(s) on them ==
|
||||
|
||||
Player2 -> Matchmaker: Requests a game session
|
||||
Matchmaker -> Agones: Create: <i>GameServerAllocation</i>
|
||||
note left
|
||||
The <i>GameServerAllocation</i> will this time
|
||||
find the Allocated <i>GameServer</i> that "Player One"
|
||||
is currently active on.
|
||||
end note
|
||||
Agones -> GameServer: Finds the Allocated <i>GameServer</i>\nwith player capacity.
|
||||
note right
|
||||
This is the same <i>GameServer</i> that "Player One"
|
||||
is currently playing on.
|
||||
end note
|
||||
Matchmaker <-- Agones: returns <i>Allocated GameServer</i> record
|
||||
Player2 <-- Matchmaker : Returns <i>GameServer</i> connection information
|
||||
Player2 -> Binary : Connects to game server process
|
||||
Binary -> SDK : SDK.Alpha.PlayerConnect(id)
|
||||
GameServer <-- SDK : Increments <i>Status.Players.Count</i>\nand add <i>id</i> to <i>Status.Players.Ids</i>
|
||||
|
||||
@enduml
|
||||
|
After Width: | Height: | Size: 118 KiB |
|
|
@ -0,0 +1,35 @@
|
|||
@startuml
|
||||
'https://plantuml.com/sequence-diagram
|
||||
|
||||
participant Matchmaker
|
||||
participant Agones
|
||||
|
||||
participant "Canary Fleet\nResource" as CanaryFleet
|
||||
participant "Stable Fleet\nResource" as StableFleet
|
||||
|
||||
Matchmaker -> Agones: Create: <i>GameServerAllocation</i>
|
||||
note left
|
||||
<i>GameServerAllocation</i> is implemented to prefer
|
||||
allocating from the Canary <i>Fleet</i>, but if a Ready
|
||||
<i>GameServer</i> cannot be found in the Canary Fleet,
|
||||
to fall back to the Stable <i>Fleet</i>.
|
||||
end note
|
||||
|
||||
group GameServerAllocation
|
||||
else Check Canary Fleet first
|
||||
Agones -> CanaryFleet: Check if <i>GameServer<i> is available
|
||||
note right
|
||||
The Canary <i>Fleet</i> is
|
||||
usually a small, fixed size
|
||||
end note
|
||||
else None available in Canary Fleet
|
||||
Agones -> StableFleet: Check if <i>GameServer<i> is available
|
||||
note right
|
||||
When the Canary <i>Fleet</i> is fully allocated, the
|
||||
allocation falls over to the Stable <i>Fleet</i>.
|
||||
end note
|
||||
end group
|
||||
|
||||
Matchmaker <-- Agones: returns <i>Allocated GameServer</i> record
|
||||
|
||||
@enduml
|
||||
|
After Width: | Height: | Size: 45 KiB |
|
|
@ -0,0 +1,67 @@
|
|||
@startuml
|
||||
participant Matchmaker
|
||||
participant "Kubernetes API" as K8sAPI
|
||||
participant Agones
|
||||
participant "Game Server\nProcess" as Binary
|
||||
participant SDK
|
||||
participant "GameServer\nResource" as GameServer
|
||||
box "Game Server Pod"
|
||||
participant Binary
|
||||
participant SDK
|
||||
end box
|
||||
|
||||
== GameServer Start ==
|
||||
|
||||
Agones -> GameServer: GameServer created through\na <i>Fleet</i> configuration
|
||||
activate GameServer
|
||||
GameServer -> Binary: Agones creates a Pod with the\nconfigured Game Server Container
|
||||
activate Binary
|
||||
activate SDK
|
||||
Binary -> SDK: SDK.Health()
|
||||
note right
|
||||
<i>Health()</i> is a continuous
|
||||
ping that occurs under
|
||||
the configured threshold.
|
||||
end note
|
||||
GameServer <-- SDK: Maintains Healthy status
|
||||
Binary -> SDK: SDK.Ready()
|
||||
note right
|
||||
Call <i>Ready()</i> when the
|
||||
Game Server can take player
|
||||
connections and is able to
|
||||
be allocated.
|
||||
end note
|
||||
GameServer <-- SDK: Update to <i>Ready</i> State
|
||||
|
||||
== Matchmaker requesting GameServer ==
|
||||
|
||||
Matchmaker -> K8sAPI: Create: <i>GameServerAllocation</i>
|
||||
note left
|
||||
Allocation atomically provides
|
||||
a GameServer from a pool
|
||||
of existing GameServers
|
||||
(Usually a <i>Fleet</i>)
|
||||
end note
|
||||
K8sAPI -> Agones: Intercepts <i>GameServerAllocation</i>\nrequest
|
||||
"Agones" -> GameServer: Finds a Ready <i>GameServer</i>,\nsets it to <i>Allocated</i> State
|
||||
K8sAPI <-- Agones: returns <i>Allocated</i>\nGameServer record
|
||||
Matchmaker <-- K8sAPI : <i>GameServerAllocation</i> is returned\nwith <i>GameServer</i> details\nincluding IP and port to connect to.
|
||||
note left
|
||||
If no <i>GameServer</i> can be
|
||||
provided, <i>GameServerAllocation</i> is
|
||||
returned with a Status
|
||||
of <i>UnAllocated</i>
|
||||
end note
|
||||
|
||||
== Players Finish Game ==
|
||||
|
||||
Binary -> GameServer: SDK.Shutdown()
|
||||
note left
|
||||
Once gameplay is complete, call
|
||||
<i>Shutdown()</i> to delete the
|
||||
<i>GameServer</i> resource and backing Pod.
|
||||
end note
|
||||
destroy Binary
|
||||
destroy SDK
|
||||
destroy GameServer
|
||||
@enduml
|
||||
|
After Width: | Height: | Size: 91 KiB |
|
|
@ -0,0 +1,76 @@
|
|||
@startuml
|
||||
participant Matchmaker
|
||||
participant Agones
|
||||
participant "Game Server\nProcess" as Binary
|
||||
participant "GameServer\nResource" as GameServer
|
||||
participant SDK
|
||||
box "Game Server Pod"
|
||||
participant Binary
|
||||
participant SDK
|
||||
end box
|
||||
|
||||
== GameServer Start ==
|
||||
|
||||
Agones -> GameServer: GameServer created through\na <i>Fleet</i> configuration
|
||||
activate GameServer
|
||||
GameServer -> Binary: Agones creates a Pod with the\nconfigured Game Server Container
|
||||
activate Binary
|
||||
activate SDK
|
||||
Binary -> SDK: SDK.Health()
|
||||
note right
|
||||
<i>Health()</i> is a continuous
|
||||
ping that occurs under
|
||||
the configured threshold.
|
||||
end note
|
||||
GameServer <-- SDK: Maintains Healthy status
|
||||
|
||||
== Match Maker Registration ==
|
||||
loop
|
||||
Binary -> SDK: SDK.GameServer()
|
||||
note left
|
||||
Matchmaker registration
|
||||
could occur on a timed loop
|
||||
to give each <i>GameServer</i>
|
||||
time to be scaled down
|
||||
while <i>Ready</i> if not allocated
|
||||
end note
|
||||
Binary <-- SDK: GameServer details
|
||||
Binary -> SDK: SDK.Reserve(duration)
|
||||
GameServer <-- SDK: Set state to <i>Reserved</i> for <i>duration</i>
|
||||
note right
|
||||
<i>Duration</i> should be longer
|
||||
than how long the matchmaker
|
||||
requires <i>Register()</i> to be
|
||||
available for, so it will not be
|
||||
scaled down
|
||||
end note
|
||||
Binary -> Matchmaker: Register()
|
||||
note left
|
||||
Register with the Matchmaker as
|
||||
available to host a game session
|
||||
with details from SDK.GameServer()
|
||||
end note
|
||||
end loop
|
||||
|
||||
== Matchmaker allocates GameServer ==
|
||||
Matchmaker -> Binary: StartGameSession()
|
||||
Binary -> SDK: Allocate()
|
||||
note right
|
||||
Disables timer to reset <i>Reserved</i> state
|
||||
back to <i>Ready</i>
|
||||
end note
|
||||
SDK --> GameServer: Set state to <i>Allocated</i>
|
||||
|
||||
== Players Finish Game ==
|
||||
|
||||
Binary -> GameServer: SDK.Shutdown()
|
||||
note left
|
||||
Once gameplay is complete, call
|
||||
<i>Shutdown()</i> to delete the
|
||||
<i>GameServer</i> resource and backing Pod.
|
||||
end note
|
||||
destroy Binary
|
||||
destroy SDK
|
||||
destroy GameServer
|
||||
|
||||
@enduml
|
||||
|
After Width: | Height: | Size: 104 KiB |
|
|
@ -0,0 +1,80 @@
|
|||
digraph {
|
||||
graph [fontname = "helvetica"];
|
||||
node [fontname = "helvetica"];
|
||||
edge [fontname = "helvetica", pad="0.2", penwidth="2"];
|
||||
|
||||
Created [ label = "game server created" ]
|
||||
PortAllocation
|
||||
Creating
|
||||
Error
|
||||
Starting
|
||||
Scheduled
|
||||
RequestReady
|
||||
Ready
|
||||
Reserved
|
||||
Allocated
|
||||
Shutdown
|
||||
Unhealthy
|
||||
Deleted [ label = "game server deleted" ]
|
||||
|
||||
Created -> PortAllocation [ label ="has any port\nwith dynamic policy", color="red" ]
|
||||
Created -> Creating [ label="only static ports", color="red" ]
|
||||
|
||||
PortAllocation -> Creating [ label="allocated unused port", color="blue" ]
|
||||
Creating -> Starting [ label="created pod", color="blue" ]
|
||||
Starting -> Scheduled [ label="we have a pod, fetch its address", color="blue" ]
|
||||
Scheduled -> Reserved [ label="SDK.reserved(seconds)", color="purple" ]
|
||||
Scheduled -> RequestReady [ label="SDK.ready()", color="purple" ]
|
||||
RequestReady -> Ready [ label="ready to be allocated", color="blue" ]
|
||||
Reserved -> Ready [label="if seconds > 0 \land failed to call \lSDK.allocate() " color="purple"]
|
||||
Allocated -> RequestReady [ label="SDK.ready()", color="purple" ]
|
||||
|
||||
Ready -> Allocated [ label="allocated for use", color="orange" ]
|
||||
Ready -> Allocated [ label="SDK.allocate() ", color="purple" ]
|
||||
Reserved -> Allocated [color="purple"]
|
||||
|
||||
Creating -> Error [ label="failed to create pod", color="blue" ]
|
||||
|
||||
Scheduled -> Shutdown [ label="SDK.shutdown()", color="purple" ]
|
||||
RequestReady -> Shutdown [ color="purple" ]
|
||||
Ready -> Shutdown [ color="purple" ]
|
||||
Allocated -> Shutdown [ color="purple" ]
|
||||
Reserved -> Shutdown [ color="purple" ]
|
||||
|
||||
|
||||
Scheduled -> Unhealthy [ label="failed to call SDK.healthy()\nin a timely manner" color="purple" ]
|
||||
RequestReady -> Unhealthy [ color="purple" ]
|
||||
Ready -> Unhealthy [ color="purple" ]
|
||||
Allocated -> Unhealthy [ color="purple" ]
|
||||
Reserved -> Unhealthy [ color="purple" ]
|
||||
|
||||
Unhealthy -> Deleted [ label="delete unhealthy game server", color="blue" ]
|
||||
Shutdown -> Deleted [ label="delete finished game server", color="blue" ]
|
||||
|
||||
subgraph cluster_01 {
|
||||
style=invis;
|
||||
{
|
||||
s1 [style="invis"];
|
||||
s2 [style="invis"];
|
||||
s1 -> s2 [ color="red", label="API user" ]
|
||||
}
|
||||
|
||||
{
|
||||
s3 [style="invis"];
|
||||
s4 [style="invis"];
|
||||
s3 -> s4 [ color="purple", label="SDK" ]
|
||||
}
|
||||
|
||||
{
|
||||
s5 [style="invis"];
|
||||
s6 [style="invis"];
|
||||
s5 -> s6 [ color="orange", label="allocation\ncontroller" ]
|
||||
}
|
||||
|
||||
{
|
||||
s7 [style="invis"];
|
||||
s8 [style="invis"];
|
||||
s7 -> s8 [ color="blue", label="game server\ncontroller" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 215 KiB |
|
|
@ -0,0 +1,118 @@
|
|||
@startuml
|
||||
participant Matchmaker
|
||||
participant Agones
|
||||
participant "Game Server\nProcess" as Binary
|
||||
participant SDK
|
||||
participant "GameServer\nResource" as GameServer
|
||||
box "Game Server Pod"
|
||||
participant Binary
|
||||
participant SDK
|
||||
end box
|
||||
|
||||
== GameServer Start ==
|
||||
|
||||
Agones -> GameServer: GameServer created through\na <i>Fleet</i> configuration
|
||||
activate GameServer
|
||||
GameServer -> Binary: Agones creates a Pod with the\nconfigured Game Server Container
|
||||
activate Binary
|
||||
activate SDK
|
||||
Binary -> SDK: SDK.WatchGameServer()
|
||||
note right
|
||||
Use the SDK Watch function
|
||||
to watch and react to allocation
|
||||
events
|
||||
end note
|
||||
|
||||
Binary -> SDK: SDK.Ready()
|
||||
note right
|
||||
Call <i>Ready()</i> when the
|
||||
Game Server can take player
|
||||
connections and is able to
|
||||
be allocated.
|
||||
end note
|
||||
GameServer <-- SDK: Update to <i>Ready</i> State
|
||||
|
||||
== No allocated <i>GameServers</i> ==
|
||||
|
||||
Matchmaker -> Agones: Create: <i>GameServerAllocation</i>
|
||||
note left
|
||||
The <i>GameServerAllocation</i> is implemented to
|
||||
optionally select an already allocated <i>GameServer</i>
|
||||
with <i>metadata.labels["agones.dev/sdk-gs-session-ready"] = "true"</i>
|
||||
if one exists. At this stage, one does not, so
|
||||
Agones will allocate a <i>Ready</i> <i>GameServer</i>.
|
||||
end note
|
||||
Agones -> GameServer: Finds a <i>Ready</i> <i>GameServer</i>.\n\nSets <i>status.state</i> to <i>Allocated</i> State\nand <i>metadata.labels["agones.dev/sdk-gs-session-ready"] = "false"</i>\nand <i>metadata.annotations["agones.dev/last-allocated"] = current timestamp</i>
|
||||
note left
|
||||
By setting the label "agones.dev/sdk-gs-session-ready" to "false"
|
||||
this remove the `GameServer` from possibly being
|
||||
re-allocated until it knows it can handle another session.
|
||||
end note
|
||||
Matchmaker <-- Agones : <i>GameServerAllocation</i> is returned\nwith <i>GameServer</i> details\nincluding IP and port to connect to.
|
||||
|
||||
SDK --> Binary: Sends SDK.WatchGameServer()\nevent for Allocation.
|
||||
note right
|
||||
This initial allocation can be determined
|
||||
as a change in <i>GameServer.status.state</i>
|
||||
from <i>Ready</i> to <i>Allocated</i>
|
||||
end note
|
||||
|
||||
Binary -> SDK: SDK.SetLabel("gs-session-ready", "true")
|
||||
note right
|
||||
Since this game process can handle <i>n</i>
|
||||
concurrent sessions, set this label to match
|
||||
optional allocation label selectors, so it can be
|
||||
re-allocated.
|
||||
(See example below for more details)
|
||||
end note
|
||||
SDK --> GameServer: Sets <i>metadata.labels["agones.dev/sdk-gs-session-ready"] = "true"</i>
|
||||
|
||||
== Allocated <i>GameServers</i> with room for more sessions ==
|
||||
|
||||
Matchmaker -> Agones: Create: <i>GameServerAllocation</i>
|
||||
note left
|
||||
The <i>GameServerAllocation</i> will this time
|
||||
find the Allocated <i>GameServer</i> with the label
|
||||
<i>metadata.labels["agones.dev/sdk-gs-session-ready"] = "true"</i>,
|
||||
indicating that it can accept more
|
||||
concurrent game sessions.
|
||||
end note
|
||||
Agones -> GameServer: Finds the Allocated <i>GameServer</i> with\n<i>metadata.labels["agones.dev/sdk-gs-session-ready"] = "true"</i>.\n\nSets <i>metadata.labels["agones.dev/sdk-gs-session-ready"] = "false"</i>\nand <i>metadata.annotations["agones.dev/last-allocated"] = current timestamp</i>.
|
||||
note right
|
||||
This is the a <i>GameServer</i> that has room
|
||||
for another concurrent game session.
|
||||
end note
|
||||
Matchmaker <-- Agones: returns <i>Allocated GameServer</i> record
|
||||
|
||||
SDK --> Binary: Sends SDK.WatchGameServer()\nevent for Allocation.
|
||||
note right
|
||||
The game server process can watch for a change
|
||||
in <i>metadata.annotations["agones.dev/last-allocated"]</i>
|
||||
to determine there is an allocation event.
|
||||
end note
|
||||
|
||||
alt <i>GameServer</i> can accept more concurrent sessions
|
||||
Binary -> SDK: SDK.SetLabel("gs-session-ready", "true")
|
||||
SDK --> GameServer: Sets <i>metadata.labels["agones.dev/sdk-gs-session-ready"] = "true"</i>.
|
||||
end alt
|
||||
note right
|
||||
If the <i>GameServer</i> can accept more
|
||||
concurrent sessions, reset the label
|
||||
<i>"agones.dev/sdk-gs-session-ready"</i>
|
||||
back to "true"
|
||||
end note
|
||||
|
||||
== <i>GameServer</i> has completed <i>n</i> number of complete sessions ==
|
||||
|
||||
Binary -> SDK: SDK.Shutdown()
|
||||
note left
|
||||
The <i>GameServer</i> process tracks the number of sessions
|
||||
that it hosts, and after <i>n</i> number, calls <i>Shutdown()</i>
|
||||
to delete the <i>GameServer</i> resource and backing Pod.
|
||||
end note
|
||||
SDK --> GameServer: Update to <i>Shutdown</i> state.
|
||||
Agones -> GameServer: Deletes GameServer resource and backing Pod.
|
||||
destroy Binary
|
||||
destroy SDK
|
||||
destroy GameServer
|
||||
@enduml
|
||||
|
After Width: | Height: | Size: 222 KiB |
|
|
@ -0,0 +1,72 @@
|
|||
@startuml
|
||||
participant Matchmaker
|
||||
participant Agones
|
||||
participant "Game Server\nProcess" as Binary
|
||||
participant SDK
|
||||
participant "GameServer\nResource" as GameServer
|
||||
box "Game Server Pod"
|
||||
participant Binary
|
||||
participant SDK
|
||||
end box
|
||||
|
||||
== GameServer Start ==
|
||||
|
||||
Agones -> GameServer: GameServer created through\na <i>Fleet</i> configuration
|
||||
activate GameServer
|
||||
GameServer -> Binary: Agones creates a Pod with the\nconfigured Game Server Container
|
||||
activate Binary
|
||||
activate SDK
|
||||
Binary -> SDK: SDK.Ready()
|
||||
note right
|
||||
Call <i>Ready()</i> when the
|
||||
Game Server can take player
|
||||
connections and is able to
|
||||
be allocated.
|
||||
end note
|
||||
GameServer <-- SDK: Update to <i>Ready</i> State
|
||||
|
||||
== Matchmaker requesting GameServer ==
|
||||
loop <i>n</i> times
|
||||
Matchmaker -> Agones: Create: <i>GameServerAllocation</i>
|
||||
note left
|
||||
Allocation atomically provides
|
||||
a GameServer from a pool
|
||||
of existing GameServers
|
||||
(Usually a <i>Fleet</i>)
|
||||
end note
|
||||
"Agones" -> GameServer: Finds a Ready <i>GameServer</i>,\nsets it to <i>Allocated</i> State
|
||||
Matchmaker <-- Agones : <i>GameServerAllocation</i> is returned\nwith <i>GameServer</i> details\nincluding IP and port to connect to.
|
||||
|
||||
== Players Finish Game ==
|
||||
|
||||
Binary -> Binary: this.ResetGameServer()
|
||||
note right
|
||||
Resets the game server process
|
||||
back to a zero state.
|
||||
end note
|
||||
|
||||
Binary -> SDK: SDK.Ready()
|
||||
note right
|
||||
Process calls <i>Ready()</i> so that
|
||||
the <i>GameServer</i> is moved back to
|
||||
the <i>Ready</i> state, and can be allocated
|
||||
once more.
|
||||
end note
|
||||
GameServer <-- SDK: Update to <i>Ready</i> State
|
||||
|
||||
end loop
|
||||
|
||||
== GameServer has completed <i>n</i> number of complete sessions ==
|
||||
|
||||
Binary -> SDK: SDK.Shutdown()
|
||||
note left
|
||||
The <i>GameServer</i> process tracks the number of sessions
|
||||
that it hosts, and after <i>n</i> number, calls <i>Shutdown()</i>
|
||||
to delete the <i>GameServer</i> resource and backing Pod.
|
||||
end note
|
||||
SDK --> GameServer: Update to <i>Shutdown</i> state.
|
||||
Agones -> GameServer: Deletes GameServer resource\n and backing Pod.
|
||||
destroy Binary
|
||||
destroy SDK
|
||||
destroy GameServer
|
||||
@enduml
|
||||
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 598 KiB |
|
|
@ -0,0 +1,21 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1000" height="1000" viewBox="0 0 1000 1000" xml:space="preserve">
|
||||
<desc>Created with Fabric.js 3.5.0</desc>
|
||||
<defs>
|
||||
</defs>
|
||||
<rect x="0" y="0" width="100%" height="100%" fill="rgba(255,255,255,0)"/>
|
||||
<g transform="matrix(42.2992 0 0 42.2992 479.8228 466.7084)" id="802661">
|
||||
<path style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(57,112,228); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-12, -12.1153)" d="M 11.1142 1.43752 C 11.6726 1.16175 12.3274 1.16175 12.8858 1.43752 L 19.9628 4.9333 C 20.5056 5.20144 20.8978 5.70105 21.0293 6.29205 L 22.7955 14.2294 C 22.925 14.8114 22.7882 15.4208 22.4222 15.8914 L 17.496 22.2276 C 17.1171 22.7149 16.5344 23 15.9171 23 H 8.08294 C 7.46563 23 6.88291 22.7149 6.504 22.2276 L 1.57778 15.8914 C 1.21185 15.4208 1.07497 14.8114 1.20446 14.2294 L 2.9707 6.29205 C 3.10221 5.70105 3.49436 5.20144 4.0372 4.9333 L 11.1142 1.43752 Z" stroke-linecap="round"/>
|
||||
</g>
|
||||
<g transform="matrix(12.921 0 0 12.921 347.0899 310.4368)" id="801018">
|
||||
<path style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-11.9993, -11.9995)" d="M 9.362 9.158 c 0 0 -3.16 0.35 -5.268 0.584 c -0.19 0.023 -0.358 0.15 -0.421 0.343 s 0 0.394 0.14 0.521 c 1.566 1.429 3.919 3.569 3.919 3.569 c -0.002 0 -0.646 3.113 -1.074 5.19 c -0.036 0.188 0.032 0.387 0.196 0.506 c 0.163 0.119 0.373 0.121 0.538 0.028 c 1.844 -1.048 4.606 -2.624 4.606 -2.624 s 2.763 1.576 4.604 2.625 c 0.168 0.092 0.378 0.09 0.541 -0.029 c 0.164 -0.119 0.232 -0.318 0.195 -0.505 c -0.428 -2.078 -1.071 -5.191 -1.071 -5.191 s 2.353 -2.14 3.919 -3.566 c 0.14 -0.131 0.202 -0.332 0.14 -0.524 s -0.23 -0.319 -0.42 -0.341 c -2.108 -0.236 -5.269 -0.586 -5.269 -0.586 s -1.31 -2.898 -2.183 -4.83 c -0.082 -0.173 -0.254 -0.294 -0.456 -0.294 s -0.375 0.122 -0.453 0.294 C 10.671 6.26 9.362 9.158 9.362 9.158 z" stroke-linecap="round"/>
|
||||
</g>
|
||||
<g transform="matrix(11.436 0 0 11.436 640.1609 321.8717)" id="323779">
|
||||
<rect style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" x="-8" y="-8" rx="0" ry="0" width="16" height="16"/>
|
||||
</g>
|
||||
<g transform="matrix(13.3101 0 0 13.3101 348.51 608.711)" id="770773">
|
||||
<circle style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" cx="0" cy="0" r="8"/>
|
||||
</g>
|
||||
<g transform="matrix(0.4498 0 0 0.4498 630.8727 595.1659)" id="874714">
|
||||
<path style="stroke: none; stroke-width: 0; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; is-custom-font: none; font-file-url: none; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" vector-effect="non-scaling-stroke" transform=" translate(-256, -255.999)" d="M 464 464 H 48 a 16 16 0 0 1 -14.07 -23.62 l 208 -384 a 16 16 0 0 1 28.14 0 l 208 384 A 16 16 0 0 1 464 464 Z" stroke-linecap="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.7 KiB |