Compare commits
18 Commits
18c1375be6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e619d4364 | ||
|
|
0b156f5b48 | ||
|
|
9efb2a0a15 | ||
|
|
ea6635f716 | ||
|
|
6b758e202d | ||
|
|
8d91a5b6e8 | ||
|
|
9110390246 | ||
|
|
f2b52c4e6e | ||
|
|
b635dd74f2 | ||
|
|
14483b7428 | ||
|
|
13dc53688d | ||
|
|
60048f74c7 | ||
|
|
c3d8cf38b4 | ||
|
|
0670f72d06 | ||
|
|
6e52807dfa | ||
|
|
76c847070c | ||
|
|
317f6b150f | ||
|
|
43e51cccb4 |
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
**.csv
|
||||||
23
README.md
23
README.md
@@ -1,10 +1,27 @@
|
|||||||
# html-kube-tester
|
# html-kube-tester
|
||||||
|
|
||||||
|
## Workload
|
||||||
|
|
||||||
Workload to test application behavior while making changes on infrastructure.
|
Workload to test application behavior while making changes on infrastructure.
|
||||||
|
|
||||||
Ingress is not included and have to be added on top.
|
Ingress fqdn has to be configured by either:
|
||||||
Feel free to customize *replicas* and *content-git-repo* in *config* folder.
|
|
||||||
|
|
||||||
Git will be displayed in an iframe with node name on top.
|
* modifying file *ingress-patch-route-name.yaml*
|
||||||
|
* using this repo as kustomize source and override inn the same way than *ingress-patch-route-name.yaml*
|
||||||
|
|
||||||
|
*replicas* and *content-git-repo* in *config* folder can be customized by modifying files or applying kustomize patch
|
||||||
|
|
||||||
|
Content git will be displayed in an iframe with node name on top. If it's empty, it will display a blank page with node name.
|
||||||
|
|
||||||
|
Node name is displayed on the top of the page and also in kube-node.json and on kube-node.txt
|
||||||
|
|
||||||
Thanks to https://github.com/amoldalwai/RoadFighter.git for having something fun to display.
|
Thanks to https://github.com/amoldalwai/RoadFighter.git for having something fun to display.
|
||||||
|
|
||||||
|
## Analyse script
|
||||||
|
|
||||||
|
A script is given to test inngress availability.
|
||||||
|
analyse.sh {ingress fqdn} [keep_results]
|
||||||
|
|
||||||
|
Option *keep_results* does not ovewrite file on startup.
|
||||||
|
|
||||||
|
Information is displayed in csv format: "Date (Epoch)";"Request duration";"HTTP Response code";"App availability";"Event";"Response content"
|
||||||
58
analyse.sh
Executable file
58
analyse.sh
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/zsh -e
|
||||||
|
|
||||||
|
# This script asserts that init.sh workload script is left as is.
|
||||||
|
|
||||||
|
date_format='+%s'
|
||||||
|
|
||||||
|
script_dir=$(dirname $(readlink -f ${0}))
|
||||||
|
results_file=${script_dir}/analyse_results.csv
|
||||||
|
tmp_headers_file=${script_dir}/analyse_request_headers
|
||||||
|
|
||||||
|
if [[ -z "${1}" ]] ; then
|
||||||
|
echo "First parameter must be url"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
analyse_url=${1}
|
||||||
|
fi
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
if [ -e "${tmp_headers_file}" ] ; then
|
||||||
|
rm -v ${tmp_headers_file}
|
||||||
|
fi
|
||||||
|
echo Ingress statistics can be viewed in ${results_file}
|
||||||
|
}
|
||||||
|
|
||||||
|
insert_event () {
|
||||||
|
insert_date=$(date ${date_format})
|
||||||
|
echo "${insert_date};;;;2;\"Event from SIGUSR1\"" | tee -a ${results_file}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Signnals handling
|
||||||
|
trap cleanup 2
|
||||||
|
trap insert_event 30
|
||||||
|
|
||||||
|
# Explanations
|
||||||
|
echo Process id to send signal is $$
|
||||||
|
echo To insert event in log, send SIGUSR1 to $$
|
||||||
|
echo following command cann be used: kill -s SIGUSR1 $$
|
||||||
|
echo
|
||||||
|
echo Launching test, press CTRL+C to exit
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Result file handling
|
||||||
|
if [[ "${2}" == "keep_results" ]] ; then
|
||||||
|
keep_results=true
|
||||||
|
else
|
||||||
|
keep_results=false
|
||||||
|
echo '"Date (Epoch)";"Request duration";"HTTP Response code";"App availability";"Event";"Response content"' | tee ${results_file}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Statistics generation
|
||||||
|
while true ; do
|
||||||
|
request_date=$(date ${date_format})
|
||||||
|
request_data="$(curl -m 2 -s -w "%output{$tmp_headers_file}%{time_total};%{http_code}" -k "${analyse_url}" | tr -d "\r" |tr -d "\n" | tr -d ";")"
|
||||||
|
request_headers=$(cat ${tmp_headers_file})
|
||||||
|
response_success=$( [[ "$(echo ${request_headers} | cut -f2 -d';')" == "200" ]] && echo 1 || echo 0)
|
||||||
|
echo "${request_date};${request_headers};${response_success};;\"${request_data}\"" | tee -a ${results_file}
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
@@ -1,19 +1,23 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
git_retries=20
|
git_retries=20
|
||||||
try=0
|
try=0
|
||||||
export GIT_SSH_COMMAND='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
|
if [ -n "${CONTENT_GIT_REPO}" ] ; then
|
||||||
until timeout 10 git clone --recurse-submodules ${CONTENT_GIT_REPO} /app ; do
|
export GIT_SSH_COMMAND='ssh -o "StrictHostKeyChecking=no" -o "UserKnownHostsFile=/dev/null"'
|
||||||
echo "Retry git pull after error ($try / $git_retries)"
|
until timeout 10 git clone --recurse-submodules ${CONTENT_GIT_REPO} /app ; do
|
||||||
try=$((try+1))
|
echo "Retry git pull after error ($try / $git_retries)"
|
||||||
if [ $try -eq $git_retries ]; then
|
try=$((try+1))
|
||||||
exit 1
|
if [ $try -eq $git_retries ]; then
|
||||||
fi
|
exit 1
|
||||||
sleep 1
|
fi
|
||||||
done
|
sleep 1
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
cd /app
|
cd /app
|
||||||
if [ -e index.html ] ; then
|
if [ -e index.html ] ; then
|
||||||
mv index.html index-embedded.html
|
mv index.html index-embedded.html
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat <<EOF >index.html
|
cat <<EOF >index.html
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@@ -21,15 +25,29 @@ cat <<EOF >index.html
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
From node ${KUBE_NODE_NAME}
|
From node ${KUBE_NODE_NAME}<br />
|
||||||
|
as <a href="./kube-node.json">json</a> - <a href="./kube-node.txt">text</a>
|
||||||
</p>
|
</p>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if [ -n "${CONTENT_GIT_REPO}" ] ; then
|
||||||
|
cat <<EOF >>index.html
|
||||||
<iframe
|
<iframe
|
||||||
id="embeddedcontent"
|
id="embeddedcontent"
|
||||||
title="embeddedcontent"
|
title="embeddedcontent"
|
||||||
width="100%"
|
width="100%"
|
||||||
height="90%"
|
height="90%"
|
||||||
src="./index-embedded.html" />
|
src="./index-embedded.html" />
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF >>index.html
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
ls -l
|
||||||
|
cat index.html
|
||||||
|
|
||||||
|
echo '{"node": "'${KUBE_NODE_NAME}'"}' > kube-node.json
|
||||||
|
echo -n ${KUBE_NODE_NAME} > kube-node.txt
|
||||||
|
|||||||
@@ -7,28 +7,13 @@ spec:
|
|||||||
replicas: 1
|
replicas: 1
|
||||||
template:
|
template:
|
||||||
spec:
|
spec:
|
||||||
affinity:
|
|
||||||
podAntiAffinity:
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 100
|
|
||||||
podAffinityTerm:
|
|
||||||
labelSelector:
|
|
||||||
matchExpressions:
|
|
||||||
- key: app.kubernetes.io/instance
|
|
||||||
operator: In
|
|
||||||
values:
|
|
||||||
- html-kube-tester
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsUser: 82
|
|
||||||
runAsGroup: 82
|
|
||||||
fsGroup: 82
|
|
||||||
runAsNonRoot: true
|
runAsNonRoot: true
|
||||||
seccompProfile:
|
seccompProfile:
|
||||||
type: RuntimeDefault
|
type: RuntimeDefault
|
||||||
initContainers:
|
initContainers:
|
||||||
- name: content-generator
|
- name: content-generator
|
||||||
image: quay.io/simbelmas/alpine-tools:stable
|
image: quay.io/simbelmas/toolbox:stable
|
||||||
command: ["html-kube-tester-init.sh"]
|
command: ["html-kube-tester-init.sh"]
|
||||||
securityContext:
|
securityContext:
|
||||||
allowPrivilegeEscalation: false
|
allowPrivilegeEscalation: false
|
||||||
@@ -61,23 +46,12 @@ spec:
|
|||||||
mountPath: /var/www/html
|
mountPath: /var/www/html
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 8080
|
- containerPort: 8080
|
||||||
|
protocol: TCP
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: 2m
|
cpu: 10m
|
||||||
memory: 10Mi
|
|
||||||
limits:
|
limits:
|
||||||
cpu: 100m
|
cpu: 40m
|
||||||
memory: 25Mi
|
|
||||||
livenessProbe: &html-kube-tester-probe
|
|
||||||
httpGet:
|
|
||||||
path: /
|
|
||||||
port: 8080
|
|
||||||
timeoutSeconds: 5
|
|
||||||
periodSeconds: 15
|
|
||||||
failureThreshold: 10
|
|
||||||
readinessProbe:
|
|
||||||
<<: *html-kube-tester-probe
|
|
||||||
periodSeconds: 2
|
|
||||||
volumes:
|
volumes:
|
||||||
- name: init
|
- name: init
|
||||||
configMap:
|
configMap:
|
||||||
|
|||||||
4
ingress-patch-route-name.yaml
Normal file
4
ingress-patch-route-name.yaml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
- op: replace
|
||||||
|
path: /spec/rules/0/host
|
||||||
|
value: html-kube-tester.example.com
|
||||||
20
ingress.yaml
Normal file
20
ingress.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: run
|
||||||
|
annotations:
|
||||||
|
route.openshift.io/termination: "edge"
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: my.app.example.com
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- backend:
|
||||||
|
service:
|
||||||
|
name: html-kube-tester
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- {}
|
||||||
@@ -5,9 +5,6 @@ namespace: html-kube-tester
|
|||||||
commonLabels:
|
commonLabels:
|
||||||
app.kubernetes.io/instance: html-kube-tester
|
app.kubernetes.io/instance: html-kube-tester
|
||||||
app.kubernetes.io/part-of: html-kube-tester
|
app.kubernetes.io/part-of: html-kube-tester
|
||||||
pod-security.kubernetes.io/enforce: restricted
|
|
||||||
pod-security.kubernetes.io/audit: restricted
|
|
||||||
pod-security.kubernetes.io/warn: restricted
|
|
||||||
|
|
||||||
configMapGenerator:
|
configMapGenerator:
|
||||||
- name: html-kube-tester-config
|
- name: html-kube-tester-config
|
||||||
@@ -20,6 +17,8 @@ resources:
|
|||||||
- namespace.yaml
|
- namespace.yaml
|
||||||
- deployment.yaml
|
- deployment.yaml
|
||||||
- service.yaml
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
#- resourceQuotas.yaml
|
||||||
|
|
||||||
replacements:
|
replacements:
|
||||||
- source:
|
- source:
|
||||||
@@ -31,4 +30,10 @@ replacements:
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: html-kube-tester
|
name: html-kube-tester
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.replicas
|
- spec.replicas
|
||||||
|
|
||||||
|
patches:
|
||||||
|
- path: ingress-patch-route-name.yaml
|
||||||
|
target:
|
||||||
|
kind: Ingress
|
||||||
|
name: run
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
metadata:
|
metadata:
|
||||||
name: html-kube-tester
|
name: html-kube-tester
|
||||||
|
labels:
|
||||||
|
pod-security.kubernetes.io/enforce: restricted
|
||||||
|
pod-security.kubernetes.io/audit: restricted
|
||||||
|
pod-security.kubernetes.io/warn: restricted
|
||||||
8
resourceQuotas.yaml
Normal file
8
resourceQuotas.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ResourceQuota
|
||||||
|
metadata:
|
||||||
|
name: compute-resources
|
||||||
|
spec:
|
||||||
|
hard:
|
||||||
|
requests.cpu: "100m"
|
||||||
|
limits.cpu: "50m"
|
||||||
@@ -5,7 +5,7 @@ metadata:
|
|||||||
spec:
|
spec:
|
||||||
ports:
|
ports:
|
||||||
- name: http
|
- name: http
|
||||||
port: 8080
|
port: 80
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
targetPort: 8080
|
targetPort: 8080
|
||||||
sessionAffinity: None
|
sessionAffinity: None
|
||||||
|
|||||||
Reference in New Issue
Block a user