merged: go-demo js-demo python python-demo rust-demo

This commit is contained in:
Haitao Pan 2025-03-28 19:37:41 +08:00
parent 0d4f42e7ad
commit 3f04917c98
54 changed files with 1324 additions and 483 deletions

View File

@ -1,158 +0,0 @@
name: Build Test And Deploy
on:
pull_request:
push:
paths:
- 'Dockerfile'
- '.github/workflows/pipieline.yaml'
workflow_dispatch:
branches:
- main
env:
TZ: Asia/Shanghai
REPO: "artifact.onwalk.net"
IMAGE: base/${{ github.repository }}
TAG: ${{ github.sha }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt-get update
sudo apt install -y golang-1.18
- name: Build
run: |
go mod tidy && go build && tar -czvpf example_pkg-0.1.0.tar.gz example_pkg
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
asset_name: example_pkg-0.1.0.tar.gz
file: example_pkg-0.1.0.tar.gz
tag: ${{ github.ref }}
overwrite: true
body: "Release v0.1.0"
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt-get update
sudo apt install -y golang-1.18
- name: Run tests
run: |
go mod tidy && go test -v
docker-image:
runs-on: ubuntu-latest
name: Build image
needs:
- build
- test
steps:
- uses: actions/checkout@master
- name: 'Artifact: build && push image'
uses: aevea/action-kaniko@master
with:
registry: ${{ secrets.HELM_REPO_REGISTRY }}
username: ${{ secrets.HELM_REPO_USER }}
password: ${{ secrets.HELM_REPO_PASSWORD }}
path: './'
build_file: 'Dockerfile'
image: ${{ env.IMAGE }}
tag: ${{ env.TAG }}
cache: true
cache_registry: cache
setup-k3s:
runs-on: ubuntu-latest
needs:
- docker-image
steps:
- uses: actions/checkout@v3
- name: update submodule
run: |
sudo apt-get update && sudo apt-get install -y git && git submodule update --init --recursive
- name: Setup K3S Cluster
working-directory: ./scripts
shell: bash
run: |
export ANSIBLE_HOST_KEY_CHECKING=False
sudo apt install jq ansible -y
mkdir -pv ~/.ssh/
cat > ~/.ssh/id_rsa << EOF
${{ secrets.SSH_PRIVATE_KEY }}
EOF
sudo chmod 0400 ~/.ssh/id_rsa
md5sum ~/.ssh/id_rsa
mkdir -pv hosts/
cat > hosts/inventory << EOF
[master]
${{ secrets.HOST_DOMAIN }} ansible_host=${{ secrets.HOST_IP }}
[all:vars]
ansible_port=22
ansible_ssh_user=${{ secrets.HOST_USER }}
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_host_key_checking=False
ingress_ip=${{ secrets.HOST_IP }}
EOF
cat hosts/inventory
ansible-playbook -i hosts/inventory init_k3s_cluster -D
deploy-app:
runs-on: ubuntu-latest
needs: [setup-k3s]
steps:
- uses: actions/checkout@v3
- name: update submodule
run: |
sudo apt-get update && sudo apt-get install -y git && git submodule update --init --recursive
- name: Deploy
working-directory: ./scripts
shell: bash
run: |
export ANSIBLE_HOST_KEY_CHECKING=False
sudo apt install jq ansible -y
mkdir -pv ~/.ssh/
cat > ~/.ssh/id_rsa << EOF
${{ secrets.SSH_PRIVATE_KEY }}
EOF
sudo chmod 0400 ~/.ssh/id_rsa
md5sum ~/.ssh/id_rsa
mkdir -pv hosts/
cat > hosts/inventory << EOF
[master]
${{ secrets.HOST_DOMAIN }} ansible_host=${{ secrets.HOST_IP }}
[all:vars]
ansible_port=22
ansible_ssh_user=${{ secrets.HOST_USER }}
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_host_key_checking=False
app_image=${{ env.REPO }}/${{ env.IMAGE }}
app_tag=${{ env.TAG }}
EOF
ansible-playbook -i hosts/inventory deploy_app -D

View File

@ -1,3 +0,0 @@
[submodule "scripts"]
path = scripts
url = https://github.com/SvcDesignScaffolding/AnsibleScripts.git

View File

@ -0,0 +1,47 @@
<template>
<div id="app">
<h1>My App</h1>
<p>{{ data }}</p>
<button @click="produce">Produce Message</button>
<button @click="consume">Consume Message</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'App',
data() {
return {
data: null,
message: { key: "value" }, // replace this with the actual message you want to produce
};
},
async created() {
try {
const response = await axios.get('http://my-app-service');
this.data = response.data;
} catch (error) {
console.error(error);
}
},
methods: {
async produce() {
try {
await axios.post('http://my-app-service/produce', this.message);
} catch (error) {
console.error(error);
}
},
async consume() {
try {
const response = await axios.get('http://my-app-service/consume');
this.data = response.data;
} catch (error) {
console.error(error);
}
},
},
};
</script>

