Skip to content

Commit 0a8a55e

Browse files
premtsd-codeclaude
andcommitted
feat: add Phase 5 K3s production manifests and deploy script
- Add k8s/ directory with 21 manifest files - Namespaces: linkedin-prod, monitoring, logging - Databases: PostgreSQL, Neo4j, Redis (StatefulSets with PVCs) - Messaging: Kafka (KRaft mode), Kafbat UI - Infrastructure: config-server, discovery-server - Microservices: 6 services with HPA (min:2, max:10), rolling updates - Observability: Zipkin, OpenSearch, OpenSearch Dashboards - Network policy for api-gateway zero-trust egress - Deploy script (k8s/deploy.sh) for ordered deployment - Update prod-ci-cd.yml with configmap apply step - Whitelist k8s/deploy.sh in .gitignore Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a325b77 commit 0a8a55e

24 files changed

+2569
-0
lines changed

.github/workflows/prod-ci-cd.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ jobs:
108108
mkdir -p ~/.kube
109109
echo "${{ secrets.KUBECONFIG }}" > ~/.kube/config
110110
chmod 600 ~/.kube/config
111+
- name: Update configmap
112+
run: kubectl apply -f k8s/configmap.yaml
111113
- name: Deploy changed services
112114
run: |
113115
for service in api-gateway user-service post-service connections-service notification-service uploader-service config-server discovery-server; do

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ build/
4848
prem-portfolio/
4949
*.ps1
5050
*.sh
51+
!k8s/deploy.sh
5152

5253
# -------------------------
5354
# Node.js & Angular (if any)

k8s/configmap.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: linkedin-config
5+
namespace: linkedin-prod
6+
data:
7+
SPRING_PROFILES_ACTIVE: "prod"
8+
EUREKA_URL: "http://discovery-server:8761/eureka"
9+
KAFKA_SERVERS: "kafka:9092"
10+
REDIS_HOST: "redis"
11+
REDIS_PORT: "6379"
12+
ZIPKIN_URL: "http://zipkin:9411"
13+
CONFIG_SERVER_URL: "http://config-server:8888"
14+
OPENSEARCH_HOST: "opensearch"
15+
OPENSEARCH_PORT: "9200"
16+
DB_URL: "jdbc:postgresql://postgres:5432/linkedinDB"
17+
DB_USER: "linkedin_user"
18+
NEO4J_URI: "bolt://neo4j:7687"
19+
NEO4J_USER: "neo4j"

k8s/databases/neo4j.yaml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
apiVersion: apps/v1
2+
kind: StatefulSet
3+
metadata:
4+
name: neo4j
5+
namespace: linkedin-prod
6+
spec:
7+
serviceName: neo4j
8+
replicas: 1
9+
selector:
10+
matchLabels:
11+
app: neo4j
12+
template:
13+
metadata:
14+
labels:
15+
app: neo4j
16+
spec:
17+
containers:
18+
- name: neo4j
19+
image: neo4j:5
20+
ports:
21+
- containerPort: 7474
22+
name: browser
23+
- containerPort: 7687
24+
name: bolt
25+
env:
26+
- name: NEO4J_AUTH
27+
valueFrom:
28+
secretKeyRef:
29+
name: linkedin-secrets
30+
key: NEO4J_PASSWORD
31+
resources:
32+
requests:
33+
memory: "512Mi"
34+
cpu: "500m"
35+
limits:
36+
memory: "2Gi"
37+
cpu: "1000m"
38+
volumeMounts:
39+
- name: neo4j-data
40+
mountPath: /data
41+
volumeClaimTemplates:
42+
- metadata:
43+
name: neo4j-data
44+
spec:
45+
accessModes: ["ReadWriteOnce"]
46+
resources:
47+
requests:
48+
storage: 5Gi
49+
---
50+
apiVersion: v1
51+
kind: Service
52+
metadata:
53+
name: neo4j
54+
namespace: linkedin-prod
55+
spec:
56+
type: NodePort
57+
selector:
58+
app: neo4j
59+
ports:
60+
- name: browser
61+
port: 7474
62+
targetPort: 7474
63+
nodePort: 32101
64+
- name: bolt
65+
port: 7687
66+
targetPort: 7687
67+
nodePort: 32102

