added
This commit is contained in:
@@ -14,3 +14,12 @@ cdebug exec --privileged -it --image nixery.dev/shell/ps/vim/tshark my-distroles
|
||||
|
||||
https://github.com/iximiuz/cdebug
|
||||
|
||||
https://github.com/donaldzou/WGDashboard#-install
|
||||
|
||||
https://learnk8s.io/troubleshooting-deployments
|
||||
|
||||
https://artifacthub.io/
|
||||
|
||||
https://github.com/kubernetes/git-sync
|
||||
|
||||
https://grpc.io/docs/languages/python/basics/
|
||||
14
git_sync/create_volume
Normal file
14
git_sync/create_volume
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: pv-git
|
||||
labels:
|
||||
app: git
|
||||
spec:
|
||||
storageClassName: manual
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
hostPath:
|
||||
path: "/mnt/data"
|
||||
51
git_sync/deployment
Normal file
51
git_sync/deployment
Normal file
@@ -0,0 +1,51 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: git-sync
|
||||
name: git-sync
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: git-sync
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: git-sync
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:latest
|
||||
name: nginx
|
||||
resources: {}
|
||||
volumeMounts:
|
||||
- name: workdir
|
||||
mountPath: /usr/share/nginx/html
|
||||
initContainers:
|
||||
- image: registry.k8s.io/git-sync/git-sync:v3.6.2
|
||||
name: gitsync
|
||||
args:
|
||||
- --repo=nutzer26@1:/home/nutzer01/content_repo.git
|
||||
- --root=/tmp/git/root
|
||||
- --ssh
|
||||
- --one-time
|
||||
volumeMounts:
|
||||
- name: git-secret
|
||||
mountPath: /etc/git-secret
|
||||
- name: workdir
|
||||
mountPath: "/tmp/git/root"
|
||||
securityContext:
|
||||
runAsUser: 65533
|
||||
volumes:
|
||||
- name: workdir
|
||||
emptyDir: {}
|
||||
- name: claim-pvc2
|
||||
secret:
|
||||
secretName: git-creds
|
||||
defaultMode: 0400
|
||||
securityContext:
|
||||
fsGroup: 65533
|
||||
status: {}
|
||||
1
git_sync/git_project/HEAD
Normal file
1
git_sync/git_project/HEAD
Normal file
@@ -0,0 +1 @@
|
||||
ref: refs/heads/master
|
||||
4
git_sync/git_project/config
Normal file
4
git_sync/git_project/config
Normal file
@@ -0,0 +1,4 @@
|
||||
[core]
|
||||
repositoryformatversion = 0
|
||||
filemode = true
|
||||
bare = true
|
||||
1
git_sync/git_project/description
Normal file
1
git_sync/git_project/description
Normal file
@@ -0,0 +1 @@
|
||||
Unnamed repository; edit this file 'description' to name the repository.
|
||||
15
git_sync/git_project/hooks/applypatch-msg.sample
Executable file
15
git_sync/git_project/hooks/applypatch-msg.sample
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message taken by
|
||||
# applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit. The hook is
|
||||
# allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "applypatch-msg".
|
||||
|
||||
. git-sh-setup
|
||||
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
|
||||
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
|
||||
:
|
||||
24
git_sync/git_project/hooks/commit-msg.sample
Executable file
24
git_sync/git_project/hooks/commit-msg.sample
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to check the commit log message.
|
||||
# Called by "git commit" with one argument, the name of the file
|
||||
# that has the commit message. The hook should exit with non-zero
|
||||
# status after issuing an appropriate message if it wants to stop the
|
||||
# commit. The hook is allowed to edit the commit message file.
|
||||
#
|
||||
# To enable this hook, rename this file to "commit-msg".
|
||||
|
||||
# Uncomment the below to add a Signed-off-by line to the message.
|
||||
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||
# hook is more suited to it.
|
||||
#
|
||||
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||
|
||||
# This example catches duplicate Signed-off-by lines.
|
||||
|
||||
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||
echo >&2 Duplicate Signed-off-by lines.
|
||||
exit 1
|
||||
}
|
||||
109
git_sync/git_project/hooks/fsmonitor-watchman.sample
Executable file
109
git_sync/git_project/hooks/fsmonitor-watchman.sample
Executable file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use IPC::Open2;
|
||||
|
||||
# An example hook script to integrate Watchman
|
||||
# (https://facebook.github.io/watchman/) with git to speed up detecting
|
||||
# new and modified files.
|
||||
#
|
||||
# The hook is passed a version (currently 1) and a time in nanoseconds
|
||||
# formatted as a string and outputs to stdout all files that have been
|
||||
# modified since the given time. Paths must be relative to the root of
|
||||
# the working tree and separated by a single NUL.
|
||||
#
|
||||
# To enable this hook, rename this file to "query-watchman" and set
|
||||
# 'git config core.fsmonitor .git/hooks/query-watchman'
|
||||
#
|
||||
my ($version, $time) = @ARGV;
|
||||
|
||||
# Check the hook interface version
|
||||
|
||||
if ($version == 1) {
|
||||
# convert nanoseconds to seconds
|
||||
# subtract one second to make sure watchman will return all changes
|
||||
$time = int ($time / 1000000000) - 1;
|
||||
} else {
|
||||
die "Unsupported query-fsmonitor hook version '$version'.\n" .
|
||||
"Falling back to scanning...\n";
|
||||
}
|
||||
|
||||
my $git_work_tree;
|
||||
if ($^O =~ 'msys' || $^O =~ 'cygwin') {
|
||||
$git_work_tree = Win32::GetCwd();
|
||||
$git_work_tree =~ tr/\\/\//;
|
||||
} else {
|
||||
require Cwd;
|
||||
$git_work_tree = Cwd::cwd();
|
||||
}
|
||||
|
||||
my $retry = 1;
|
||||
|
||||
launch_watchman();
|
||||
|
||||
sub launch_watchman {
|
||||
|
||||
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty')
|
||||
or die "open2() failed: $!\n" .
|
||||
"Falling back to scanning...\n";
|
||||
|
||||
# In the query expression below we're asking for names of files that
|
||||
# changed since $time but were not transient (ie created after
|
||||
# $time but no longer exist).
|
||||
#
|
||||
# To accomplish this, we're using the "since" generator to use the
|
||||
# recency index to select candidate nodes and "fields" to limit the
|
||||
# output to file names only.
|
||||
|
||||
my $query = <<" END";
|
||||
["query", "$git_work_tree", {
|
||||
"since": $time,
|
||||
"fields": ["name"]
|
||||
}]
|
||||
END
|
||||
|
||||
print CHLD_IN $query;
|
||||
close CHLD_IN;
|
||||
my $response = do {local $/; <CHLD_OUT>};
|
||||
|
||||
die "Watchman: command returned no output.\n" .
|
||||
"Falling back to scanning...\n" if $response eq "";
|
||||
die "Watchman: command returned invalid output: $response\n" .
|
||||
"Falling back to scanning...\n" unless $response =~ /^\{/;
|
||||
|
||||
my $json_pkg;
|
||||
eval {
|
||||
require JSON::XS;
|
||||
$json_pkg = "JSON::XS";
|
||||
1;
|
||||
} or do {
|
||||
require JSON::PP;
|
||||
$json_pkg = "JSON::PP";
|
||||
};
|
||||
|
||||
my $o = $json_pkg->new->utf8->decode($response);
|
||||
|
||||
if ($retry > 0 and $o->{error} and $o->{error} =~ m/unable to resolve root .* directory (.*) is not watched/) {
|
||||
print STDERR "Adding '$git_work_tree' to watchman's watch list.\n";
|
||||
$retry--;
|
||||
qx/watchman watch "$git_work_tree"/;
|
||||
die "Failed to make watchman watch '$git_work_tree'.\n" .
|
||||
"Falling back to scanning...\n" if $? != 0;
|
||||
|
||||
# Watchman will always return all files on the first query so
|
||||
# return the fast "everything is dirty" flag to git and do the
|
||||
# Watchman query just to get it over with now so we won't pay
|
||||
# the cost in git to look up each individual file.
|
||||
print "/\0";
|
||||
eval { launch_watchman() };
|
||||
exit 0;
|
||||
}
|
||||
|
||||
die "Watchman: $o->{error}.\n" .
|
||||
"Falling back to scanning...\n" if $o->{error};
|
||||
|
||||
binmode STDOUT, ":utf8";
|
||||
local $, = "\0";
|
||||
print @{$o->{files}};
|
||||
}
|
||||
8
git_sync/git_project/hooks/post-update.sample
Executable file
8
git_sync/git_project/hooks/post-update.sample
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare a packed repository for use over
|
||||
# dumb transports.
|
||||
#
|
||||
# To enable this hook, rename this file to "post-update".
|
||||
|
||||
exec git update-server-info
|
||||
14
git_sync/git_project/hooks/pre-applypatch.sample
Executable file
14
git_sync/git_project/hooks/pre-applypatch.sample
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed
|
||||
# by applypatch from an e-mail message.
|
||||
#
|
||||
# The hook should exit with non-zero status after issuing an
|
||||
# appropriate message if it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-applypatch".
|
||||
|
||||
. git-sh-setup
|
||||
precommit="$(git rev-parse --git-path hooks/pre-commit)"
|
||||
test -x "$precommit" && exec "$precommit" ${1+"$@"}
|
||||
:
|
||||
49
git_sync/git_project/hooks/pre-commit.sample
Executable file
49
git_sync/git_project/hooks/pre-commit.sample
Executable file
@@ -0,0 +1,49 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git commit" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message if
|
||||
# it wants to stop the commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-commit".
|
||||
|
||||
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||
then
|
||||
against=HEAD
|
||||
else
|
||||
# Initial commit: diff against an empty tree object
|
||||
against=$(git hash-object -t tree /dev/null)
|
||||
fi
|
||||
|
||||
# If you want to allow non-ASCII filenames set this variable to true.
|
||||
allownonascii=$(git config --bool hooks.allownonascii)
|
||||
|
||||
# Redirect output to stderr.
|
||||
exec 1>&2
|
||||
|
||||
# Cross platform projects tend to avoid non-ASCII filenames; prevent
|
||||
# them from being added to the repository. We exploit the fact that the
|
||||
# printable range starts at the space character and ends with tilde.
|
||||
if [ "$allownonascii" != "true" ] &&
|
||||
# Note that the use of brackets around a tr range is ok here, (it's
|
||||
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||
# the square bracket bytes happen to fall in the designated range.
|
||||
test $(git diff --cached --name-only --diff-filter=A -z $against |
|
||||
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
|
||||
then
|
||||
cat <<\EOF
|
||||
Error: Attempt to add a non-ASCII file name.
|
||||
|
||||
This can cause problems if you want to work with people on other platforms.
|
||||
|
||||
To be portable it is advisable to rename the file.
|
||||
|
||||
If you know what you are doing you can disable this check using:
|
||||
|
||||
git config hooks.allownonascii true
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If there are whitespace errors, print the offending file names and fail.
|
||||
exec git diff-index --check --cached $against --
|
||||
13
git_sync/git_project/hooks/pre-merge-commit.sample
Executable file
13
git_sync/git_project/hooks/pre-merge-commit.sample
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to verify what is about to be committed.
|
||||
# Called by "git merge" with no arguments. The hook should
|
||||
# exit with non-zero status after issuing an appropriate message to
|
||||
# stderr if it wants to stop the merge commit.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-merge-commit".
|
||||
|
||||
. git-sh-setup
|
||||
test -x "$GIT_DIR/hooks/pre-commit" &&
|
||||
exec "$GIT_DIR/hooks/pre-commit"
|
||||
:
|
||||
53
git_sync/git_project/hooks/pre-push.sample
Executable file
53
git_sync/git_project/hooks/pre-push.sample
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
|
||||
# An example hook script to verify what is about to be pushed. Called by "git
|
||||
# push" after it has checked the remote status, but before anything has been
|
||||
# pushed. If this script exits with a non-zero status nothing will be pushed.
|
||||
#
|
||||
# This hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- Name of the remote to which the push is being done
|
||||
# $2 -- URL to which the push is being done
|
||||
#
|
||||
# If pushing without using a named remote those arguments will be equal.
|
||||
#
|
||||
# Information about the commits which are being pushed is supplied as lines to
|
||||
# the standard input in the form:
|
||||
#
|
||||
# <local ref> <local sha1> <remote ref> <remote sha1>
|
||||
#
|
||||
# This sample shows how to prevent push of commits where the log message starts
|
||||
# with "WIP" (work in progress).
|
||||
|
||||
remote="$1"
|
||||
url="$2"
|
||||
|
||||
z40=0000000000000000000000000000000000000000
|
||||
|
||||
while read local_ref local_sha remote_ref remote_sha
|
||||
do
|
||||
if [ "$local_sha" = $z40 ]
|
||||
then
|
||||
# Handle delete
|
||||
:
|
||||
else
|
||||
if [ "$remote_sha" = $z40 ]
|
||||
then
|
||||
# New branch, examine all commits
|
||||
range="$local_sha"
|
||||
else
|
||||
# Update to existing branch, examine new commits
|
||||
range="$remote_sha..$local_sha"
|
||||
fi
|
||||
|
||||
# Check for WIP commit
|
||||
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
|
||||
if [ -n "$commit" ]
|
||||
then
|
||||
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
exit 0
|
||||
169
git_sync/git_project/hooks/pre-rebase.sample
Executable file
169
git_sync/git_project/hooks/pre-rebase.sample
Executable file
@@ -0,0 +1,169 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||
#
|
||||
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||
# its job, and can prevent the command from running by exiting with
|
||||
# non-zero status.
|
||||
#
|
||||
# The hook is called with the following parameters:
|
||||
#
|
||||
# $1 -- the upstream the series was forked from.
|
||||
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||
#
|
||||
# This sample shows how to prevent topic branches that are already
|
||||
# merged to 'next' branch from getting rebased, because allowing it
|
||||
# would result in rebasing already published history.
|
||||
|
||||
publish=next
|
||||
basebranch="$1"
|
||||
if test "$#" = 2
|
||||
then
|
||||
topic="refs/heads/$2"
|
||||
else
|
||||
topic=`git symbolic-ref HEAD` ||
|
||||
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||
fi
|
||||
|
||||
case "$topic" in
|
||||
refs/heads/??/*)
|
||||
;;
|
||||
*)
|
||||
exit 0 ;# we do not interrupt others.
|
||||
;;
|
||||
esac
|
||||
|
||||
# Now we are dealing with a topic branch being rebased
|
||||
# on top of master. Is it OK to rebase it?
|
||||
|
||||
# Does the topic really exist?
|
||||
git show-ref -q "$topic" || {
|
||||
echo >&2 "No such branch $topic"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Is topic fully merged to master?
|
||||
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||
if test -z "$not_in_master"
|
||||
then
|
||||
echo >&2 "$topic is fully merged to master; better remove it."
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
fi
|
||||
|
||||
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||
if test "$only_next_1" = "$only_next_2"
|
||||
then
|
||||
not_in_topic=`git rev-list "^$topic" master`
|
||||
if test -z "$not_in_topic"
|
||||
then
|
||||
echo >&2 "$topic is already up to date with master"
|
||||
exit 1 ;# we could allow it, but there is no point.
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||
/usr/bin/perl -e '
|
||||
my $topic = $ARGV[0];
|
||||
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||
my (%not_in_next) = map {
|
||||
/^([0-9a-f]+) /;
|
||||
($1 => 1);
|
||||
} split(/\n/, $ARGV[1]);
|
||||
for my $elem (map {
|
||||
/^([0-9a-f]+) (.*)$/;
|
||||
[$1 => $2];
|
||||
} split(/\n/, $ARGV[2])) {
|
||||
if (!exists $not_in_next{$elem->[0]}) {
|
||||
if ($msg) {
|
||||
print STDERR $msg;
|
||||
undef $msg;
|
||||
}
|
||||
print STDERR " $elem->[1]\n";
|
||||
}
|
||||
}
|
||||
' "$topic" "$not_in_next" "$not_in_master"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
<<\DOC_END
|
||||
|
||||
This sample hook safeguards topic branches that have been
|
||||
published from being rewound.
|
||||
|
||||
The workflow assumed here is:
|
||||
|
||||
* Once a topic branch forks from "master", "master" is never
|
||||
merged into it again (either directly or indirectly).
|
||||
|
||||
* Once a topic branch is fully cooked and merged into "master",
|
||||
it is deleted. If you need to build on top of it to correct
|
||||
earlier mistakes, a new topic branch is created by forking at
|
||||
the tip of the "master". This is not strictly necessary, but
|
||||
it makes it easier to keep your history simple.
|
||||
|
||||
* Whenever you need to test or publish your changes to topic
|
||||
branches, merge them into "next" branch.
|
||||
|
||||
The script, being an example, hardcodes the publish branch name
|
||||
to be "next", but it is trivial to make it configurable via
|
||||
$GIT_DIR/config mechanism.
|
||||
|
||||
With this workflow, you would want to know:
|
||||
|
||||
(1) ... if a topic branch has ever been merged to "next". Young
|
||||
topic branches can have stupid mistakes you would rather
|
||||
clean up before publishing, and things that have not been
|
||||
merged into other branches can be easily rebased without
|
||||
affecting other people. But once it is published, you would
|
||||
not want to rewind it.
|
||||
|
||||
(2) ... if a topic branch has been fully merged to "master".
|
||||
Then you can delete it. More importantly, you should not
|
||||
build on top of it -- other people may already want to
|
||||
change things related to the topic as patches against your
|
||||
"master", so if you need further changes, it is better to
|
||||
fork the topic (perhaps with the same name) afresh from the
|
||||
tip of "master".
|
||||
|
||||
Let's look at this example:
|
||||
|
||||
o---o---o---o---o---o---o---o---o---o "next"
|
||||
/ / / /
|
||||
/ a---a---b A / /
|
||||
/ / / /
|
||||
/ / c---c---c---c B /
|
||||
/ / / \ /
|
||||
/ / / b---b C \ /
|
||||
/ / / / \ /
|
||||
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||
|
||||
|
||||
A, B and C are topic branches.
|
||||
|
||||
* A has one fix since it was merged up to "next".
|
||||
|
||||
* B has finished. It has been fully merged up to "master" and "next",
|
||||
and is ready to be deleted.
|
||||
|
||||
* C has not merged to "next" at all.
|
||||
|
||||
We would want to allow C to be rebased, refuse A, and encourage
|
||||
B to be deleted.
|
||||
|
||||
To compute (1):
|
||||
|
||||
git rev-list ^master ^topic next
|
||||
git rev-list ^master next
|
||||
|
||||
if these match, topic has not merged in next at all.
|
||||
|
||||
To compute (2):
|
||||
|
||||
git rev-list master..topic
|
||||
|
||||
if this is empty, it is fully merged to "master".
|
||||
|
||||
DOC_END
|
||||
24
git_sync/git_project/hooks/pre-receive.sample
Executable file
24
git_sync/git_project/hooks/pre-receive.sample
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to make use of push options.
|
||||
# The example simply echoes all push options that start with 'echoback='
|
||||
# and rejects all pushes when the "reject" push option is used.
|
||||
#
|
||||
# To enable this hook, rename this file to "pre-receive".
|
||||
|
||||
if test -n "$GIT_PUSH_OPTION_COUNT"
|
||||
then
|
||||
i=0
|
||||
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
|
||||
do
|
||||
eval "value=\$GIT_PUSH_OPTION_$i"
|
||||
case "$value" in
|
||||
echoback=*)
|
||||
echo "echo from the pre-receive-hook: ${value#*=}" >&2
|
||||
;;
|
||||
reject)
|
||||
exit 1
|
||||
esac
|
||||
i=$((i + 1))
|
||||
done
|
||||
fi
|
||||
42
git_sync/git_project/hooks/prepare-commit-msg.sample
Executable file
42
git_sync/git_project/hooks/prepare-commit-msg.sample
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to prepare the commit log message.
|
||||
# Called by "git commit" with the name of the file that has the
|
||||
# commit message, followed by the description of the commit
|
||||
# message's source. The hook's purpose is to edit the commit
|
||||
# message file. If the hook fails with a non-zero status,
|
||||
# the commit is aborted.
|
||||
#
|
||||
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||
|
||||
# This hook includes three examples. The first one removes the
|
||||
# "# Please enter the commit message..." help message.
|
||||
#
|
||||
# The second includes the output of "git diff --name-status -r"
|
||||
# into the message, just before the "git status" output. It is
|
||||
# commented because it doesn't cope with --amend or with squashed
|
||||
# commits.
|
||||
#
|
||||
# The third example adds a Signed-off-by line to the message, that can
|
||||
# still be edited. This is rarely a good idea.
|
||||
|
||||
COMMIT_MSG_FILE=$1
|
||||
COMMIT_SOURCE=$2
|
||||
SHA1=$3
|
||||
|
||||
/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE"
|
||||
|
||||
# case "$COMMIT_SOURCE,$SHA1" in
|
||||
# ,|template,)
|
||||
# /usr/bin/perl -i.bak -pe '
|
||||
# print "\n" . `git diff --cached --name-status -r`
|
||||
# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;;
|
||||
# *) ;;
|
||||
# esac
|
||||
|
||||
# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||
# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE"
|
||||
# if test -z "$COMMIT_SOURCE"
|
||||
# then
|
||||
# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE"
|
||||
# fi
|
||||
128
git_sync/git_project/hooks/update.sample
Executable file
128
git_sync/git_project/hooks/update.sample
Executable file
@@ -0,0 +1,128 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# An example hook script to block unannotated tags from entering.
|
||||
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
||||
#
|
||||
# To enable this hook, rename this file to "update".
|
||||
#
|
||||
# Config
|
||||
# ------
|
||||
# hooks.allowunannotated
|
||||
# This boolean sets whether unannotated tags will be allowed into the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowdeletetag
|
||||
# This boolean sets whether deleting tags will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.allowmodifytag
|
||||
# This boolean sets whether a tag may be modified after creation. By default
|
||||
# it won't be.
|
||||
# hooks.allowdeletebranch
|
||||
# This boolean sets whether deleting branches will be allowed in the
|
||||
# repository. By default they won't be.
|
||||
# hooks.denycreatebranch
|
||||
# This boolean sets whether remotely creating branches will be denied
|
||||
# in the repository. By default this is allowed.
|
||||
#
|
||||
|
||||
# --- Command line
|
||||
refname="$1"
|
||||
oldrev="$2"
|
||||
newrev="$3"
|
||||
|
||||
# --- Safety check
|
||||
if [ -z "$GIT_DIR" ]; then
|
||||
echo "Don't run this script from the command line." >&2
|
||||
echo " (if you want, you could supply GIT_DIR then run" >&2
|
||||
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
||||
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Config
|
||||
allowunannotated=$(git config --bool hooks.allowunannotated)
|
||||
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
|
||||
denycreatebranch=$(git config --bool hooks.denycreatebranch)
|
||||
allowdeletetag=$(git config --bool hooks.allowdeletetag)
|
||||
allowmodifytag=$(git config --bool hooks.allowmodifytag)
|
||||
|
||||
# check for no description
|
||||
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
||||
case "$projectdesc" in
|
||||
"Unnamed repository"* | "")
|
||||
echo "*** Project description file hasn't been set" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Check types
|
||||
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
||||
zero="0000000000000000000000000000000000000000"
|
||||
if [ "$newrev" = "$zero" ]; then
|
||||
newrev_type=delete
|
||||
else
|
||||
newrev_type=$(git cat-file -t $newrev)
|
||||
fi
|
||||
|
||||
case "$refname","$newrev_type" in
|
||||
refs/tags/*,commit)
|
||||
# un-annotated tag
|
||||
short_refname=${refname##refs/tags/}
|
||||
if [ "$allowunannotated" != "true" ]; then
|
||||
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
||||
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,delete)
|
||||
# delete tag
|
||||
if [ "$allowdeletetag" != "true" ]; then
|
||||
echo "*** Deleting a tag is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/tags/*,tag)
|
||||
# annotated tag
|
||||
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
||||
then
|
||||
echo "*** Tag '$refname' already exists." >&2
|
||||
echo "*** Modifying a tag is not allowed in this repository." >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,commit)
|
||||
# branch
|
||||
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
||||
echo "*** Creating a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/heads/*,delete)
|
||||
# delete branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
refs/remotes/*,commit)
|
||||
# tracking branch
|
||||
;;
|
||||
refs/remotes/*,delete)
|
||||
# delete tracking branch
|
||||
if [ "$allowdeletebranch" != "true" ]; then
|
||||
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
# Anything else (is there anything else?)
|
||||
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# --- Finished
|
||||
exit 0
|
||||
6
git_sync/git_project/info/exclude
Normal file
6
git_sync/git_project/info/exclude
Normal file
@@ -0,0 +1,6 @@
|
||||
# git ls-files --others --exclude-from=.git/info/exclude
|
||||
# Lines that start with '#' are comments.
|
||||
# For a project mostly in C, the following would be a good set of
|
||||
# exclude patterns (uncomment them if you want to use them):
|
||||
# *.[oa]
|
||||
# *~
|
||||
13
git_sync/pvc
Normal file
13
git_sync/pvc
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: pvc-claim-2
|
||||
labels:
|
||||
app: git
|
||||
spec:
|
||||
storageClassName: manual
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 3Gi
|
||||
128
k3d/blue-green/doku
Normal file
128
k3d/blue-green/doku
Normal file
@@ -0,0 +1,128 @@
|
||||
Blue Green Deployment
|
||||
|
||||
create version 1 and 2 and services
|
||||
|
||||
# prepare namespace
|
||||
|
||||
|
||||
mkdir ~/blue-green && cd ~/blue-green
|
||||
kubectl create namespace blue-green
|
||||
kubectl config set-context --current --namespace blue-green
|
||||
|
||||
# create manifests
|
||||
|
||||
cat >nginx-v1.yaml <<EOF
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
name: webv1
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:1.19.3
|
||||
name: nginx
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
EOF
|
||||
|
||||
cat >nginx-v2.yaml <<EOF
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V2.0.0
|
||||
name: webv2
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web
|
||||
version: V2.0.0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V2.0.0
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:1.19.8
|
||||
name: nginx
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
EOF
|
||||
cat >nginx-svc.yaml <<EOF
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
name: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 80
|
||||
selector:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
EOF
|
||||
|
||||
Deployment from blue to green
|
||||
|
||||
|
||||
# deploy blue
|
||||
|
||||
kubectl apply -f nginx-v1.yaml
|
||||
kubectl apply -f nginx-svc.yaml
|
||||
kubectl describe deployment webv1
|
||||
kubectl describe svc nginx
|
||||
kubectl get ep nginx
|
||||
|
||||
# deploy green
|
||||
kubectl apply -f nginx-v2.yaml
|
||||
|
||||
# traffic shift
|
||||
kubectl patch service nginx --patch '{"spec":{"selector":{"version":"V2.0.0"}}}'
|
||||
|
||||
# Test if the second deployment was successful
|
||||
kubectl describe deployment webv2
|
||||
kubectl describe svc nginx
|
||||
kubectl get ep nginx
|
||||
|
||||
# cleanup v1
|
||||
|
||||
kubectl delete deploy webv1
|
||||
|
||||
WARNING:Traefik shift don't change established connection!!
|
||||
|
||||
kubectl run nc -it --rm --image curlimages/curl -- /bin/sh
|
||||
nc nginx.blue-green.svc.cluster.local 80
|
||||
GET /index.html HTTP/1.1
|
||||
Host: localhost
|
||||
|
||||
...
|
||||
|
||||
# switch at other terminal the load with patch
|
||||
#kubectl patch service nginx --patch '{"spec":{"selector":{"version":"V1.0.0"}}}'
|
||||
|
||||
GET /index.html HTTP/1.1
|
||||
Host: localhost
|
||||
|
||||
# same server/pod answer ...
|
||||
|
||||
14
k3d/blue-green/nginx-svc.yaml
Normal file
14
k3d/blue-green/nginx-svc.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
name: nginx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
targetPort: 80
|
||||
selector:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
25
k3d/blue-green/nginx-v1.yaml
Normal file
25
k3d/blue-green/nginx-v1.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
name: webv1
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V1.0.0
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:1.19.3
|
||||
name: nginx_new
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
25
k3d/blue-green/nginx-v2.yaml
Normal file
25
k3d/blue-green/nginx-v2.yaml
Normal file
@@ -0,0 +1,25 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V2.0.0
|
||||
name: webv2
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web
|
||||
version: V2.0.0
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: web
|
||||
version: V2.0.0
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:1.19.8
|
||||
name: nginx_old
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
@@ -73,4 +73,16 @@ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" \
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y kubectl
|
||||
|
||||
source <(kubectl completion bash)
|
||||
source <(k3d completion bash)
|
||||
|
||||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
|
||||
chmod 700 get_helm.sh
|
||||
./get_helm.sh
|
||||
source <(helm completion bash)
|
||||
|
||||
|
||||
default Namespace nächste commands
|
||||
|
||||
kubectl config set-context --current --namespace whoami
|
||||
201
k3d/pod_init/doku
Normal file
201
k3d/pod_init/doku
Normal file
@@ -0,0 +1,201 @@
|
||||
Pod init container
|
||||
|
||||
https://kubernetes.io/docs/concepts/workloads/pods/init-containers/
|
||||
|
||||
A Pod can have multiple containers running apps within it, but it can also have one or more init containers, which are run before the app containers are started.
|
||||
|
||||
Init containers are exactly like regular containers, except:
|
||||
|
||||
Init containers always run to completion.
|
||||
Each init container must complete successfully before the next one starts.
|
||||
|
||||
If a Pod's init container fails, the kubelet repeatedly restarts that init container until it succeeds. However, if the Pod has a restartPolicy of Never, and an init container fails during startup of that Pod, Kubernetes treats the overall Pod as failed.
|
||||
|
||||
kubectl delete service whoami
|
||||
cat >myapp-pod.yaml <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox:1.28
|
||||
command: ['sh', '-c', 'echo The app is running! && sleep 30']
|
||||
initContainers:
|
||||
- name: init-whoami
|
||||
image: busybox:1.28
|
||||
command: ['sh', '-c', "until nslookup whoami.\$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for whoami; sleep 2; done"]
|
||||
EOF
|
||||
kubectl apply -f myapp-pod.yaml
|
||||
kubectl describe pod myapp-pod
|
||||
# initContainer not ready
|
||||
kubectl apply -f service.yaml
|
||||
kubectl describe pod myapp-pod
|
||||
|
||||
https://github.com/groundnuty/k8s-wait-for
|
||||
|
||||
cat >myapp-pod-exists.yaml <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod-exists
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox:1.28
|
||||
command: ['sh', '-c', 'echo The app is running! && sleep 30']
|
||||
initContainers:
|
||||
- name: init-whoami
|
||||
image: busybox:1.28
|
||||
command: ['sh', '-c', "until nslookup whoami.\$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for whoami; sleep 2; done"]
|
||||
- name: wait-for-whoami-pods
|
||||
image: ghcr.io/groundnuty/k8s-wait-for:v1.7
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- "pod-wr"
|
||||
- "-lapp=whoami"
|
||||
EOF
|
||||
|
||||
kubectl scale deployment whoami --replicas=0
|
||||
kubectl apply -f myapp-pod-exists.yaml
|
||||
|
||||
kubectl create role pod-reader \
|
||||
--verb=get --verb=list --verb=watch \
|
||||
--resource=pods,services,deployments
|
||||
|
||||
kubectl get role pod-reader -o yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
creationTimestamp: "2022-10-27T13:11:32Z"
|
||||
name: pod-reader
|
||||
namespace: whoami-1
|
||||
resourceVersion: "48787"
|
||||
uid: 2aadcee7-66bc-4ebe-8acc-5f76e2065480
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
- services
|
||||
verbs:
|
||||
- get
|
||||
- listhttps://artifacthub.io/
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- deployments
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
|
||||
|
||||
kubectl create rolebinding default-pod-reader \
|
||||
--role=pod-reader \
|
||||
--serviceaccount=whoami-1:default \
|
||||
--namespace=whoami-1
|
||||
|
||||
kubectl get rolebindings.rbac.authorization.k8s.io default-pod-reader -o yaml
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
creationTimestamp: "2022-10-27T13:15:02Z"
|
||||
name: default-pod-reader
|
||||
namespace: whoami-1
|
||||
resourceVersion: "48886"https://artifacthub.io/
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: pod-reader
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: whoami-1
|
||||
|
||||
kubectl auth can-i list deployments.apps \
|
||||
--as system:serviceaccount:whoami-1:default
|
||||
yes
|
||||
kubectl auth can-i create deployments.apps \
|
||||
--as system:serviceaccount:whoami-1:default
|
||||
no
|
||||
|
||||
kubectl scale deployment whoami --replicas=1
|
||||
kubectl logs myapp-pod-exists -c wait-for-whoami-pods
|
||||
[2022-10-27 13:34:14] Waiting for pod -lapp=whoami...
|
||||
[2022-10-27 13:34:16] pod -lapp=whoami is ready.
|
||||
kubectl get pods
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
...
|
||||
myapp-pod-exists 0/1 Completed 1 (36s ago) 31m
|
||||
|
||||
Postgres initContainer
|
||||
|
||||
apiVersion: apps/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: webapp
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: webapp
|
||||
spec:
|
||||
volumes:
|
||||
- name: config-volume
|
||||
configMap:
|
||||
name: app-config
|
||||
initContainers:
|
||||
- name: check-db-ready
|
||||
image: postgres:15
|
||||
command: ['sh', '-c',
|
||||
'until pg_isready -h postgres -p 5432;
|
||||
do echo waiting for database; sleep 2; done;']
|
||||
|
||||
Git Sync
|
||||
|
||||
https://github.com/kubernetes/git-sync
|
||||
https://github.com/kubernetes/git-sync/blob/master/docs/ssh.md
|
||||
https://github.com/kubernetes/git-sync/blob/master/docs/kubernetes.md
|
||||
https://www.heise.de/tipps-tricks/SSH-Key-erstellen-so-geht-s-4400280.html
|
||||
|
||||
Challenges:
|
||||
|
||||
Create SSH Key
|
||||
Create local git repo
|
||||
Create a secret with SSH Key
|
||||
Create a pod with git sync initContainer from local repo
|
||||
|
||||
Create SSH Key
|
||||
|
||||
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_cnbc-rsa
|
||||
# without password...
|
||||
|
||||
Example to use Git Sync
|
||||
|
||||
# make a directory (owned by you) for the volume
|
||||
export DIR="/tmp/git-data"
|
||||
mkdir -p $DIR
|
||||
|
||||
# run the container (as your own UID)
|
||||
|
||||
# run the container
|
||||
docker container run -d \
|
||||
-v $DIR:/tmp/git \
|
||||
-u$(id -u):$(id -g) \
|
||||
k8s.gcr.io/git-sync/git-sync:v4.0.0 \
|
||||
--repo=https://github.com/kubernetes/git-sync \
|
||||
--root=/tmp/git/root \
|
||||
--period=30s
|
||||
|
||||
# run an nginx container to serve the content
|
||||
docker container run -d \
|
||||
-p 8080:80 \
|
||||
-v $DIR:/usr/share/nginx/html \
|
||||
nginx
|
||||
|
||||
31
k3d/stress/deployment2.yaml
Normal file
31
k3d/stress/deployment2.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: web
|
||||
name: web
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: web
|
||||
spec:
|
||||
containers:
|
||||
- image: bee42/whoami:2.2.0
|
||||
name: whoami
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "500m"
|
||||
274
k3d/stress/doku
Normal file
274
k3d/stress/doku
Normal file
@@ -0,0 +1,274 @@
|
||||
Deployment with Ressource Constraints
|
||||
|
||||
https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
|
||||
It's a good practice to assign a CPU request and a CPU limit to a container. Containers cannot use more CPU than the configured limit. Provided the system has CPU time free, a container is guaranteed to be allocated as much CPU as it requests.
|
||||
|
||||
mkdir ~/stress && cd ~/stress
|
||||
kubectl create namespace stress
|
||||
kubectl config set-context --current --namespace stress
|
||||
|
||||
cat >deployment2.yaml <<EOF
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: web
|
||||
name: web
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: web
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: web
|
||||
spec:
|
||||
containers:
|
||||
- image: bee42/whoami:2.2.0
|
||||
name: whoami
|
||||
ports:
|
||||
- containerPort: 80
|
||||
resources:
|
||||
requests:
|
||||
memory: "64Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "128Mi"
|
||||
cpu: "500m"
|
||||
EOF
|
||||
|
||||
kubectl apply -f deployment2.yaml
|
||||
kubectl get pods
|
||||
kubectl get all
|
||||
kubectl describe deployment web
|
||||
kubectl rollout history deployment web
|
||||
# set change cause
|
||||
kubectl annotate deployment web kubernetes.io/change-cause='set cpu limit 500'
|
||||
kubectl rollout history deployment web
|
||||
|
||||
https://kubernetes.io/docs/tasks/configure-pod-container/quality-service-pod/
|
||||
QoS
|
||||
https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/quota-pod-namespace/
|
||||
ResoureQuota
|
||||
|
||||
Generate Stress
|
||||
|
||||
https://linux.die.net/man/1/stress
|
||||
|
||||
create your own stress tool
|
||||
|
||||
mkdir -p ~/stress && cd ~/stress
|
||||
cat >Dockerfile <<EOF
|
||||
FROM ubuntu
|
||||
|
||||
RUN apt-get update && apt-get install -y stress && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENTRYPOINT ["/usr/bin/stress", "--verbose"]
|
||||
CMD []
|
||||
EOF
|
||||
docker build -t 127.0.0.1:5000/bee42/stress .
|
||||
docker push 127.0.0.1:5000/bee42/stress
|
||||
|
||||
Todo:
|
||||
|
||||
apply the pod
|
||||
check with kubectl top pods
|
||||
|
||||
cat >pod.yaml <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: cpu-demo
|
||||
spec:
|
||||
containers:
|
||||
- name: cpu
|
||||
image: cnbc-registry:5000/bee42/stress
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
requests:
|
||||
cpu: "0.5"
|
||||
args:
|
||||
- --cpu
|
||||
- "2"
|
||||
EOF
|
||||
kubectl apply -f pod.yaml
|
||||
kubectl describe pod cpu-demo
|
||||
# wait a minute
|
||||
kubectl top pods
|
||||
NAME CPU(cores) MEMORY(bytes)
|
||||
cpu-demo 1962m 1Mi
|
||||
hey 0m 0Mi
|
||||
load 0m 1Mi
|
||||
web-7cdc98f947-2n2dp 0m 3Mi
|
||||
web-7cdc98f947-gn2cg 0m 4Mi
|
||||
|
||||
# Consume more cpu the limits set!
|
||||
|
||||
# PLEASE KILL this pod
|
||||
kubectl delete pod cpu-demo --force=true --grace-period=0
|
||||
|
||||
stress-deploy.yaml
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cpu-demo
|
||||
labels:
|
||||
app: cpu-demo
|
||||
spec:
|
||||
replicas: 4
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cpu-demo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cpu-demo
|
||||
spec:
|
||||
containers:
|
||||
- name: stress
|
||||
image: cnbc-registry:5000/bee42/stress
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
requests:
|
||||
cpu: "0.5"
|
||||
args:
|
||||
- --cpu
|
||||
- "2"
|
||||
nodeName: k3d-cnbc-agent-1
|
||||
|
||||
kubectl apply -f stress-deploy.yaml
|
||||
kubectl top pods
|
||||
kubectl top nodes
|
||||
NAME CPU(cores) MEMORY(bytes)
|
||||
cpu-demo-595664dd8-lschw 1022m 1Mi
|
||||
cpu-demo-595664dd8-npx4w 975m 1Mi
|
||||
cpu-demo-595664dd8-p249m 993m 1Mi
|
||||
cpu-demo-595664dd8-twn84 940m 1Mi
|
||||
web-588896757f-52gx9 0m 1Mi
|
||||
|
||||
kubectl scale deploy cpu-demo --replicas=3
|
||||
|
||||
sleep 45
|
||||
|
||||
kubectl top nodes
|
||||
kubectl top pods
|
||||
NAME CPU(cores) MEMORY(bytes)
|
||||
cpu-demo-595664dd8-npx4w 1017m 1Mi
|
||||
cpu-demo-595664dd8-p249m 988m 1Mi
|
||||
cpu-demo-595664dd8-twn84 980m 1Mi
|
||||
web-588896757f-52gx9 1m 1Mi
|
||||
|
||||
https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/
|
||||
Kubelet parameter
|
||||
|
||||
Tipp:
|
||||
|
||||
use imagePullSecerts to auth container registries
|
||||
|
||||
https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
|
||||
|
||||
Memory Overload
|
||||
|
||||
https://www.cyberciti.biz/faq/stress-test-linux-unix-server-with-stress-ng/
|
||||
https://sysdig.com/blog/troubleshoot-kubernetes-oom/
|
||||
|
||||
k3d node create --cluster cnbc --role agent --memory 2G k3d-cnbc-agent-2
|
||||
kubectl get nodes
|
||||
# wait for ready
|
||||
kubectl apply -f mem-deploy.yaml
|
||||
|
||||
kubectl top nodes
|
||||
# OK!
|
||||
kubectl scale deploy mem-demo --replicas=4
|
||||
|
||||
# Hups...
|
||||
kubectl scale deploy mem-demo --replicas=5
|
||||
# wait 60 secs
|
||||
kubectl get pods -w
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
web-588896757f-52gx9 1/1 Running 0 60m
|
||||
mem-demo-67998d7456-4ntqw 1/1 Running 0 4m20s
|
||||
mem-demo-67998d7456-htvnn 1/1 Running 0 4m20s
|
||||
mem-demo-67998d7456-4f2wd 1/1 Running 0 2m2s
|
||||
mem-demo-67998d7456-kx4xv 1/1 Running 2 (49s ago) 4m20s
|
||||
mem-demo-67998d7456-d86cs 0/1 OOMKilled 2 (25s ago) 58s
|
||||
mem-demo-67998d7456-d86cs 0/1 CrashLoopBackOff 2 (12s ago) 65s
|
||||
mem-demo-67998d7456-d86cs 1/1 Running 3 (28s ago) 81s
|
||||
mem-demo-67998d7456-4ntqw 0/1 OOMKilled 0 4m44s
|
||||
mem-demo-67998d7456-4ntqw 1/1 Running 1 (2s ago) 4m45s
|
||||
mem-demo-67998d7456-4f2wd 0/1 OOMKilled 0 2m29s
|
||||
mem-demo-67998d7456-4f2wd 1/1 Running 1 (2s ago) 2m30s
|
||||
mem-demo-67998d7456-d86cs 0/1 OOMKilled 3 (35s ago) 88s
|
||||
mem-demo-67998d7456-d86cs 0/1 CrashLoopBackOff 3 (12s ago) 99s
|
||||
|
||||
# fix: scale down
|
||||
kubectl scale deploy mem-demo --replicas=4
|
||||
|
||||
# cleanup deploy
|
||||
kubectl delete -f mem-deploy.yaml
|
||||
|
||||
# drain node
|
||||
|
||||
kubectl drain k3d-k3d-cnbc-agent-2-0
|
||||
k3d node delete k3d-k3d-cnbc-agent-2-0
|
||||
kubectl delete node k3d-k3d-cnbc-agent-2-0
|
||||
|
||||
mem-deploy.yaml
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mem-demo
|
||||
labels:
|
||||
app: mem-demo
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mem-demo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mem-demo
|
||||
spec:
|
||||
containers:
|
||||
- name: stress
|
||||
image: cnbc-registry:5000/bee42/stress
|
||||
resources:
|
||||
limits:
|
||||
memory: "500Mi"
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
args:
|
||||
- "-m"
|
||||
- "1"
|
||||
- "--vm-bytes"
|
||||
- "490M"
|
||||
nodeName: k3d-k3d-cnbc-agent-2-0
|
||||
|
||||
Kubernetes Failures
|
||||
|
||||
https://codeberg.org/hjacobs/kubernetes-failure-stories
|
||||
https://medium.com/omio-engineering/cpu-limits-and-aggressive-throttling-in-kubernetes-c5b20bd8a718
|
||||
https://home.robusta.dev/blog/stop-using-cpu-limits
|
||||
|
||||
Best practices for CPU limits and requests on Kubernetes
|
||||
|
||||
Use CPU requests for everything
|
||||
Make sure they are accurate
|
||||
Do not use CPU limits.
|
||||
|
||||
What about memory limits and requests?
|
||||
|
||||
Always use memory limits
|
||||
Always use memory requests
|
||||
Always set your memory requests equal to your limits
|
||||
|
||||
14
k3d/volumes/pv
Normal file
14
k3d/volumes/pv
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: task-pv-volume
|
||||
labels:
|
||||
type: local
|
||||
spec:
|
||||
storageClassName: manual
|
||||
capacity:
|
||||
storage: 10Gi
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
hostPath:
|
||||
path: "/mnt/data"
|
||||
0
k3d/volumes/pvc
Normal file
0
k3d/volumes/pvc
Normal file
10
k8s/carpool/Dockerfile
Normal file
10
k8s/carpool/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM python:3.8-slim-buster
|
||||
WORKDIR /app
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip3 install --disable-pip-version-check -r requirements.txt
|
||||
COPY . .
|
||||
ENV FLASK_APP=python_rest
|
||||
EXPOSE 5000
|
||||
STOPSIGNAL SIGINT
|
||||
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
|
||||
23
k8s/carpool/deployment.yaml
Normal file
23
k8s/carpool/deployment.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: carpool
|
||||
labels:
|
||||
app: carpool
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: carpool
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: carpool
|
||||
spec:
|
||||
containers:
|
||||
- name: carpool
|
||||
image: cnbc-registry:5000/bee42/carpool:0.1.0
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: FLASK_APP
|
||||
value: python_rest
|
||||
714
k8s/carpool/doku
Normal file
714
k8s/carpool/doku
Normal file
@@ -0,0 +1,714 @@
|
||||
carpool examples
|
||||
|
||||
mkdir ~/carpool && cd ~/carpool
|
||||
# create app
|
||||
vi python_rest.py
|
||||
vi requirements.txt
|
||||
vi Dockerfile
|
||||
|
||||
python_rest.py
|
||||
|
||||
python_rest.py
|
||||
|
||||
from flask import Flask, request, jsonify
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_marshmallow import Marshmallow, fields
|
||||
from flask_cors import CORS
|
||||
|
||||
# Init app
|
||||
app = Flask(__name__)
|
||||
|
||||
#enable CORS
|
||||
CORS(app)
|
||||
# connect to already existing and running Database
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:cnbc@postgres:5432/esentricar'
|
||||
|
||||
# not important but otherwise we get a warning every time
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
|
||||
#Init db
|
||||
db = SQLAlchemy(app)
|
||||
#Init ma
|
||||
ma = Marshmallow(app)
|
||||
|
||||
# Pool Car Class/Model
|
||||
class Pool_Car(db.Model):
|
||||
|
||||
#define table, in our case already existing
|
||||
__tablename__ = 'cars'
|
||||
car_id = db.Column(db.Integer, primary_key=True)
|
||||
license_plate = db.Column(db.String(30), unique=True)
|
||||
car_type = db.Column(db.String(20))
|
||||
fuel = db.Column(db.String(20))
|
||||
number_of_seats =db.Column(db.Integer)
|
||||
|
||||
|
||||
# set class attributes
|
||||
def __init__(self, license_plate, car_type, fuel, number_of_seats):
|
||||
self.license_plate = license_plate
|
||||
self.car_type = car_type
|
||||
self.fuel = fuel
|
||||
self.number_of_seats = number_of_seats
|
||||
|
||||
class Pool_CarSchema(ma.Schema):
|
||||
class Meta:
|
||||
fields = ('car_id','license_plate','car_type','fuel','number_of_seats')
|
||||
|
||||
# Init schema
|
||||
pool_car_schema = Pool_CarSchema()
|
||||
pool_cars_schema = Pool_CarSchema(many=True)
|
||||
|
||||
|
||||
# Create a Pool_Car
|
||||
@app.route('/car', methods=['POST'])
|
||||
def add_pool_car():
|
||||
# Get request data as json
|
||||
car_entity = request.get_json()
|
||||
license_plate= car_entity.get('license_plate')
|
||||
car_type = car_entity.get('car_type')
|
||||
fuel = car_entity.get('fuel')
|
||||
number_of_seats = car_entity.get('number_of_seats')
|
||||
|
||||
new_pool_car = Pool_Car(license_plate, car_type, fuel, number_of_seats)
|
||||
|
||||
db.session.add(new_pool_car)
|
||||
db.session.commit()
|
||||
|
||||
return pool_car_schema.jsonify(new_pool_car)
|
||||
|
||||
# Get car_id,license_plate,car_type of all products of the table
|
||||
@app.route('/car', methods=['GET'])
|
||||
def get_pool_cars():
|
||||
all_pool_cars = Pool_Car.query.all()
|
||||
result = pool_cars_schema.dump(all_pool_cars)
|
||||
car_list= []
|
||||
for item in result:
|
||||
car_details = { "car_id":None, "license_plate":None, "car_type":None}
|
||||
car_details['car_id'] = item['car_id']
|
||||
car_details['license_plate'] = item['license_plate']
|
||||
car_details['car_type'] = item['car_type']
|
||||
car_list.append(car_details)
|
||||
return jsonify(car_list)
|
||||
|
||||
# Get Single Products
|
||||
@app.route('/car/<car_id>', methods=['GET'])
|
||||
def get_pool_car(car_id):
|
||||
pool_car = Pool_Car.query.get(car_id)
|
||||
return pool_car_schema.jsonify(pool_car)
|
||||
|
||||
# Delete Product
|
||||
@app.route('/car/<car_id>', methods=['DELETE'])
|
||||
def delete_pool_car(car_id):
|
||||
pool_car = Pool_Car.query.get(car_id)
|
||||
db.session.delete(pool_car)
|
||||
db.session.commit()
|
||||
|
||||
return pool_car_schema.jsonify(pool_car)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True) #port='5002'
|
||||
|
||||
requirements.txt
|
||||
|
||||
requirements.txt
|
||||
|
||||
Flask==1.1.1
|
||||
Flask-Cors==3.0.8
|
||||
flask-marshmallow==0.10.1
|
||||
Flask-SQLAlchemy==2.4.1
|
||||
werkzeug==2.0.2
|
||||
marshmallow==3.2.2
|
||||
SQLAlchemy==1.3.11
|
||||
marshmallow-sqlalchemy==0.19.0
|
||||
psycopg2-binary==2.8.4
|
||||
itsdangerous==2.0.1
|
||||
Jinja2==3.0.3
|
||||
|
||||
Dockerfile
|
||||
|
||||
Dockerfile
|
||||
|
||||
# syntax=docker/dockerfile:1
|
||||
FROM python:3.8-slim-buster
|
||||
WORKDIR /app
|
||||
COPY requirements.txt requirements.txt
|
||||
RUN pip3 install --disable-pip-version-check -r requirements.txt
|
||||
COPY . .
|
||||
ENV FLASK_APP=python_rest
|
||||
EXPOSE 5000
|
||||
STOPSIGNAL SIGINT
|
||||
CMD [ "python3", "-m" , "flask", "run", "--host=0.0.0.0"]
|
||||
|
||||
Build app
|
||||
|
||||
docker build -t bee42/carpool:0.1.0 .
|
||||
curl http://127.0.0.1:5000/v2/_catalog
|
||||
{"repositories":[]}
|
||||
docker tag bee42/carpool:0.1.0 127.0.0.1:5000/bee42/carpool:0.1.0
|
||||
docker push 127.0.0.1:5000/bee42/carpool:0.1.0
|
||||
curl http://127.0.0.1:5000/v2/_catalog
|
||||
{"repositories":["bee42/carpool"]}
|
||||
curl http://127.0.0.1:5000/v2/bee42/carpool/tags/list
|
||||
{"name":"bee42/carpool","tags":["0.1.0"]}
|
||||
|
||||
|
||||
|
||||
CarPool Deploy Postgres
|
||||
|
||||
New Kubernetes Manifests:
|
||||
|
||||
Persistence Volume
|
||||
Config Map
|
||||
|
||||
mkdir ~/carpool/postgres && cd ~/carpool/postgres
|
||||
|
||||
# define kubernetes manifests
|
||||
|
||||
postgres-deploy.yaml
|
||||
|
||||
postgres-deploy.yaml
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: postgres
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:10.4
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: postgres-config
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/postgresql/data
|
||||
name: postgredb
|
||||
- name: config
|
||||
mountPath: "/docker-entrypoint-initdb.d"
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: carpool
|
||||
items:
|
||||
- key: "esentricar.sql"
|
||||
path: "esentricar.sql"
|
||||
- name: postgredb
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres-pv-claim
|
||||
|
||||
postgres-schema-cm.yaml
|
||||
|
||||
postgres-schema-cm.yaml
|
||||
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: carpool
|
||||
data:
|
||||
esentricar.sql: |
|
||||
CREATE DATABASE esentricar;
|
||||
\c esentricar;
|
||||
CREATE TABLE cars (
|
||||
car_id SERIAL PRIMARY KEY,
|
||||
license_plate varchar(30) NOT NULL,
|
||||
car_type varchar(30) NOT NULL,
|
||||
fuel varchar(30) NOT NULL,
|
||||
number_of_seats integer NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX cars_license_plate
|
||||
ON cars (license_plate);
|
||||
|
||||
postgres-config.yaml
|
||||
|
||||
postgres-config.yaml
|
||||
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: postgres-config
|
||||
labels:
|
||||
app: postgres
|
||||
data:
|
||||
POSTGRES_DB: postgresdb
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: cnbc
|
||||
|
||||
postgres-service.yaml
|
||||
|
||||
postgres-service.yaml
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
name: postgres
|
||||
spec:
|
||||
ports:
|
||||
- name: postgres
|
||||
port: 5432
|
||||
protocol: TCP
|
||||
targetPort: 5432
|
||||
selector:
|
||||
app: postgres
|
||||
type: ClusterIP
|
||||
|
||||
postgres-pv-claim.yaml
|
||||
|
||||
postgres-pv-claim.yaml
|
||||
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: postgres-pv-claim
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
|
||||
Create database
|
||||
|
||||
kubectl create namespace carpool
|
||||
kubectl config set-context --current --namespace=carpool
|
||||
# apply all manifests
|
||||
kubectl apply -f .
|
||||
kubectl get all
|
||||
kubectl get configmaps
|
||||
NAME DATA AGE
|
||||
kube-root-ca.crt 1 21m
|
||||
postgres-config 3 42s
|
||||
carpool 1 42s
|
||||
kubectl get pvc,pv
|
||||
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
|
||||
persistentvolumeclaim/postgres-pv-claim Bound pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e 1Gi RWO local-path 84s
|
||||
|
||||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
persistentvolume/pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e 1Gi RWO Delete Bound carpool/postgres-pv-claim local-path 79s
|
||||
kubectl describe pv
|
||||
Name: pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e
|
||||
Labels: <none>
|
||||
Annotations: pv.kubernetes.io/provisioned-by: rancher.io/local-path
|
||||
Finalizers: [kubernetes.io/pv-protection]
|
||||
StorageClass: local-path
|
||||
Status: Bound
|
||||
Claim: carpool/postgres-pv-claim
|
||||
Reclaim Policy: Delete
|
||||
Access Modes: RWO
|
||||
VolumeMode: Filesystem
|
||||
Capacity: 1Gi
|
||||
Node Affinity:
|
||||
Required Terms:
|
||||
Term 0: kubernetes.io/hostname in [k3d-cnbc-agent-1]
|
||||
Message:
|
||||
Source:
|
||||
Type: HostPath (bare host directory volume)
|
||||
Path: /var/lib/rancher/k3s/storage/pvc-e6e7ba0f-ff3e-4bfa-be1b-4db6629d027e_carpool_postgres-pv-claim
|
||||
HostPathType: DirectoryOrCreate
|
||||
Events: <none>
|
||||
|
||||
kubectl logs postgres-65974d6d58-72vk5
|
||||
The files belonging to this database system will be owned by user "postgres".
|
||||
This user must also own the server process.
|
||||
|
||||
The database cluster will be initialized with locale "en_US.utf8".
|
||||
The default database encoding has accordingly been set to "UTF8".
|
||||
The default text search configuration will be set to "english".
|
||||
|
||||
Data page checksums are disabled.
|
||||
|
||||
fixing permissions on existing directory /var/lib/postgresql/data ... ok
|
||||
creating subdirectories ... ok
|
||||
selecting default max_connections ... 100
|
||||
selecting default shared_buffers ... 128MB
|
||||
selecting dynamic shared memory implementation ... posix
|
||||
creating configuration files ... ok
|
||||
running bootstrap script ... ok
|
||||
performing post-bootstrap initialization ... ok
|
||||
syncing data to disk ... ok
|
||||
|
||||
Success. You can now start the database server using:
|
||||
|
||||
pg_ctl -D /var/lib/postgresql/data -l logfile start
|
||||
|
||||
|
||||
WARNING: enabling "trust" authentication for local connections
|
||||
You can change this by editing pg_hba.conf or using the option -A, or
|
||||
--auth-local and --auth-host, the next time you run initdb.
|
||||
waiting for server to start....2022-03-08 12:30:20.872 UTC [42] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
|
||||
2022-03-08 12:30:20.901 UTC [43] LOG: database system was shut down at 2022-03-08 12:30:20 UTC
|
||||
2022-03-08 12:30:20.911 UTC [42] LOG: database system is ready to accept connections
|
||||
done
|
||||
server started
|
||||
CREATE DATABASE
|
||||
|
||||
ALTER ROLE
|
||||
|
||||
|
||||
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/esentricar.sql
|
||||
CREATE DATABASE
|
||||
You are now connected to database "esentricar" as user "postgres".
|
||||
CREATE TABLE
|
||||
CREATE INDEX
|
||||
|
||||
|
||||
2022-03-08 12:30:21.781 UTC [42] LOG: received fast shutdown request
|
||||
waiting for server to shut down....2022-03-08 12:30:21.783 UTC [42] LOG: aborting any active transactions
|
||||
2022-03-08 12:30:21.787 UTC [42] LOG: worker process: logical replication launcher (PID 49) exited with exit code 1
|
||||
2022-03-08 12:30:21.790 UTC [44] LOG: shutting down
|
||||
2022-03-08 12:30:21.820 UTC [42] LOG: database system is shut down
|
||||
done
|
||||
server stopped
|
||||
|
||||
PostgreSQL init process complete; ready for start up.
|
||||
|
||||
2022-03-08 12:30:21.904 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
|
||||
2022-03-08 12:30:21.904 UTC [1] LOG: listening on IPv6 address "::", port 5432
|
||||
2022-03-08 12:30:21.909 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
|
||||
2022-03-08 12:30:21.929 UTC [79] LOG: database system was shut down at 2022-03-08 12:30:21 UTC
|
||||
2022-03-08 12:30:21.938 UTC [1] LOG: database system is ready to accept connections
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Carpool Deploy App
|
||||
|
||||
deploy service
|
||||
create first car
|
||||
|
||||
mkdir ~/carpool/app && cd ~/carpool/app
|
||||
vi deployment.yaml
|
||||
vi service.yaml
|
||||
|
||||
Find name of your local registry cnbc-registry
|
||||
|
||||
docker container ls
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
6f83432dbef0 rancher/k3d-proxy:5.3.0 "/bin/sh -c nginx-pr…" 29 hours ago Up 29 hours 0.0.0.0:8580->80/tcp, :::8580->80/tcp, 0.0.0.0:8543->443/tcp, :::8543->443/tcp, 0.0.0.0:8545->6443/tcp k3d-cnbc-serverlb
|
||||
5f26dbd03241 rancher/k3s:v1.22.6-k3s1 "/bin/k3s agent" 29 hours ago Up 29 hours k3d-cnbc-agent-1
|
||||
24d5876390bd rancher/k3s:v1.22.6-k3s1 "/bin/k3s agent" 29 hours ago Up 29 hours k3d-cnbc-agent-0
|
||||
b5a50e960917 rancher/k3s:v1.22.6-k3s1 "/bin/k3s server --t…" 29 hours ago Up 29 hours k3d-cnbc-server-0
|
||||
8f73928c8294 registry:2 "/entrypoint.sh /etc…" 29 hours ago Up 29 hours 0.0.0.0:5000->5000/tcp cnbc-registry
|
||||
|
||||
deployment.yaml
|
||||
|
||||
deployment.yaml
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: carpool
|
||||
labels:
|
||||
app: carpool
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: carpool
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: carpool
|
||||
spec:
|
||||
containers:
|
||||
- name: carpool
|
||||
image: cnbc-registry:5000/bee42/carpool:0.1.0
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: FLASK_APP
|
||||
value: python_rest
|
||||
|
||||
service.yaml
|
||||
|
||||
service.yaml
|
||||
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: carpool
|
||||
name: carpool
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 5000
|
||||
protocol: TCP
|
||||
targetPort: 5000
|
||||
selector:
|
||||
app: carpool
|
||||
type: ClusterIP
|
||||
|
||||
cd ..
|
||||
sudo apt install -y tree
|
||||
tree .
|
||||
.
|
||||
├── app
|
||||
│ ├── deployment.yaml
|
||||
│ └── service.yaml
|
||||
├── Dockerfile
|
||||
├── postgres
|
||||
│ ├── postgres-config.yaml
|
||||
│ ├── postgres-deploy.yaml
|
||||
│ ├── postgres-pv-claim.yaml
|
||||
│ ├── postgres-schema-cm.yaml
|
||||
│ └── postgres-service.yaml
|
||||
├── python_rest.py
|
||||
└── requirements.txt
|
||||
|
||||
Deploy App carpool
|
||||
|
||||
# create deployment and service manifests
|
||||
kubectl apply -f app
|
||||
kubectl get all
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
pod/postgres-65974d6d58-72vk5 1/1 Running 0 26m
|
||||
pod/carpool-67d9fcf5f4-8cwdg 1/1 Running 0 11s
|
||||
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
service/postgres ClusterIP 10.43.178.140 <none> 5432/TCP 26m
|
||||
service/carpool ClusterIP 10.43.223.216 <none> 5000/TCP 11s
|
||||
|
||||
NAME READY UP-TO-DATE AVAILABLE AGE
|
||||
deployment.apps/postgres 1/1 1 1 26m
|
||||
deployment.apps/carpool 1/1 1 1 11s
|
||||
|
||||
NAME DESIRED CURRENT READY AGE
|
||||
replicaset.apps/postgres-65974d6d58 1 1 1 26m
|
||||
replicaset.apps/carpool-67d9fcf5f4 1 1 1 11s
|
||||
|
||||
Access app
|
||||
|
||||
kubectl run curl --tty -i --image curlimages/curl -- /bin/sh
|
||||
# check registry access
|
||||
curl cnbc-registry:5000/v2/
|
||||
curl cnbc-registry:5000/v2/_catalog
|
||||
curl http://cnbc-registry:5000/v2/bee42/carpool/tags/list
|
||||
{"repositories":["bee42/carpool"]}
|
||||
# create data
|
||||
cd /tmp
|
||||
cat >car_1.json <<EOF
|
||||
{
|
||||
"license_plate": "BO-PR-72",
|
||||
"car_type": "mini clubman SD",
|
||||
"fuel": "diesel",
|
||||
"number_of_seats": "5"
|
||||
}
|
||||
EOF
|
||||
curl -i -X POST http://carpool:5000/car \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary "@car_1.json"
|
||||
HTTP/1.0 200 OK
|
||||
Content-Type: application/json
|
||||
Content-Length: 105
|
||||
Access-Control-Allow-Origin: *
|
||||
Server: Werkzeug/2.0.3 Python/3.8.12
|
||||
Date: Tue, 08 Mar 2022 12:57:40 GMT
|
||||
|
||||
{"car_id":1,"car_type":"mini clubman SD","fuel":"diesel","license_plate":"BO-PR-72","number_of_seats":5}
|
||||
# access data
|
||||
curl http://carpool:5000/car
|
||||
[{"car_id":1,"car_type":"mini clubman SD","license_plate":"BO-PR-72"}]
|
||||
|
||||
#check ips nach neustart
|
||||
kubectl get nodes -o wide
|
||||
docker network inspect k3d-cnbc
|
||||
kubectl edit cm -n kube-system coredns
|
||||
NodeHosts: |
|
||||
172.19.0.1 host.k3d.internal
|
||||
172.19.0.6 k3d-cnbc-serverlb
|
||||
172.19.0.3 k3d-cnbc-agent-0
|
||||
172.19.0.2 k3d-cnbc-server-0
|
||||
172.19.0.4 k3d-cnbc-agent-1
|
||||
172.19.0.5 cnbc-registry
|
||||
|
||||
Patch python_rest.py
|
||||
|
||||
Add import
|
||||
get env parameter
|
||||
concat postgres url with env var parameter
|
||||
|
||||
Optimize the App
|
||||
|
||||
no static postgres config
|
||||
define a app configmap
|
||||
|
||||
Edit app
|
||||
|
||||
vi ~/carpool/python_rest.py
|
||||
|
||||
import os
|
||||
|
||||
# Init app
|
||||
app = Flask(__name__)
|
||||
|
||||
user = os.environ.get('POSTGRES_USER', 'postgres')
|
||||
db = os.environ.get('POSTGRES_DB', 'esentricar' )
|
||||
passwd = os.environ.get('POSTGRES_PASSWORD', 'cnbc')
|
||||
host = os.environ.get('POSTGRES_HOST', 'postgres')
|
||||
#enable CORS
|
||||
CORS(app)
|
||||
# connect to already existing and running Database
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://' + user + ':' + passwd + '@' + host + ':5432/' + db
|
||||
|
||||
or patch:
|
||||
|
||||
cat >python_rest.py.patch <<EOF
|
||||
5a6,7
|
||||
> import os
|
||||
>
|
||||
8a11,14
|
||||
> user = os.environ.get('POSTGRES_USER', 'postgres')
|
||||
> db = os.environ.get('POSTGRES_DB', 'esentricar' )
|
||||
> passwd = os.environ.get('POSTGRES_PASSWORD', 'cnbc')
|
||||
> host = os.environ.get('POSTGRES_HOST', 'postgres')
|
||||
12c18
|
||||
< app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:cnbc@postgres:5432/esentricar'
|
||||
---
|
||||
> app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://' + user + ':' + passwd + '@' + host + ':5432/' + db
|
||||
EOF
|
||||
|
||||
patch -p0 < python_rest.py.patch python_rest.py
|
||||
|
||||
docker build -t bee42/carpool:0.2.0 .
|
||||
curl http://127.0.0.1:5000/v2/
|
||||
docker tag bee42/carpool:0.2.0 127.0.0.1:5000/bee42/carpool:0.2.0
|
||||
docker push 127.0.0.1:5000/bee42/carpool:0.2.0
|
||||
curl http://127.0.0.1:5000/v2/bee42/carpool/tags/list
|
||||
{"name":"bee42/carpool","tags":["0.1.0","0.2.0"]}
|
||||
|
||||
app/app-config.yaml
|
||||
|
||||
app-config.yaml
|
||||
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: app-config
|
||||
labels:
|
||||
app: carpool
|
||||
data:
|
||||
POSTGRES_DB: esentricar
|
||||
POSTGRES_PASSWORD: cnbc
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_HOST: postgres
|
||||
|
||||
app/deployment.yaml
|
||||
|
||||
deployment.yaml
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: carpool
|
||||
labels:
|
||||
app: carpool
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: carpool
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: carpool
|
||||
spec:
|
||||
containers:
|
||||
- name: carpool
|
||||
image: cnbc-registry:5000/bee42/carpool:0.2.0
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: FLASK_APP
|
||||
value: python_rest
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: app-config
|
||||
|
||||
kubectl apply -f app
|
||||
|
||||
# later curl exec
|
||||
kubectl attach -ti curl
|
||||
curl http://carpool:5000/car
|
||||
[{"car_id":1,"car_type":"mini clubman SD","license_plate":"BO-PR-72"}]
|
||||
# remove all
|
||||
kubectl get pv
|
||||
# patch pv if you need the data after redeploy :)
|
||||
|
||||
PV=$(kubectl get pvc -o json -lapp=postgres | jq -r .items[].spec.volumeName)
|
||||
|
||||
kubectl patch pv $PV -p "{\"spec\":{\"persistentVolumeReclaimPolicy\":\"Retain\"}}"
|
||||
|
||||
kubectl delete namespace carpool
|
||||
kubectl create namespace carpool
|
||||
kubectl apply -f postgres
|
||||
kubectl apply -f app
|
||||
|
||||
# Problem: Auto reassociation of pv does't work
|
||||
kubectl get pv
|
||||
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
|
||||
pvc-ab3ea061-9180-4e34-95d5-0100a149747d 1Gi RWO Retain Released carpool/postgres-pv-claim local-path 24m
|
||||
pvc-57cae9ed-3ebe-4181-819a-7a9cfd745606 1Gi RWO Delete Bound carpool/postgres-pv-claim local-path 28s
|
||||
|
||||
kubectl delete namespace carpool
|
||||
kubectl patch pv $PV --type json -p '[{"op": "remove", "path": "/spec/claimRef/uid"}]'
|
||||
kubectl create namespace carpool
|
||||
kubectl apply -f postgres
|
||||
kubectl apply -f app
|
||||
|
||||
Options define a node port services
|
||||
|
||||
cat ~/carpool/app/node-service.yaml <<EOF
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: carpool-node
|
||||
name: carpool-node
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 5000
|
||||
protocol: TCP
|
||||
targetPort: 5000
|
||||
selector:
|
||||
app: carpool
|
||||
type: NodePort
|
||||
status:
|
||||
loadBalancer: {}
|
||||
EOF
|
||||
kubectl get nodes -o wide
|
||||
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
|
||||
k3d-cnbc-agent-0 Ready worker 30h v1.22.7+k3s1 172.18.0.4 <none> K3s dev 5.4.0-109-generic containerd://1.5.9-k3s1
|
||||
k3d-cnbc-agent-1 Ready worker 30h v1.22.7+k3s1 172.18.0.3 <none> K3s dev 5.4.0-109-generic containerd://1.5.9-k3s1
|
||||
k3d-cnbc-server-0 Ready control-plane,master 30h v1.22.7+k3s1 172.18.0.2 <none> K3s dev 5.4.0-109-generic containerd://1.5.9-k3s1
|
||||
kubectl apply -f ~/carpool/app/node-service.yaml
|
||||
|
||||
kubectl get service
|
||||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
postgres ClusterIP 10.43.173.36 <none> 5432/TCP 5m37s
|
||||
carpool ClusterIP 10.43.41.38 <none> 5000/TCP 5m11s
|
||||
carpool-node NodePort 10.43.44.24 <none> 5000:31231/TCP 7s
|
||||
|
||||
curl 172.18.0.3:31231/car
|
||||
[{"car_id":1,"car_type":"mini clubman SD","license_plate":"BO-PR-72"}]
|
||||
|
||||
11
k8s/carpool/esentricar.sql
Normal file
11
k8s/carpool/esentricar.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
CREATE DATABASE esentricar;
|
||||
\c esentricar;
|
||||
CREATE TABLE cars (
|
||||
car_id SERIAL PRIMARY KEY,
|
||||
license_plate varchar(30) NOT NULL,
|
||||
car_type varchar(30) NOT NULL,
|
||||
fuel varchar(30) NOT NULL,
|
||||
number_of_seats integer NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX cars_license_plate
|
||||
ON cars (license_plate);
|
||||
1
k8s/carpool/index.env
Normal file
1
k8s/carpool/index.env
Normal file
@@ -0,0 +1 @@
|
||||
POSTGRES_PASSWORD=postgres
|
||||
10
k8s/carpool/postgres-config.yaml
Normal file
10
k8s/carpool/postgres-config.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: postgres-config
|
||||
labels:
|
||||
app: postgres
|
||||
data:
|
||||
POSTGRES_DB: postgresdb
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: cnbc
|
||||
39
k8s/carpool/postgres-deploy.yaml
Normal file
39
k8s/carpool/postgres-deploy.yaml
Normal file
@@ -0,0 +1,39 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: postgres
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: postgres
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
containers:
|
||||
- name: postgres
|
||||
image: postgres:10.4
|
||||
imagePullPolicy: "IfNotPresent"
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: postgres-config
|
||||
volumeMounts:
|
||||
- mountPath: /var/lib/postgresql/data
|
||||
name: postgredb
|
||||
- name: config
|
||||
mountPath: "/docker-entrypoint-initdb.d"
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: carpool
|
||||
items:
|
||||
- key: "esentricar.sql"
|
||||
path: "esentricar.sql"
|
||||
- name: postgredb
|
||||
persistentVolumeClaim:
|
||||
claimName: postgres-pv-claim
|
||||
13
k8s/carpool/postgres-pv-claim.yaml
Normal file
13
k8s/carpool/postgres-pv-claim.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: postgres-pv-claim
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
storageClassName: local-path
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
17
k8s/carpool/postgres-schema-cm.yaml
Normal file
17
k8s/carpool/postgres-schema-cm.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: carpool
|
||||
data:
|
||||
esentricar.sql: |
|
||||
CREATE DATABASE esentricar;
|
||||
\c esentricar;
|
||||
CREATE TABLE cars (
|
||||
car_id SERIAL PRIMARY KEY,
|
||||
license_plate varchar(30) NOT NULL,
|
||||
car_type varchar(30) NOT NULL,
|
||||
fuel varchar(30) NOT NULL,
|
||||
number_of_seats integer NOT NULL
|
||||
);
|
||||
CREATE UNIQUE INDEX cars_license_plate
|
||||
ON cars (license_plate);
|
||||
15
k8s/carpool/postgres-service.yaml
Normal file
15
k8s/carpool/postgres-service.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: postgres
|
||||
name: postgres
|
||||
spec:
|
||||
ports:
|
||||
- name: postgres
|
||||
port: 5432
|
||||
protocol: TCP
|
||||
targetPort: 5432
|
||||
selector:
|
||||
app: postgres
|
||||
type: ClusterIP
|
||||
98
k8s/carpool/python_rest.py
Normal file
98
k8s/carpool/python_rest.py
Normal file
@@ -0,0 +1,98 @@
|
||||
from flask import Flask, request, jsonify
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_marshmallow import Marshmallow, fields
|
||||
from flask_cors import CORS
|
||||
|
||||
# Init app
|
||||
app = Flask(__name__)
|
||||
|
||||
#enable CORS
|
||||
CORS(app)
|
||||
# connect to already existing and running Database
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:cnbc@postgres:5432/esentricar'
|
||||
|
||||
# not important but otherwise we get a warning every time
|
||||
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
|
||||
|
||||
#Init db
|
||||
db = SQLAlchemy(app)
|
||||
#Init ma
|
||||
ma = Marshmallow(app)
|
||||
|
||||
# Pool Car Class/Model
|
||||
class Pool_Car(db.Model):
|
||||
|
||||
#define table, in our case already existing
|
||||
__tablename__ = 'cars'
|
||||
car_id = db.Column(db.Integer, primary_key=True)
|
||||
license_plate = db.Column(db.String(30), unique=True)
|
||||
car_type = db.Column(db.String(20))
|
||||
fuel = db.Column(db.String(20))
|
||||
number_of_seats =db.Column(db.Integer)
|
||||
|
||||
|
||||
# set class attributes
|
||||
def __init__(self, license_plate, car_type, fuel, number_of_seats):
|
||||
self.license_plate = license_plate
|
||||
self.car_type = car_type
|
||||
self.fuel = fuel
|
||||
self.number_of_seats = number_of_seats
|
||||
|
||||
class Pool_CarSchema(ma.Schema):
|
||||
class Meta:
|
||||
fields = ('car_id','license_plate','car_type','fuel','number_of_seats')
|
||||
|
||||
# Init schema
|
||||
pool_car_schema = Pool_CarSchema()
|
||||
pool_cars_schema = Pool_CarSchema(many=True)
|
||||
|
||||
|
||||
# Create a Pool_Car
|
||||
@app.route('/car', methods=['POST'])
|
||||
def add_pool_car():
|
||||
# Get request data as json
|
||||
car_entity = request.get_json()
|
||||
license_plate= car_entity.get('license_plate')
|
||||
car_type = car_entity.get('car_type')
|
||||
fuel = car_entity.get('fuel')
|
||||
number_of_seats = car_entity.get('number_of_seats')
|
||||
|
||||
new_pool_car = Pool_Car(license_plate, car_type, fuel, number_of_seats)
|
||||
|
||||
db.session.add(new_pool_car)
|
||||
db.session.commit()
|
||||
|
||||
return pool_car_schema.jsonify(new_pool_car)
|
||||
|
||||
# Get car_id,license_plate,car_type of all products of the table
|
||||
@app.route('/car', methods=['GET'])
|
||||
def get_pool_cars():
|
||||
all_pool_cars = Pool_Car.query.all()
|
||||
result = pool_cars_schema.dump(all_pool_cars)
|
||||
car_list= []
|
||||
for item in result:
|
||||
car_details = { "car_id":None, "license_plate":None, "car_type":None}
|
||||
car_details['car_id'] = item['car_id']
|
||||
car_details['license_plate'] = item['license_plate']
|
||||
car_details['car_type'] = item['car_type']
|
||||
car_list.append(car_details)
|
||||
return jsonify(car_list)
|
||||
|
||||
# Get Single Products
|
||||
@app.route('/car/<car_id>', methods=['GET'])
|
||||
def get_pool_car(car_id):
|
||||
pool_car = Pool_Car.query.get(car_id)
|
||||
return pool_car_schema.jsonify(pool_car)
|
||||
|
||||
# Delete Product
|
||||
@app.route('/car/<car_id>', methods=['DELETE'])
|
||||
def delete_pool_car(car_id):
|
||||
pool_car = Pool_Car.query.get(car_id)
|
||||
db.session.delete(pool_car)
|
||||
db.session.commit()
|
||||
|
||||
return pool_car_schema.jsonify(pool_car)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True) #port='5002'
|
||||
11
k8s/carpool/requirements.txt
Normal file
11
k8s/carpool/requirements.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Flask==1.1.1
|
||||
Flask-Cors==3.0.8
|
||||
flask-marshmallow==0.10.1
|
||||
Flask-SQLAlchemy==2.4.1
|
||||
werkzeug==2.0.2
|
||||
marshmallow==3.2.2
|
||||
SQLAlchemy==1.3.11
|
||||
marshmallow-sqlalchemy==0.19.0
|
||||
psycopg2-binary==2.8.4
|
||||
itsdangerous==2.0.1
|
||||
Jinja2==3.0.3
|
||||
15
k8s/carpool/service.yaml
Normal file
15
k8s/carpool/service.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: carpool
|
||||
name: carpool
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 5000
|
||||
protocol: TCP
|
||||
targetPort: 5000
|
||||
selector:
|
||||
app: carpool
|
||||
type: ClusterIP
|
||||
82
k8s/config_map
Normal file
82
k8s/config_map
Normal file
@@ -0,0 +1,82 @@
|
||||
kubectl create deploy nginx --image nginx --dry-run=client -o yaml >nginx-deploy.yaml
|
||||
vi nginx-deploy.yaml
|
||||
# add volume mounts and volumes from configMap
|
||||
|
||||
# create config Map
|
||||
echo Linuxhotel >index.html
|
||||
|
||||
kubectl create configmap htdocs --from-file index.html=index.html --dry-run=client -o yaml >htdocs-cm.yaml
|
||||
|
||||
kubectl -n nginx apply -f htdocs-cm.yaml
|
||||
kubectl -n nginx apply -f nginx-deploy.yaml
|
||||
|
||||
kubectl -n nginx exec -ti nginx-6fc76484c-q8tmd -- /bin/sh
|
||||
# more /usr/share/nginx/html/index.html
|
||||
|
||||
kubectl edit -n nginx cm htdocs
|
||||
# change content
|
||||
apiVersion: v1
|
||||
data:
|
||||
index.html: |
|
||||
Linuxhotel Cloud Native Base Camp
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: htdocs
|
||||
|
||||
# See it change at running pods!
|
||||
|
||||
kubectl -n nginx exec -ti nginx-6fc76484c-q8tmd -- /bin/sh
|
||||
# more /usr/share/nginx/html/index.html
|
||||
Linuxhotel Cloud Native Base Camp
|
||||
|
||||
|
||||
|
||||
|
||||
htdocs-cm.yaml
|
||||
|
||||
apiVersion: v1
|
||||
data:
|
||||
index.html: |
|
||||
Linuxhotel
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: htdocs
|
||||
|
||||
|
||||
|
||||
|
||||
nginx-deploy.yaml
|
||||
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: nginx
|
||||
name: nginx
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
strategy: {}
|
||||
template:
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
name: nginx
|
||||
resources: {}
|
||||
volumeMounts:
|
||||
- name: htdocs
|
||||
mountPath: /usr/share/nginx/html
|
||||
volumes:
|
||||
- name: htdocs
|
||||
configMap:
|
||||
name: htdocs
|
||||
status: {}
|
||||
|
||||
6
k8s/pods
6
k8s/pods
@@ -67,4 +67,8 @@ kubectl get rs -o json |jq -r .items[].metadata.annotations.\"deployment.kuberne
|
||||
kubectl get pods
|
||||
kubectl get pod <web pod> -o yaml | sed 's/\(image: nginx\):.*$/\1:1.19.3/' | kubectl replace -f -
|
||||
|
||||
#kubectl get pod web-548df7676c-v48kv -o yaml | sed 's/\(image: nginx\):.*$/\1:1.19.4/' | kubectl replace -f - web-548df7676c-rzp7v
|
||||
#kubectl get pod web-548df7676c-v48kv -o yaml | sed 's/\(image: nginx\):.*$/\1:1.19.4/' | kubectl replace -f - web-548df7676c-rzp7v
|
||||
|
||||
curl -i -X POST http://carpool:5000/car \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary "@car_2.json"
|
||||
93
k8s/pvc
Normal file
93
k8s/pvc
Normal file
@@ -0,0 +1,93 @@
|
||||
Retain static PersistentVolumeClaim
|
||||
|
||||
Change Claim to static hostPath volume
|
||||
|
||||
cat >~/carpool/postgres/postgres-pv-claim.yaml <<EOF
|
||||
kind: PersistentVolumeClaim
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: postgres-pv-claim
|
||||
labels:
|
||||
app: postgres
|
||||
spec:
|
||||
storageClassName: ""
|
||||
volumeName: postgres-pv
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
EOF
|
||||
|
||||
Create static PersistenceVolume
|
||||
|
||||
cat >~/carpool/postgres/postgres-pv.yaml <<EOF
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata:
|
||||
name: postgres-pv
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
capacity:
|
||||
storage: 1Gi
|
||||
claimRef:
|
||||
name: postgres-pv-claim
|
||||
namespace: carpool
|
||||
hostPath:
|
||||
path: /data
|
||||
type: DirectoryOrCreate
|
||||
nodeAffinity:
|
||||
required:
|
||||
nodeSelectorTerms:
|
||||
- matchExpressions:
|
||||
- key: kubernetes.io/hostname
|
||||
operator: In
|
||||
values:
|
||||
- k3d-cnbc-agent-1
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
storageClassName: ""
|
||||
volumeMode: Filesystem
|
||||
EOF
|
||||
|
||||
Szenario:
|
||||
|
||||
kubectl delete namespace carpool
|
||||
kubectl delete pv <...>
|
||||
|
||||
kubectl create namespace carpool
|
||||
kubectl apply -f postgres
|
||||
kubectl apply -f app
|
||||
kubectl run curl -ti --image=curlimages/curl -- /bin/sh
|
||||
cd /tmp
|
||||
cat >car_1.json <<EOF
|
||||
{
|
||||
"license_plate": "BO-PR-72",
|
||||
"car_type": "mini clubman SD",
|
||||
"fuel": "diesel",
|
||||
"number_of_seats": "5"
|
||||
}
|
||||
EOF
|
||||
curl -i -X POST http://carpool:5000/car \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary "@car_1.json"
|
||||
|
||||
curl http://carpool:5000/car
|
||||
exit
|
||||
|
||||
# delete again and check retaining of pv
|
||||
kubectl delete namespace carpool
|
||||
kubectl get pv
|
||||
|
||||
# if not edit Postgres pvc and pod pending
|
||||
|
||||
kubectl edit pv <...>
|
||||
# remove claim-ref uid and resource version
|
||||
kubectl create ns carpool
|
||||
kubectl apply -f postgres
|
||||
kubectl apply -f app
|
||||
kubectl run curl -ti --image=curlimages/curl -- /bin/sh
|
||||
curl http://carpool:5000/car
|
||||
# data exists
|
||||
exit
|
||||
|
||||
@@ -9,7 +9,6 @@ services:
|
||||
- /var/cache/nginx
|
||||
- /run
|
||||
read_only: true
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
|
||||
152
traefik/doku
Normal file
152
traefik/doku
Normal file
@@ -0,0 +1,152 @@
|
||||
mkdir ~/traefik && cd ~/traefik
|
||||
helm repo add traefik https://helm.traefik.io/traefik
|
||||
helm repo update
|
||||
helm pull traefik/traefik --untar
|
||||
cd traefik
|
||||
tree .
|
||||
|
||||
.
|
||||
├── Changelog.md
|
||||
├── Chart.yaml
|
||||
├── crds
|
||||
│ ├── ingressroutetcp.yaml
|
||||
│ ├── ingressrouteudp.yaml
|
||||
│ ├── ingressroute.yaml
|
||||
│ ├── middlewarestcp.yaml
|
||||
│ ├── middlewares.yaml
|
||||
│ ├── serverstransports.yaml
|
||||
│ ├── tlsoptions.yaml
|
||||
│ ├── tlsstores.yaml
|
||||
│ └── traefikservices.yaml
|
||||
├── Guidelines.md
|
||||
├── LICENSE
|
||||
├── README.md
|
||||
├── templates
|
||||
│ ├── daemonset.yaml
|
||||
│ ├── dashboard-hook-ingressroute.yaml
|
||||
│ ├── deployment.yaml
|
||||
│ ├── extra-objects.yaml
|
||||
│ ├── gatewayclass.yaml
|
||||
│ ├── gateway.yaml
|
||||
│ ├── _helpers.tpl
|
||||
│ ├── hpa.yaml
|
||||
│ ├── ingressclass.yaml
|
||||
│ ├── poddisruptionbudget.yaml
|
||||
│ ├── _podtemplate.tpl
|
||||
│ ├── pvc.yaml
|
||||
│ ├── rbac
|
||||
│ │ ├── clusterrolebinding.yaml
|
||||
│ │ ├── clusterrole.yaml
|
||||
│ │ ├── podsecuritypolicy.yaml
|
||||
│ │ ├── rolebinding.yaml
|
||||
│ │ ├── role.yaml
|
||||
│ │ └── serviceaccount.yaml
|
||||
│ ├── _service.tpl
|
||||
│ ├── service.yaml
|
||||
│ ├── tlsoption.yaml
|
||||
│ └── tlsstore.yaml
|
||||
└── values.yaml
|
||||
|
||||
3 directories, 37 files
|
||||
|
||||
# install
|
||||
kubectl create ns traefik-v2
|
||||
helm install --namespace=traefik-v2 \
|
||||
traefik traefik/traefik
|
||||
kubectl -n traefik-v2 get all
|
||||
|
||||
cd ../web/
|
||||
|
||||
cat >ingress-values.yaml <<EOF
|
||||
ingress:
|
||||
enabled: true
|
||||
className: ""
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: web.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
EOF
|
||||
|
||||
helm template --values ingress-values.yaml --set image.tag=1.21.3 . |more
|
||||
helm upgrade web --values ingress-values.yaml --set image.tag=1.21.3 .
|
||||
curl -H "Host: web.local" http://127.0.0.1:8580
|
||||
|
||||
Beispiel Ingress Manifest
|
||||
|
||||
# Source: web/templates/ingress.yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: release-name-web
|
||||
labels:
|
||||
helm.sh/chart: web-0.1.0
|
||||
app.kubernetes.io/name: web
|
||||
app.kubernetes.io/instance: release-name
|
||||
app.kubernetes.io/version: "1.16.0"
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
spec:
|
||||
rules:
|
||||
- host: "web.local"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: release-name-web
|
||||
port:
|
||||
number: 80
|
||||
|
||||
cat >~/carpool/app/ingress.yaml <<EOF
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: carpool
|
||||
labels:
|
||||
app.kubernetes.io/name: carpool
|
||||
annotations:
|
||||
kubernetes.io/ingress.class: traefik
|
||||
spec:
|
||||
rules:
|
||||
- host: "carpool.local"
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
backend:
|
||||
service:
|
||||
name: carpool
|
||||
port:
|
||||
number: 5000
|
||||
EOF
|
||||
kubectl apply -n carpool -f ~/carpool/app/ingress.yaml
|
||||
curl -H "Host: carpool.local" http://127.0.0.1:8580/car
|
||||
[{"car_id":1,"car_type":"mini clubman SD","license_plate":"BO-PR-72"}]
|
||||
TRAEFIK_PODNAME=$(kubectl -n traefik-v2 get pods -l app.kubernetes.io/name=traefik -o jsonpath="{range .items[*]}{@.metadata.name}{end}")
|
||||
kubectl -n traefik-v2 port-forward $TRAEFIK_PODNAME 9000:9000 &
|
||||
# open browser http://127.0.0.1:9000/dashboard/
|
||||
|
||||
|
||||
# or
|
||||
|
||||
# cloud instance
|
||||
IP4=$(/sbin/ip -o -4 addr list eth0 | awk '{print $4}' | cut -d/ -f1)
|
||||
# notebook
|
||||
IP4=$(/sbin/ip -o -4 addr list br2 | awk '{print $4}' | cut -d/ -f1
|
||||
|
||||
kubectl -n traefik-v2 port-forward $TRAEFIK_PODNAME --address $IP4 9000:9000 &
|
||||
|
||||
# open browser http://$IP4:9000/dashboard/
|
||||
|
||||
|
||||
331
traefik/get_helm.sh
Executable file
331
traefik/get_helm.sh
Executable file
@@ -0,0 +1,331 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright The Helm Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# The install script is based off of the MIT-licensed script from glide,
|
||||
# the package manager for Go: https://github.com/Masterminds/glide.sh/blob/master/get
|
||||
|
||||
: ${BINARY_NAME:="helm"}
|
||||
: ${USE_SUDO:="true"}
|
||||
: ${DEBUG:="false"}
|
||||
: ${VERIFY_CHECKSUM:="true"}
|
||||
: ${VERIFY_SIGNATURES:="false"}
|
||||
: ${HELM_INSTALL_DIR:="/usr/local/bin"}
|
||||
: ${GPG_PUBRING:="pubring.kbx"}
|
||||
|
||||
HAS_CURL="$(type "curl" &> /dev/null && echo true || echo false)"
|
||||
HAS_WGET="$(type "wget" &> /dev/null && echo true || echo false)"
|
||||
HAS_OPENSSL="$(type "openssl" &> /dev/null && echo true || echo false)"
|
||||
HAS_GPG="$(type "gpg" &> /dev/null && echo true || echo false)"
|
||||
HAS_GIT="$(type "git" &> /dev/null && echo true || echo false)"
|
||||
|
||||
# initArch discovers the architecture for this system.
|
||||
initArch() {
|
||||
ARCH=$(uname -m)
|
||||
case $ARCH in
|
||||
armv5*) ARCH="armv5";;
|
||||
armv6*) ARCH="armv6";;
|
||||
armv7*) ARCH="arm";;
|
||||
aarch64) ARCH="arm64";;
|
||||
x86) ARCH="386";;
|
||||
x86_64) ARCH="amd64";;
|
||||
i686) ARCH="386";;
|
||||
i386) ARCH="386";;
|
||||
esac
|
||||
}
|
||||
|
||||
# initOS discovers the operating system for this system.
|
||||
initOS() {
|
||||
OS=$(echo `uname`|tr '[:upper:]' '[:lower:]')
|
||||
|
||||
case "$OS" in
|
||||
# Minimalist GNU for Windows
|
||||
mingw*|cygwin*) OS='windows';;
|
||||
esac
|
||||
}
|
||||
|
||||
# runs the given command as root (detects if we are root already)
|
||||
runAsRoot() {
|
||||
if [ $EUID -ne 0 -a "$USE_SUDO" = "true" ]; then
|
||||
sudo "${@}"
|
||||
else
|
||||
"${@}"
|
||||
fi
|
||||
}
|
||||
|
||||
# verifySupported checks that the os/arch combination is supported for
|
||||
# binary builds, as well whether or not necessary tools are present.
|
||||
verifySupported() {
|
||||
local supported="darwin-amd64\ndarwin-arm64\nlinux-386\nlinux-amd64\nlinux-arm\nlinux-arm64\nlinux-ppc64le\nlinux-s390x\nwindows-amd64"
|
||||
if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then
|
||||
echo "No prebuilt binary for ${OS}-${ARCH}."
|
||||
echo "To build from source, go to https://github.com/helm/helm"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${HAS_CURL}" != "true" ] && [ "${HAS_WGET}" != "true" ]; then
|
||||
echo "Either curl or wget is required"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${VERIFY_CHECKSUM}" == "true" ] && [ "${HAS_OPENSSL}" != "true" ]; then
|
||||
echo "In order to verify checksum, openssl must first be installed."
|
||||
echo "Please install openssl or set VERIFY_CHECKSUM=false in your environment."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${VERIFY_SIGNATURES}" == "true" ]; then
|
||||
if [ "${HAS_GPG}" != "true" ]; then
|
||||
echo "In order to verify signatures, gpg must first be installed."
|
||||
echo "Please install gpg or set VERIFY_SIGNATURES=false in your environment."
|
||||
exit 1
|
||||
fi
|
||||
if [ "${OS}" != "linux" ]; then
|
||||
echo "Signature verification is currently only supported on Linux."
|
||||
echo "Please set VERIFY_SIGNATURES=false or verify the signatures manually."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${HAS_GIT}" != "true" ]; then
|
||||
echo "[WARNING] Could not find git. It is required for plugin installation."
|
||||
fi
|
||||
}
|
||||
|
||||
# checkDesiredVersion checks if the desired version is available.
|
||||
checkDesiredVersion() {
|
||||
if [ "x$DESIRED_VERSION" == "x" ]; then
|
||||
# Get tag from release URL
|
||||
local latest_release_url="https://github.com/helm/helm/releases"
|
||||
if [ "${HAS_CURL}" == "true" ]; then
|
||||
TAG=$(curl -Ls $latest_release_url | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1)
|
||||
elif [ "${HAS_WGET}" == "true" ]; then
|
||||
TAG=$(wget $latest_release_url -O - 2>&1 | grep 'href="/helm/helm/releases/tag/v3.[0-9]*.[0-9]*\"' | sed -E 's/.*\/helm\/helm\/releases\/tag\/(v[0-9\.]+)".*/\1/g' | head -1)
|
||||
fi
|
||||
else
|
||||
TAG=$DESIRED_VERSION
|
||||
fi
|
||||
}
|
||||
|
||||
# checkHelmInstalledVersion checks which version of helm is installed and
|
||||
# if it needs to be changed.
|
||||
checkHelmInstalledVersion() {
|
||||
if [[ -f "${HELM_INSTALL_DIR}/${BINARY_NAME}" ]]; then
|
||||
local version=$("${HELM_INSTALL_DIR}/${BINARY_NAME}" version --template="{{ .Version }}")
|
||||
if [[ "$version" == "$TAG" ]]; then
|
||||
echo "Helm ${version} is already ${DESIRED_VERSION:-latest}"
|
||||
return 0
|
||||
else
|
||||
echo "Helm ${TAG} is available. Changing from version ${version}."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# downloadFile downloads the latest binary package and also the checksum
|
||||
# for that binary.
|
||||
downloadFile() {
|
||||
HELM_DIST="helm-$TAG-$OS-$ARCH.tar.gz"
|
||||
DOWNLOAD_URL="https://get.helm.sh/$HELM_DIST"
|
||||
CHECKSUM_URL="$DOWNLOAD_URL.sha256"
|
||||
HELM_TMP_ROOT="$(mktemp -dt helm-installer-XXXXXX)"
|
||||
HELM_TMP_FILE="$HELM_TMP_ROOT/$HELM_DIST"
|
||||
HELM_SUM_FILE="$HELM_TMP_ROOT/$HELM_DIST.sha256"
|
||||
echo "Downloading $DOWNLOAD_URL"
|
||||
if [ "${HAS_CURL}" == "true" ]; then
|
||||
curl -SsL "$CHECKSUM_URL" -o "$HELM_SUM_FILE"
|
||||
curl -SsL "$DOWNLOAD_URL" -o "$HELM_TMP_FILE"
|
||||
elif [ "${HAS_WGET}" == "true" ]; then
|
||||
wget -q -O "$HELM_SUM_FILE" "$CHECKSUM_URL"
|
||||
wget -q -O "$HELM_TMP_FILE" "$DOWNLOAD_URL"
|
||||
fi
|
||||
}
|
||||
|
||||
# verifyFile verifies the SHA256 checksum of the binary package
|
||||
# and the GPG signatures for both the package and checksum file
|
||||
# (depending on settings in environment).
|
||||
verifyFile() {
|
||||
if [ "${VERIFY_CHECKSUM}" == "true" ]; then
|
||||
verifyChecksum
|
||||
fi
|
||||
if [ "${VERIFY_SIGNATURES}" == "true" ]; then
|
||||
verifySignatures
|
||||
fi
|
||||
}
|
||||
|
||||
# installFile installs the Helm binary.
|
||||
installFile() {
|
||||
HELM_TMP="$HELM_TMP_ROOT/$BINARY_NAME"
|
||||
mkdir -p "$HELM_TMP"
|
||||
tar xf "$HELM_TMP_FILE" -C "$HELM_TMP"
|
||||
HELM_TMP_BIN="$HELM_TMP/$OS-$ARCH/helm"
|
||||
echo "Preparing to install $BINARY_NAME into ${HELM_INSTALL_DIR}"
|
||||
runAsRoot cp "$HELM_TMP_BIN" "$HELM_INSTALL_DIR/$BINARY_NAME"
|
||||
echo "$BINARY_NAME installed into $HELM_INSTALL_DIR/$BINARY_NAME"
|
||||
}
|
||||
|
||||
# verifyChecksum verifies the SHA256 checksum of the binary package.
|
||||
verifyChecksum() {
|
||||
printf "Verifying checksum... "
|
||||
local sum=$(openssl sha1 -sha256 ${HELM_TMP_FILE} | awk '{print $2}')
|
||||
local expected_sum=$(cat ${HELM_SUM_FILE})
|
||||
if [ "$sum" != "$expected_sum" ]; then
|
||||
echo "SHA sum of ${HELM_TMP_FILE} does not match. Aborting."
|
||||
exit 1
|
||||
fi
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
# verifySignatures obtains the latest KEYS file from GitHub main branch
|
||||
# as well as the signature .asc files from the specific GitHub release,
|
||||
# then verifies that the release artifacts were signed by a maintainer's key.
|
||||
verifySignatures() {
|
||||
printf "Verifying signatures... "
|
||||
local keys_filename="KEYS"
|
||||
local github_keys_url="https://raw.githubusercontent.com/helm/helm/main/${keys_filename}"
|
||||
if [ "${HAS_CURL}" == "true" ]; then
|
||||
curl -SsL "${github_keys_url}" -o "${HELM_TMP_ROOT}/${keys_filename}"
|
||||
elif [ "${HAS_WGET}" == "true" ]; then
|
||||
wget -q -O "${HELM_TMP_ROOT}/${keys_filename}" "${github_keys_url}"
|
||||
fi
|
||||
local gpg_keyring="${HELM_TMP_ROOT}/keyring.gpg"
|
||||
local gpg_homedir="${HELM_TMP_ROOT}/gnupg"
|
||||
mkdir -p -m 0700 "${gpg_homedir}"
|
||||
local gpg_stderr_device="/dev/null"
|
||||
if [ "${DEBUG}" == "true" ]; then
|
||||
gpg_stderr_device="/dev/stderr"
|
||||
fi
|
||||
gpg --batch --quiet --homedir="${gpg_homedir}" --import "${HELM_TMP_ROOT}/${keys_filename}" 2> "${gpg_stderr_device}"
|
||||
gpg --batch --no-default-keyring --keyring "${gpg_homedir}/${GPG_PUBRING}" --export > "${gpg_keyring}"
|
||||
local github_release_url="https://github.com/helm/helm/releases/download/${TAG}"
|
||||
if [ "${HAS_CURL}" == "true" ]; then
|
||||
curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc"
|
||||
curl -SsL "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" -o "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc"
|
||||
elif [ "${HAS_WGET}" == "true" ]; then
|
||||
wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc"
|
||||
wget -q -O "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" "${github_release_url}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc"
|
||||
fi
|
||||
local error_text="If you think this might be a potential security issue,"
|
||||
error_text="${error_text}\nplease see here: https://github.com/helm/community/blob/master/SECURITY.md"
|
||||
local num_goodlines_sha=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)')
|
||||
if [[ ${num_goodlines_sha} -lt 2 ]]; then
|
||||
echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz.sha256!"
|
||||
echo -e "${error_text}"
|
||||
exit 1
|
||||
fi
|
||||
local num_goodlines_tar=$(gpg --verify --keyring="${gpg_keyring}" --status-fd=1 "${HELM_TMP_ROOT}/helm-${TAG}-${OS}-${ARCH}.tar.gz.asc" 2> "${gpg_stderr_device}" | grep -c -E '^\[GNUPG:\] (GOODSIG|VALIDSIG)')
|
||||
if [[ ${num_goodlines_tar} -lt 2 ]]; then
|
||||
echo "Unable to verify the signature of helm-${TAG}-${OS}-${ARCH}.tar.gz!"
|
||||
echo -e "${error_text}"
|
||||
exit 1
|
||||
fi
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
# fail_trap is executed if an error occurs.
|
||||
fail_trap() {
|
||||
result=$?
|
||||
if [ "$result" != "0" ]; then
|
||||
if [[ -n "$INPUT_ARGUMENTS" ]]; then
|
||||
echo "Failed to install $BINARY_NAME with the arguments provided: $INPUT_ARGUMENTS"
|
||||
help
|
||||
else
|
||||
echo "Failed to install $BINARY_NAME"
|
||||
fi
|
||||
echo -e "\tFor support, go to https://github.com/helm/helm."
|
||||
fi
|
||||
cleanup
|
||||
exit $result
|
||||
}
|
||||
|
||||
# testVersion tests the installed client to make sure it is working.
|
||||
testVersion() {
|
||||
set +e
|
||||
HELM="$(command -v $BINARY_NAME)"
|
||||
if [ "$?" = "1" ]; then
|
||||
echo "$BINARY_NAME not found. Is $HELM_INSTALL_DIR on your "'$PATH?'
|
||||
exit 1
|
||||
fi
|
||||
set -e
|
||||
}
|
||||
|
||||
# help provides possible cli installation arguments
|
||||
help () {
|
||||
echo "Accepted cli arguments are:"
|
||||
echo -e "\t[--help|-h ] ->> prints this help"
|
||||
echo -e "\t[--version|-v <desired_version>] . When not defined it fetches the latest release from GitHub"
|
||||
echo -e "\te.g. --version v3.0.0 or -v canary"
|
||||
echo -e "\t[--no-sudo] ->> install without sudo"
|
||||
}
|
||||
|
||||
# cleanup temporary files to avoid https://github.com/helm/helm/issues/2977
|
||||
cleanup() {
|
||||
if [[ -d "${HELM_TMP_ROOT:-}" ]]; then
|
||||
rm -rf "$HELM_TMP_ROOT"
|
||||
fi
|
||||
}
|
||||
|
||||
# Execution
|
||||
|
||||
#Stop execution on any error
|
||||
trap "fail_trap" EXIT
|
||||
set -e
|
||||
|
||||
# Set debug if desired
|
||||
if [ "${DEBUG}" == "true" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
# Parsing input arguments (if any)
|
||||
export INPUT_ARGUMENTS="${@}"
|
||||
set -u
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
'--version'|-v)
|
||||
shift
|
||||
if [[ $# -ne 0 ]]; then
|
||||
export DESIRED_VERSION="${1}"
|
||||
else
|
||||
echo -e "Please provide the desired version. e.g. --version v3.0.0 or -v canary"
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
'--no-sudo')
|
||||
USE_SUDO="false"
|
||||
;;
|
||||
'--help'|-h)
|
||||
help
|
||||
exit 0
|
||||
;;
|
||||
*) exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
set +u
|
||||
|
||||
initArch
|
||||
initOS
|
||||
verifySupported
|
||||
checkDesiredVersion
|
||||
if ! checkHelmInstalledVersion; then
|
||||
downloadFile
|
||||
verifyFile
|
||||
installFile
|
||||
fi
|
||||
testVersion
|
||||
cleanup
|
||||
23
traefik/web-helm/.helmignore
Normal file
23
traefik/web-helm/.helmignore
Normal file
@@ -0,0 +1,23 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
24
traefik/web-helm/Chart.yaml
Normal file
24
traefik/web-helm/Chart.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
apiVersion: v2
|
||||
name: web-helm
|
||||
description: A Helm chart for Kubernetes
|
||||
|
||||
# A chart can be either an 'application' or a 'library' chart.
|
||||
#
|
||||
# Application charts are a collection of templates that can be packaged into versioned archives
|
||||
# to be deployed.
|
||||
#
|
||||
# Library charts provide useful utilities or functions for the chart developer. They're included as
|
||||
# a dependency of application charts to inject those utilities and functions into the rendering
|
||||
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
|
||||
type: application
|
||||
|
||||
# This is the chart version. This version number should be incremented each time you make changes
|
||||
# to the chart and its templates, including the app version.
|
||||
# Versions are expected to follow Semantic Versioning (https://semver.org/)
|
||||
version: 0.1.0
|
||||
|
||||
# This is the version number of the application being deployed. This version number should be
|
||||
# incremented each time you make changes to the application. Versions are not expected to
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "1.16.0"
|
||||
22
traefik/web-helm/templates/NOTES.txt
Normal file
22
traefik/web-helm/templates/NOTES.txt
Normal file
@@ -0,0 +1,22 @@
|
||||
1. Get the application URL by running these commands:
|
||||
{{- if .Values.ingress.enabled }}
|
||||
{{- range $host := .Values.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "web-helm.fullname" . }})
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "web-helm.fullname" . }}'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "web-helm.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "web-helm.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
echo "Visit http://127.0.0.1:8080 to use your application"
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
|
||||
{{- end }}
|
||||
62
traefik/web-helm/templates/_helpers.tpl
Normal file
62
traefik/web-helm/templates/_helpers.tpl
Normal file
@@ -0,0 +1,62 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "web-helm.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "web-helm.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "web-helm.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "web-helm.labels" -}}
|
||||
helm.sh/chart: {{ include "web-helm.chart" . }}
|
||||
{{ include "web-helm.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "web-helm.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "web-helm.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "web-helm.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "web-helm.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
61
traefik/web-helm/templates/deployment.yaml
Normal file
61
traefik/web-helm/templates/deployment.yaml
Normal file
@@ -0,0 +1,61 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "web-helm.fullname" . }}
|
||||
labels:
|
||||
{{- include "web-helm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "web-helm.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "web-helm.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "web-helm.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.service.port }}
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
28
traefik/web-helm/templates/hpa.yaml
Normal file
28
traefik/web-helm/templates/hpa.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
{{- if .Values.autoscaling.enabled }}
|
||||
apiVersion: autoscaling/v2beta1
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ include "web-helm.fullname" . }}
|
||||
labels:
|
||||
{{- include "web-helm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ include "web-helm.fullname" . }}
|
||||
minReplicas: {{ .Values.autoscaling.minReplicas }}
|
||||
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
|
||||
metrics:
|
||||
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
- type: Resource
|
||||
resource:
|
||||
name: memory
|
||||
targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
61
traefik/web-helm/templates/ingress.yaml
Normal file
61
traefik/web-helm/templates/ingress.yaml
Normal file
@@ -0,0 +1,61 @@
|
||||
{{- if .Values.ingress.enabled -}}
|
||||
{{- $fullName := include "web-helm.fullname" . -}}
|
||||
{{- $svcPort := .Values.service.port -}}
|
||||
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
|
||||
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
|
||||
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
|
||||
apiVersion: networking.k8s.io/v1beta1
|
||||
{{- else -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
{{- end }}
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{- include "web-helm.labels" . | nindent 4 }}
|
||||
{{- with .Values.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
|
||||
ingressClassName: {{ .Values.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
|
||||
pathType: {{ .pathType }}
|
||||
{{- end }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
name: {{ $fullName }}
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- else }}
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
traefik/web-helm/templates/service.yaml
Normal file
15
traefik/web-helm/templates/service.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "web-helm.fullname" . }}
|
||||
labels:
|
||||
{{- include "web-helm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "web-helm.selectorLabels" . | nindent 4 }}
|
||||
12
traefik/web-helm/templates/serviceaccount.yaml
Normal file
12
traefik/web-helm/templates/serviceaccount.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
{{- if .Values.serviceAccount.create -}}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "web-helm.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "web-helm.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
traefik/web-helm/templates/tests/test-connection.yaml
Normal file
15
traefik/web-helm/templates/tests/test-connection.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "web-helm.fullname" . }}-test-connection"
|
||||
labels:
|
||||
{{- include "web-helm.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
containers:
|
||||
- name: wget
|
||||
image: busybox
|
||||
command: ['wget']
|
||||
args: ['{{ include "web-helm.fullname" . }}:{{ .Values.service.port }}']
|
||||
restartPolicy: Never
|
||||
82
traefik/web-helm/values.yaml
Normal file
82
traefik/web-helm/values.yaml
Normal file
@@ -0,0 +1,82 @@
|
||||
# Default values for web-helm.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: nginx
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
serviceAccount:
|
||||
# Specifies whether a service account should be created
|
||||
create: true
|
||||
# Annotations to add to the service account
|
||||
annotations: {}
|
||||
# The name of the service account to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
name: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext: {}
|
||||
# fsGroup: 2000
|
||||
|
||||
securityContext: {}
|
||||
# capabilities:
|
||||
# drop:
|
||||
# - ALL
|
||||
# readOnlyRootFilesystem: true
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
className: ""
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: chart-example.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
resources: {}
|
||||
# We usually recommend not to specify default resources and to leave this as a conscious
|
||||
# choice for the user. This also increases chances charts run on environments with little
|
||||
# resources, such as Minikube. If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
autoscaling:
|
||||
enabled: false
|
||||
minReplicas: 1
|
||||
maxReplicas: 100
|
||||
targetCPUUtilizationPercentage: 80
|
||||
# targetMemoryUtilizationPercentage: 80
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
Reference in New Issue
Block a user