This commit is contained in:
2024-02-20 17:15:27 +08:00
committed by huty
parent 6706e1a633
commit 34158042ad
1529 changed files with 177765 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
version: "3.7"
services:
ch10-web-ping:
image: kiamol/ch10-web-ping:latest-linux-amd64

View File

@@ -0,0 +1,5 @@
version: "3.7"
services:
ch10-web-ping:
image: kiamol/ch10-web-ping:latest-linux-arm64

View File

@@ -0,0 +1,7 @@
version: "3.7"
services:
ch10-web-ping:
image: kiamol/ch10-web-ping:latest
build:
context: ./web-ping

View File

@@ -0,0 +1,10 @@
$images=$(yq e '.services.[].image' docker-compose.yml)
foreach ($image in $images)
{
docker manifest create --amend $image `
"$($image)-linux-arm64" `
"$($image)-linux-amd64"
docker manifest push $image
}

View File

@@ -0,0 +1,17 @@
FROM node:16.13.1-alpine3.14 AS builder
WORKDIR /src
COPY src/package.json .
RUN npm install
FROM node:16.13.1-alpine3.14
CMD ["node", "/app/app.js"]
ENV TARGET="blog.sixeyed.com" \
METHOD="HEAD" \
INTERVAL="3000"
WORKDIR /app
COPY --from=builder /src/node_modules/ /app/node_modules/
COPY src/ .

View File

@@ -0,0 +1,25 @@
const https = require('https');
const log = require("./log");
const options = {
hostname: process.env.TARGET,
method: process.env.METHOD
};
log.Logger.info('** web-ping ** Pinging: %s; method: %s; %dms intervals', options.hostname, options.method, process.env.INTERVAL);
let i = 1;
let start = new Date().getTime();
setInterval(() => {
start = new Date().getTime();
log.Logger.debug('Making request number: %d; at %d', i++, start);
var req = https.request(options, (res) => {
var end = new Date().getTime();
var duration = end-start;
log.Logger.debug('Got response status: %s at %d; duration: %dms', res.statusCode, end, duration);
});
req.on('error', (e) => {
console.error(e);
});
req.end();
}, process.env.INTERVAL)

View File

@@ -0,0 +1,16 @@
const { format, transports } = require('winston');
var logConfig = module.exports = {};
logConfig.options = {
transports: [
new transports.Console({
level: 'debug',
format: format.combine(
format.splat(),
format.printf(log => {
return `${log.message}`
})
)
})
]
};

View File

@@ -0,0 +1,5 @@
const winston = require('winston');
var logConfig = require('./config/logConfig');
const logger = winston.createLogger(logConfig.options);
exports.Logger = logger;

View File

@@ -0,0 +1,9 @@
{
"name": "web-ping",
"version": "1.0.0",
"main": "app.js",
"author": "kiamol",
"dependencies": {
"winston": "3.3.3"
}
}

View File

@@ -0,0 +1,60 @@
# Ch10 lab
Run the app using plain manifests (from this `lab` folder):
```
kubectl apply -f ./todo-list/
```
Get the URL and browse:
```
kubectl get svc todo-web -o jsonpath='http://{.status.loadBalancer.ingress[0].*}:8080'
```
## Sample Solution
My Helm chart templates the Kubernetes manifests for all the resources:
- [templates/todo-web-configMap.yaml](./ch10-lab-solution/templates/todo-web-configMap.yaml)
- [templates/todo-web-deployment.yaml](./ch10-lab-solution/templates/todo-web-deployment.yaml)
- [templates/todo-web-service.yaml](./ch10-lab-solution/templates/todo-web-service.yaml)
The [default values](./ch10-lab-solution/values.yaml) specify the Test environment and a Service port of 8080.
Validate the chart:
```
helm lint ./ch10-lab-solution
```
Install the test setup:
```
helm install lab-test ./ch10-lab-solution
```
> You can browse on port 8080, and the /config path returns a 404
Install the dev setup:
```
helm install -f dev-values.yaml lab-dev ./ch10-lab-solution
```
> You can browse on port 8088, and the /config path is working
## Teardown
Uninstall the Helm releases:
```
helm uninstall lab-test lab-dev
```
Delete other lab resources by their labels:
```
kubectl delete all -l kiamol=ch10-lab
```

View 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/

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: ch10-lab-solution
description: Solution to Kiamol ch10 lab
type: application
version: 0.1.0
appVersion: 1.0.0

