#关于 gateway 注入
Gateway 注入利用与 sidecar 注入相同的机制,将 Envoy 代理部署到 gateway Pod 中。部署 gateway 的步骤如下:
- 在 Istio 控制平面可见的命名空间中创建 Kubernetes
Deployment和对应的Service。 - 对 Deployment 添加注解和标签,使 Istio 控制平面注入配置为 gateway 的 Envoy 代理。
- 应用 Istio 的
Gateway和VirtualService资源以控制入口或出口流量。
#Linux 内核兼容性通知
对于运行 Linux 内核版本早于 4.11(例如 CentOS 7)的节点,gateway 安装前需要额外配置。
如果您的内核版本为 4.11 或更高版本,请跳过本节。
#Istio Gateway
#前提条件
- 本地安装
jq用于处理本步骤中的 JSON。
#操作步骤
在某些操作系统(例如 CentOS 7)及较旧的 Linux 内核上,gateway 可能无法监听 1024 以下的端口。建议配置 gateway 使用 1024 以上的端口以避免权限限制。如果必须使用特权端口(1024 以下),请通过修改 gateway-injection-template.txt 配置,为 gateway 的 istio-proxy 容器添加 NET_BIND_SERVICE 能力,或通过更新容器安全上下文设置以 root 用户身份运行 gateway。
-
创建一个名为
gateway-injection-template.txt的 YAML 文件,内容为 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: [] {{- 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 channel between istioagent and Envoy - mountPath: /etc/istio/proxy name: istio-envoy - mountPath: /var/run/secrets/tokens name: istio-token {{- if .Values.global.mountMtlsCerts }} # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - 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 channel between istioagent and 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 }} # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. - 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,因为旧 Linux 内核不支持net.ipv4.ip_unprivileged_port_start。
- 移除
-
对
Istio资源的默认gateway注入模板进行 patch:TEMPLATE_CONTENT=$(cat gateway-injection-template.txt) PATCH_DATA=$(jq -n \ --arg template "${TEMPLATE_CONTENT}" \ '{ "spec": { "values": { "sidecarInjectorWebhook": { "templates": { "gateway": $template } } } } }') # 最后将 patch 应用到名为 `default` 的 Istio 资源: kubectl patch istio default --type=merge -p "${PATCH_DATA}" -
运行以下命令等待控制平面返回
Ready状态条件:kubectl wait --for condition=Ready istio/default --timeout=3m
#Kubernetes Gateway API
#前提条件
- Alauda Container Platform 4.2.0 或更高版本,或将 Gateway API CRD 升级到最新版本。
#操作步骤
在某些操作系统(例如 CentOS 7)及较旧的 Linux 内核上,gateway 可能无法监听 1024 以下的端口。建议配置 gateway 使用 1024 以上的端口以避免权限限制。如果必须使用特权端口(1024 以下),请通过创建 ConfigMap 自定义容器安全上下文设置,配置 gateway 为其 istio-proxy 容器添加 NET_BIND_SERVICE 能力,或以 root 用户身份运行 gateway。
-
在计划部署 Gateway 的同一命名空间中创建名为
asm-kube-gateway-options的 ConfigMap:apiVersion: v1 kind: ConfigMap metadata: name: asm-kube-gateway-options # 将 `<your-gateway-namespace>` 替换为您 Gateway 实际部署的命名空间。 namespace: <your-gateway-namespace> data: deployment: | spec: template: spec: securityContext: sysctls: []- 移除
sysctls,因为旧 Linux 内核不支持net.ipv4.ip_unprivileged_port_start。
- 移除
-
在 Gateway 资源中通过添加
infrastructure.parametersRef字段引用该 ConfigMap:apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: <your-gateway-name> namespace: <your-gateway-namespace> spec: # 在 Gateway CR 中添加以下基础设施配置 infrastructure: parametersRef: group: "" kind: ConfigMap name: asm-kube-gateway-options # ... 其余 Gateway 配置该配置确保 gateway 部署使用 ConfigMap 中定义的自定义安全上下文设置。