commit 24b9717db2755c1e5baa3fd0a60491ba1ad67a94 Author: Thomas Kruse Date: Wed Sep 2 22:11:05 2026 +0200 init diff --git a/admission/Dockerfile b/admission/Dockerfile new file mode 100644 index 0000000..625c412 --- /dev/null +++ b/admission/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3-alpine +RUN pip3 install Flask + +COPY app.py /app/app.py +COPY tls.crt /app/ +COPY tls.key /app/ +ENV PYTHONUNBUFFERED=1 + +WORKDIR /app +CMD ["python", "app.py"] +EXPOSE 443 diff --git a/admission/app.py b/admission/app.py new file mode 100644 index 0000000..3261983 --- /dev/null +++ b/admission/app.py @@ -0,0 +1,68 @@ +from flask import Flask, request, jsonify +import json +import base64 + +app = Flask(__name__) + +@app.route('/mutate', methods=['POST']) +def mutate(): + request_info = request.get_json() + pod = request_info['request']['object'] + uid = request_info['request']['uid'] + + patch = [] + if 'metadata' in pod and 'labels' in pod['metadata']: + labels = pod['metadata']['labels'] + if 'env' not in labels: + patch.append({ + "op": "add", + "path": "/metadata/labels/env", + "value": "training" + }) + else: + patch.append({ + "op": "add", + "path": "/metadata/labels", + "value": {"env": "training"} + }) + + admission_response = { + "apiVersion": "admission.k8s.io/v1", + "kind": "AdmissionReview", + "response": { + "uid": uid, + "allowed": True, + "patch": base64.b64encode(json.dumps(patch).encode()).decode(), + "patchType": "JSONPatch" + } + } + print (admission_response) + print (jsonify(admission_response)) + return jsonify(admission_response) + +@app.route('/validate', methods=['POST']) +def validate(): + request_info = request.get_json() + pod = request_info['request']['object'] + uid = request_info['request']['uid'] + + allowed = True + reason = "" + admission_response = { + "apiVersion": "admission.k8s.io/v1", + "kind": "AdmissionReview", + "response": { + "uid": uid, + "allowed": allowed + } + } + + admission_response["response"]["status"] = { + "message": reason + } + return jsonify(admission_response) + +if __name__ == '__main__': + context = ('tls.crt', 'tls.key') + print(context) + app.run(host='0.0.0.0', port=443, ssl_context=context) diff --git a/admission/commands b/admission/commands new file mode 100644 index 0000000..05d1199 --- /dev/null +++ b/admission/commands @@ -0,0 +1,36 @@ + +openssl req -x509 -newkey rsa:2048 -keyout tls.key -out tls.crt \ +-subj "/CN=admission.webhook.svc" -nodes -sha256 -days 365 + +openssl req -x509 -newkey rsa:2048 -keyout tls.key -out tls.crt \ + -sha256 -days 365 -nodes -subj "/CN=admission.webhook.svc" \ + -extensions san -config <(printf "[req]\ndistinguished_name=req\n[ san ]\nsubjectAltName=DNS:admission.webhook.svc") + + +base64 -w0 tls.crt + +minikube start --memory 4096 --cpus 2 --ports 5000:5000 +minikube addons enable registry + +minikube image build -t localhost:5000/admission . +minikube image push localhost:5000/admission:latest + +kubectl -n webhook rollout restart deployment admission + +docker build -t ttl.sh/admission . +docker push ttl.sh/admission + +docker build -t localhost:5000/admission . +docker push localhost:5000/admission + + +kubectl apply -f k8s +kubectl -n webhook get pods -w + +kubectl -n controlled delete pods --all +kubectl apply -f k8s +kubectl -n controlled get pods --show-labels + + +kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io sample +kubectl delete mutatingwebhookconfigurations.admissionregistration.k8s.io sample diff --git a/admission/k8s/0-ns.yaml b/admission/k8s/0-ns.yaml new file mode 100644 index 0000000..1a3ffc2 --- /dev/null +++ b/admission/k8s/0-ns.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: webhook + \ No newline at end of file diff --git a/admission/k8s/1-svc.yaml b/admission/k8s/1-svc.yaml new file mode 100644 index 0000000..3754d5d --- /dev/null +++ b/admission/k8s/1-svc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: admission + namespace: webhook +spec: + selector: + app: admission + ports: + - port: 443 + targetPort: 443 + diff --git a/admission/k8s/100-controlled-ns.yaml b/admission/k8s/100-controlled-ns.yaml new file mode 100644 index 0000000..1023e3c --- /dev/null +++ b/admission/k8s/100-controlled-ns.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: controlled + \ No newline at end of file diff --git a/admission/k8s/101-pod.yaml b/admission/k8s/101-pod.yaml new file mode 100644 index 0000000..5dabc31 --- /dev/null +++ b/admission/k8s/101-pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: demo + namespace: controlled +spec: + containers: + - name: demo + image: ghcr.io/trion-development/echoserver:1 + resources: {} + ports: + - containerPort: 3000 + diff --git a/admission/k8s/102-pod.yaml b/admission/k8s/102-pod.yaml new file mode 100644 index 0000000..a2de579 --- /dev/null +++ b/admission/k8s/102-pod.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: demo-two + namespace: controlled + labels: + some: value +spec: + containers: + - name: demo + image: ghcr.io/trion-development/echoserver:1 + resources: {} + ports: + - containerPort: 3000 + diff --git a/admission/k8s/2-deployment.yaml b/admission/k8s/2-deployment.yaml new file mode 100644 index 0000000..ff948c1 --- /dev/null +++ b/admission/k8s/2-deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: admission + namespace: webhook +spec: + selector: + matchLabels: + app: admission + template: + metadata: + labels: + app: admission + spec: + containers: + - name: app + image: localhost:5000/admission:latest #worst practice + # image: localhost:5000/admission:1 + resources: + requests: + memory: "128Mi" + cpu: "50m" + ports: + - containerPort: 443 diff --git a/admission/k8s/3-admission.yaml b/admission/k8s/3-admission.yaml new file mode 100644 index 0000000..039d180 --- /dev/null +++ b/admission/k8s/3-admission.yaml @@ -0,0 +1,31 @@ +apiVersion: admissionregistration.k8s.io/v1 +# kind: ValidatingWebhookConfiguration +kind: MutatingWebhookConfiguration +metadata: + name: sample +webhooks: + - name: "sample-webhook.trion.de" + admissionReviewVersions: [v1] + rules: + - apiGroups: [""] + apiVersions: ["v1"] + operations: ["CREATE"] + resources: ["pods"] + clientConfig: # url OR service + #url: "https://outside.example.com" + service: + name: admission + namespace: webhook + path: "/mutate" + # path: "/validate" + port: 443 + caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFVENDQWZtZ0F3SUJBZ0lVWFFIM0ZkdmVYQ0ZwY2k2eE5acy83bjVXeDhrd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0lERWVNQndHQTFVRUF3d1ZZV1J0YVhOemFXOXVMbmRsWW1odmIyc3VjM1pqTUI0WERUSTFNRFV5TWpFdwpNemswTlZvWERUSTJNRFV5TWpFd016azBOVm93SURFZU1Cd0dBMVVFQXd3VllXUnRhWE56YVc5dUxuZGxZbWh2CmIyc3VjM1pqTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF2OW54VjBHMmpOSmkKbzVRemFzb1QvVkl1eTdYZityRnI3UFF6RHVnejRQVXIwakRBNmluZURvV3VSQlhXMDV3Z2tnazJzSFpiYjJNegpQYUNlZkFDUWpwOEZ5QUxMYjFOcVVjVThJajdjMEZ2Mk1HME84bXUrNXNwNUoyLyt6cWl6bGJyMFFEQnd1YU9oCmYzN28zblVFdUgyMEtJODNTMXgzOEJNNnRyOWo4ZlN2YTlselpBZTl5K25Sc1hGb1NST2xDbGRYTGJTSDBNN3IKNU96Z1JJSTQrK3JOR0N4ZTdwRndPeGxiTEJTa0VQYUJUem4wTkhnYkJ5TzJNM25FVkJwcHlsKzBBZkU1QWI2OAo0VllVM3A5U2ZrNmlSaHVRSWRCWURTTUtEQ3gwY01VWWp1YlRpZ0FadFZoaW1lQlBmZ3RIQSt5M1hvcjM3UEJLCmNHZFdXL2VXdlFJREFRQUJvME13UVRBZ0JnTlZIUkVFR1RBWGdoVmhaRzFwYzNOcGIyNHVkMlZpYUc5dmF5NXoKZG1Nd0hRWURWUjBPQkJZRUZKQlA2aU5uUDdxVkt0QVVCRTFFeEx6OVd1Y3RNQTBHQ1NxR1NJYjNEUUVCQ3dVQQpBNElCQVFCdFdLTXVYbmlVRGx2cnZVeGRHUGVPMTV5TTFRMXdnaGE5bE5laXl2NHI2NFNTWi80Q3pWV2pWVWVDCmJvU1VoeDhPV2h1VjhWbjVOM0xhemVjVmpyemdBeWM5aUoxWUMrYlVPWHpyR3RRaEhUS0liNlkwNlVRclJWOG0KVGc3RVdLM1VxV2xwcG9WcU8xYU9QYUt5T3YzK2xGOUF1dFZ6YW1MS1FjQVRMS1VmSk05dWRLRTZtS2FJQlNHVwo2eU1tRC9XWTNCeG9URi9JWWhSSjQyWmtIMGlSK2FOaStBMmN4K1ZSZUFTWEVMUVg4ZlZJSVE2M0twWmxNNHRvCnB1WFZzcG4yaktvVWlqRVJwSWNpZHlxaXVVSitNWVg0SStFUEs0aTdWZnpvaVJJRXA3TmhPUVZpaGt3dHc0Tk0KSzgrVHg0YVJsY2xPeTNBM3dqOUxmN2kxdHc3NAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + sideEffects: None # or NoneOnDryRun + namespaceSelector: + matchExpressions: + - key: kubernetes.io/metadata.name + operator: In + values: + - controlled +# matchLabels: +# enforce-image: enabled diff --git a/admission/tls.crt b/admission/tls.crt new file mode 100644 index 0000000..e01e665 --- /dev/null +++ b/admission/tls.crt @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfmgAwIBAgIUXQH3FdveXCFpci6xNZs/7n5Wx8kwDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVYWRtaXNzaW9uLndlYmhvb2suc3ZjMB4XDTI1MDUyMjEw +Mzk0NVoXDTI2MDUyMjEwMzk0NVowIDEeMBwGA1UEAwwVYWRtaXNzaW9uLndlYmhv +b2suc3ZjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv9nxV0G2jNJi +o5QzasoT/VIuy7Xf+rFr7PQzDugz4PUr0jDA6ineDoWuRBXW05wgkgk2sHZbb2Mz +PaCefACQjp8FyALLb1NqUcU8Ij7c0Fv2MG0O8mu+5sp5J2/+zqizlbr0QDBwuaOh +f37o3nUEuH20KI83S1x38BM6tr9j8fSva9lzZAe9y+nRsXFoSROlCldXLbSH0M7r +5OzgRII4++rNGCxe7pFwOxlbLBSkEPaBTzn0NHgbByO2M3nEVBppyl+0AfE5Ab68 +4VYU3p9Sfk6iRhuQIdBYDSMKDCx0cMUYjubTigAZtVhimeBPfgtHA+y3Xor37PBK +cGdWW/eWvQIDAQABo0MwQTAgBgNVHREEGTAXghVhZG1pc3Npb24ud2ViaG9vay5z +dmMwHQYDVR0OBBYEFJBP6iNnP7qVKtAUBE1ExLz9WuctMA0GCSqGSIb3DQEBCwUA +A4IBAQBtWKMuXniUDlvrvUxdGPeO15yM1Q1wgha9lNeiyv4r64SSZ/4CzVWjVUeC +boSUhx8OWhuV8Vn5N3LazecVjrzgAyc9iJ1YC+bUOXzrGtQhHTKIb6Y06UQrRV8m +Tg7EWK3UqWlppoVqO1aOPaKyOv3+lF9AutVzamLKQcATLKUfJM9udKE6mKaIBSGW +6yMmD/WY3BxoTF/IYhRJ42ZkH0iR+aNi+A2cx+VReASXELQX8fVIIQ63KpZlM4to +puXVspn2jKoUijERpIcidyqiuUJ+MYX4I+EPK4i7VfzoiRIEp7NhOQVihkwtw4NM +K8+Tx4aRlclOy3A3wj9Lf7i1tw74 +-----END CERTIFICATE----- diff --git a/admission/tls.key b/admission/tls.key new file mode 100644 index 0000000..9aa2d63 --- /dev/null +++ b/admission/tls.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC/2fFXQbaM0mKj +lDNqyhP9Ui7Ltd/6sWvs9DMO6DPg9SvSMMDqKd4Oha5EFdbTnCCSCTawdltvYzM9 +oJ58AJCOnwXIAstvU2pRxTwiPtzQW/YwbQ7ya77mynknb/7OqLOVuvRAMHC5o6F/ +fujedQS4fbQojzdLXHfwEzq2v2Px9K9r2XNkB73L6dGxcWhJE6UKV1cttIfQzuvk +7OBEgjj76s0YLF7ukXA7GVssFKQQ9oFPOfQ0eBsHI7YzecRUGmnKX7QB8TkBvrzh +VhTen1J+TqJGG5Ah0FgNIwoMLHRwxRiO5tOKABm1WGKZ4E9+C0cD7Ldeivfs8Epw +Z1Zb95a9AgMBAAECggEADqmIvlMcBoCAYAwQL0B+bUUopRJN/zTWu2dLt6nwvRKV +D3KrwQ8DajdhQtGAd5peYDWADoBygH15CblgI2NPqPa8/wo8+KchYFp4kWLIhswL +HAGvEMFB98AlqOlFn2RZRT+NMegB1Xjh+4J8KEmShh8P88GY8j4rlGzZIeUCrcJp +nlVT47d02N9dJRGeRL6qZ2Dlr/4CJjhrgSAQmG6wgHsmaQtVtiAnF7y8WABvIelT +mybzROFpq4F47io2Zc4XJioUsN1iLujUKoV2rfZ2+KarGmfGTwaYApMzWBf4V/pQ +ZUbbEPEdzyOUecWWX/ESynAr93k7G1EeC8LTtivlqQKBgQDTJnNWMZiQt7BFss49 +QyaQzSEVFPZJekPdzETh4eZJBhGxeKce14mToLKr4xqMP4blCXBus8dC1C+cQ63J +AZ1zcy6Nsx6rGixPJJNvuQsjXBdpyFhYSCKL+NSXzD+isODkNtcBlbjCgch59PzC +r5yQiTAHHjr/WSs9OQZo82oa9wKBgQDomhfePhZIFUUzCek5fHTxT4upd3N6MeJe +Dsv00ajfNEF//vm+6GyOnNz8hx9qH7cWvsGpsr7AtYB3C9DKoRKRVNidc4z9PovD +ZjJQMeOqbOzH7FKiZMrGiJuyYSYB96Mr8tTR7jRBNeBX/3R+ll/aYnYIJZrnnUPX +KeijWRpa6wKBgH2m7AvnB7tXFHblqQWb6F9TMtSw3L9tGuXqoTMqkzfxfKX3/rvD +2AMaJjlTtICxbTzvGRFHutRyIMMFI23yoBgL+zAn36BCuwt94J8jpxUrwGMa7jfa +9XQGZ7zNtzDBwZMNb3Vp+8EEKqEowSG6D5mTihkyTDmYfrq4LLBX6lSRAoGBAKeW +lsnerAkloiUi5/IuVMeky3i/gukw1et098id4vFm4iaJnIHLTqP2K1abOKwqy6zM +phZRnhSU8UlUrwu/v/QMUMIpBhVUojiYAno7Z9BcCMIG6Ibu3hbrSFremhbiyKMa +o/HZkbbGTay5dsLaL5fWRzqZdaGZcs6s+FvxEAcfAoGBAJvfkqvwQ2UadVLNltsl +ygFdaGZNyRKUS+KQitOjltKXgebL2ZYk4eCWqwCDhjWKwdPHJkq1fGjBED9yYVVG +ORRNqvPh3E2HLhnG4efQLObN++FsZC5roC5wZDm0fjwJfLgfBP4kuBy18CKZs27f +JtSwkRdyLwGjiM1IY0UHR/8/ +-----END PRIVATE KEY----- diff --git a/affinity/os-affinity.yaml b/affinity/os-affinity.yaml new file mode 100644 index 0000000..dab6a48 --- /dev/null +++ b/affinity/os-affinity.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: demo + image: ghcr.io/trion-development/echoserver:1 + resources: {} + ports: + - containerPort: 3000 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/os + operator: In + values: + - linux + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - myapp + topologyKey: kubernetes.io/hostname diff --git a/audit/commands b/audit/commands new file mode 100644 index 0000000..7685198 --- /dev/null +++ b/audit/commands @@ -0,0 +1,10 @@ +minikube start \ + --extra-config=apiserver.audit-policy-file=/etc/ssl/certs/policy.yaml \ + --extra-config=apiserver.audit-log-path=- --mount \ + --mount-string="$(pwd)/policy.yaml:/etc/ssl/certs/policy.yaml" + + +kubectl -n kube-system logs kube-apiserver-minikube -f + + +https://gist.githubusercontent.com/noqcks/9cc2f70e12898f0227396a906b06cab6/raw/ea0e80e594f29850611a8bee7376b89cb22d6628/audit-policy-example.yml diff --git a/audit/policy.yaml b/audit/policy.yaml new file mode 100644 index 0000000..bbc49f1 --- /dev/null +++ b/audit/policy.yaml @@ -0,0 +1,14 @@ +apiVersion: audit.k8s.io/v1 +kind: Policy +rules: + - level: Metadata + resources: + - group: "" + resources: ["pods"] + - level: RequestResponse + verbs: ["create", "update", "patch"] + resources: + - group: "apps" + resources: ["deployments"] + - level: None + users: ["system:kube-proxy"] diff --git a/cert/csr.yaml b/cert/csr.yaml new file mode 100644 index 0000000..a4a2ea6 --- /dev/null +++ b/cert/csr.yaml @@ -0,0 +1,15 @@ +apiVersion: certificates.k8s.io/v1 +kind: CertificateSigningRequest +metadata: + name: sample +spec: + request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2JUQ0NBVlVDQVFBd0tERW1NQ1FHQTFVRUF3d2RjMkZ0Y0d4bExtUmxiVzh1YzNaakxtTnNkWE4wWlhJdQpiRzlqWVd3d2dnRWlNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURORVBpeHlSbytYQ3lyCjZTMlFoWGFwN0lONDRXd09OUWZuUERmRUxISkJtRmRGOUdWSDk5MU9Ydi93MEdhZk9YV0dXeE96T09VYjd2aTYKNFp6WXpqT29TTFU1TG1wdlVMaElyN3NscU12ek5pdm93VlA4QS8xTkRCR04xdld3NjY5eE84ejdCdUhvT1NHUwpraDFnOTMxQTlsaWJIU2RyS0l2N3JYdFFsNVdTaU1EYkdGU0xOdVJqRytSNFY3VW8vVVh1MURRaHZ1MU9DZk8rClhrd2FBRC8ycVNJY2tRUGdVblk0d0RsTDZkRDlPbjIxVHNXRS9BaUs1cm12V0t0VWw3aWlFOERJbndoMkZDRjYKZnIzZEVVYjZFdG82T0dTK1RnT3AyK1JsNWoxLzU5aHcrNTAxcm81VGcxY2N0eGNwMFlHV2Y4Zmd1U2xMQXRNZQpva1VnZU9tUEFnTUJBQUdnQURBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQW1lcDY3MGV5WkJaRGVzdGIxVGU3Ck5qSkFnZVcwNU1zT1NOQ3h5NFRPOUdXc2xsdmt2WjhpaCsvdHBaVTB0bGlNZXJ0QUNBSGlYSmJGUys0UEg5MXkKTmgrNlVOTk00Z3hhUzRCRFA1QThaeXRCT1RvZGFXeGF5UjYyMXFralA5Z1U3K3kvd0dXSTBEdWFDdlhtU3oyUgpjSVlVMkRYMnBHUVpsV01ROEFxWjNTNjlsT0dwVG9MekZmYjEreFNEWkJ4d0JCWVpYdnc2clB3VXlIaEw3TDFpCk92a3Eva3FzMUYwYnp4S0cwVlBsQ0hzS2IwbFdneVYwUmZ0UzNmU2hHSi9vUzcyb2JoaGVwaGtxdVNlTGRtcDUKakFabERWWVp5bndmbUEwTTIxYXVpbmpoeE9hL3dVMW5RSUorcWs1NzNwSy9rbXU0QWFxNEMxMjc0WFprcVpFNgppQT09Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo= +# openssl req -new -newkey rsa:2048 -nodes -keyout tls.key -out tls.csr -subj "/CN=sample.demo.svc.cluster.local" +# base64 -w0 +# kubectl get csr sample -o yaml + signerName: kubernetes.io/kube-apiserver-client + usages: + - client auth + - digital signature + - key encipherment + diff --git a/cert/tls.csr b/cert/tls.csr new file mode 100644 index 0000000..1a23f11 --- /dev/null +++ b/cert/tls.csr @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICbTCCAVUCAQAwKDEmMCQGA1UEAwwdc2FtcGxlLmRlbW8uc3ZjLmNsdXN0ZXIu +bG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNEPixyRo+XCyr +6S2QhXap7IN44WwONQfnPDfELHJBmFdF9GVH991OXv/w0GafOXWGWxOzOOUb7vi6 +4ZzYzjOoSLU5LmpvULhIr7slqMvzNivowVP8A/1NDBGN1vWw669xO8z7BuHoOSGS +kh1g931A9libHSdrKIv7rXtQl5WSiMDbGFSLNuRjG+R4V7Uo/UXu1DQhvu1OCfO+ +XkwaAD/2qSIckQPgUnY4wDlL6dD9On21TsWE/AiK5rmvWKtUl7iiE8DInwh2FCF6 +fr3dEUb6Eto6OGS+TgOp2+Rl5j1/59hw+501ro5Tg1cctxcp0YGWf8fguSlLAtMe +okUgeOmPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAmep670eyZBZDestb1Te7 +NjJAgeW05MsOSNCxy4TO9GWsllvkvZ8ih+/tpZU0tliMertACAHiXJbFS+4PH91y +Nh+6UNNM4gxaS4BDP5A8ZytBOTodaWxayR621qkjP9gU7+y/wGWI0DuaCvXmSz2R +cIYU2DX2pGQZlWMQ8AqZ3S69lOGpToLzFfb1+xSDZBxwBBYZXvw6rPwUyHhL7L1i +Ovkq/kqs1F0bzxKG0VPlCHsKb0lWgyV0RftS3fShGJ/oS72obhhephkquSeLdmp5 +jAZlDVYZynwfmA0M21auinjhxOa/wU1nQIJ+qk573pK/kmu4Aaq4C1274XZkqZE6 +iA== +-----END CERTIFICATE REQUEST----- diff --git a/cert/tls.key b/cert/tls.key new file mode 100644 index 0000000..dc29240 --- /dev/null +++ b/cert/tls.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNEPixyRo+XCyr +6S2QhXap7IN44WwONQfnPDfELHJBmFdF9GVH991OXv/w0GafOXWGWxOzOOUb7vi6 +4ZzYzjOoSLU5LmpvULhIr7slqMvzNivowVP8A/1NDBGN1vWw669xO8z7BuHoOSGS +kh1g931A9libHSdrKIv7rXtQl5WSiMDbGFSLNuRjG+R4V7Uo/UXu1DQhvu1OCfO+ +XkwaAD/2qSIckQPgUnY4wDlL6dD9On21TsWE/AiK5rmvWKtUl7iiE8DInwh2FCF6 +fr3dEUb6Eto6OGS+TgOp2+Rl5j1/59hw+501ro5Tg1cctxcp0YGWf8fguSlLAtMe +okUgeOmPAgMBAAECggEAAUUNN+t9wAoQafzGzWFRNhcsrRaFegB968KMPq0yz6L1 +bgBao3/98vHdkrroKfgW53GnRQWl/cuHNncWVR8gFGnYN5/wkicM+KY/Aq6dknb7 +9K+/+Gkpf80LVExmyQz3k1asR+clfUpWpjBOHJvec8ckXiMpuwtwiZ/IiggJj0LX +xbNBHzdyCILltRxlLbLSVbUg/uIsBEJ3xG7eXuYqDZi3ihNjK0PxZN/5ZxDt1VjT +EihY9dnMpQJvYsOWBUcWiFmy35BO5mpWikKYgE3AgPH10R6u5WCraso1lzTuEhwQ +b9ZA9DMZKj2OsWC8YjpVJx/VnpD4tZti0jcMCnwbAQKBgQDYthgmAJcsZ2MznMGI +SI/eA2P+hErIK68LJi6x/4xh7bthSzWzYmNHVirTgJ7/kZygonSCzOh01O/yR0DH +N5otM0b6CsDFDFhT1QRZ/2V3dYkp1AwQGsnpNVlqcfs0ai9DWdxjMwt95IKKNKOG +EtW+9lGTjcT9e8UPwnU9r81Q8QKBgQDyPmoKLSjDUpXKQtpX7wvA3Sh03hv+93SP +qWfJG5gpR78t6faMVqQx2Yp55Bmb3LapEkMmGKnCDvPVAfn8G1V2jidTx96JTwWZ +UhjBwQOI/KGdv76uUEFLyTGo6wTE8sk/ylSA3A5dHrXmdvfqaZaERgTANbw973a/ +05nayrnifwKBgEisuGh2JjxT56a1WQm1G9oeVPhTsShzzd31Tg+PXaqxqPc126pu +wlB4CyCmr6uRT29nS59ZzFLx3g3n60dj1CZ4XcMYvBDY1P44H5920LZBCmCmpez4 +ruGwbG4QD2hCe9sgVZJG2gG8EjL6+CPMSTYjMLRFBNzlFu70DZFEVZxhAoGAcP/S +YTrdl/dvLjFvPrOgrO+9Tn7JWm8+LUGdyz8XBLKWKKnJu38zCpnqsZ9Int8fSdDe +B+hbT82/yi4o2YQ6opn/GGLUmQKGnxWfvMn3hzAph7eJEDEZtGt+wcgXqnOCk0Ij +lxSPkrqfqYj3bp6gesVas/qc+9s3bpYbX+dPPKsCgYAh6ly1uSs/vhKliRrv8haA +A7YiCT7pL5JMYNFIwLKQame3j+Phh38NC8h6meLK8jSDo8AcVtQpwfOH+Jj3X1MZ +yHbB4efITWPhfFP8n2satv8bWRf0p4YpAr4SgFcZgKIyIdhw1TN3cLElFePQj84J +CcgYwcBmbio2YIEdRPmeNg== +-----END PRIVATE KEY----- diff --git a/limit-range/container-cpu.yaml b/limit-range/container-cpu.yaml new file mode 100644 index 0000000..b8606f0 --- /dev/null +++ b/limit-range/container-cpu.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: LimitRange +metadata: + name: container-cpu + namespace: custom-namespace +spec: + limits: + - default: # defines default limits + cpu: 500m + defaultRequest: # default requests + cpu: 500m + max: # define the limit range + cpu: "1" + min: + cpu: 100m + type: Container + diff --git a/network-policy/0-policy.template b/network-policy/0-policy.template new file mode 100644 index 0000000..3e0e487 --- /dev/null +++ b/network-policy/0-policy.template @@ -0,0 +1,31 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + namespace: isolated +spec: + podSelector: + matchLabels: + app: my + policyTypes: + - Egress + ingress: + - from: + - ipBlock: + cidr: 172.17.0.0/16 + except: + - 172.17.1.0/24 + - namespaceSelector: + matchLabels: + project: demo + kubernetes.io/metadata.name: app + - podSelector: + matchLabels: + role: frontend + egress: + - to: + - namespaceSelector: + matchLabels: + ... + ports: + - protocol: .. + port: .. diff --git a/network-policy/commands b/network-policy/commands new file mode 100644 index 0000000..f026565 --- /dev/null +++ b/network-policy/commands @@ -0,0 +1,4 @@ + +minikube start --cpus 2 --memory 8192 --ports 80:80 --driver docker --cni calico + +kubectl run shell --rm -it --image trion/curl:1 \ No newline at end of file diff --git a/network-policy/default-deny.yaml b/network-policy/default-deny.yaml new file mode 100644 index 0000000..50c0860 --- /dev/null +++ b/network-policy/default-deny.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: default-deny-ingress + namespace: demo +spec: + podSelector: {} + policyTypes: + - Ingress diff --git a/network-policy/dns-egress.yaml b/network-policy/dns-egress.yaml new file mode 100644 index 0000000..9a45b69 --- /dev/null +++ b/network-policy/dns-egress.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-dns-access + namespace: demo +spec: + podSelector: + matchLabels: {} + policyTypes: + - Egress + egress: + - to: + - namespaceSelector: + matchLabels: + name: kube-system + ports: + - protocol: UDP + port: 53 diff --git a/network-policy/web-client/0-namespace.yaml b/network-policy/web-client/0-namespace.yaml new file mode 100644 index 0000000..ce4fc36 --- /dev/null +++ b/network-policy/web-client/0-namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: isolated diff --git a/network-policy/web-client/1-pods.yaml b/network-policy/web-client/1-pods.yaml new file mode 100644 index 0000000..b014355 --- /dev/null +++ b/network-policy/web-client/1-pods.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Pod +metadata: + name: web + namespace: isolated + labels: + app: web +spec: + containers: + - name: web + image: ghcr.io/trion-development/echoserver:1 + ports: + - containerPort: 3000 + resources: {} +--- +apiVersion: v1 +kind: Pod +metadata: + name: client + namespace: isolated + labels: + app: client +spec: + containers: + - name: curl + image: trion/curl:1 + tty: true + resources: {} diff --git a/network-policy/web-client/2-service.yaml b/network-policy/web-client/2-service.yaml new file mode 100644 index 0000000..32e622e --- /dev/null +++ b/network-policy/web-client/2-service.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Service +metadata: + name: web + namespace: isolated +spec: + selector: + app: web + ports: + - protocol: TCP + port: 80 + targetPort: 3000 diff --git a/network-policy/web-client/3-deny-all.yaml b/network-policy/web-client/3-deny-all.yaml new file mode 100644 index 0000000..2094172 --- /dev/null +++ b/network-policy/web-client/3-deny-all.yaml @@ -0,0 +1,19 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: deny-all-ingress + namespace: isolated +spec: + podSelector: {} + policyTypes: + - Ingress +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: deny-all-egress + namespace: isolated +spec: + podSelector: {} + policyTypes: + - Egress diff --git a/network-policy/web-client/4-allow-http.yaml b/network-policy/web-client/4-allow-http.yaml new file mode 100644 index 0000000..e93dbf6 --- /dev/null +++ b/network-policy/web-client/4-allow-http.yaml @@ -0,0 +1,21 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-client-to-web + namespace: isolated +spec: + podSelector: + matchLabels: + app: web + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + app: client + ports: + - protocol: TCP + port: 80 + - protocol: TCP + port: 3000 \ No newline at end of file diff --git a/network-policy/web-client/5-allow-dns.yaml b/network-policy/web-client/5-allow-dns.yaml new file mode 100644 index 0000000..b6885ad --- /dev/null +++ b/network-policy/web-client/5-allow-dns.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-dns-client + namespace: isolated +spec: + podSelector: {} + policyTypes: + - Egress + egress: + - to: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - protocol: UDP + port: 53 diff --git a/network-policy/web-client/6-allow-extern.yaml b/network-policy/web-client/6-allow-extern.yaml new file mode 100644 index 0000000..1ce7493 --- /dev/null +++ b/network-policy/web-client/6-allow-extern.yaml @@ -0,0 +1,20 @@ +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: allow-client-egress-internet + namespace: isolated +spec: + podSelector: + matchLabels: + app: client + policyTypes: + - Egress + egress: + - to: + - ipBlock: + cidr: 0.0.0.0/0 + ports: + - protocol: TCP + port: 80 + - protocol: TCP + port: 443 diff --git a/network-policy/web-client/commands b/network-policy/web-client/commands new file mode 100644 index 0000000..bac2bcf --- /dev/null +++ b/network-policy/web-client/commands @@ -0,0 +1,2 @@ +kubectl -n isolated get pods -o wide + diff --git a/node-scheduling/node-name.yaml b/node-scheduling/node-name.yaml new file mode 100644 index 0000000..201660f --- /dev/null +++ b/node-scheduling/node-name.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + nodeName: worker-1 + containers: + - name: nginx + image: nginx + resources: {} \ No newline at end of file diff --git a/node-scheduling/node-selector.yaml b/node-scheduling/node-selector.yaml new file mode 100644 index 0000000..1c0a357 --- /dev/null +++ b/node-scheduling/node-selector.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + nodeSelector: + gpu: amd + containers: + - name: nginx + image: nginx + resources: {} \ No newline at end of file diff --git a/pod-sec/0-ns.yaml b/pod-sec/0-ns.yaml new file mode 100644 index 0000000..ed2f156 --- /dev/null +++ b/pod-sec/0-ns.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: restricted + labels: + pod-security.kubernetes.io/enforce: baseline + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/warn: restricted diff --git a/pod-sec/1-pod.yaml b/pod-sec/1-pod.yaml new file mode 100644 index 0000000..6ac8e88 --- /dev/null +++ b/pod-sec/1-pod.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Pod +metadata: + name: safe + namespace: restricted +spec: + volumes: + - name: data + emptyDir: {} + initContainers: + - name: init + image: alpine:3 + volumeMounts: + - name: data + mountPath: /data + args: + - /bin/sh + - -c + - mkdir /data/nginx; chown -R 1000 /data + containers: + - name: app + image: nginx + resources: {} + ports: + - containerPort: 80 + volumeMounts: + - name: data + mountPath: /var/cache + - name: data + mountPath: /run + securityContext: + runAsNonRoot: true + runAsUser: 1000 + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + add: + - BIND_SERVICE + \ No newline at end of file diff --git a/pod-sec/101-pod.yaml b/pod-sec/101-pod.yaml new file mode 100644 index 0000000..9bd1463 --- /dev/null +++ b/pod-sec/101-pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: demo + namespace: restricted +spec: + containers: + - name: demo + image: ghcr.io/trion-development/echoserver:1 + resources: {} + ports: + - containerPort: 3000 + diff --git a/pod-sec/commands b/pod-sec/commands new file mode 100644 index 0000000..f679053 --- /dev/null +++ b/pod-sec/commands @@ -0,0 +1,2 @@ +kubectl run --dry-run=client -o yaml --image ghcr.io/trion-development/echoserver:1 echo + diff --git a/rbac/01-clusterrole.yaml b/rbac/01-clusterrole.yaml new file mode 100644 index 0000000..a0826ec --- /dev/null +++ b/rbac/01-clusterrole.yaml @@ -0,0 +1,8 @@ +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: pod-reader-role +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["list", "get"] diff --git a/rbac/02-sa.yaml b/rbac/02-sa.yaml new file mode 100644 index 0000000..caab458 --- /dev/null +++ b/rbac/02-sa.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: pod-reader diff --git a/rbac/03-binding.yaml b/rbac/03-binding.yaml new file mode 100644 index 0000000..a3d4adc --- /dev/null +++ b/rbac/03-binding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: pod-role-binding + namespace: demo +subjects: + - kind: ServiceAccount + name: pod-reader + namespace: demo +roleRef: + kind: ClusterRole + name: pod-reader-role + apiGroup: rbac.authorization.k8s.io diff --git a/rbac/04-pod.yaml b/rbac/04-pod.yaml new file mode 100644 index 0000000..2629067 --- /dev/null +++ b/rbac/04-pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: sample + namespace: demo +spec: + serviceAccount: pod-reader + terminationGracePeriodSeconds: 1 + containers: + - name: app + image: trion/curl:1 + tty: true + resources: {} diff --git a/rbac/commands b/rbac/commands new file mode 100644 index 0000000..6c9bc98 --- /dev/null +++ b/rbac/commands @@ -0,0 +1,17 @@ +kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods --dry-run=client -o yaml + +kubectl create rolebinding pod-reader-binding \ + --clusterrole=pod-reader-role \ + --serviceaccount=demo:pod-reader \ + --dry-run=client -o yaml + + +kubectl create serviceaccount pod-reader --dry-run=client -o yaml + +kubectl create token pod-reader + +kubectl create token default --duration 10m + + + +curl --cacert ca.crt -H "Authorization: Bearer $TOKEN" https://kubernetes.default/api/v1/namespaces/demo/pods diff --git a/rbac/cronjob.yaml b/rbac/cronjob.yaml new file mode 100644 index 0000000..92e9513 --- /dev/null +++ b/rbac/cronjob.yaml @@ -0,0 +1,20 @@ +apiVersion: batch/v1 +kind: CronJob +metadata: + name: kraftfahrt-scaler +spec: + schedule: "0 0 * * * " + jobTemplate: + spec: + template: + spec: + serviceAccount: deployment-scaler + containers: + - name: scale-checka + image: trion/curl:1 + command: + - /bin/sh + - -c + - | + # if restendpoint == true ; then curl https://kubernetes.default deployment replicas=10 + restartPolicy: OnFailure diff --git a/resource-quota/sample.yaml b/resource-quota/sample.yaml new file mode 100644 index 0000000..a3a4d43 --- /dev/null +++ b/resource-quota/sample.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: count + namespace: custom-namespace +spec: + hard: + limits.cpu: "400m" + limits.memory: 1Gi + requests.cpu: "100m" + pods: "4" + services.loadbalancers: "1" + count/deployments.apps: "4" diff --git a/runtimeclass/class.yaml b/runtimeclass/class.yaml new file mode 100644 index 0000000..ae3458a --- /dev/null +++ b/runtimeclass/class.yaml @@ -0,0 +1,13 @@ +apiVersion: node.k8s.io/v1 +kind: RuntimeClass +metadata: + name: runc +handler: runc # requires containerd +overhead: + podFixed: + memory: 100Mi + cpu: 100m +scheduling: + nodeSelector: + kubernetes.io/os: linux + # tolerations: \ No newline at end of file diff --git a/runtimeclass/commands b/runtimeclass/commands new file mode 100644 index 0000000..44b74e9 --- /dev/null +++ b/runtimeclass/commands @@ -0,0 +1,6 @@ +minikube start --cpus 4 --memory 8192 --ports 80:80 --container-runtime=containerd + +kubectl get node -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}' + +minikube ssh +sudo cat /etc/containerd/config.toml diff --git a/runtimeclass/pod.yaml b/runtimeclass/pod.yaml new file mode 100644 index 0000000..ba77fb5 --- /dev/null +++ b/runtimeclass/pod.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Pod +metadata: + name: demo +spec: + runtimeClassName: runc + containers: + - name: demo + image: ghcr.io/trion-development/echoserver:1 + resources: {} + ports: + - containerPort: 3000 + diff --git a/taints/commands b/taints/commands new file mode 100644 index 0000000..142e375 --- /dev/null +++ b/taints/commands @@ -0,0 +1,12 @@ +kubectl taint nodes minikube demo=student:NoSchedule + +minikube start --nodes 3 --keep-context=true -p scheduling + +kubectl taint nodes m02 key=reserved:NoSchedule + + +kubectl drain m02 --ignore-daemonsets --delete-emptydir-data + +kubectl uncordon nodes m02 + +minikube delete -p scheduling diff --git a/taints/pod.yaml b/taints/pod.yaml new file mode 100644 index 0000000..9431283 --- /dev/null +++ b/taints/pod.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Pod +metadata: + name: mypod +spec: + containers: + - name: nginx + image: nginx + resources: {} + tolerations: + - key: "demo" + operator: "Equal" + value: "student" + effect: "NoSchedule"