View File

@@ -0,0 +1,13 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-config
labels:
kiamol: ch10-lab
data:
config.json: |-
{
"ConfigController": {
"Enabled" : {{ .Values.configControllerEnabled }}
}
}

View File

@@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
labels:
kiamol: ch10-lab
spec:
selector:
matchLabels:
app: {{ .Release.Name }}
environment: {{ .Values.environment | lower }}
template:
metadata:
labels:
app: {{ .Release.Name }}
environment: {{ .Values.environment | lower }}
spec:
containers:
- name: web
image: kiamol/ch04-todo-list
env:
- name: ASPNETCORE_ENVIRONMENT
value: {{ .Values.environment | title }}
volumeMounts:
- name: config
mountPath: "/app/config"
readOnly: true
volumes:
- name: config
configMap:
name: {{ .Release.Name }}-config

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
labels:
kiamol: ch10-lab
spec:
ports:
- port: {{ .Values.servicePort }}
targetPort: 80
selector:
app: {{ .Release.Name }}
environment: {{ .Values.environment | lower }}
type: {{ .Values.serviceType }}

View File

@@ -0,0 +1,8 @@
# environment - Dev, Test or Prod
environment: Test
# whether the config UI is enabled
configControllerEnabled: false
# port for the Service:
servicePort: 8080
# type of the Service:
serviceType: LoadBalancer

View File

@@ -0,0 +1,3 @@
environment: Dev
configControllerEnabled: true
servicePort: 8088

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: todo-web-config
labels:
kiamol: ch10-lab
# ConfigController.Enabled should be parameterized
data:
config.json: |-
{
"ConfigController": {
"Enabled" : false
}
}

View File

@@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: todo-web # this needs to be templated
labels:
kiamol: ch10-lab
spec:
selector:
matchLabels: # this needs to be templated
app: todo-web
environment: test
template:
metadata:
labels: # this needs to be templated
app: todo-web
environment: test
spec:
containers:
- name: web
image: kiamol/ch04-todo-list
env:
- name: ASPNETCORE_ENVIRONMENT
value: Test # this should be parameterized
volumeMounts:
- name: config
mountPath: "/app/config"
readOnly: true
volumes:
- name: config
configMap:
name: todo-web-config # this needs to be templated

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: todo-web # this needs to be templated
labels:
kiamol: ch10-lab
spec:
ports:
- port: 8081 # this should be parameterized
targetPort: 80
selector: # this needs to be templated
app: todo-web
environment: test
type: LoadBalancer # this should be parameterized

View 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/

View File

@@ -0,0 +1,14 @@
apiVersion: v2
name: pi
description: A Pi calculator
type: application
version: 0.1.0
dependencies:
- name: vweb
version: 2.0.0
repository: https://kiamol.net
condition: vweb.enabled
- name: proxy
version: 0.1.0
repository: file://../proxy
condition: proxy.enabled

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-web
labels:
kiamol: ch10
spec:
ports:
- port: 80
name: http
selector:
app: {{ .Release.Name }}
component: web
type: {{ .Values.serviceType }}

View File

@@ -0,0 +1,25 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-web
labels:
kiamol: ch10
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
component: web
template:
metadata:
labels:
app: {{ .Release.Name }}
component: web
spec:
containers:
- image: kiamol/ch05-pi
command: ["dotnet", "Pi.Web.dll", "-m", "web"]
name: web
ports:
- containerPort: 80
name: http

View File

@@ -0,0 +1,18 @@
# number of app Pods to run
replicaCount: 2
# type of the app Service:
serviceType: LoadBalancer
# settings for vweb
vweb:
# whether to deploy vweb
enabled: false
# settings for the reverse proxy
proxy:
# whether to deploy the proxy
enabled: false
# name of the app Service to proxy
upstreamToProxy: "{{ .Release.Name }}-web"
# port of the proxy Service
servicePort: 8030
# number of proxy Pods to run
replicaCount: 2

View 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/

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: proxy
description: A reverse proxy using Nginx
type: application
version: 0.1.0
appVersion: 1.16.0

View File

