Как создать пользовательский контроллер шлюза istio ingress?

Наш кластер GKE используется несколькими командами в компании. У каждой команды может быть свой общий домен (и, следовательно, они хотят иметь разные настройки CA-сертификата и разные контроллеры входного шлюза). Как это сделать в Истио? Все учебные / вводные статьи на веб-сайте Istio используют общий входной шлюз. См. Пример общего входного шлюза, который устанавливается istio-1.0.0: https://istio.io/docs/tasks/traffic-management/secure-ingress/

spec:
  selector:
    istio: ingressgateway # use istio default ingress gateway

2 ответа

Решение

Хорошо, я нашел ответ, посмотрев код установки Istio через helm. Таким образом, в основном у istio есть официальный способ (но не документированный в их файле readme.md) добавить дополнительный шлюз (входной и выходной шлюз). Я знаю это, потому что я нашел этот файл yaml в их репозитории github и прочитал комментарий (также глядя на gateway код шаблона диаграммы для спецификации и ее логика).

Итак, я решил это, например, определив этот файл values-custom-gateway.yaml:

# Gateways Configuration
# By default (if enabled) a pair of Ingress and Egress Gateways will be created for the mesh.
# You can add more gateways in addition to the defaults but make sure those are uniquely named
# and that NodePorts are not conflicting.
# Disable specifc gateway by setting the `enabled` to false.
#
gateways:
  enabled: true

  agung-ingressgateway:
    namespace: agung-ns
    enabled: true
    labels:
      app: agung-istio-ingressgateway
      istio: agung-ingressgateway
    replicaCount: 1
    autoscaleMin: 1
    autoscaleMax: 2
    resources: {}
      # limits:
      #  cpu: 100m
      #  memory: 128Mi
      #requests:
      #  cpu: 1800m
      #  memory: 256Mi

    loadBalancerIP: ""
    serviceAnnotations: {}
    type: LoadBalancer #change to NodePort, ClusterIP or LoadBalancer if need be

    ports:
      ## You can add custom gateway ports
    - port: 80
      targetPort: 80
      name: http2
      # nodePort: 31380
    - port: 443
      name: https
      # nodePort: 31390
    - port: 31400
      name: tcp
    secretVolumes:
    - name: ingressgateway-certs
      secretName: istio-ingressgateway-certs
      mountPath: /etc/istio/ingressgateway-certs
    - name: ingressgateway-ca-certs
      secretName: istio-ingressgateway-ca-certs
      mountPath: /etc/istio/ingressgateway-ca-certs

Если вы посмотрите на файл yaml выше, я указал namespace Кроме как istio-system нс. В этом случае у нас может быть способ настроить TLS и сертификат, используемый нашим пользовательским шлюзом. Так же agung-ingressgateway в качестве держателя пользовательского контроллера шлюза спецификация используется в качестве имени контроллера шлюза.

Затем я просто устанавливаю istio через helm upgrade --install так что helm может разумно обновить istio с помощью дополнительного шлюза.

helm upgrade my-istio-release-name <istio-chart-folder> --install

После успешного обновления я могу указать свой селектор Gateway:

---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: agung-gateway
  namespace: agung-ns
spec:
  selector:
    app: agung-istio-ingressgateway # use custom gateway
    # istio: ingressgateway # use Istio default gateway implementation
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"
  - port:
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt
      privateKey: /etc/istio/ingressgateway-certs/tls.key
    hosts:
    - "*"

Это то, что я использую в Istio 1.4.

Чтобы сгенерировать новый istio-ingressgateway Deployment, Service и ServiceAccount в вашем собственном пространстве имен (bookinfo в этом примере)

helm template install/kubernetes/helm/istio/ \
  --namespace bookinfo \
  --set global.istioNamespace=istio-system \
  -x charts/gateways/templates/deployment.yaml \
  -x charts/gateways/templates/service.yaml  \
  -x charts/gateways/templates/serviceaccount.yaml \
  --set gateways.istio-ingressgateway.enabled=true \
  --set gateways.istio-egressgateway.enabled=false \
  --set gateways.istio-ingressgateway.labels.app=custom-istio-ingressgateway \
  --set gateways.istio-ingressgateway.labels.istio=custom-ingressgateway \
  > customingress.yaml

затем примените сгенерированный файл:

kubectl apply -f customingress.yaml

Теперь вы можете ссылаться на это из своего ресурса шлюза, например:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: custom-ingressgateway # use the CUSTOM istio controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

Вы можете установить собственные аннотации Service, добавив их в команду шаблона helm следующим образом:

 --set gateways.istio-ingressgateway.serviceAnnotations.'service\.kubernetes\.io/ibm-load-balancer-cloud-provider-ip-type'=private \

Я пробовал это и работал:

---
# Source: istio/charts/gateways/templates/serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: beta-ingressgateway-service-account
  namespace: beta
  labels:
    app: ingressgateway-beta
---

---
# Source: istio/charts/gateways/templates/clusterrole.yaml

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  labels:
    app: gateways
  name: ingressgateway-beta
rules:
- apiGroups: ["extensions"]
  resources: ["thirdpartyresources", "virtualservices", "destinationrules", "gateways"]
  verbs: ["get", "watch", "list", "update"]
---

---
# Source: istio/charts/gateways/templates/clusterrolebindings.yaml

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: ingressgateway-beta
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: ingressgateway-beta
subjects:
  - kind: ServiceAccount
    name: beta-ingressgateway-service-account
    namespace: beta
---

---
# Source: istio/charts/gateways/templates/service.yaml

apiVersion: v1
kind: Service
metadata:
  name: ingressgateway-beta
  namespace: beta
  annotations:
  labels:
    istio: ingressgateway-beta