View File

@ -0,0 +1,6 @@
FROM python:3.7-alpine
WORKDIR /app
COPY . /app
RUN pip install fastapi uvicorn mysql-connector-python redis confluent-kafka
EXPOSE 80
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]

View File

@ -0,0 +1,15 @@
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
RUN npm install axios
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,58 @@
from fastapi import FastAPI
from starlette.requests import Request
import mysql.connector
import redis
import json
from confluent_kafka import Producer, Consumer, KafkaError
app = FastAPI()
cache = redis.Redis(host='redis-service', port=6379)
# Kafka producer configuration
p = Producer({'bootstrap.servers': 'my-kafka-service:9092'})
# Kafka consumer configuration
c = Consumer({
'bootstrap.servers': 'my-kafka-service:9092',
'group.id': 'mygroup',
'auto.offset.reset': 'earliest'
})
c.subscribe(['mytopic'])
@app.get('/')
async def read_root():
data = cache.get('mydata')
if data is not None:
return data
db = mysql.connector.connect(
host="mysql-service",
user="username",
password="password",
database="mydb"
)
cursor = db.cursor()
cursor.execute("SELECT * FROM your_table")
results = cursor.fetchall()
data = json.dumps(results)
cache.set('mydata', data)
return data
@app.post('/produce')
async def produce(request: Request):
data = await request.json()
p.produce('mytopic', json.dumps(data))
return {'message': 'Message produced'}
@app.get('/consume')
async def consume():
msg = c.poll(1.0)
if msg is None:
return {'message': 'No message'}
if msg.error():
return {'error': str(msg.error())}
data = json.loads(msg.value().decode('utf-8'))
return data

View File

@ -0,0 +1,5 @@
import redis
def get_cache_connection():
cache = redis.Redis(host='redis-service', port=6379)
return cache

View File

@ -0,0 +1,11 @@
import mysql.connector
def get_db_connection():
db = mysql.connector.connect(
host="mysql-service",
user="username",
password="password",
database="mydb"
)
return db

View File

@ -0,0 +1,6 @@
from fastapi import FastAPI
from routes.main import router as main_router
app = FastAPI()
app.include_router(main_router)

View File

@ -0,0 +1,14 @@
from confluent_kafka import Producer, Consumer
def get_kafka_producer():
p = Producer({'bootstrap.servers': 'my-kafka-service:9092'})
return p
def get_kafka_consumer():
c = Consumer({
'bootstrap.servers': 'my-kafka-service:9092',
'group.id': 'mygroup',
'auto.offset.reset': 'earliest'
})
c.subscribe(['mytopic'])
return c

View File

@ -0,0 +1,44 @@
from fastapi import APIRouter, Request
from db.mysql import get_db_connection
from cache.redis import get_cache_connection
from messaging.kafka import get_kafka_producer, get_kafka_consumer
import json
router = APIRouter()
@router.get('/')
async def read_root():
cache = get_cache_connection()
data = cache.get('mydata')
if data is not None:
return data
db = get_db_connection()
cursor = db.cursor()
cursor.execute("SELECT * FROM your_table")
results = cursor.fetchall()
data = json.dumps(results)
cache.set('mydata', data)
return data
@router.post('/produce')
async def produce(request: Request):
data = await request.json()
p = get_kafka_producer()
p.produce('mytopic', json.dumps(data))
return {'message': 'Message produced'}
@router.get('/consume')
async def consume():
c = get_kafka_consumer()
msg = c.poll(1.0)
if msg is None:
return 'No message', 200
if msg.error():
return 'Error: {}'.format(msg.error()), 500
data = json.loads(msg.value().decode('utf-8'))
return json.dumps(data), 200

