Внедрение gateway использует тот же механизм, что и внедрение sidecar, для развертывания прокси Envoy в pod'ах gateway. Чтобы развернуть gateway:
Deployment
и соответствующий Service
в namespace, видимом для контрольной плоскости Istio.Gateway
и VirtualService
для управления входящим или исходящим трафиком.Для узлов с версиями ядра Linux ниже 4.11 (например, CentOS 7) требуется дополнительная настройка перед установкой gateway.
Пропустите этот раздел, если версия вашего ядра 4.11 или новее.
jq
локально для обработки JSON на следующих шагах.Создайте YAML-файл с именем gateway-injection-template.txt
, содержащий шаблон внедрения по умолчанию для gateway.
{{- $containers := list }}
{{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}}
metadata:
labels:
service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }}
service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }}
annotations:
istio.io/rev: {{ .Revision | default "default" | quote }}
{{- if ge (len $containers) 1 }}
{{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }}
kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}"
{{- end }}
{{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }}
kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}"
{{- end }}
{{- end }}
spec:
securityContext:
{{- if .Values.gateways.securityContext }}
{{- toYaml .Values.gateways.securityContext | nindent 4 }}
{{- else }}
sysctls: []
capabilities:
add: [CAP_NET_BIND_SERVICE]
{{- end }}
containers:
- name: istio-proxy
{{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }}
image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}"
{{- else }}
image: "{{ .ProxyImage }}"
{{- end }}
ports:
- containerPort: 15090
protocol: TCP
name: http-envoy-prom
args:
- proxy
- router
- --domain
- $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }}
- --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }}
- --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }}
- --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}
{{- if .Values.global.sts.servicePort }}
- --stsPort={{ .Values.global.sts.servicePort }}
{{- end }}
{{- if .Values.global.logAsJson }}
- --log_as_json
{{- end }}
{{- if .Values.global.proxy.lifecycle }}
lifecycle:
{{ toYaml .Values.global.proxy.lifecycle | indent 6 }}
{{- end }}
securityContext:
runAsUser: {{ .ProxyUID | default "1337" }}
runAsGroup: {{ .ProxyGID | default "1337" }}
env:
- name: PILOT_CERT_PROVIDER
value: {{ .Values.global.pilotCertProvider }}
- name: CA_ADDR
{{- if .Values.global.caAddress }}
value: {{ .Values.global.caAddress }}
{{- else }}
value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012
{{- end }}
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: INSTANCE_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
- name: HOST_IP
valueFrom:
fieldRef:
fieldPath: status.hostIP
- name: ISTIO_CPU_LIMIT
valueFrom:
resourceFieldRef:
resource: limits.cpu
- name: PROXY_CONFIG
value: |
{{ protoToJSON .ProxyConfig }}
- name: ISTIO_META_POD_PORTS
value: |-
[
{{- $first := true }}
{{- range $index1, $c := .Spec.Containers }}
{{- range $index2, $p := $c.Ports }}
{{- if (structToJSON $p) }}
{{if not $first}},{{end}}{{ structToJSON $p }}
{{- $first = false }}
{{- end }}
{{- end}}
{{- end}}
]
- name: GOMEMLIMIT
valueFrom:
resourceFieldRef:
resource: limits.memory
- name: GOMAXPROCS
valueFrom:
resourceFieldRef:
resource: limits.cpu
{{- if .CompliancePolicy }}
- name: COMPLIANCE_POLICY
value: "{{ .CompliancePolicy }}"
{{- end }}
- name: ISTIO_META_APP_CONTAINERS
value: "{{ $containers | join "," }}"
- name: ISTIO_META_CLUSTER_ID
value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}"
- name: ISTIO_META_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: ISTIO_META_INTERCEPTION_MODE
value: "{{ .ProxyConfig.InterceptionMode.String }}"
{{- if .Values.global.network }}
- name: ISTIO_META_NETWORK
value: "{{ .Values.global.network }}"
{{- end }}
{{- if .DeploymentMeta.Name }}
- name: ISTIO_META_WORKLOAD_NAME
value: "{{ .DeploymentMeta.Name }}"
{{ end }}
{{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }}
- name: ISTIO_META_OWNER
value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }}
{{- end}}
{{- if .Values.global.meshID }}
- name: ISTIO_META_MESH_ID
value: "{{ .Values.global.meshID }}"
{{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}
- name: ISTIO_META_MESH_ID
value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}"
{{- end }}
{{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}
- name: TRUST_DOMAIN
value: "{{ . }}"
{{- end }}
{{- range $key, $value := .ProxyConfig.ProxyMetadata }}
- name: {{ $key }}
value: "{{ $value }}"
{{- end }}
{{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}}
readinessProbe:
httpGet:
path: /healthz/ready
port: 15021
initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }}
periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }}
timeoutSeconds: 3
failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }}
volumeMounts:
- name: workload-socket
mountPath: /var/run/secrets/workload-spiffe-uds
- name: credential-socket
mountPath: /var/run/secrets/credential-uds
{{- if eq .Values.global.caName "GkeWorkloadCertificate" }}
- name: gke-workload-certificate
mountPath: /var/run/secrets/workload-spiffe-credentials
readOnly: true
{{- else }}
- name: workload-certs
mountPath: /var/run/secrets/workload-spiffe-credentials
{{- end }}
{{- if eq .Values.global.pilotCertProvider "istiod" }}
- mountPath: /var/run/secrets/istio
name: istiod-ca-cert
{{- end }}
- mountPath: /var/lib/istio/data
name: istio-data
# SDS канал между istioagent и Envoy
- mountPath: /etc/istio/proxy
name: istio-envoy
- mountPath: /var/run/secrets/tokens
name: istio-token
{{- if .Values.global.mountMtlsCerts }}
# Используйте ключ и сертификат, смонтированные в /etc/certs/ для внутрикластерных mTLS коммуникаций.
- mountPath: /etc/certs/
name: istio-certs
readOnly: true
{{- end }}
- name: istio-podinfo
mountPath: /etc/istio/pod
volumes:
- emptyDir: {}
name: workload-socket
- emptyDir: {}
name: credential-socket
{{- if eq .Values.global.caName "GkeWorkloadCertificate" }}
- name: gke-workload-certificate
csi:
driver: workloadcertificates.security.cloud.google.com
{{- else}}
- emptyDir: {}
name: workload-certs
{{- end }}
# SDS канал между istioagent и Envoy
- emptyDir:
medium: Memory
name: istio-envoy
- name: istio-data
emptyDir: {}
- name: istio-podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
- name: istio-token
projected:
sources:
- serviceAccountToken:
path: istio-token
expirationSeconds: 43200
audience: {{ .Values.global.sds.token.aud }}
{{- if eq .Values.global.pilotCertProvider "istiod" }}
- name: istiod-ca-cert
{{- if eq (.Values.pilot.env).ENABLE_CLUSTER_TRUST_BUNDLE_API true }}
projected:
sources:
- clusterTrustBundle:
name: istio.io:istiod-ca:root-cert
path: root-cert.pem
{{- else }}
configMap:
name: istio-ca-root-cert
{{- end }}
{{- end }}
{{- if .Values.global.mountMtlsCerts }}
# Используйте ключ и сертификат, смонтированные в /etc/certs/ для внутрикластерных mTLS коммуникаций.
- name: istio-certs
secret:
optional: true
{{ if eq .Spec.ServiceAccountName "" }}
secretName: istio.default
{{ else -}}
secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }}
{{ end -}}
{{- end }}
{{- if .Values.global.imagePullSecrets }}
imagePullSecrets:
{{- range .Values.global.imagePullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
sysctls
, так как net.ipv4.ip_unprivileged_port_start
недоступен в старых ядрах Linux.CAP_NET_BIND_SERVICE
в список capabilities, чтобы разрешить gateway слушать порты ниже 1024.Примените патч к шаблону внедрения gateway
для ресурса Istio
:
TEMPLATE_CONTENT=$(cat gateway-injection-template.txt)
PATCH_DATA=$(jq -n \
--arg template "${TEMPLATE_CONTENT}" \
'{
"spec": {
"values": {
"sidecarInjectorWebhook": {
"templates": {
"gateway": $template
}
}
}
}
}')
# Наконец примените патч к ресурсу Istio с именем `default`:
kubectl patch istio default --type=merge -p "${PATCH_DATA}"
Дождитесь, пока контрольная плоскость не вернет состояние Ready
, выполнив следующую команду:
kubectl wait --for condition=Ready istio/default --timeout=3m