From 233b1c56326d7aa622de23530b694250c5142af8 Mon Sep 17 00:00:00 2001 From: erjxsrn Date: Wed, 20 Aug 2025 12:14:25 +0100 Subject: [PATCH 1/2] SEF Implementation changeswq --- Dockerfile => Dockerfile.app | 6 +- Dockerfile.envoy | 13 +++ README.md | 11 ++- .../eric-product-info.yaml | 7 ++ .../templates/configmap/envoy-configmap.yaml | 91 ++++++++++++++++++ .../templates/deployment/deployment.yaml | 96 +++++++++++++++++++ .../templates/ingress/ingress.yaml | 43 --------- .../templates/service/service.yaml | 10 +- .../values.yaml | 19 +++- docker-compose.yaml | 27 ++++++ 10 files changed, 271 insertions(+), 52 deletions(-) rename Dockerfile => Dockerfile.app (70%) create mode 100644 Dockerfile.envoy create mode 100644 charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml delete mode 100644 charts/eric-oss-hello-world-python-app/templates/ingress/ingress.yaml create mode 100644 docker-compose.yaml diff --git a/Dockerfile b/Dockerfile.app similarity index 70% rename from Dockerfile rename to Dockerfile.app index 6dca988..b5523ed 100644 --- a/Dockerfile +++ b/Dockerfile.app @@ -8,10 +8,10 @@ LABEL \ WORKDIR /code -COPY ./eric-oss-hello-world-python-app ./eric-oss-hello-world-python-app +COPY ./hello-world-pysa ./hello-world-pysa COPY requirements.txt . -RUN chmod +x ./eric-oss-hello-world-python-app/main.py +RUN chmod +x ./hello-world-pysa/main.py RUN pip install --upgrade pip @@ -22,4 +22,4 @@ RUN echo "$USER_ID:!::0:::::" >>/etc/shadow USER $USER_ID -CMD ["./eric-oss-hello-world-python-app/main.py"] \ No newline at end of file +CMD ["./hello-world-pysa/main.py"] \ No newline at end of file diff --git a/Dockerfile.envoy b/Dockerfile.envoy new file mode 100644 index 0000000..6795947 --- /dev/null +++ b/Dockerfile.envoy @@ -0,0 +1,13 @@ +FROM envoyproxy/envoy:v1.35.0 + +USER root + +RUN mkdir -p /etc/envoy + +RUN groupmod -g 1000 envoy && usermod -u 1000 -g 1000 envoy + +USER 1000 + +EXPOSE 8080 8443 + +CMD ["envoy", "-c", "/etc/envoy/envoy.yaml", "--log-level", "info"] diff --git a/README.md b/README.md index 4ffd17f..53ab215 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,10 @@ Refer to: [Python on Dockerâ„¢ Hub](https://hub.docker.com/_/python) Run the following command to build the image. ```bash -docker build . -t proj-eric-oss-drop/eric-oss-hello-world-python-app: --build-arg APP_VERSION= +APP_VERSION= \ +APP_IMAGE=proj-eric-oss-drop/eric-oss-hello-world-python-app: \ +ENVOY_IMAGE=proj-eric-oss-drop/eric-oss-hello-world-python-app-envoy: \ +docker compose build --no-cache ``` ## Run Docker Image @@ -57,6 +60,7 @@ A port binding on port 8050 is done to expose the endpoints. ```bash docker run -p 8050:8050 --rm --name python-sample-app proj-eric-oss-drop/eric-oss-hello-world-python-app: +docker run -d --name envoy --link python-sample-app -p 8080:8080 -p 8443:8443 proj-eric-oss-drop/eric-oss-hello-world-python-app-envoy: ``` Run a curl request to the /sample-app/python/hello endpoint of the app. @@ -122,7 +126,10 @@ Generate an archive of the Docker image and store it temporarily in the `csar-ou directory. ```bash -docker save proj-eric-oss-drop/eric-oss-hello-world-python-app: -o csar-output/docker.tar +docker save \ + proj-eric-oss-drop/eric-oss-hello-world-python-app: \ + proj-eric-oss-drop/eric-oss-hello-world-python-app-envoy: \ + -o ./csar-output/docker.tar ``` Run the following command locally to create a CSAR App package using the diff --git a/charts/eric-oss-hello-world-python-app/eric-product-info.yaml b/charts/eric-oss-hello-world-python-app/eric-product-info.yaml index ecd4eb7..4e13db1 100644 --- a/charts/eric-oss-hello-world-python-app/eric-product-info.yaml +++ b/charts/eric-oss-hello-world-python-app/eric-product-info.yaml @@ -8,3 +8,10 @@ images: repoPath: "REPO_PATH" name: "eric-oss-hello-world-python-app" tag: "VERSION" + eric-oss-hello-world-python-app-envoy: + productName: "Envoy for hello world sample app" + productNumber: "" + registry: "armdocker.rnd.ericsson.se" + repoPath: "REPO_PATH" + name: "eric-oss-hello-world-python-app-envoy" + tag: "VERSION" diff --git a/charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml b/charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml new file mode 100644 index 0000000..757d2c6 --- /dev/null +++ b/charts/eric-oss-hello-world-python-app/templates/configmap/envoy-configmap.yaml @@ -0,0 +1,91 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "eric-oss-hello-world-python-app.name" . }}-envoy-template +data: + ENVOY_CONFIG_FILE: |- + static_resources: + listeners: + # TLS listener for mTLS endpoint + - name: listener_https + address: + socket_address: + address: 0.0.0.0 + port_value: 8443 + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress_http_secure + route_config: + virtual_hosts: + - name: secure_service + domains: ["*"] + routes: + - match: + path: "/sample-app/python/hello" + route: + cluster: eric-oss-hello-world-python-app-cluster + http_filters: + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + transport_socket: + name: envoy.transport_sockets.tls + typed_config: + "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext + require_client_certificate: true + common_tls_context: + tls_certificates: + - certificate_chain: + filename: {{ printf "%s/%s" (default $.Values.instantiationDefaults.envoyAppCertMountPath $.Values.envoyAppCertMountPath) (default $.Values.instantiationDefaults.envoyAppCertFileName $.Values.envoyAppCertFileName) | quote }} + private_key: + filename: {{ printf "%s/%s" (default $.Values.instantiationDefaults.envoyAppCertMountPath $.Values.envoyAppCertMountPath) (default $.Values.instantiationDefaults.envoyAppKeyFileName $.Values.envoyAppKeyFileName) | quote }} + validation_context: + trusted_ca: + filename: {{ printf "%s/%s" (default $.Values.instantiationDefaults.envoyPlatformCaCertMountPath $.Values.envoyPlatformCaCertMountPath) (default $.Values.instantiationDefaults.envoyPlatformCaCertFileName $.Values.envoyPlatformCaCertFileName) | quote }} + + # Plain HTTP listener for other endpoints + - name: listener_http + address: + socket_address: + address: 0.0.0.0 + port_value: 8080 + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + stat_prefix: ingress_http_plain + route_config: + virtual_hosts: + - name: plain_service + domains: ["*"] + routes: + - match: + path: "/sample-app/python/health" + route: + cluster: eric-oss-hello-world-python-app-cluster + - match: + path: "/sample-app/python/metrics" + route: + cluster: eric-oss-hello-world-python-app-cluster + http_filters: + - name: envoy.filters.http.router + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router + + clusters: + - name: eric-oss-hello-world-python-app-cluster + type: STATIC + load_assignment: + cluster_name: eric-oss-hello-world-python-app-service + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: 8050 diff --git a/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml b/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml index 4aaea3c..54aadbb 100644 --- a/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/deployment/deployment.yaml @@ -55,6 +55,14 @@ spec: items: - key: LOG_CTRL_FILE path: logcontrol.json + - name: envoy-config + configMap: + name: {{ include "eric-oss-hello-world-python-app.name" . }}-envoy-template + items: + - key: ENVOY_CONFIG_FILE + path: envoy.yaml + - name: envoy-config-dir + emptyDir: {} - name: platform-cacerts secret: secretName: {{ index .Values "platformCaCertSecretName" | quote }} @@ -67,6 +75,14 @@ spec: secret: secretName: {{ include "eric-oss-hello-world-python-app.clientSecret" . | quote }} defaultMode: 420 + - name: envoy-platform-cacerts + secret: + secretName: {{ index .Values "envoyPlatformCaCertSecretName" | quote }} + defaultMode: 420 + - name: envoy-app-certs + secret: + secretName: {{ index .Values "envoyAppSecretName" | quote }} + defaultMode: 420 containers: - name: eric-oss-hello-world-python-app image: {{ template "eric-oss-hello-world-python-app.imagePath" (dict "imageId" "eric-oss-hello-world-python-app" "values" .Values "files" .Files) }} @@ -182,6 +198,86 @@ spec: {{- end }} resources: {{- toYaml .Values.resources.helloWorld | nindent 12 }} + - name: envoy + image: {{ template "eric-oss-hello-world-python-app.imagePath" (dict "imageId" "eric-oss-hello-world-python-app-envoy" "values" .Values "files" .Files) }} + imagePullPolicy: {{ include "eric-oss-hello-world-python-app.registryImagePullPolicy" . | quote }} + securityContext: + {{- if semverCompare ">=1.30.0" .Capabilities.KubeVersion.GitVersion }} + appArmorProfile: + type: {{ include "eric-oss-hello-world-python-app.appArmorProfile.type" . | default "RuntimeDefault" }} + {{- end }} + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - all + {{- include "eric-oss-hello-world-python-app.seccomp-profile" . | indent 12 }} + command: ["/bin/sh", "-c"] + args: + - | + echo "==== Dumping envoy config ====" + cat /etc/envoy/envoy.yaml + echo "==== Starting Envoy ====" + exec envoy -c /etc/envoy/envoy.yaml --log-level info --base-id 1 + ports: + - name: envoy-http + containerPort: 8080 + protocol: TCP + - name: envoy-https + containerPort: 8443 + protocol: TCP + livenessProbe: + tcpSocket: + port: 8443 + {{- if (index .Values "probes" "envoy" "livenessProbe" "initialDelaySeconds") }} + {{ print "initialDelaySeconds: " (index .Values "probes" "envoy" "livenessProbe" "initialDelaySeconds") }} + {{- end }} + {{- if (index .Values "probes" "envoy" "livenessProbe" "failureThreshold") }} + {{ print "failureThreshold: " (index .Values "probes" "envoy" "livenessProbe" "failureThreshold") }} + {{- end }} + {{- if (index .Values "probes" "envoy" "livenessProbe" "periodSeconds") }} + {{ print "periodSeconds: " (index .Values "probes" "envoy" "livenessProbe" "periodSeconds") }} + {{- end }} + {{- if (index .Values "probes" "envoy" "livenessProbe" "timeoutSeconds") }} + {{ print "timeoutSeconds: " (index .Values "probes" "envoy" "livenessProbe" "timeoutSeconds") }} + {{- end }} + readinessProbe: + tcpSocket: + port: 8443 + {{- if (index .Values "probes" "envoy" "readinessProbe" "initialDelaySeconds") }} + {{ print "initialDelaySeconds: " (index .Values "probes" "envoy" "readinessProbe" "initialDelaySeconds") }} + {{- end }} + {{- if (index .Values "probes" "envoy" "readinessProbe" "failureThreshold") }} + {{ print "failureThreshold: " (index .Values "probes" "envoy" "readinessProbe" "failureThreshold") }} + {{- end }} + {{- if (index .Values "probes" "envoy" "readinessProbe" "periodSeconds") }} + {{ print "periodSeconds: " (index .Values "probes" "envoy" "readinessProbe" "periodSeconds") }} + {{- end }} + {{- if (index .Values "probes" "envoy" "readinessProbe" "timeoutSeconds") }} + {{ print "timeoutSeconds: " (index .Values "probes" "envoy" "readinessProbe" "timeoutSeconds") }} + {{- end }} + env: + - name: ENVOY_APP_CERT_FULL_PATH + value: {{ printf "%s/%s" (default .Values.instantiationDefaults.envoyAppCertMountPath .Values.envoyAppCertMountPath) .Values.envoyAppCertFileName }} + - name: ENVOY_APP_KEY_FULL_PATH + value: {{ printf "%s/%s" (default .Values.instantiationDefaults.envoyAppCertMountPath .Values.envoyAppCertMountPath) .Values.envoyAppKeyFileName }} + - name: ENVOY_CA_CERT_FULL_PATH + value: {{ printf "%s/%s" (default .Values.instantiationDefaults.envoyPlatformCaCertMountPath .Values.envoyPlatformCaCertMountPath) .Values.envoyPlatformCaCertFileName }} + volumeMounts: + - name: envoy-config + mountPath: /etc/envoy + readOnly: true + - name: envoy-platform-cacerts + mountPath: {{ index .Values "envoyPlatformCaCertMountPath" | default .Values.instantiationDefaults.envoyPlatformCaCertMountPath | quote }} + readOnly: true + - name: envoy-app-certs + mountPath: {{ index .Values "envoyAppCertMountPath" | default .Values.instantiationDefaults.envoyAppCertMountPath | quote }} + readOnly: true {{- if include "eric-oss-hello-world-python-app.pullSecrets" . }} imagePullSecrets: - name: {{ template "eric-oss-hello-world-python-app.pullSecrets" . }} diff --git a/charts/eric-oss-hello-world-python-app/templates/ingress/ingress.yaml b/charts/eric-oss-hello-world-python-app/templates/ingress/ingress.yaml deleted file mode 100644 index ca297c9..0000000 --- a/charts/eric-oss-hello-world-python-app/templates/ingress/ingress.yaml +++ /dev/null @@ -1,43 +0,0 @@ -{{- if .Values.ingress.enabled -}} -{{- $fullName := include "eric-oss-hello-world-python-app.name" . -}} -{{- $servicePort := .Values.service.port -}} ---- -apiVersion: networking.k8s.io/v1beta1 -kind: Ingress -metadata: - name: {{ $fullName }} - labels: - {{- include "eric-oss-hello-world-python-app.labels" . | indent 4 }} - {{- if .Values.labels }} - {{ .Values.labels | toYaml | indent 4 }} - {{- end }} - {{- with .Values.ingress }} - annotations: - {{- include "eric-oss-hello-world-python-app.product-info" . | indent 4 }} - {{- if .annotations }} - {{ .annotations | toYaml | indent 4 }} - {{- end }} - {{- if .ingressClass }} - kubernetes.io/ingress.class: {{.ingressClass }} - {{- end -}} - {{- end }} -spec: -{{- if .Values.ingress.tls }} - tls: - {{- range .Values.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} -{{- end }} - rules: - - host: {{ .Values.ingress.host }} - http: - paths: - - path: / - backend: - serviceName: {{ $fullName }} - servicePort: {{ $servicePort }} -{{- end }} diff --git a/charts/eric-oss-hello-world-python-app/templates/service/service.yaml b/charts/eric-oss-hello-world-python-app/templates/service/service.yaml index d90cef5..0188b1c 100644 --- a/charts/eric-oss-hello-world-python-app/templates/service/service.yaml +++ b/charts/eric-oss-hello-world-python-app/templates/service/service.yaml @@ -15,10 +15,14 @@ spec: ipFamilies: [{{ .Values.global.internalIPFamily }}] {{- end }} ports: - - port: {{ .Values.service.port }} - targetPort: 8050 + - port: {{ .Values.service.httpport }} + targetPort: 8080 protocol: TCP - name: http + name: envoy-http + - port: {{ .Values.service.httpsport }} + targetPort: 8443 + protocol: TCP + name: envoy-https selector: app.kubernetes.io/name: {{ include "eric-oss-hello-world-python-app.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} diff --git a/charts/eric-oss-hello-world-python-app/values.yaml b/charts/eric-oss-hello-world-python-app/values.yaml index 2c4b392..0cf4cc7 100644 --- a/charts/eric-oss-hello-world-python-app/values.yaml +++ b/charts/eric-oss-hello-world-python-app/values.yaml @@ -43,7 +43,8 @@ seccompProfile: service: type: ClusterIP - port: 8050 + httpport: 8080 + httpsport: 8443 ingress: enabled: false @@ -116,6 +117,17 @@ probes: initialDelaySeconds: 60 periodSeconds: 10 timeoutSeconds: 10 + envoy: + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 10 + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 10 # Pod priority configuration for deployments podPriority: @@ -127,6 +139,11 @@ instantiationDefaults: platformCaCertMountPath: "/etc/tls-ca/platform/" appCertMountPath: "/etc/tls/log/" clientCredsMountPath: "/etc/client-creds/" + envoyPlatformCaCertMountPath: "/etc/certs/ca" + envoyAppCertMountPath: "/etc/certs/app" + #envoyPlatformCaCertFileName: "dummy1.crt" + #envoyAppCertFileName: "dummy2.crt" + #envoyAppKeyFileName: "dummy3.key" global: clientCredentials: diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..6a35154 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,27 @@ +version: "3.9" + +services: + app: + build: + context: . + dockerfile: Dockerfile.app + args: + APP_VERSION: ${APP_VERSION} + image: ${APP_IMAGE} + container_name: eric-oss-hello-world-python-app + ports: + - "8050:8050" + restart: unless-stopped + + envoy: + build: + context: . + dockerfile: Dockerfile.envoy + image: ${ENVOY_IMAGE} + container_name: envoy + depends_on: + - app + ports: + - "8080:8080" + - "8443:8443" + restart: unless-stopped \ No newline at end of file From 6a54c447de835ee9125bcb769e7ae60f83ee2be4 Mon Sep 17 00:00:00 2001 From: erjxsrn Date: Wed, 20 Aug 2025 12:48:35 +0100 Subject: [PATCH 2/2] Update Dockerfile.app for SEF implementation --- Dockerfile.app | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Dockerfile.app b/Dockerfile.app index b5523ed..84d3c44 100644 --- a/Dockerfile.app +++ b/Dockerfile.app @@ -8,10 +8,10 @@ LABEL \ WORKDIR /code -COPY ./hello-world-pysa ./hello-world-pysa +COPY ./eric-oss-hello-world-python-app ./eric-oss-hello-world-python-app COPY requirements.txt . -RUN chmod +x ./hello-world-pysa/main.py +RUN chmod +x ./eric-oss-hello-world-python-app/main.py RUN pip install --upgrade pip @@ -22,4 +22,6 @@ RUN echo "$USER_ID:!::0:::::" >>/etc/shadow USER $USER_ID -CMD ["./hello-world-pysa/main.py"] \ No newline at end of file +CMD ["./eric-oss-hello-world-python-app/main.py"] + +