介绍

使用 Sidecar 模式部署服务网格时,无需在节点上运行代理(因此您不需要基础结构的协作),但是集群中将运行多个相同的 Sidecar 副本。从另一个角度看:我可以为一组微服务部署到一个服务网格中,你也可以部署一个有特定实现的服务网格。在 Sidecar 部署方式中,你会为每个应用的容器部署一个伴生容器。Sidecar 接管进出应用容器的所有流量。在 Kubernetes 的 Pod 中,在原有的应用容器旁边运行一个 Sidecar 容器,可以理解为两个容器共享存储、网络等资源,可以广义的将这个注入了 Sidecar 容器的 Pod 理解为一台主机,两个容器共享主机资源。

注入容器

注入容器包含两个:init容器和istio-proxy容器

  • Init 容器 istio-init:用于给 Sidecar 容器即 Envoy 代理做初始化,设置 iptables 端口转发
  • Envoy sidecar 容器 istio-proxy:运行 Envoy 代理

Sidecar注入示例分析

bookinfo官方示例

  • bookinfo应用的yaml文件配置:Service、Deployment

  • productpage 容器的 Dockerfile(istio\samples\bookinfo\src\productpage\Dockerfile)

FROM python:2.7-slim

COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

COPY test-requirements.txt ./
RUN pip install --no-cache-dir -r test-requirements.txt

COPY productpage.py /opt/microservices/
COPY tests/unit/* /opt/microservices/
COPY templates /opt/microservices/templates
COPY requirements.txt /opt/microservices/

EXPOSE 9080
WORKDIR /opt/microservices
RUN python -m unittest discover
CMD python productpage.py 9080

Dockerfile 中没有配置 ENTRYPOINT,所以 CMD 的配置 python productpage.py 9080 将作为默认的 ENTRYPOINT

  • 创建productpage并且注入sidecar之后的配置

Service 的配置没有变化,所有的变化都在 Deployment 里。Init 容器 istio-init和Envoy sidecar 容器 istio-proxy。

init容器

介绍

Init 容器与普通的容器非常像,除了如下两点:

* Init 容器总是运行到成功完成为止。

* 每个 Init 容器都必须在下一个 Init 容器启动之前成功完成。

如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 为 Never,它不会重新启动。

如果为一个 Pod 指定了多个 Init 容器,那些容器会按顺序一次运行一个。只有当前面的 Init 容器必须运行成功后,才可以运行下一个 Init 容器。当所有的 Init 容器运行完成后,Kubernetes 才初始化 Pod 和运行应用容器。

解析
  • Istio 在 Pod 中注入的 Init 容器名为 istio-init,们在上面 Istio 注入完成后的 YAML 文件中看到了该容器的启动参数。
-p 15001 -u 1337 -m REDIRECT -i '*' -x "" -b 9080 -d ""
  • 该容器的 Dockerfile 查看 ENTRYPOINT是什么以确定启动时执行的命令。(istio\pilot\docker\Dockerfile.proxy_init)
FROM ubuntu:xenial
RUN apt-get update && apt-get upgrade -y && apt-get install -y \
    iproute2 \
    iptables \
 && rm -rf /var/lib/apt/lists/*

ADD istio-iptables.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/istio-iptables.sh"]
init容器启动入口

istio-init 容器的入口是 /usr/local/bin/istio-iptables.sh,位置在istio\tools\deb\istio-iptables.sh

istio-iptables.sh -p PORT -u UID -g GID [-m mode] [-b ports] [-d ports] [-i CIDR] [-x CIDR] [-h]
  -p: 指定重定向所有 TCP 流量的 Envoy 端口(默认为 $ENVOY_PORT = 15001)
  -u: 指定未应用重定向的用户的 UID。通常,这是代理容器的 UID(默认为 $ENVOY_USER 的 uid,istio_proxy 的 uid 或 1337)
  -g: 指定未应用重定向的用户的 GID。(与 -u param 相同的默认值)
  -m: 指定入站连接重定向到 Envoy 的模式,“REDIRECT” 或 “TPROXY”(默认为 $ISTIO_INBOUND_INTERCEPTION_MODE)
  -b: 逗号分隔的入站端口列表,其流量将重定向到 Envoy(可选)。使用通配符 “*” 表示重定向所有端口。为空时表示禁用所有入站重定向(默认为 $ISTIO_INBOUND_PORTS)
  -d: 指定要从重定向到 Envoy 中排除(可选)的入站端口列表,以逗号格式分隔。使用通配符“*” 表示重定向所有入站流量(默认为 $ISTIO_LOCAL_EXCLUDE_PORTS)
  -i: 指定重定向到 Envoy(可选)的 IP 地址范围,以逗号分隔的 CIDR 格式列表。使用通配符 “*” 表示重定向所有出站流量。空列表将禁用所有出站重定向(默认为 $ISTIO_SERVICE_CIDR)
  -x: 指定将从重定向中排除的 IP 地址范围,以逗号分隔的 CIDR 格式列表。使用通配符 “*” 表示重定向所有出站流量(默认为 $ISTIO_SERVICE_EXCLUDE_CIDR)。

环境变量位于 $ISTIO_SIDECAR_CONFIG(默认在:/var/lib/istio/envoy/sidecar.env)
  • 完整的启动命令
/usr/local/bin/istio-iptables.sh -p 15001 -u 1337 -m REDIRECT -i '*' -x "" -b 9080 -d ""
命令解析
  • 将应用容器的所有流量都转发到 Envoy 的 15001 端口。
  • 使用 istio-proxy 用户身份运行, UID 为 1337,即 Envoy 所处的用户空间,这也是 istio-proxy 容器默认使用的用户,见 YAML 配置中的 runAsUser 字段。
  • 使用默认的 REDIRECT 模式来重定向流量。
  • 将所有出站流量都重定向到 Envoy 代理。
  • 将所有访问 9080 端口(即应用容器 productpage 的端口)的流量重定向到 Envoy 代理。

Init 容器初始化完毕后就会自动终止

istio-proxy容器

Logo

开源、云原生的融合云平台

更多推荐