ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c
9 changed files with 145336 additions and 0 deletions

View file

@ -0,0 +1,49 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata: {name: short-election}
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: [""]
apiVersions: [v1]
operations: [UPDATE]
resources: [pods]
matchConditions:
- name: tunnel-account
expression: request.userInfo.username == 'system:serviceaccount:short:tunnel'
variables:
- name: labels
expression: "has(object.metadata.labels) ? object.metadata.labels : {}"
- name: oldLabels
expression: "has(oldObject.metadata.labels) ? oldObject.metadata.labels : {}"
validations:
- expression: >-
oldObject.metadata.namespace == 'short' &&
oldObject.spec.serviceAccountName == 'tunnel' &&
'app.kubernetes.io/name' in variables.oldLabels &&
variables.oldLabels['app.kubernetes.io/name'] == 'tunnel'
message: The tunnel may only update tunnel pods.
- expression: object.spec == oldObject.spec
message: The tunnel may not change pod specifications.
- expression: >-
variables.labels.all(k, k == 'role' ||
(k in variables.oldLabels && variables.labels[k] == variables.oldLabels[k])) &&
variables.oldLabels.all(k, k == 'role' || k in variables.labels) &&
(!('role' in variables.labels) || variables.labels['role'] == 'active')
message: The tunnel may only set or remove the active role label.
- expression: >-
(has(object.metadata.annotations) ? object.metadata.annotations : {}) ==
(has(oldObject.metadata.annotations) ? oldObject.metadata.annotations : {}) &&
(has(object.metadata.ownerReferences) ? object.metadata.ownerReferences : []) ==
(has(oldObject.metadata.ownerReferences) ? oldObject.metadata.ownerReferences : []) &&
(has(object.metadata.finalizers) ? object.metadata.finalizers : []) ==
(has(oldObject.metadata.finalizers) ? oldObject.metadata.finalizers : [])
message: The tunnel may not change annotations, owners, or finalizers.
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata: {name: short-election}
spec:
policyName: short-election
validationActions: [Deny]

View file

@ -0,0 +1,156 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: tunnel
namespace: short
spec:
replicas: 2
template:
spec:
imagePullSecrets:
- name: pull
initContainers:
- name: stage
image: short-image
args:
- stage
- /agent/short
securityContext:
runAsUser: 65532
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
cpu: 25m
memory: 32Mi
limits:
memory: 64Mi
volumeMounts:
- name: agent
mountPath: /agent
containers:
- name: tunnel
image: docker.io/openeuler/strongswan@sha256:7cf59f44ca5e0b12938ce1cf66de437c6f7686d3d112c7057f30d8e055a608bc
command:
- /agent/short
args:
- tunnel
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
securityContext:
runAsNonRoot: false
runAsUser: 0
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
add:
- NET_ADMIN
- NET_BIND_SERVICE
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
ports:
- name: health
containerPort: 9090
readinessProbe:
httpGet:
path: /ready
port: health
periodSeconds: 5
volumeMounts:
- name: agent
mountPath: /agent
readOnly: true
- name: runtime
mountPath: /config
readOnly: true
- name: strongswan
mountPath: /usr/local/etc/strongswan.conf
subPath: strongswan.conf
readOnly: true
- name: run
mountPath: /var/run
- name: api
mountPath: /var/run/secrets/kubernetes.io/serviceaccount
readOnly: true
volumes:
- name: api
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 3600
- configMap:
name: kube-root-ca.crt
items:
- key: ca.crt
path: ca.crt
- name: agent
emptyDir: {}
- name: run
emptyDir: {}
- name: runtime
secret:
secretName: peers
items:
- key: config
path: runtime.json
- name: strongswan
configMap:
name: charon
securityContext:
fsGroup: 65532
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
serviceAccountName: tunnel
automountServiceAccountToken: false
terminationGracePeriodSeconds: 30
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- topologyKey: kubernetes.io/hostname
labelSelector:
matchLabels:
app.kubernetes.io/name: tunnel
app.kubernetes.io/instance: short
metadata:
labels:
app.kubernetes.io/name: tunnel
app.kubernetes.io/instance: short
selector:
matchLabels:
app.kubernetes.io/name: tunnel
app.kubernetes.io/instance: short
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: tunnel
namespace: short
spec:
minAvailable: 1
selector:
matchLabels:
app.kubernetes.io/name: tunnel
app.kubernetes.io/instance: short

View file