View File

@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
- name: MYSQL_DATABASE
value: "mydb"
- name: MYSQL_USER
value: "username"
- name: MYSQL_PASSWORD
value: "password"
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:latest
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
selector:
app: redis
ports:
- protocol: TCP
port: 6379
targetPort: 6379

View File

@ -0,0 +1,4 @@
kubectl apply -f mysql-deployment.yaml
kubectl apply -f mysql-service.yaml
kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml

View File

@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-deployment
spec:
replicas: 3
selector:
matchLabels:
app: vue-app
template:
metadata:
labels:
app: vue-app
spec:
containers:
- name: vue-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: vue-service
spec:
selector:
app: vue-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -0,0 +1,47 @@
<template>
<div id="app">
<h1>My App</h1>
<p>{{ data }}</p>
<button @click="produce">Produce Message</button>
<button @click="consume">Consume Message</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'App',
data() {
return {
data: null,
message: { key: "value" }, // replace this with the actual message you want to produce
};
},
async created() {
try {
const response = await axios.get('http://my-app-service');
this.data = response.data;
} catch (error) {
console.error(error);
}
},
methods: {
async produce() {
try {
await axios.post('http://my-app-service/produce', this.message);
} catch (error) {
console.error(error);
}
},
async consume() {
try {
const response = await axios.get('http://my-app-service/consume');
this.data = response.data;
} catch (error) {
console.error(error);
}
},
},
};
</script>

View File

@ -0,0 +1,6 @@
FROM python:3.7-alpine
WORKDIR /app
COPY . /app
RUN pip install fastapi uvicorn mysql-connector-python redis confluent-kafka pip install bali-core grpclib
EXPOSE 80
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "80"]

View File

@ -0,0 +1,15 @@
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
RUN npm install axios
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,58 @@
from fastapi import FastAPI
from starlette.requests import Request
import mysql.connector
import redis
import json
from confluent_kafka import Producer, Consumer, KafkaError
app = FastAPI()
cache = redis.Redis(host='redis-service', port=6379)
# Kafka producer configuration
p = Producer({'bootstrap.servers': 'my-kafka-service:9092'})
# Kafka consumer configuration
c = Consumer({
'bootstrap.servers': 'my-kafka-service:9092',
'group.id': 'mygroup',
'auto.offset.reset': 'earliest'
})
c.subscribe(['mytopic'])
@app.get('/')
async def read_root():
data = cache.get('mydata')
if data is not None:
return data
db = mysql.connector.connect(
host="mysql-service",
user="username",
password="password",
database="mydb"
)
cursor = db.cursor()
cursor.execute("SELECT * FROM your_table")
results = cursor.fetchall()
data = json.dumps(results)
cache.set('mydata', data)
return data
@app.post('/produce')
async def produce(request: Request):
data = await request.json()
p.produce('mytopic', json.dumps(data))
return {'message': 'Message produced'}
@app.get('/consume')
async def consume():
msg = c.poll(1.0)
if msg is None:
return {'message': 'No message'}
if msg.error():
return {'error': str(msg.error())}
data = json.loads(msg.value().decode('utf-8'))
return data

View File

@ -0,0 +1,5 @@
import redis
def get_cache_connection():
cache = redis.Redis(host='redis-service', port=6379)
return cache

View File

@ -0,0 +1,11 @@
import mysql.connector
def get_db_connection():
db = mysql.connector.connect(
host="mysql-service",
user="username",
password="password",
database="mydb"
)
return db

View File

@ -0,0 +1,11 @@
from grpclib.server import Server
from routes.main import AppService
async def main():
server = Server([AppService()])
await server.start('127.0.0.1', 50051)
print('Serving on localhost:50051')
if __name__ == '__main__':
import asyncio
asyncio.run(main())

View File

@ -0,0 +1,14 @@
from confluent_kafka import Producer, Consumer
def get_kafka_producer():
p = Producer({'bootstrap.servers': 'my-kafka-service:9092'})
return p
def get_kafka_consumer():
c = Consumer({
'bootstrap.servers': 'my-kafka-service:9092',
'group.id': 'mygroup',
'auto.offset.reset': 'earliest'
})
c.subscribe(['mytopic'])
return c

