Сервисная сетка следующего поколения — анализ архитектуры istio

задняя часть Микросервисы Архитектура Service Mesh Istio

фронтПоделиться, мы упомянули, что по соображениям производительности и стабильности мы не использовалиistioВ качестве представленной технологии Service Mesh второго поколения Envoy напрямую используется с собственной службой xDS.

Тем не менее, нам еще нужно понятьIstio, в конце концов, это будущее Service Mesh. Неудивительно, что в ближайшем будущем гребешки также перейдут на платформу Service Mesh второго поколения.

Эта статья направлена ​​наIstioПростой анализ архитектуры будет включать в себя анализ части исходного кода.

1. Архитектура Истио

мы представляемEnvoyпри упоминании,EnvoyДинамическая конфигурация дает нам возможность: мы можем следоватьEnvoyСпецификация для управления путем реализации службы, предоставляющей определенный API.Envoyмаршрутизация, правила трафика, ограничения скорости, журналы и т. д.

существуетIstioв концепции,EnvoyЭтот тип прокси, который фактически выполняет пересылку и управление трафиком, называетсяпанель данных. И те, которые обеспечивают управление APIEnvoyПоведенческие службы называютсяпанель управления.

Теперь позаимствуйте картинку с официального сайта, чтобы объяснитьIstioСхема:

Панель данных начинается сsidecarФорма и микросервисы развертываются вместе, и каждый экземпляр микросервиса развертывается через собственныйsidecarЧтобы добиться отправки и получения запросов, микросервисы и микросервисы взаимодействуют не напрямую, а черезsidecarпрокси (форвардинг) для осуществления связи.sidecarСформируйте сеть вызовов напрямую, как «сетку».

панель управленияPilot, Mixer, Istio-Authсочинение. мы начинаем сkubernetesРазвернуть с помощьюEnvoyдля панели данныхIstioПредставить в качестве примера.

Pilotявляется ядром панели управления и имеет важное значение. будетkubernetesинформация о ресурсах переведена наEnvoyСоответствующие API-интерфейсы xDS (CDS, SDS/EDS, RDS), необходимые для обеспечения обнаружения служб, в том числе определяемых пользователем.IstioСоответствующая конфигурация, переведенная вEnvoyПонятные правила маршрутизации (RDS).

MixerРеализовать сбор данных и некоторое дополнительное управление потоком. Сначала панель данныхMixerДанные запроса отчета, которые основаны наIstioСпецификация структурирована.MixerЭти отчетные данные можно обрабатывать различными способами, например, распечатывать журналы, преобразовывать их в метрики, необходимые Prometheus для удобного сбора данных для мониторинга производительности, ограничивать скорость и т. д.MixerЭто подключаемый модуль, и эта обработка данных осуществляется путем настройки одного за другим подключаемых модулей.

2. Pilot

Возьмем в качестве примера среду Kubernetes:PilotКаждый Pod на самом деле содержит два «контейнера»:discoveryа такжеistio-proxy

2.1 discovery

discoveryСоответствующее изображениеdocker.io/istio/pilot:0.4.0,ДаPilotРеальный поставщик функций, его адрес прослушивания:tcp://127.0.0.1:8080, основная задача — пропускать ресурсы Kubernetes черезxDSФорма обслуживания означаетEnvoyпонятная конфигурация.

в:

xDSОсновной код:pilot/proxy/envoy/discovery.go

// Struct,核心数据结构
type DiscoveryService struct {
	proxy.Environment
	server *http.Server

	sdsCache *discoveryCache
	cdsCache *discoveryCache
	rdsCache *discoveryCache
	ldsCache *discoveryCache
}

// Register adds routes a web service container
func (ds *DiscoveryService) Register(container *restful.Container) {
	ws := &restful.WebService{}
	ws.Produces(restful.MIME_JSON)

	// 例如: List all known services (informational, not invoked by Envoy)
	ws.Route(ws.
		GET("/v1/registration").
		To(ds.ListAllEndpoints).
        Doc("Services in SDS"))

    // 其他 xDS ...
}

Основной код для перевода ресурсов Kubernetes:pilot/platform/kube/controller.go

// 例如: list services
func (c *Controller) Services() ([]*model.Service, error) {
	list := c.services.informer.GetStore().List()
	out := make([]*model.Service, 0, len(list))

	for _, item := range list {
		if svc := convertService(*item.(*v1.Service), c.domainSuffix); svc != nil {
			out = append(out, svc)
		}
	}
	return out, nil
}

2.2 istio-proxy

istio-proxyСоответствующее изображениеdocker.io/istio/proxy:0.4.0,ДаPilotУслугиsidecar, ответственный за обратный прокси-сервер для отправкиdiscoveryпросить, слушатьtcp://0.0.0.0:15003. ЭтоEnvoyБазовая конфигурация выглядит следующим образом:

