diff --git a/deploy/envoy/Chart.yaml b/deploy/envoy/Chart.yaml new file mode 100644 index 000000000..ff17126fa --- /dev/null +++ b/deploy/envoy/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +name: envoy +description: |- + Helm chart to deploy [envoy](https://www.envoyproxy.io/). +type: application +version: 0.0.10 +appVersion: "v1.18.2" +icon: https://www.envoyproxy.io/docs/envoy/latest/_static/envoy-logo.png diff --git a/deploy/envoy/README.md b/deploy/envoy/README.md new file mode 100644 index 000000000..48324a604 --- /dev/null +++ b/deploy/envoy/README.md @@ -0,0 +1,41 @@ +# envoy + +![Version: 0.0.9](https://img.shields.io/badge/Version-0.0.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.18.2](https://img.shields.io/badge/AppVersion-v1.18.2-informational?style=flat-square) + +Helm chart to deploy [envoy](https://www.envoyproxy.io/). + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | affinity for scheduler pod assignment | +| args | list | `[]` | extra args to pass to container | +| configYaml | string | `"admin:\n access_log_path: /tmp/admin_access.log\n address:\n socket_address:\n protocol: TCP\n address: 0.0.0.0\n port_value: 9901\nstatic_resources:\n listeners:\n - name: listener_0\n address:\n socket_address:\n protocol: TCP\n address: 0.0.0.0\n port_value: 10000\n filter_chains:\n - filters:\n - name: envoy.filters.network.http_connection_manager\n typed_config:\n \"@type\": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager\n stat_prefix: ingress_http\n access_log:\n - name: envoy.access_loggers.file\n typed_config:\n \"@type\": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog\n # For the demo config in the Docker container we use:\n # - system logs -> `/dev/stderr`\n # - (listener) access_logs -> `/dev/stdout`\n path: /dev/stdout\n route_config:\n name: local_route\n virtual_hosts:\n - name: local_service\n domains: [\"*\"]\n routes:\n - match:\n prefix: \"/\"\n route:\n host_rewrite_literal: www.envoyproxy.io\n cluster: service_envoyproxy_io\n http_filters:\n - name: envoy.filters.http.router\n clusters:\n - name: service_envoyproxy_io\n connect_timeout: 30s\n type: LOGICAL_DNS\n # Comment out the following line to test on v6 networks\n dns_lookup_family: V4_ONLY\n lb_policy: ROUND_ROBIN\n load_assignment:\n cluster_name: service_envoyproxy_io\n endpoints:\n - lb_endpoints:\n - endpoint:\n address:\n socket_address:\n address: www.envoyproxy.io\n port_value: 443\n transport_socket:\n name: envoy.transport_sockets.tls\n typed_config:\n \"@type\": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext\n sni: www.envoyproxy.io"` | config yaml | +| containerAdminPort | int | `9901` | | +| containerPort | int | `10000` | container port, should match admin port_value from config.yaml | +| env | string | `nil` | environment variables for the deployment | +| fullnameOverride | string | `""` | full name of the chart. | +| image.pullPolicy | string | `"IfNotPresent"` | image pull policy | +| image.repository | string | `"envoyproxy/envoy"` | image repository | +| image.tag | string | `""` | image tag (chart's appVersion value will be used if not set) | +| imagePullSecrets | list | `[]` | image pull secret for private images | +| livenessProbe.httpGet.path | string | `"/"` | path for liveness probe | +| livenessProbe.httpGet.port | string | `"http"` | port for liveness probe | +| nameOverride | string | `""` | override name of the chart | +| nodeSelector | object | `{}` | node for scheduler pod assignment | +| podSecurityContext | object | `{}` | specifies security settings for a pod | +| readinessProbe.httpGet.path | string | `"/"` | path for readiness probe | +| readinessProbe.httpGet.port | string | `"http"` | port for readiness probe | +| replicaCount | int | `1` | number of replicas for haproxy deployment. | +| resources | object | `{}` | custom resource configuration | +| service.annotations | object | `{}` | annotations to add to the service | +| service.port | int | `80` | service port | +| service.type | string | `"ClusterIP"` | service type | +| serviceAccount.annotations | object | `{}` | annotations to add to the service account | +| serviceAccount.create | bool | `false` | specifies whether a service account should be created | +| serviceAccount.name | string | `nil` | the name of the service account to use; if not set and create is true, a name is generated using the fullname template | +| serviceMonitor.additionalLabels | object | `{}` | additional labels for service monitor | +| serviceMonitor.enabled | bool | `false` | ServiceMonitor CRD is created for a prometheus operator | +| tolerations | list | `[]` | tolerations for scheduler pod assignment | +| volumeMounts | string | `nil` | volume mounts | +| volumes | string | `nil` | volumes | diff --git a/deploy/envoy/templates/NOTES.txt b/deploy/envoy/templates/NOTES.txt new file mode 100644 index 000000000..e8b685e4f --- /dev/null +++ b/deploy/envoy/templates/NOTES.txt @@ -0,0 +1,14 @@ +{{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "envoy.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "envoy.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "envoy.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "envoy.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/deploy/envoy/templates/_helpers.tpl b/deploy/envoy/templates/_helpers.tpl new file mode 100644 index 000000000..456dc55b8 --- /dev/null +++ b/deploy/envoy/templates/_helpers.tpl @@ -0,0 +1,118 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "envoy.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "envoy.config" -}} +node: + cluster: {{ .Values.node.cluster }} + id: {{ .Values.node.id }} + +dynamic_resources: + ads_config: + api_type: GRPC + transport_api_version: V3 + grpc_services: + - envoy_grpc: + cluster_name: xds_cluster + cds_config: + resource_api_version: V3 + ads: {} + lds_config: + resource_api_version: V3 + ads: {} + +admin: + access_log_path: /tmp/admin_access.log + address: + socket_address: + protocol: TCP + address: 0.0.0.0 + port_value: {{ .Values.containerAdminPort }} +static_resources: + clusters: + - type: STRICT_DNS + typed_extension_protocol_options: + envoy.extensions.upstreams.http.v3.HttpProtocolOptions: + "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions + explicit_http_config: + http2_protocol_options: {} + name: xds_cluster + connect_timeout: 1s + lb_policy: ROUND_ROBIN + load_assignment: + cluster_name: xds_cluster + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: {{ .Values.xds_cluster.address }} + port_value: {{ .Values.xds_cluster.port }} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "envoy.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "envoy.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "envoy.labels" -}} +helm.sh/chart: {{ include "envoy.chart" . }} +{{ include "envoy.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "envoy.selectorLabels" -}} +app.kubernetes.io/name: {{ include "envoy.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "envoy.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "envoy.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the tag for the docker image to use +*/}} +{{- define "envoy.tag" -}} +{{- .Values.image.tag | default .Chart.AppVersion -}} +{{- end -}} diff --git a/deploy/envoy/templates/configmap.yaml b/deploy/envoy/templates/configmap.yaml new file mode 100644 index 000000000..7ebe15a3e --- /dev/null +++ b/deploy/envoy/templates/configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "envoy.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "envoy.labels" . | nindent 4 }} +data: + envoy.yaml: |- {{ include "envoy.config" . | nindent 4 }} diff --git a/deploy/envoy/templates/deployment.yaml b/deploy/envoy/templates/deployment.yaml new file mode 100644 index 000000000..7ee512b55 --- /dev/null +++ b/deploy/envoy/templates/deployment.yaml @@ -0,0 +1,78 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "envoy.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "envoy.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "envoy.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "envoy.selectorLabels" . | nindent 8 }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "envoy.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ include "envoy.tag" . }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - -c + - /config/envoy.yaml + {{- range .Values.args }} + - {{ . | quote }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.containerPort }} + protocol: TCP + - name: http-admin + containerPort: {{ .Values.containerAdminPort }} + protocol: TCP + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.env }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /config + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ include "envoy.fullname" . }} + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/deploy/envoy/templates/service.yaml b/deploy/envoy/templates/service.yaml new file mode 100644 index 000000000..969d212c4 --- /dev/null +++ b/deploy/envoy/templates/service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "envoy.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "envoy.labels" . | nindent 4 }} +{{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "envoy.selectorLabels" . | nindent 4 }} diff --git a/deploy/envoy/templates/serviceAdmin.yaml b/deploy/envoy/templates/serviceAdmin.yaml new file mode 100644 index 000000000..c44845dfd --- /dev/null +++ b/deploy/envoy/templates/serviceAdmin.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "envoy.fullname" . }}-admin + namespace: {{ .Release.Namespace }} + labels: + {{- include "envoy.labels" . | nindent 4 }} + admin: "true" +spec: + type: ClusterIP + ports: + - port: {{ .Values.service.port }} + targetPort: http-admin + protocol: TCP + name: http + selector: + {{- include "envoy.selectorLabels" . | nindent 4 }} diff --git a/deploy/envoy/templates/serviceaccount.yaml b/deploy/envoy/templates/serviceaccount.yaml new file mode 100644 index 000000000..4ec3767e9 --- /dev/null +++ b/deploy/envoy/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "envoy.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "envoy.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/deploy/envoy/templates/servicemonitor.yaml b/deploy/envoy/templates/servicemonitor.yaml new file mode 100644 index 000000000..7e10f2ba5 --- /dev/null +++ b/deploy/envoy/templates/servicemonitor.yaml @@ -0,0 +1,20 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "envoy.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "envoy.labels" . | nindent 4 }} + {{- if .Values.serviceMonitor.additionalLabels }} + {{- toYaml .Values.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: http + path: "/stats/prometheus" + selector: + matchLabels: + {{- include "envoy.selectorLabels" . | nindent 6 }} + admin: "true" +{{- end }} diff --git a/deploy/envoy/templates/tests/test-connection.yaml b/deploy/envoy/templates/tests/test-connection.yaml new file mode 100644 index 000000000..eb422b48c --- /dev/null +++ b/deploy/envoy/templates/tests/test-connection.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "envoy.fullname" . }}-test-connection" + namespace: {{ .Release.Namespace }} + labels: + {{- include "envoy.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "envoy.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/deploy/envoy/values.yaml b/deploy/envoy/values.yaml new file mode 100644 index 000000000..98ff97943 --- /dev/null +++ b/deploy/envoy/values.yaml @@ -0,0 +1,109 @@ +# replicaCount -- number of replicas for haproxy deployment. +replicaCount: 1 + +image: + # image.repository -- image repository + repository: envoyproxy/envoy + # image.tag -- image tag (chart's appVersion value will be used if not set) + tag: "" + # image.pullPolicy -- image pull policy + pullPolicy: IfNotPresent + +# imagePullSecrets -- image pull secret for private images +imagePullSecrets: [] +# nameOverride -- override name of the chart +nameOverride: "" +# fullnameOverride -- full name of the chart. +fullnameOverride: "" + +serviceAccount: + # serviceAccount.create -- specifies whether a service account should be created + create: false + # serviceAccount.annotations -- annotations to add to the service account + annotations: {} + # serviceAccount.name -- the name of the service account to use; if not set and create is true, a name is generated using the fullname template + name: + +# podSecurityContext -- specifies security settings for a pod +podSecurityContext: {} +# fsGroup: 2000 + +service: + # service.type -- service type + type: ClusterIP + # service.port -- service port + port: 80 + # service.annotations -- annotations to add to the service + annotations: {} + +# resources -- custom resource configuration +resources: {} +# limits: +# cpu: 100m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +# nodeSelector -- node for scheduler pod assignment +nodeSelector: {} + +# tolerations -- tolerations for scheduler pod assignment +tolerations: [] + +# affinity -- affinity for scheduler pod assignment +affinity: {} + +# volumeMounts -- volume mounts +volumeMounts: +# - name: data +# mountPath: /envoy-data + +# volumes -- volumes +volumes: +# - name: data +# emptyDir: {} + +# env -- environment variables for the deployment +env: +# - name: NODE_LABEL_REGION +# value: "failure-domain.beta.kubernetes.io/region" +# - name: NODE_LABEL_INSTANCE_TYPE +# value: "beta.kubernetes.io/instance-type" + +# args -- extra args to pass to container +args: [] + +serviceMonitor: + # serviceMonitor.enabled -- ServiceMonitor CRD is created for a prometheus operator + enabled: false + # serviceMonitor.additionalLabels -- additional labels for service monitor + additionalLabels: {} + +livenessProbe: + httpGet: + # livenessProbe.httpGet.path -- path for liveness probe + path: / + # livenessProbe.httpGet.port -- port for liveness probe + port: http + +readinessProbe: + httpGet: + # readinessProbe.httpGet.path -- path for readiness probe + path: / + # readinessProbe.httpGet.port -- port for readiness probe + port: http + +# containerPort -- container port, should match static port_value from config.yaml +containerPort: 10000 + +# containerPort -- container port, should match admin port_value from config.yaml +containerAdminPort: 9901 + +node: + cluster: test-cluster + id: test-id + +xds_cluster: + address: 192.168.65.2 + port: 9999