-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathservice.yaml
More file actions
220 lines (219 loc) · 7.68 KB
/
Copy pathservice.yaml
File metadata and controls
220 lines (219 loc) · 7.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
apiVersion: apps/v1
kind: Deployment
metadata:
name: service_name
labels:
app: service_name
spec:
replicas: 1
selector:
matchLabels:
app: service_name
template:
metadata:
labels:
app: service_name
spec:
# Works around a real bug found while testing against a live cluster:
# glibc's getaddrinfo() issues parallel A/AAAA queries by default, and
# on this environment's networking that races on a shared socket and
# fails with "OSError: [Errno 16] Device or resource busy" - silently
# breaking every hostname-based connection for any Python/glibc-based
# process (confirmed via the init container's aws-cli failing while
# simpler tools like busybox's wget/nslookup, which don't hit the same
# glibc code path, worked fine). single-request forces sequential
# queries instead, avoiding the race entirely.
dnsConfig:
options:
- name: single-request
volumes:
- name: workspace-volume
emptyDir: {}
initContainers:
- name: copy-s3-resources
image: amazon/aws-cli
command: ["/bin/sh", "-c"]
args:
# --endpoint-url is conditional (${S3_ENDPOINT:+...}) so this
# still works unmodified against real AWS S3 (leave S3_ENDPOINT
# blank below) as well as R2/MinIO/any S3-compatible endpoint -
# found by actually testing against MinIO, where this container
# would otherwise have tried to reach real AWS and failed.
- >
aws s3 cp s3://your-bucket-name/code/service_name/ /workspace/ --recursive ${S3_ENDPOINT:+--endpoint-url "$S3_ENDPOINT"} &&
echo "Resources copied from S3";
env:
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: sandbox-secrets
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: sandbox-secrets
key: AWS_SECRET_ACCESS_KEY
- name: S3_ENDPOINT
value: "your-s3-endpoint" # leave blank for real AWS S3; set for R2/MinIO/etc - must match the runner container's S3_ENDPOINT below
volumeMounts:
- name: workspace-volume
mountPath: /workspace
containers:
- name: runner
image: ghcr.io/shauryaasharma/runner:latest
ports:
- containerPort: 3001
- containerPort: 3000
env:
- name: REPL_ID
value: service_name
- name: OWNER_ID
value: owner_id_placeholder
- name: AWS_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: sandbox-secrets
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: sandbox-secrets
key: AWS_SECRET_ACCESS_KEY
- name: JWT_SECRET
valueFrom:
secretKeyRef:
name: sandbox-secrets
key: JWT_SECRET
- name: S3_BUCKET
value: "your-bucket-name"
- name: S3_ENDPOINT
value: "your-s3-endpoint"
volumeMounts:
- name: workspace-volume
mountPath: /workspace
resources:
# Bounty $25 Use ephemeral-storage to add space limits here
# Lowered from 1 CPU/1Gi to fit on a free-tier Micro node (956Mi
# total RAM, shared with k3s itself + ingress-nginx) - found by
# actually trying to schedule a pod here and hitting "Insufficient
# memory" since the original 1Gi request alone exceeded the
# node's entire capacity. Raise this back up once running on
# real Ampere/bigger-node capacity.
requests:
cpu: "100m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "400Mi"
---
apiVersion: v1
kind: Service
metadata:
name: service_name
spec:
selector:
app: service_name
ports:
- protocol: TCP
name: ws
port: 3001
targetPort: 3001
- protocol: TCP
name: user
port: 3000
targetPort: 3000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: service_name
# annotations:
# Uncomment once TLS is set up (see README "TLS via cert-manager") to
# force HTTP -> HTTPS. Leave commented out until then, or this breaks
# plain-HTTP access before a certificate actually exists.
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
# No tls: block needed here - TLS for every project's subdomain is served
# via the ingress controller's cluster-wide default certificate (see
# k8s/ingress-controller.yaml and README "TLS via cert-manager"), not a
# per-project certificate. This avoids issuing (and rate-limiting against)
# a brand new Let's Encrypt cert every time a project starts.
rules:
- host: service_name.ws_domain_placeholder
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service_name
port:
number: 3001
- host: service_name.app_domain_placeholder
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: service_name
port:
number: 3000
---
# NOTE: NetworkPolicy objects are only enforced if your cluster's CNI plugin
# supports it (Calico, Cilium, Weave Net, etc.) - plain flannel does NOT
# enforce these rules; they get created but silently ignored. If you're on
# flannel, switch to Canal (flannel + Calico's policy engine) or a
# policy-enforcing CNI, or this whole block is a no-op.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: service_name
spec:
podSelector:
matchLabels:
app: service_name
policyTypes:
- Ingress
- Egress
ingress:
# Only the ingress controller may reach this pod's ws (3001) and user-app
# (3000) ports - blocks every other pod, including other projects', from
# connecting directly. Adjust the namespace label if your ingress
# controller isn't in "ingress-nginx" (see k8s/ingress-controller.yaml,
# which installs it there).
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: ingress-nginx
ports:
- protocol: TCP
port: 3001
- protocol: TCP
port: 3000
egress:
# DNS - needed to resolve S3/R2 endpoints and package registries (npm/pip).
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
# Everything else EXCEPT the cluster's own internal ranges. This is what
# stops one project's pod from reaching another project's pod or the
# Kubernetes API server, while still allowing npm/pip installs and S3/R2
# access out to the open internet. The two CIDRs below are common
# kubeadm defaults - confirm (or replace) them for your cluster:
# pod CIDR: kubectl cluster-info dump | grep -m1 cluster-cidr
# service CIDR: check your provider's docs (EKS/GKE/AKS/k3s all default
# to different ranges); the API server's ClusterIP
# (`kubectl get svc kubernetes`) falls inside it.
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.42.0.0/16 # pod CIDR - k3s default
- 10.43.0.0/16 # service CIDR (covers the API server) - k3s default