@ -0,0 +1,5 @@
apiVersion: v1
kind: ConfigMap
metadata: {name: endpoints, namespace: short}
data:
ike: "192.0.2.20"

View file

@ -0,0 +1,19 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
- vault.yaml
- policy.yaml
- endpoints.yaml
- rbac.yaml
- admission.yaml
replacements:
- source: {kind: ConfigMap, name: endpoints, fieldPath: data.ike}
targets:
- select: {kind: Service, name: ike}
fieldPaths: ["metadata.annotations.[lbipam.cilium.io/ips]"]
configMapGenerator:
- name: charon
namespace: short
files: [strongswan.conf]

View file

@ -0,0 +1,59 @@
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata: {name: tunnel, namespace: short}
spec:
endpointSelector:
matchLabels: {app.kubernetes.io/name: tunnel, app.kubernetes.io/instance: short}
ingress:
- fromCIDRSet: [{cidrGroupRef: short}]
toPorts:
- ports: [{port: "500", protocol: UDP}, {port: "4500", protocol: UDP}]
- fromEntities: [host]
toPorts:
- ports: [{port: "9090", protocol: TCP}]
egress:
- toCIDRSet: [{cidrGroupRef: short}]
toPorts:
- ports: [{port: "500", protocol: UDP}, {port: "4500", protocol: UDP}]
- toEntities: [kube-apiserver]
toPorts:
- ports: [{port: "6443", protocol: TCP}]
- toEntities: [ingress]
toPorts:
- ports: [{port: "80", protocol: TCP}, {port: "443", protocol: TCP}]
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: short
app.kubernetes.io/name: short-canary
app.kubernetes.io/instance: short
toPorts:
- ports: [{port: "8080", protocol: TCP}]
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: minecraft
app.kubernetes.io/name: minecraft
app.kubernetes.io/instance: skies
toPorts:
- ports: [{port: "25565", protocol: TCP}]
---
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata: {name: short-tunnel-host}
spec:
nodeSelector: {}
egress:
- toEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: short
app.kubernetes.io/name: tunnel
app.kubernetes.io/instance: short
toPorts:
- ports: [{port: "9090", protocol: TCP}]
ingress:
- fromEndpoints:
- matchLabels:
k8s:io.kubernetes.pod.namespace: short
app.kubernetes.io/name: tunnel
app.kubernetes.io/instance: short
toPorts:
- ports: [{port: "32768", endPort: 60999, protocol: TCP}]

View file

@ -0,0 +1,26 @@
apiVersion: v1
kind: ServiceAccount
metadata: {name: tunnel, namespace: short}
automountServiceAccountToken: false
---
apiVersion: coordination.k8s.io/v1
kind: Lease
metadata: {name: tunnel, namespace: short}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: {name: tunnel, namespace: short}
rules:
- apiGroups: [coordination.k8s.io]
resources: [leases]
resourceNames: [tunnel]
verbs: [get, update]
- apiGroups: [""]
resources: [pods]
verbs: [list, patch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: {name: tunnel, namespace: short}
roleRef: {apiGroup: rbac.authorization.k8s.io, kind: Role, name: tunnel}
subjects: [{kind: ServiceAccount, name: tunnel, namespace: short}]

View file

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: ike
namespace: short
labels: {app.kubernetes.io/name: tunnel, io.cilium/bgp-announce: "true"}
annotations: {lbipam.cilium.io/ips: ""}
spec:
type: LoadBalancer
publishNotReadyAddresses: true
externalTrafficPolicy: Local
selector: {app.kubernetes.io/name: tunnel, app.kubernetes.io/instance: short, role: active}
ports:
- {name: ike, port: 500, targetPort: 500, protocol: UDP}
- {name: natt, port: 4500, targetPort: 4500, protocol: UDP}

View file

@ -0,0 +1,11 @@
charon {
install_routes = no
install_routes_xfrmi = no
filelog {
stdout {
path = /dev/stdout
default = 1
flush_line = yes
}
}
}

View file

@ -0,0 +1,18 @@
apiVersion: secrets.hashicorp.com/v1beta1
kind: VaultStaticSecret
metadata: {name: peers, namespace: short}
spec:
vaultAuthRef: short
type: kv-v2
mount: secret
path: short/peers
refreshAfter: 10s
destination:
create: true
overwrite: true
name: peers
transformation:
excludeRaw: true
excludes: [.*]
templates:
config: {text: '{{ get .Secrets "config" }}'}