{
  "listeners": [
   {
    "address": "tcp://0.0.0.0:15003",
    "name": "tcp_0.0.0.0_15003",
    "filters": [
     {
      "type": "read",
      "name": "tcp_proxy",
      "config": {
       "stat_prefix": "tcp",
       "route_config": {
        "routes": [
         {
          "cluster": "in.8080"
         }
        ]
       }
      }
     }
    ],
    "bind_to_port": true
   }
  ],
  "admin": {
    "access_log_path": "/dev/stdout",
    "address": "tcp://127.0.0.1:15000"
  },
  "cluster_manager": {
    "clusters": [
      {
        "name": "in.8080",
        "connect_timeout_ms": 1000,
        "type": "static",
        "lb_type": "round_robin",
        "hosts": [
          {
            "url": "tcp://127.0.0.1:8080"
          }
        ]
      }
    ]
  }
}

3. Sidecar

Возьмем в качестве примера среду Kubernetes: как плоскость данныхSidecar, по сути, в каждый Pod микросервиса будет вставлено два контейнера:proxy-initа такжеistio-proxy

3.1 istio-proxy

istio-proxyСоответствующее изображениеdocker.io/istio/proxy:0.4.0, является фактическим носителем функции Sidecar, мониторингtcp://0.0.0.0:15003, принимает весь TCP-трафик, предназначенный для Pod, и распределяет весь TCP-трафик от Pod. Фактически прокси состоит из двух частей: процесс управленияagentи процесс реального агентаEnvoy.

agentответственный за созданиеEnvoyконфигурации и должным образом контролироватьEnvoyрабочее состояние, будет проводиться при необходимостиEnvoyУправление процессами (например, перезагрузка Envoy после изменения конфигурации). Также отвечает заMixerВзаимодействие компонентов (включая отчетные данные и т. д.).

agentО генерацииEnvoyОсновной код конфигурации находится по адресу:pilot/proxy/envoy/config.go

func buildConfig(config meshconfig.ProxyConfig, pilotSAN []string) *Config {
	listeners := Listeners{}

	clusterRDS := buildCluster(config.DiscoveryAddress, RDSName, config.ConnectTimeout)
	clusterLDS := buildCluster(config.DiscoveryAddress, LDSName, config.ConnectTimeout)
	clusters := Clusters{clusterRDS, clusterLDS}

	out := &Config{
		Listeners: listeners,
		LDS: &LDSCluster{
			Cluster:        LDSName,
			RefreshDelayMs: protoDurationToMS(config.DiscoveryRefreshDelay),
		},
		Admin: Admin{
			AccessLogPath: DefaultAccessLog,
			Address:       fmt.Sprintf("tcp://%s:%d", LocalhostAddress, config.ProxyAdminPort),
		},
		ClusterManager: ClusterManager{
			Clusters: clusters,
			SDS: &DiscoveryCluster{
				Cluster:        buildCluster(config.DiscoveryAddress, SDSName, config.ConnectTimeout),
				RefreshDelayMs: protoDurationToMS(config.DiscoveryRefreshDelay),
			},
			CDS: &DiscoveryCluster{
				Cluster:        buildCluster(config.DiscoveryAddress, CDSName, config.ConnectTimeout),
				RefreshDelayMs: protoDurationToMS(config.DiscoveryRefreshDelay),
			},
		},
		StatsdUDPIPAddress: config.StatsdUdpAddress,
    }
    // 其他相关逻辑  ...
}

Примечательно,istio-proxyОн может работать в различных «ролях» и будет генерировать разные конфигурации в соответствии с разными ролями. Например2.2 节в, какPilotпрокси, его конфигурация такая же, какSidecarразные.

3.2 proxy-init

proxy-initСоответствующее изображениеdocker.io/istio/proxy_init:0.4.0. существует3.1 节, Мы говорим о:istio-proxyОн будет принимать весь tcp-трафик, отправленный в под, и распределять весь tcp-трафик, отправленный из пода, но нам не нужно учитывать это, когда мы на самом деле пишем код, тогдаIstioКак это делается? Ответ черезproxy-init!Конкретный подход: путем инъекцииiptablesПравила, которые переписывают входящий и исходящий трафик пода таким образом, чтобы входящий и исходящий трафик перенаправлялся в подistio-proxyразные порты прослушивания.

Например, правило перенаправления для входящего трафика:

iptables -t nat -N ISTIO_REDIRECT                                             -m comment --comment "istio/redirect-common-chain"
iptables -t nat -A ISTIO_REDIRECT -p tcp -j REDIRECT --to-port ${ENVOY_PORT}  -m comment --comment "istio/redirect-to-envoy-port"
iptables -t nat -A PREROUTING -j ISTIO_REDIRECT                               -m comment --comment "istio/install-istio-prerouting"

4. Резюме

Istio, инфраструктура Service Mesh следующего поколения, еще не доступна для производства, но ее идеи и архитектура заслуживают изучения. Есть надежда, что эта статья будетIstioЗаинтересованные студенты полезны.