View File

@ -0,0 +1,31 @@
from bali.core import Service
from db.mysql import get_db_connection
from cache.redis import get_cache_connection
from messaging.kafka import get_kafka_producer, get_kafka_consumer
from app_pb2 import ProduceRequest, ProduceResponse, ConsumeRequest, ConsumeResponse
from app_grpc import AppBase
class AppService(AppBase, Service):
def __init__(self):
super().__init__()
self.producer = get_kafka_producer()
self.consumer = get_kafka_consumer()
self.cache = get_cache_connection()
self.db = get_db_connection()
async def Produce(self, stream):
request = await stream.recv_message()
data = request.data
self.producer.produce('mytopic', data)
await stream.send_message(ProduceResponse(message='Message produced'))
async def Consume(self, stream):
await stream.recv_message()
msg = self.consumer.poll(1.0)
if msg is None:
data = 'No message'
elif msg.error():
data = 'Error: {}'.format(msg.error())
else:
data = msg.value().decode('utf-8')
await stream.send_message(ConsumeResponse(data=data))

View File

@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
- name: MYSQL_DATABASE
value: "mydb"
- name: MYSQL_USER
value: "username"
- name: MYSQL_PASSWORD
value: "password"
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:latest
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
selector:
app: redis
ports:
- protocol: TCP
port: 6379
targetPort: 6379

View File

@ -0,0 +1,4 @@
kubectl apply -f mysql-deployment.yaml
kubectl apply -f mysql-service.yaml
kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml

View File

@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-deployment
spec:
replicas: 3
selector:
matchLabels:
app: vue-app
template:
metadata:
labels:
app: vue-app
spec:
containers:
- name: vue-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: vue-service
spec:
selector:
app: vue-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -0,0 +1,27 @@
<template>
<div id="app">
<h1>My App</h1>
<p>{{ data }}</p>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'App',
data() {
return {
data: null,
};
},
async created() {
try {
const response = await axios.get('http://my-app-service'); // replace with your Flask app's service URL
this.data = response.data;
} catch (error) {
console.error(error);
}
},
};
</script>

View File

@ -0,0 +1,6 @@
FROM python:3.7-alpine
WORKDIR /app
COPY . /app
RUN pip install flask mysql-connector-python redis
EXPOSE 80
CMD ["python", "app.py"]

View File

@ -0,0 +1,15 @@
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
RUN npm install axios
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,20 @@
from flask import Flask
import mysql.connector
app = Flask(__name__)
@app.route('/')
def hello_world():
db = mysql.connector.connect(
host="mysql-service", # Kubernetes service name for your MySQL service
user="username",
password="password",
database="mydb"
)
cursor = db.cursor()
cursor.execute("SELECT * FROM your_table") # Replace 'your_table' with your table name
results = cursor.fetchall()
return str(results) # Convert results to string to return as HTTP response
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)

View File

@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
- name: MYSQL_DATABASE
value: "mydb"
- name: MYSQL_USER
value: "username"
- name: MYSQL_PASSWORD
value: "password"
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:latest
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
selector:
app: redis
ports:
- protocol: TCP
port: 6379
targetPort: 6379

View File

@ -0,0 +1,4 @@
kubectl apply -f mysql-deployment.yaml
kubectl apply -f mysql-service.yaml
kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml

View File

@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-deployment
spec:
replicas: 3
selector:
matchLabels:
app: vue-app
template:
metadata:
labels:
app: vue-app
spec:
containers:
- name: vue-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: vue-service
spec:
selector:
app: vue-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -0,0 +1,47 @@
<template>
<div id="app">
<h1>My App</h1>
<p>{{ data }}</p>
<button @click="produce">Produce Message</button>
<button @click="consume">Consume Message</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'App',
data() {
return {
data: null,
message: { key: "value" }, // replace this with the actual message you want to produce
};
},
async created() {
try {
const response = await axios.get('http://my-app-service');
this.data = response.data;
} catch (error) {
console.error(error);
}
},
methods: {
async produce() {
try {
await axios.post('http://my-app-service/produce', this.message);
} catch (error) {
console.error(error);
}
},
async consume() {
try {
const response = await axios.get('http://my-app-service/consume');
this.data = response.data;
} catch (error) {
console.error(error);
}
},
},
};
</script>