@@ -0,0 +1,45 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ .Release.Name }}-config
labels:
kiamol: ch10
data:
nginx.conf: |-
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=STATIC:10m inactive=24h max_size={{ .Values.cacheMaxSixe }};
gzip on;
gzip_proxied any;
map $sent_http_content_type $expires {
default off;
~image/ {{ .Values.imageExpiresDuration }};
}
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
proxy_pass http://{{ tpl .Values.upstreamToProxy . }};
proxy_set_header Host $host;
proxy_cache STATIC;
proxy_cache_valid 200 1d;
proxy_cache_use_stale error timeout invalid_header updating
http_500 http_502 http_503 http_504;
add_header X-Cache $upstream_cache_status;
add_header X-Host $hostname;
}
}
}

View File

@@ -0,0 +1,36 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}-proxy
labels:
kiamol: ch10
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
component: proxy
template:
metadata:
labels:
app: {{ .Release.Name }}
component: proxy
spec:
containers:
- image: nginx:1.17-alpine
name: nginx
ports:
- containerPort: 80
name: http
volumeMounts:
- name: config
mountPath: "/etc/nginx/"
readOnly: true
- name: cache-volume
mountPath: /data/nginx/cache
volumes:
- name: config
configMap:
name: {{ .Release.Name }}-config
- name: cache-volume
emptyDir: {}

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}-proxy
labels:
kiamol: ch10
spec:
ports:
- port: {{ .Values.servicePort }}
targetPort: http
selector:
app: {{ .Release.Name }}
component: proxy
type: {{ .Values.serviceType }}

View File

@@ -0,0 +1,6 @@
upstreamToProxy: web
cacheMaxSixe: 1g
imageExpiresDuration: 6M
replicaCount: 1
servicePort: 8080
serviceType: LoadBalancer

View 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/

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: vweb
description: Simple versioned web app
type: application
version: 1.0.0
appVersion: 1.0.0

View File

@@ -0,0 +1,27 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
kiamol: ch10
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
containers:
- name: web
image: kiamol/ch09-vweb:v1
ports:
- name: http
containerPort: 80

View File

@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
kiamol: ch10
spec:
ports:
- port: {{ .Values.servicePort }}
targetPort: http
selector:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
type: LoadBalancer

View File

@@ -0,0 +1,4 @@
# port for the Service to listen on
servicePort: 8090
# number of replicas for the web Pod
replicaCount: 2

View 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/

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: vweb
description: Simple versioned web app
type: application
version: 2.0.0
appVersion: 2.0.0

View File

@@ -0,0 +1,27 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
kiamol: ch10
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
containers:
- name: web
image: kiamol/ch09-vweb:v2
ports:
- name: http
containerPort: 80

View File

@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
labels:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
kiamol: ch10
spec:
ports:
- port: {{ .Values.servicePort }}
targetPort: http
{{- if eq .Values.serviceType "NodePort" }}
nodePort: {{ .Values.servicePort }}
{{- end }}
selector:
app.kubernetes.io/name: vweb
app.kubernetes.io/instance: {{ .Release.Name }}
type: {{ .Values.serviceType }}

View File

@@ -0,0 +1,6 @@
# port for the Service to listen on
servicePort: 8090
# type of the Service:
serviceType: LoadBalancer
# number of replicas for the web Pod
replicaCount: 2

View File

@@ -0,0 +1 @@
pingIntervalMilliseconds: 15000

View 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/

View File

@@ -0,0 +1,6 @@
apiVersion: v2
name: web-ping
description: A simple web pinger
type: application
version: 0.1.0
appVersion: 1.0.0

View File

@@ -0,0 +1,29 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Release.Name }}
labels:
kiamol: {{ .Values.kiamolChapter }}
spec:
selector:
matchLabels:
app: web-ping
instance: {{ .Release.Name }}
template:
metadata:
labels:
app: web-ping
instance: {{ .Release.Name }}
spec:
containers:
- name: app
image: kiamol/ch10-web-ping
env:
- name: TARGET
value: {{ .Values.targetUrl }}
- name: METHOD
value: {{ .Values.httpMethod }}
- name: INTERVAL
value: {{ .Values.pingIntervalMilliseconds | quote }}

View File

@@ -0,0 +1,8 @@
# targetUrl - URL of the website to ping
targetUrl: blog.sixeyed.com
# httpMethod - HTTP method to use for pings
httpMethod: HEAD
# pingIntervalMilliseconds - interval between pings in ms
pingIntervalMilliseconds: 30000
# chapter where this exercise is used
kiamolChapter: ch10