• Русский
  • О внедрении gateway

    Внедрение gateway использует тот же механизм, что и внедрение sidecar, для развертывания прокси Envoy в pod'ах gateway. Чтобы развернуть gateway:

    1. Создайте Kubernetes Deployment и соответствующий Service в namespace, видимом для контрольной плоскости Istio.
    2. Добавьте аннотации и метки к deployment, чтобы контрольная плоскость Istio внедрила прокси Envoy, настроенный как gateway.
    3. Примените ресурсы Istio Gateway и VirtualService для управления входящим или исходящим трафиком.

    Содержание

    Уведомление о совместимости с ядром Linux

    Для узлов с версиями ядра Linux ниже 4.11 (например, CentOS 7) требуется дополнительная настройка перед установкой gateway.

    INFO

    Пропустите этот раздел, если версия вашего ядра 4.11 или новее.

    Предварительные требования

    • Установите jq локально для обработки JSON на следующих шагах.

    Процедура

    1. Создайте YAML-файл с именем gateway-injection-template.txt, содержащий шаблон внедрения по умолчанию для gateway.

      Нажмите, чтобы развернуть
      gateway-injection-template.txt
      {{- $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 }}
      1. Удалите sysctls, так как net.ipv4.ip_unprivileged_port_start недоступен в старых ядрах Linux.
      2. Добавьте CAP_NET_BIND_SERVICE в список capabilities, чтобы разрешить gateway слушать порты ниже 1024.
    2. Примените патч к шаблону внедрения 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}"
    3. Дождитесь, пока контрольная плоскость не вернет состояние Ready, выполнив следующую команду:

      kubectl wait --for condition=Ready istio/default --timeout=3m