View File

@ -0,0 +1,6 @@
FROM python:3.7-alpine
WORKDIR /app
COPY . /app
RUN pip install flask mysql-connector-python redis confluent-kafka
EXPOSE 80
CMD ["python", "app.py"]

View File

@ -0,0 +1,15 @@
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
RUN npm install axios
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,42 @@
from flask import Flask, request
import json
import redis
import mysql.connector
from confluent_kafka import Producer, Consumer, KafkaError
app = Flask(__name__)
cache = redis.Redis(host='redis-service', port=6379)
# Kafka producer configuration
p = Producer({'bootstrap.servers': 'my-kafka-service:9092'}) # replace 'my-kafka-service' with your Kafka service name
# Kafka consumer configuration
c = Consumer({
'bootstrap.servers': 'my-kafka-service:9092', # replace 'my-kafka-service' with your Kafka service name
'group.id': 'mygroup',
'auto.offset.reset': 'earliest'
})
c.subscribe(['mytopic'])
@app.route('/produce', methods=['POST'])
def produce():
data = request.json
p.produce('mytopic', json.dumps(data))
return 'Message produced'
@app.route('/consume')
def consume():
msg = c.poll(1.0)
if msg is None:
return 'No message'
if msg.error():
return 'Error: {}'.format(msg.error())
data = json.loads(msg.value().decode('utf-8'))
return data
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)

View File

@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
- name: MYSQL_DATABASE
value: "mydb"
- name: MYSQL_USER
value: "username"
- name: MYSQL_PASSWORD
value: "password"
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -0,0 +1,31 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis-deployment
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:latest
ports:
- containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
spec:
selector:
app: redis
ports:
- protocol: TCP
port: 6379
targetPort: 6379

View File

@ -0,0 +1,4 @@
kubectl apply -f mysql-deployment.yaml
kubectl apply -f mysql-service.yaml
kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml

View File

@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-deployment
spec:
replicas: 3
selector:
matchLabels:
app: vue-app
template:
metadata:
labels:
app: vue-app
spec:
containers:
- name: vue-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: vue-service
spec:
selector:
app: vue-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

27
app/python/LNMP/App.vue Normal file
View File

@ -0,0 +1,27 @@
<template>
<div id="app">
<h1>My App</h1>
<p>{{ data }}</p>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: 'App',
data() {
return {
data: null,
};
},
async created() {
try {
const response = await axios.get('http://my-app-service'); // replace with your Flask app's service URL
this.data = response.data;
} catch (error) {
console.error(error);
}
},
};
</script>

View File

@ -0,0 +1,6 @@
FROM python:3.7-alpine
WORKDIR /app
COPY . /app
RUN pip install flask mysql-connector-python
EXPOSE 80
CMD ["python", "app.py"]

View File

@ -0,0 +1,15 @@
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
RUN npm install axios
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

20
app/python/LNMP/app.py Normal file
View File

@ -0,0 +1,20 @@
from flask import Flask
import mysql.connector
app = Flask(__name__)
@app.route('/')
def hello_world():
db = mysql.connector.connect(
host="mysql-service", # Kubernetes service name for your MySQL service
user="username",
password="password",
database="mydb"
)
cursor = db.cursor()
cursor.execute("SELECT * FROM your_table") # Replace 'your_table' with your table name
results = cursor.fetchall()
return str(results) # Convert results to string to return as HTTP response
if __name__ == '__main__':
app.run(host='0.0.0.0', port=80)

View File

@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deployment
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
- name: MYSQL_DATABASE
value: "mydb"
- name: MYSQL_USER
value: "username"
- name: MYSQL_PASSWORD
value: "password"
ports:
- containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-deployment
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

4
app/python/LNMP/run.sh Normal file
View File

@ -0,0 +1,4 @@
kubectl apply -f mysql-deployment.yaml
kubectl apply -f mysql-service.yaml
kubectl apply -f app-deployment.yaml
kubectl apply -f app-service.yaml

View File

