Kubernetes Egress 流量服务

    这部分内容表明这些访问外部服务的 Kubernetes 机制在 Istio 中依然有效。您只需要配置使用 TLS 模式即可,并不需要 Istio 的双向 TLS。因为外部服务不是 Istio 服务网格的一部分,所以它们无法执行 Istio 的双向 TLS。您在配置 TLS 模式时,一要按照外部服务的 TLS 模式的要求、二要遵从您的工作负载访问外部服务的方式。当您的工作负载发起的是 HTTP 请求但是外部服务需要 TLS,你可以通过 Istio 发起 TLS。当您的工作负载已经使用 TLS 来加密流量,您可以禁用 Istio 的双向 TLS。

    虽然此部分的示例使用 HTTP 协议,但是用于引导出口流量的 Kubernetes 服务也可以与其他协议一起使用。

    • 按照中的说明安装 Istio。

    • 启动 sleep 示例,以获取发送请求的测试源。如果您启用了,运行以下命令部署示例应用程序:

    Zip

    否则,在使用以下命令部署 sleep 应用程序之前,手动注入 sidecar:

    1. $ kubectl apply -f <(istioctl kube-inject -f @samples/sleep/sleep.yaml@)
    • 为了发送请求,您需要创建 SOURCE_POD 环境变量来存储源 pod 的名称:
    1. $ export SOURCE_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
    • 为没有 Istio 控制的源 pod 创建一个命名空间:
    1. $ kubectl create namespace without-istio
    • 启动 sleep 在命名空间 without-istio 中的事例。

    1. $ kubectl apply -f @samples/sleep/sleep.yaml@ -n without-istio
    • 发送请求,创建环境变量 SOURCE_POD_WITHOUT_ISTIO 来保存源 pod 的名称:
    1. $ export SOURCE_POD_WITHOUT_ISTIO=$(kubectl get pod -n without-istio -l app=sleep -o jsonpath={.items..metadata.name})
    • 验证是否未注入 Istio Sidecar,即 pod 中有一个容器:
    1. $ kubectl get pod $SOURCE_POD_WITHOUT_ISTIO -n without-istio
    2. NAME READY STATUS RESTARTS AGE
    3. sleep-66c8d79ff5-8tqrl 1/1 Running 0 32s
    • 在默认命名空间中,为 httpbin.org 创建一个 Kubernetes ExternalName 服务:
    1. $ kubectl apply -f - <<EOF
    2. kind: Service
    3. apiVersion: v1
    4. metadata:
    5. name: my-httpbin
    6. spec:
    7. type: ExternalName
    8. externalName: httpbin.org
    9. ports:
    10. - name: http
    11. protocol: TCP
    12. port: 80
    13. EOF
    • 观察您的服务。注意它没有集群 IP。
    • 从没有 Istio Sidecar 的源 pod 通过 Kubernetes 服务的主机名访问 httpbin.org。注意下面的 curl 命令使用 :<service name>.<namespace>.svc.cluster.local
    1. $ kubectl exec -it $SOURCE_POD_WITHOUT_ISTIO -n without-istio -c sleep -- curl my-httpbin.default.svc.cluster.local/headers
    2. {
    3. "headers": {
    4. "Accept": "*/*",
    5. "Host": "my-httpbin.default.svc.cluster.local",
    6. "User-Agent": "curl/7.55.0"
    7. }
    • 在这个例子中,未加密的 HTTP 请求被发送到 httpbin.org。仅出于示例目的,您禁用 TLS 模式,并允许外部服务的未加密流量。在现实生活中,我们建议由 Istio 执行 Egress TLS 起源
    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: DestinationRule
    4. metadata:
    5. name: my-httpbin
    6. host: my-httpbin.default.svc.cluster.local
    7. trafficPolicy:
    8. tls:
    9. mode: DISABLE
    10. EOF
    • 通过带有 Istio Sidecar 的源 pod 通过 Kubernetes 服务的主机名访问 httpbin.org。注意 Istio Sidecar 添加的 headers,例如, X-Istio-AttributesX-Envoy-Decorator-Operation。另请注意 Host header 等于您的服务的主机名。
    1. $ kubectl exec -it $SOURCE_POD -c sleep -- curl my-httpbin.default.svc.cluster.local/headers
    2. {
    3. "headers": {
    4. "Accept": "*/*",
    5. "Host": "my-httpbin.default.svc.cluster.local",
    6. "User-Agent": "curl/7.55.0",
    7. "X-B3-Sampled": "0",
    8. "X-B3-Spanid": "5b68b3f953945a08",
    9. "X-B3-Traceid": "0847ba2513aa0ffc5b68b3f953945a08",
    10. "X-Envoy-Decorator-Operation": "my-httpbin.default.svc.cluster.local:80/*",
    11. "X-Istio-Attributes": "CigKGGRlc3RpbmF0aW9uLnNlcnZpY2UubmFtZRIMEgpteS1odHRwYmluCioKHWRlc3RpbmF0aW9uLnNlcnZpY2UubmFtZXNwYWNlEgkSB2RlZmF1bHQKOwoKc291cmNlLnVpZBItEitrdWJlcm5ldGVzOi8vc2xlZXAtNjZjOGQ3OWZmNS04aG1neC5kZWZhdWx0CkAKF2Rlc3RpbmF0aW9uLnNlcnZpY2UudWlkEiUSI2lzdGlvOi8vZGVmYXVsdC9zZXJ2aWNlcy9teS1odHRwYmluCkIKGGRlc3RpbmF0aW9uLnNlcnZpY2UuaG9zdBImEiRteS1odHRwYmluLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWw="
    12. }
    13. }
    1. $ kubectl delete destinationrule my-httpbin
    2. $ kubectl delete service my-httpbin
    • 为 Wikipedia 创建没有 selector 的 Kubernetes 服务:
    1. $ kubectl apply -f - <<EOF
    2. kind: Service
    3. apiVersion: v1
    4. metadata:
    5. name: my-wikipedia
    6. spec:
    7. ports:
    8. - protocol: TCP
    9. port: 443
    10. name: tls
    11. EOF
    • 为您的服务创建 endpoints。从 中选择几个 IP。
    1. $ kubectl apply -f - <<EOF
    2. kind: Endpoints
    3. apiVersion: v1
    4. metadata:
    5. subsets:
    6. - addresses:
    7. - ip: 91.198.174.192
    8. ports:
    9. - port: 443
    10. name: tls
    11. EOF
    • 观察您的服务。请注意,它具有一个群集 IP,您可以使用它访问 wikipedia.org
    1. $ kubectl get svc my-wikipedia
    2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
    3. my-wikipedia ClusterIP 172.21.156.230 <none> 443/TCP 21h
    • 从没有 Istio sidecar 的源 Pod 通过您的向您的 Kubernetes 服务集群 IP 来发送 HTTPS 请求到 wikipedia.org。使用 curl—resolve 选项通过集群 IP 访问 wikipedia.org
    • 在这种情况下,工作负载将 HTTPS 请求(开放 TLS 连接)发送到 wikipedia.org。流量已经通过工作负载加密,因此您可以安全地禁用 Istio 的双向 TLS:
    1. $ kubectl apply -f - <<EOF
    2. apiVersion: networking.istio.io/v1alpha3
    3. kind: DestinationRule
    4. metadata:
    5. name: my-wikipedia
    6. spec:
    7. host: my-wikipedia.default.svc.cluster.local
    8. trafficPolicy:
    9. tls:
    10. mode: DISABLE
    11. EOF
    • 使用 Istio Sidecar 从源 Pod 中通过 Kubernetes 服务的群集 IP 访问 wikipedia.org
    1. $ kubectl exec -it $SOURCE_POD -c sleep -- curl -s --resolve en.wikipedia.org:443:$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}') https://en.wikipedia.org/wiki/Main_Page | grep -o "<title>.*</title>"
    2. <title>Wikipedia, the free encyclopedia</title>
    • 检查访问是否确实由群集 IP 完成。在 curl -v 的输出中注意这句话 Connected to en.wikipedia.org (172.21.156.230),其中提到了在您的服务输出中作为群集 IP 打印的 IP。
    1. $ kubectl exec -it $SOURCE_POD -c sleep -- curl -v --resolve en.wikipedia.org:443:$(kubectl get service my-wikipedia -o jsonpath='{.spec.clusterIP}') https://en.wikipedia.org/wiki/Main_Page -o /dev/null
    2. * Added en.wikipedia.org:443:172.21.156.230 to DNS cache
    3. * Hostname en.wikipedia.org was found in DNS cache
    4. * Trying 172.21.156.230...
    5. * TCP_NODELAY set
    6. * Connected to en.wikipedia.org (172.21.156.230) port 443 (#0)
    7. ...

    清理没有 endpoints 的 Kubernetes 服务

    1. $ kubectl delete destinationrule my-wikipedia
    2. $ kubectl delete endpoints my-wikipedia
    3. $ kubectl delete service my-wikipedia
    • 停止服务 :

    Zip

    1. $ kubectl delete -f @samples/sleep/sleep.yaml@
    • 停止命名空间 without-istio 中的服务 :

    Zip

    1. $ kubectl delete -f @samples/sleep/sleep.yaml@ -n without-istio
    • 删除命名空间 without-istio

    管控出口流量的备选方案比较,包括性能因素。

    Istio 中的安全管控出口流量,第二部分

    使用 Istio 的出口流量管控来阻止相关出口流量攻击。

    涉及出口流量攻击和出口流量管控要求。

    评估加入 Egress gateway 对性能造成的影响。

    使用外部 MongoDB 服务

    描述了一个基于 Istio 的 Bookinfo 示例的简单场景。

    描述如何配置 Istio 进行 HTTP Egress 流量监控和访问策略。