spec:
  type: LoadBalancer
  selector:
    istio: ingressgateway-beta
  ports:
    -
      name: http
      port: 80
      targetPort: 80
    -
      name: https
      port: 443
      targetPort: 443
---

---
# Source: istio/charts/gateways/templates/deployment.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: ingressgateway-beta
  namespace: beta
  labels:
    istio: ingressgateway-beta
spec:
  replicas: 1
  template:
    metadata:
      labels:
        istio: ingressgateway-beta
      annotations:
        sidecar.istio.io/inject: "false"
        scheduler.alpha.kubernetes.io/critical-pod: ""
    spec:
      serviceAccountName: beta-ingressgateway-service-account
      tolerations:
      - key: "env"
        operator: "Equal"
        value: "beta"
        effect: "NoSchedule"
      nodeSelector:
        env: beta
      containers:
        - name: istio-proxy
          image: "ISTIO_PROXY_IMAGE"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
            - containerPort: 443
          args:
          - proxy
          - router
          - -v
          - "2"
          - --discoveryRefreshDelay
          - '1s' #discoveryRefreshDelay
          - --drainDuration
          - '45s' #drainDuration
          - --parentShutdownDuration
          - '1m0s' #parentShutdownDuration
          - --connectTimeout
          - '10s' #connectTimeout
          - --serviceCluster
          - ingressgateway-beta
          - --zipkinAddress
          - zipkin.istio-system:9411
          - --proxyAdminPort
          - "15000"
          - --controlPlaneAuthPolicy
          - NONE
          - --discoveryAddress
          - istio-pilot.istio-system:8080
          resources:
            requests:
              cpu: 10m
          env:
          - name: POD_NAME
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: metadata.name
          - name: POD_NAMESPACE
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: metadata.namespace
          - name: INSTANCE_IP
            valueFrom:
              fieldRef:
                apiVersion: v1
                fieldPath: status.podIP
          - name: ISTIO_META_POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          volumeMounts:
          - name: istio-certs
            mountPath: /etc/certs
            readOnly: true
          - name: ingressgateway-beta-certs
            mountPath: "/etc/istio/ingressgateway-beta-certs"
            readOnly: true
          - name: ingressgateway-beta-ca-certs
            mountPath: "/etc/istio/ingressgateway-beta-ca-certs"
            readOnly: true
      volumes:
      - name: istio-certs
        secret:
          secretName: istio.beta-ingressgateway-service-account
          optional: true
      - name: ingressgateway-beta-certs
        secret:
          secretName: "istio-ingressgateway-beta-certs"
          optional: true
      - name: ingressgateway-beta-ca-certs
        secret:
          secretName: "istio-ingressgateway-beta-ca-certs"
          optional: true
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: beta.kubernetes.io/arch
                operator: In
                values:
                - amd64
                - ppc64le
                - s390x
          preferredDuringSchedulingIgnoredDuringExecution:
          - weight: 2
            preference:
              matchExpressions:
              - key: beta.kubernetes.io/arch
                operator: In
                values:
                - amd64
          - weight: 2
            preference:
              matchExpressions:
              - key: beta.kubernetes.io/arch
                operator: In
                values:
                - ppc64le
          - weight: 2
            preference:
              matchExpressions:
              - key: beta.kubernetes.io/arch
                operator: In
                values:
                - s390x
---

---
# Source: istio/charts/gateways/templates/autoscale.yaml
# Source: istio/charts/gateways/templates/autoscale.yaml

apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
    name: ingressgateway-beta
    namespace: beta
spec:
    maxReplicas: 5
    minReplicas: 1
    scaleTargetRef:
      apiVersion: apps/v1beta1
      kind: Deployment
      name: ingressgateway-beta
    metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 80
---

не забудьте заменить ISTIO_PROXY_IMAGE, nodeSelector а также tolerations

На самом деле это очень просто. Вход Istio - это просто обычный сервис Kubernetes типа "Балансировщик нагрузки". Итак, если вы хотите создать дополнительный IngresGateway, вы можете просто применить свой сервис (вы можете указать любые порты, которые захотите):

apiVersion: v1
kind: Service
metadata:
  name: istio-ingressgateway-custom
  namespace: istio-system
  annotations:
  labels:
    chart: gateways-1.0.5
    release: istio
    heritage: Tiller
    app: istio-ingressgateway
    istio: ingressgateway
spec:
  type: LoadBalancer
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  ports:
    -
      name: http2
      nodePort: 31381
      port: 80
      targetPort: 80
    -
      name: https
      nodePort: 31391
      port: 443
      targetPort: 555
    -
      name: tcp
      nodePort: 31401
      port: 31400
    -
      name: tcp-pilot-grpc-tls
      port: 15011
      targetPort: 15011
    -
      name: tcp-citadel-grpc-tls
      port: 8060
      targetPort: 8060
    -
      name: tcp-dns-tls
      port: 853
      targetPort: 853
    -
      name: http2-prometheus
      port: 15030
      targetPort: 15030
    -
      name: http2-grafana
      port: 15031
      targetPort: 15031
---

Учитывая, что у вас есть это в файле с именем "customingress.yaml", то вы применяете это с помощью команды:

kubectl apply -f customingress.yaml

Думаю, я еще не пробовал:

  1. Создайте несколько развертываний шлюза istio-ingressgateway с разными метками, такими как: istio: ingressgateway1, istio: ingressgateway2, ... и разными ключами tls.

  2. Создайте несколько шлюзов, чтобы использовать разные входные шлюзы.

  3. Создайте несколько виртуальных сервисов для использования разных шлюзов.

Другие вопросы по тегам