@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-deployment
spec:
replicas: 3
selector:
matchLabels:
app: vue-app
template:
metadata:
labels:
app: vue-app
spec:
containers:
- name: vue-app
image: your-repo/your-tag # replace with your Docker image name and tag
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: vue-service
spec:
selector:
app: vue-app
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer

View File

@ -1,159 +0,0 @@
name: Build Test And Deploy
on:
pull_request:
push:
paths:
- 'Dockerfile'
- '.github/workflows/pipieline.yaml'
workflow_dispatch:
branches:
- main
env:
TZ: Asia/Shanghai
REPO: "artifact.onwalk.net"
IMAGE: base/${{ github.repository }}
TAG: ${{ github.sha }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y rustc cargo
- name: Build
run: |
cargo build --release
tar -czvpf my_rust_server-0.0.1.tar.gz target/release/my_rust_server
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
asset_name: my_rust_server-0.0.1.tar.gz
file: my_rust_server-0.0.1.tar.gz
tag: ${{ github.ref }}
overwrite: true
body: "Release v0.1.0"
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y rustc cargo
- name: Run tests
run: |
echo "To do ..."
docker-image:
runs-on: ubuntu-latest
name: Build image
needs:
- build
- test
steps:
- uses: actions/checkout@master
- name: 'Artifact: build && push debian-c-sysinfo image'
uses: aevea/action-kaniko@master
with:
registry: ${{ secrets.HELM_REPO_REGISTRY }}
username: ${{ secrets.HELM_REPO_USER }}
password: ${{ secrets.HELM_REPO_PASSWORD }}
path: './'
build_file: 'Dockerfile'
image: ${{ env.IMAGE }}
tag: ${{ env.TAG }}
cache: true
cache_registry: cache
setup-k3s:
runs-on: ubuntu-latest
needs:
- docker-image
steps:
- uses: actions/checkout@v3
- name: update submodule
run: |
sudo apt-get update && sudo apt-get install -y git && git submodule update --init --recursive
- name: Setup K3S Cluster
working-directory: ./scripts
shell: bash
run: |
export ANSIBLE_HOST_KEY_CHECKING=False
sudo apt install jq ansible -y
mkdir -pv ~/.ssh/
cat > ~/.ssh/id_rsa << EOF
${{ secrets.SSH_PRIVATE_KEY }}
EOF
sudo chmod 0400 ~/.ssh/id_rsa
md5sum ~/.ssh/id_rsa
mkdir -pv hosts/
cat > hosts/inventory << EOF
[master]
${{ secrets.HOST_DOMAIN }} ansible_host=${{ secrets.HOST_IP }}
[all:vars]
ansible_port=22
ansible_ssh_user=${{ secrets.HOST_USER }}
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_host_key_checking=False
ingress_ip=${{ secrets.HOST_IP }}
EOF
cat hosts/inventory
ansible-playbook -i hosts/inventory init_k3s_cluster -D
deploy-app:
runs-on: ubuntu-latest
needs: [setup-k3s]
steps:
- uses: actions/checkout@v3
- name: update submodule
run: |
sudo apt-get update && sudo apt-get install -y git && git submodule update --init --recursive
- name: Deploy
working-directory: ./scripts
shell: bash
run: |
export ANSIBLE_HOST_KEY_CHECKING=False
sudo apt install jq ansible -y
mkdir -pv ~/.ssh/
cat > ~/.ssh/id_rsa << EOF
${{ secrets.SSH_PRIVATE_KEY }}
EOF
sudo chmod 0400 ~/.ssh/id_rsa
md5sum ~/.ssh/id_rsa
mkdir -pv hosts/
cat > hosts/inventory << EOF
[master]
${{ secrets.HOST_DOMAIN }} ansible_host=${{ secrets.HOST_IP }}
[all:vars]
ansible_port=22
ansible_ssh_user=${{ secrets.HOST_USER }}
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_host_key_checking=False
app_image=${{ env.REPO }}/${{ env.IMAGE }}
app_tag=${{ env.TAG }}
EOF
ansible-playbook -i hosts/inventory deploy_app -D

View File

@ -1,160 +0,0 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

View File

@ -1,3 +0,0 @@
[submodule "scripts"]
path = scripts
url = https://github.com/SvcDesignScaffolding/AnsibleScripts.git