k8s/databases/postgres.yaml

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
apiVersion: apps/v1
2+
kind: StatefulSet
3+
metadata:
4+
name: postgres
5+
namespace: linkedin-prod
6+
spec:
7+
serviceName: postgres
8+
replicas: 1
9+
selector:
10+
matchLabels:
11+
app: postgres
12+
template:
13+
metadata:
14+
labels:
15+
app: postgres
16+
spec:
17+
containers:
18+
- name: postgres
19+
image: postgres:15
20+
ports:
21+
- containerPort: 5432
22+
env:
23+
- name: POSTGRES_DB
24+
value: linkedinDB
25+
- name: POSTGRES_USER
26+
value: linkedin_user
27+
- name: POSTGRES_PASSWORD
28+
valueFrom:
29+
secretKeyRef:
30+
name: linkedin-secrets
31+
key: DB_PASSWORD
32+
resources:
33+
requests:
34+
memory: "512Mi"
35+
cpu: "500m"
36+
limits:
37+
memory: "1Gi"
38+
cpu: "1000m"
39+
volumeMounts:
40+
- name: postgres-data
41+
mountPath: /var/lib/postgresql/data
42+
livenessProbe:
43+
exec:
44+
command:
45+
- pg_isready
46+
- -U
47+
- linkedin_user
48+
initialDelaySeconds: 30
49+
periodSeconds: 10
50+
readinessProbe:
51+
exec:
52+
command:
53+
- pg_isready
54+
- -U
55+
- linkedin_user
56+
initialDelaySeconds: 10
57+
periodSeconds: 5
58+
volumeClaimTemplates:
59+
- metadata:
60+
name: postgres-data
61+
spec:
62+
accessModes: ["ReadWriteOnce"]
63+
resources:
64+
requests:
65+
storage: 10Gi
66+
---
67+
apiVersion: v1
68+
kind: Service
69+
metadata:
70+
name: postgres
71+
namespace: linkedin-prod
72+
spec:
73+
type: NodePort
74+
selector:
75+
app: postgres
76+
ports:
77+
- port: 5432
78+
targetPort: 5432
79+
nodePort: 32100

k8s/databases/redis.yaml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
apiVersion: apps/v1
2+
kind: StatefulSet
3+
metadata:
4+
name: redis
5+
namespace: linkedin-prod
6+
spec:
7+
serviceName: redis
8+
replicas: 1
9+
selector:
10+
matchLabels:
11+
app: redis
12+
template:
13+
metadata:
14+
labels:
15+
app: redis
16+
spec:
17+
containers:
18+
- name: redis
19+
image: bitnami/redis:latest
20+
ports:
21+
- containerPort: 6379
22+
env:
23+
- name: REDIS_PASSWORD
24+
valueFrom:
25+
secretKeyRef:
26+
name: linkedin-secrets
27+
key: REDIS_PASSWORD
28+
resources:
29+
requests:
30+
memory: "256Mi"
31+
cpu: "250m"
32+
limits:
33+
memory: "512Mi"
34+
cpu: "500m"
35+
volumeMounts:
36+
- name: redis-data
37+
mountPath: /bitnami/redis/data
38+
volumeClaimTemplates:
39+
- metadata:
40+
name: redis-data
41+
spec:
42+
accessModes: ["ReadWriteOnce"]
43+
resources:
44+
requests:
45+
storage: 2Gi
46+
---
47+
apiVersion: v1
48+
kind: Service
49+
metadata:
50+
name: redis
51+
namespace: linkedin-prod
52+
spec:
53+
type: NodePort
54+
selector:
55+
app: redis
56+
ports:
57+
- port: 6379
58+
targetPort: 6379
59+
nodePort: 32103

k8s/deploy.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "Deploying LinkedIn to K3s Production..."
5+
6+
echo "Creating namespaces..."
7+
kubectl apply -f k8s/namespace.yaml
8+
9+
echo "Creating configmap and secrets..."
10+
kubectl apply -f k8s/configmap.yaml
11+
kubectl apply -f k8s/secrets.yaml
12+
13+
echo "Deploying databases..."
14+
kubectl apply -f k8s/databases/postgres.yaml
15+
kubectl apply -f k8s/databases/neo4j.yaml
16+
kubectl apply -f k8s/databases/redis.yaml
17+
18+
echo "Waiting for databases..."
19+
kubectl rollout status statefulset/postgres -n linkedin-prod --timeout=3m
20+
kubectl rollout status statefulset/redis -n linkedin-prod --timeout=3m
21+
22+
echo "Deploying messaging..."
23+
kubectl apply -f k8s/messaging/kafka.yaml
24+
sleep 30
25+
kubectl apply -f k8s/messaging/kafbat-ui.yaml
26+
27+
echo "Deploying infrastructure..."
28+
kubectl apply -f k8s/infrastructure/config-server.yaml
29+
kubectl rollout status deployment/config-server -n linkedin-prod --timeout=3m
30+
31+
kubectl apply -f k8s/infrastructure/discovery-server.yaml
32+
kubectl rollout status deployment/discovery-server -n linkedin-prod --timeout=3m
33+
34+
echo "Deploying microservices..."
35+
kubectl apply -f k8s/microservices/
36+
kubectl rollout status deployment/api-gateway -n linkedin-prod --timeout=5m
37+
kubectl rollout status deployment/user-service -n linkedin-prod --timeout=5m
38+
kubectl rollout status deployment/post-service -n linkedin-prod --timeout=5m
39+
40+
echo "Deploying observability..."
41+
kubectl apply -f k8s/observability/
42+
43+
echo "Applying network policies..."
44+
kubectl apply -f k8s/network-policy.yaml
45+
46+
echo ""
47+
echo "Deployment complete!"
48+
echo ""
49+
kubectl get pods -n linkedin-prod
50+
echo ""
51+
kubectl get services -n linkedin-prod
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: config-server
5+
namespace: linkedin-prod
6+
spec:
7+
replicas: 1
8+
selector:
9+
matchLabels:
10+
app: config-server
11+
strategy:
12+
type: RollingUpdate
13+
rollingUpdate:
14+
maxSurge: 1
15+
maxUnavailable: 0
16+
template:
17+
metadata:
18+
labels:
19+
app: config-server
20+
spec:
21+
containers:
22+
- name: config-server
23+
image: premtsd18/config-server:amd64
24+
ports:
25+
- containerPort: 8888
26+
envFrom:
27+
- configMapRef:
28+
name: linkedin-config
29+
- secretRef:
30+
name: linkedin-secrets
31+
resources:
32+
requests:
33+
memory: "256Mi"
34+
cpu: "250m"
35+
limits:
36+
memory: "512Mi"
37+
cpu: "500m"
38+
livenessProbe:
39+
httpGet:
40+
path: /actuator/health/liveness
41+
port: 8888
42+
initialDelaySeconds: 60
43+
periodSeconds: 10
44+
failureThreshold: 3
45+
readinessProbe:
46+
httpGet:
47+
path: /actuator/health/readiness
48+
port: 8888
49+
initialDelaySeconds: 40
50+
periodSeconds: 5
51+
failureThreshold: 3
52+
---
53+
apiVersion: v1
54+
kind: Service
55+
metadata:
56+
name: config-server
57+
namespace: linkedin-prod
58+
spec:
59+
selector:
60+
app: config-server
61+
ports:
62+
- port: 8888
63+
targetPort: 8888

0 commit comments

Comments
 (0)